Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
Pull networking fixes from David Miller:
 "Things seem to be settling down as far as networking is concerned,
  let's hope this trend continues...

   1) Add iov_iter_revert() and use it to fix the behavior of
      skb_copy_datagram_msg() et al., from Al Viro.

   2) Fix the protocol used in the synthetic SKB we cons up for the
      purposes of doing a simulated route lookup for RTM_GETROUTE
      requests. From Florian Larysch.

   3) Don't add noop_qdisc to the per-device qdisc hashes, from Cong
      Wang.

   4) Don't call netdev_change_features with the team lock held, from
      Xin Long.

   5) Revert TCP F-RTO extension to catch more spurious timeouts because
      it interacts very badly with some middle-boxes. From Yuchung
      Cheng.

   6) Fix the loss of error values in l2tp {s,g}etsockopt calls, from
      Guillaume Nault.

   7) ctnetlink uses bit positions where it should be using bit masks,
      fix from Liping Zhang.

   8) Missing RCU locking in netfilter helper code, from Gao Feng.

   9) Avoid double frees and use-after-frees in tcp_disconnect(), from
      Eric Dumazet.

  10) Don't do a changelink before we register the netdevice in
      bridging, from Ido Schimmel.

  11) Lock the ipv6 device address list properly, from Rabin Vincent"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (29 commits)
  netfilter: ipt_CLUSTERIP: Fix wrong conntrack netns refcnt usage
  netfilter: nft_hash: do not dump the auto generated seed
  drivers: net: usb: qmi_wwan: add QMI_QUIRK_SET_DTR for Telit PID 0x1201
  ipv6: Fix idev->addr_list corruption
  net: xdp: don't export dev_change_xdp_fd()
  bridge: netlink: register netdevice before executing changelink
  bridge: implement missing ndo_uninit()
  bpf: reference may_access_skb() from __bpf_prog_run()
  tcp: clear saved_syn in tcp_disconnect()
  netfilter: nf_ct_expect: use proper RCU list traversal/update APIs
  netfilter: ctnetlink: skip dumping expect when nfct_help(ct) is NULL
  netfilter: make it safer during the inet6_dev->addr_list traversal
  netfilter: ctnetlink: make it safer when checking the ct helper name
  netfilter: helper: Add the rcu lock when call __nf_conntrack_helper_find
  netfilter: ctnetlink: using bit to represent the ct event
  netfilter: xt_TCPMSS: add more sanity tests on tcph->doff
  net: tcp: Increase TCP_MIB_OUTRSTS even though fail to alloc skb
  l2tp: don't mask errors in pppol2tp_getsockopt()
  l2tp: don't mask errors in pppol2tp_setsockopt()
  tcp: restrict F-RTO to work-around broken middle-boxes
  ...
  • Loading branch information
Linus Torvalds committed Apr 15, 2017
2 parents 9117439 + f4c13c8 commit 7e703ec
Show file tree
Hide file tree
Showing 31 changed files with 238 additions and 91 deletions.
2 changes: 1 addition & 1 deletion drivers/net/can/ifi_canfd/ifi_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
int work_done = 0;

u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD);
u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);

/* Handle bus state changes */
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/can/rcar/rcar_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,8 +826,7 @@ static int rcar_can_probe(struct platform_device *pdev)

devm_can_led_init(ndev);

dev_info(&pdev->dev, "device registered (regs @ %p, IRQ%d)\n",
priv->regs, ndev->irq);
dev_info(&pdev->dev, "device registered (IRQ%d)\n", ndev->irq);

return 0;
fail_candev:
Expand Down
19 changes: 11 additions & 8 deletions drivers/net/team/team.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ static void team_port_disable(struct team *team,
#define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_RXCSUM | NETIF_F_ALL_TSO)

static void ___team_compute_features(struct team *team)
static void __team_compute_features(struct team *team)
{
struct team_port *port;
u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
Expand Down Expand Up @@ -1023,16 +1023,10 @@ static void ___team_compute_features(struct team *team)
team->dev->priv_flags |= IFF_XMIT_DST_RELEASE;
}

static void __team_compute_features(struct team *team)
{
___team_compute_features(team);
netdev_change_features(team->dev);
}

static void team_compute_features(struct team *team)
{
mutex_lock(&team->lock);
___team_compute_features(team);
__team_compute_features(team);
mutex_unlock(&team->lock);
netdev_change_features(team->dev);
}
Expand Down Expand Up @@ -1641,6 +1635,7 @@ static void team_uninit(struct net_device *dev)
team_notify_peers_fini(team);
team_queue_override_fini(team);
mutex_unlock(&team->lock);
netdev_change_features(dev);
}

static void team_destructor(struct net_device *dev)
Expand Down Expand Up @@ -1928,6 +1923,10 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev)
mutex_lock(&team->lock);
err = team_port_add(team, port_dev);
mutex_unlock(&team->lock);

if (!err)
netdev_change_features(dev);

return err;
}

Expand All @@ -1939,6 +1938,10 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
mutex_lock(&team->lock);
err = team_port_del(team, port_dev);
mutex_unlock(&team->lock);

if (!err)
netdev_change_features(dev);

return err;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/usb/qmi_wwan.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */
{QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
{QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
Expand Down
19 changes: 15 additions & 4 deletions drivers/net/usb/usbnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,7 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
" value=0x%04x index=0x%04x size=%d\n",
cmd, reqtype, value, index, size);

if (data) {
if (size) {
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
goto out;
Expand All @@ -1938,8 +1938,13 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
err = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
cmd, reqtype, value, index, buf, size,
USB_CTRL_GET_TIMEOUT);
if (err > 0 && err <= size)
memcpy(data, buf, err);
if (err > 0 && err <= size) {
if (data)
memcpy(data, buf, err);
else
netdev_dbg(dev->net,
"Huh? Data requested but thrown away.\n");
}
kfree(buf);
out:
return err;
Expand All @@ -1960,7 +1965,13 @@ static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
buf = kmemdup(data, size, GFP_KERNEL);
if (!buf)
goto out;
}
} else {
if (size) {
WARN_ON_ONCE(1);
err = -EINVAL;
goto out;
}
}

err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
cmd, reqtype, value, index, buf, size,
Expand Down
6 changes: 5 additions & 1 deletion include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ struct iov_iter {
};
union {
unsigned long nr_segs;
int idx;
struct {
int idx;
int start_idx;
};
};
};

Expand Down Expand Up @@ -81,6 +84,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
size_t iov_iter_copy_from_user_atomic(struct page *page,
struct iov_iter *i, unsigned long offset, size_t bytes);
void iov_iter_advance(struct iov_iter *i, size_t bytes);
void iov_iter_revert(struct iov_iter *i, size_t bytes);
int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
size_t iov_iter_single_seg_count(const struct iov_iter *i);
size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
Expand Down
12 changes: 6 additions & 6 deletions kernel/bpf/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,12 +1162,12 @@ static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn)
LD_ABS_W: /* BPF_R0 = ntohl(*(u32 *) (skb->data + imm32)) */
off = IMM;
load_word:
/* BPF_LD + BPD_ABS and BPF_LD + BPF_IND insns are
* only appearing in the programs where ctx ==
* skb. All programs keep 'ctx' in regs[BPF_REG_CTX]
* == BPF_R6, bpf_convert_filter() saves it in BPF_R6,
* internal BPF verifier will check that BPF_R6 ==
* ctx.
/* BPF_LD + BPD_ABS and BPF_LD + BPF_IND insns are only
* appearing in the programs where ctx == skb
* (see may_access_skb() in the verifier). All programs
* keep 'ctx' in regs[BPF_REG_CTX] == BPF_R6,
* bpf_convert_filter() saves it in BPF_R6, internal BPF
* verifier will check that BPF_R6 == ctx.
*
* BPF_ABS and BPF_IND are wrappers of function calls,
* so they scratch BPF_R1-BPF_R5 registers, preserve
Expand Down
63 changes: 63 additions & 0 deletions lib/iov_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,68 @@ void iov_iter_advance(struct iov_iter *i, size_t size)
}
EXPORT_SYMBOL(iov_iter_advance);

void iov_iter_revert(struct iov_iter *i, size_t unroll)
{
if (!unroll)
return;
i->count += unroll;
if (unlikely(i->type & ITER_PIPE)) {
struct pipe_inode_info *pipe = i->pipe;
int idx = i->idx;
size_t off = i->iov_offset;
while (1) {
size_t n = off - pipe->bufs[idx].offset;
if (unroll < n) {
off -= (n - unroll);
break;
}
unroll -= n;
if (!unroll && idx == i->start_idx) {
off = 0;
break;
}
if (!idx--)
idx = pipe->buffers - 1;
off = pipe->bufs[idx].offset + pipe->bufs[idx].len;
}
i->iov_offset = off;
i->idx = idx;
pipe_truncate(i);
return;
}
if (unroll <= i->iov_offset) {
i->iov_offset -= unroll;
return;
}
unroll -= i->iov_offset;
if (i->type & ITER_BVEC) {
const struct bio_vec *bvec = i->bvec;
while (1) {
size_t n = (--bvec)->bv_len;
i->nr_segs++;
if (unroll <= n) {
i->bvec = bvec;
i->iov_offset = n - unroll;
return;
}
unroll -= n;
}
} else { /* same logics for iovec and kvec */
const struct iovec *iov = i->iov;
while (1) {
size_t n = (--iov)->iov_len;
i->nr_segs++;
if (unroll <= n) {
i->iov = iov;
i->iov_offset = n - unroll;
return;
}
unroll -= n;
}
}
}
EXPORT_SYMBOL(iov_iter_revert);

/*
* Return the count of just the current iov_iter segment.
*/
Expand Down Expand Up @@ -839,6 +901,7 @@ void iov_iter_pipe(struct iov_iter *i, int direction,
i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
i->iov_offset = 0;
i->count = count;
i->start_idx = i->idx;
}
EXPORT_SYMBOL(iov_iter_pipe);

Expand Down
20 changes: 11 additions & 9 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ static int br_dev_init(struct net_device *dev)
return err;
}

static void br_dev_uninit(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);

br_multicast_uninit_stats(br);
br_vlan_flush(br);
free_percpu(br->stats);
}

static int br_dev_open(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
Expand Down Expand Up @@ -332,6 +341,7 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_open = br_dev_open,
.ndo_stop = br_dev_stop,
.ndo_init = br_dev_init,
.ndo_uninit = br_dev_uninit,
.ndo_start_xmit = br_dev_xmit,
.ndo_get_stats64 = br_get_stats64,
.ndo_set_mac_address = br_set_mac_address,
Expand All @@ -356,14 +366,6 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_features_check = passthru_features_check,
};

static void br_dev_free(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);

free_percpu(br->stats);
free_netdev(dev);
}

static struct device_type br_type = {
.name = "bridge",
};
Expand All @@ -376,7 +378,7 @@ void br_dev_setup(struct net_device *dev)
ether_setup(dev);

dev->netdev_ops = &br_netdev_ops;
dev->destructor = br_dev_free;
dev->destructor = free_netdev;
dev->ethtool_ops = &br_ethtool_ops;
SET_NETDEV_DEVTYPE(dev, &br_type);
dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
Expand Down
1 change: 0 additions & 1 deletion net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)

br_fdb_delete_by_port(br, NULL, 0, 1);

br_vlan_flush(br);
br_multicast_dev_del(br);
cancel_delayed_work_sync(&br->gc_work);

Expand Down
7 changes: 5 additions & 2 deletions net/bridge/br_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -2031,8 +2031,6 @@ void br_multicast_dev_del(struct net_bridge *br)

out:
spin_unlock_bh(&br->multicast_lock);

free_percpu(br->mcast_stats);
}

int br_multicast_set_router(struct net_bridge *br, unsigned long val)
Expand Down Expand Up @@ -2531,6 +2529,11 @@ int br_multicast_init_stats(struct net_bridge *br)
return 0;
}

void br_multicast_uninit_stats(struct net_bridge *br)
{
free_percpu(br->mcast_stats);
}

static void mcast_stats_add_dir(u64 *dst, u64 *src)
{
dst[BR_MCAST_DIR_RX] += src[BR_MCAST_DIR_RX];
Expand Down
7 changes: 5 additions & 2 deletions net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,14 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev,
spin_unlock_bh(&br->lock);
}

err = br_changelink(dev, tb, data);
err = register_netdevice(dev);
if (err)
return err;

return register_netdevice(dev);
err = br_changelink(dev, tb, data);
if (err)
unregister_netdevice(dev);
return err;
}

static size_t br_get_size(const struct net_device *brdev)
Expand Down
5 changes: 5 additions & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p,
const struct sk_buff *skb, u8 type, u8 dir);
int br_multicast_init_stats(struct net_bridge *br);
void br_multicast_uninit_stats(struct net_bridge *br);
void br_multicast_get_stats(const struct net_bridge *br,
const struct net_bridge_port *p,
struct br_mcast_stats *dest);
Expand Down Expand Up @@ -760,6 +761,10 @@ static inline int br_multicast_init_stats(struct net_bridge *br)
return 0;
}

static inline void br_multicast_uninit_stats(struct net_bridge *br)
{
}

static inline int br_multicast_igmp_type(const struct sk_buff *skb)
{
return 0;
Expand Down
Loading

0 comments on commit 7e703ec

Please sign in to comment.