Commit 505f48b5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  fib_rules: fix unresolved_rules counting
  r8169: fix wrong eee setting for rlt8111evl
  r8169: fix driver shutdown WoL regression.
  ehea: Change maintainer to me
  pptp: pptp_rcv_core() misses pskb_may_pull() call
  tproxy: copy transparent flag when creating a time wait
  pptp: fix skb leak in pptp_xmit()
  bonding: use local function pointer of bond->recv_probe in bond_handle_frame
  smsc911x: Add support for SMSC LAN89218
  tg3: negate USE_PHYLIB flag check
  netconsole: enable netconsole can make net_device refcnt incorrent
  bluetooth: Properly clone LSM attributes to newly created child connections
  l2tp: fix a potential skb leak in l2tp_xmit_skb()
  bridge: fix hang on removal of bridge via netlink
  x25: Prevent skb overreads when checking call user data
  x25: Handle undersized/fragmented skbs
  x25: Validate incoming call user data lengths
  udplite: fast-path computation of checksum coverage
  IPVS netns shutdown/startup dead-lock
  netfilter: nf_conntrack: fix event flooding in GRE protocol tracker
parents 486cf46f afaef734
......@@ -2460,7 +2460,7 @@ S: Supported
F: drivers/infiniband/hw/ehca/
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
M: Breno Leitao <leitao@linux.vnet.ibm.com>
M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ehea/
......
......@@ -1435,6 +1435,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
void (*recv_probe)(struct sk_buff *, struct bonding *,
struct slave *);
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
......@@ -1448,11 +1450,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
if (bond->recv_probe) {
recv_probe = ACCESS_ONCE(bond->recv_probe);
if (recv_probe) {
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
if (likely(nskb)) {
bond->recv_probe(nskb, bond, slave);
recv_probe(nskb, bond, slave);
dev_kfree_skb(nskb);
}
}
......
......@@ -307,6 +307,11 @@ static ssize_t store_enabled(struct netconsole_target *nt,
return err;
if (enabled < 0 || enabled > 1)
return -EINVAL;
if (enabled == nt->enabled) {
printk(KERN_INFO "netconsole: network logging has already %s\n",
nt->enabled ? "started" : "stopped");
return -EINVAL;
}
if (enabled) { /* 1 */
......
......@@ -285,8 +285,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
ip_send_check(iph);
ip_local_out(skb);
return 1;
tx_error:
kfree_skb(skb);
return 1;
}
......@@ -305,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
}
header = (struct pptp_gre_header *)(skb->data);
headersize = sizeof(*header);
/* test if acknowledgement present */
if (PPTP_GRE_IS_A(header->ver)) {
__u32 ack = (PPTP_GRE_IS_S(header->flags)) ?
header->ack : header->seq; /* ack in different place if S = 0 */
__u32 ack;
if (!pskb_may_pull(skb, headersize))
goto drop;
header = (struct pptp_gre_header *)(skb->data);
/* ack in different place if S = 0 */
ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq;
ack = ntohl(ack);
......@@ -318,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
/* also handle sequence number wrap-around */
if (WRAPPED(ack, opt->ack_recv))
opt->ack_recv = ack;
} else {
headersize -= sizeof(header->ack);
}
/* test if payload present */
if (!PPTP_GRE_IS_S(header->flags))
goto drop;
headersize = sizeof(*header);
payload_len = ntohs(header->payload_len);
seq = ntohl(header->seq);
/* no ack present? */
if (!PPTP_GRE_IS_A(header->ver))
headersize -= sizeof(header->ack);
/* check for incomplete packet (length smaller than expected) */
if (skb->len - headersize < payload_len)
if (!pskb_may_pull(skb, headersize + payload_len))
goto drop;
payload = skb->data + headersize;
......
......@@ -2859,7 +2859,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0004);
rtl_writephy(tp, 0x1f, 0x0007);
rtl_writephy(tp, 0x1e, 0x0020);
rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100);
rtl_w1w0_phy(tp, 0x15, 0x0000, 0x0100);
rtl_writephy(tp, 0x1f, 0x0002);
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x0d, 0x0007);
......@@ -3316,6 +3316,37 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
}
}
static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_29:
case RTL_GIGA_MAC_VER_30:
case RTL_GIGA_MAC_VER_32:
case RTL_GIGA_MAC_VER_33:
case RTL_GIGA_MAC_VER_34:
RTL_W32(RxConfig, RTL_R32(RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
break;
default:
break;
}
}
static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
{
if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
return false;
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, MII_BMCR, 0x0000);
rtl_wol_suspend_quirk(tp);
return true;
}
static void r810x_phy_power_down(struct rtl8169_private *tp)
{
rtl_writephy(tp, 0x1f, 0x0000);
......@@ -3330,18 +3361,8 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
static void r810x_pll_power_down(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, MII_BMCR, 0x0000);
if (tp->mac_version == RTL_GIGA_MAC_VER_29 ||
tp->mac_version == RTL_GIGA_MAC_VER_30)
RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
AcceptMulticast | AcceptMyPhys);
if (rtl_wol_pll_power_down(tp))
return;
}
r810x_phy_power_down(tp);
}
......@@ -3430,17 +3451,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
tp->mac_version == RTL_GIGA_MAC_VER_33)
rtl_ephy_write(ioaddr, 0x19, 0xff64);
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, MII_BMCR, 0x0000);
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
tp->mac_version == RTL_GIGA_MAC_VER_33 ||
tp->mac_version == RTL_GIGA_MAC_VER_34)
RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
AcceptMulticast | AcceptMyPhys);
if (rtl_wol_pll_power_down(tp))
return;
}
r8168_phy_power_down(tp);
......@@ -5788,11 +5800,30 @@ static const struct dev_pm_ops rtl8169_pm_ops = {
#endif /* !CONFIG_PM */
static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
/* WoL fails with 8168b when the receiver is disabled. */
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_11:
case RTL_GIGA_MAC_VER_12:
case RTL_GIGA_MAC_VER_17:
pci_clear_master(tp->pci_dev);
RTL_W8(ChipCmd, CmdRxEnb);
/* PCI commit */
RTL_R8(ChipCmd);
break;
default:
break;
}
}
static void rtl_shutdown(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
rtl8169_net_suspend(dev);
......@@ -5806,16 +5837,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
spin_unlock_irq(&tp->lock);
if (system_state == SYSTEM_POWER_OFF) {
/* WoL fails with 8168b when the receiver is disabled. */
if ((tp->mac_version == RTL_GIGA_MAC_VER_11 ||
tp->mac_version == RTL_GIGA_MAC_VER_12 ||
tp->mac_version == RTL_GIGA_MAC_VER_17) &&
(tp->features & RTL_FEATURE_WOL)) {
pci_clear_master(pdev);
RTL_W8(ChipCmd, CmdRxEnb);
/* PCI commit */
RTL_R8(ChipCmd);
if (__rtl8169_get_wol(tp) & WAKE_ANY) {
rtl_wol_suspend_quirk(tp);
rtl_wol_shutdown_quirk(tp);
}
pci_wake_from_d3(pdev, true);
......
......@@ -26,6 +26,7 @@
* LAN9215, LAN9216, LAN9217, LAN9218
* LAN9210, LAN9211
* LAN9220, LAN9221
* LAN89218
*
*/
......@@ -1983,6 +1984,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
case 0x01170000:
case 0x01160000:
case 0x01150000:
case 0x218A0000:
/* LAN911[5678] family */
pdata->generation = pdata->idrev & 0x0000FFFF;
break;
......
......@@ -15577,7 +15577,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
cancel_work_sync(&tp->reset_task);
if (!tg3_flag(tp, USE_PHYLIB)) {
if (tg3_flag(tp, USE_PHYLIB)) {
tg3_phy_fini(tp);
tg3_mdio_fini(tp);
}
......
......@@ -900,6 +900,7 @@ struct netns_ipvs {
volatile int sync_state;
volatile int master_syncid;
volatile int backup_syncid;
struct mutex sync_mutex;
/* multicast interface name */
char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
......
......@@ -66,40 +66,34 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
return 0;
}
static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
/* Slow-path computation of checksum. Socket is locked. */
static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
{
const struct udp_sock *up = udp_sk(skb->sk);
int cscov = up->len;
__wsum csum = 0;
/*
* Sender has set `partial coverage' option on UDP-Lite socket
*/
if (up->pcflag & UDPLITE_SEND_CC) {
if (up->pcflag & UDPLITE_SEND_CC) {
/*
* Sender has set `partial coverage' option on UDP-Lite socket.
* The special case "up->pcslen == 0" signifies full coverage.
*/
if (up->pcslen < up->len) {
/* up->pcslen == 0 means that full coverage is required,
* partial coverage only if 0 < up->pcslen < up->len */
if (0 < up->pcslen) {
cscov = up->pcslen;
}
uh->len = htons(up->pcslen);
if (0 < up->pcslen)
cscov = up->pcslen;
udp_hdr(skb)->len = htons(up->pcslen);
}
/*
* NOTE: Causes for the error case `up->pcslen > up->len':
* (i) Application error (will not be penalized).
* (ii) Payload too big for send buffer: data is split
* into several packets, each with its own header.
* In this case (e.g. last segment), coverage may
* exceed packet length.
* Since packets with coverage length > packet length are
* illegal, we fall back to the defaults here.
*/
/*
* NOTE: Causes for the error case `up->pcslen > up->len':
* (i) Application error (will not be penalized).
* (ii) Payload too big for send buffer: data is split
* into several packets, each with its own header.
* In this case (e.g. last segment), coverage may
* exceed packet length.
* Since packets with coverage length > packet length are
* illegal, we fall back to the defaults here.
*/
}
return cscov;
}
static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
{
int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
__wsum csum = 0;
skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
......@@ -115,16 +109,21 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
return csum;
}
/* Fast-path computation of checksum. Socket may not be locked. */
static inline __wsum udplite_csum(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
const struct udp_sock *up = udp_sk(skb->sk);
const int off = skb_transport_offset(skb);
const int len = skb->len - off;
int len = skb->len - off;
if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
if (0 < up->pcslen)
len = up->pcslen;
udp_hdr(skb)->len = htons(up->pcslen);
}
skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
return skb_checksum(skb, off, min(cscov, len), 0);
return skb_checksum(skb, off, len, 0);
}
extern void udplite4_register(void);
......
......@@ -26,6 +26,8 @@
/* Bluetooth L2CAP sockets. */
#include <linux/security.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
......@@ -933,6 +935,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
chan->force_reliable = pchan->force_reliable;
chan->flushable = pchan->flushable;
chan->force_active = pchan->force_active;
security_sk_clone(parent, sk);
} else {
switch (sk->sk_type) {
......
......@@ -42,6 +42,7 @@
#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/security.h>
#include <net/sock.h>
#include <asm/system.h>
......@@ -264,6 +265,8 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
pi->sec_level = rfcomm_pi(parent)->sec_level;
pi->role_switch = rfcomm_pi(parent)->role_switch;
security_sk_clone(parent, sk);
} else {
pi->dlc->defer_setup = 0;
......
......@@ -41,6 +41,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/list.h>
#include <linux/security.h>
#include <net/sock.h>
#include <asm/system.h>
......@@ -403,8 +404,10 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
{
BT_DBG("sk %p", sk);
if (parent)
if (parent) {
sk->sk_type = parent->sk_type;
security_sk_clone(parent, sk);
}
}
static struct proto sco_proto = {
......
......@@ -161,9 +161,10 @@ static void del_nbp(struct net_bridge_port *p)
call_rcu(&p->rcu, destroy_nbp_rcu);
}
/* called with RTNL */
static void del_br(struct net_bridge *br, struct list_head *head)
/* Delete bridge device */
void br_dev_delete(struct net_device *dev, struct list_head *head)
{
struct net_bridge *br = netdev_priv(dev);
struct net_bridge_port *p, *n;
list_for_each_entry_safe(p, n, &br->port_list, list) {
......@@ -268,7 +269,7 @@ int br_del_bridge(struct net *net, const char *name)
}
else
del_br(netdev_priv(dev), NULL);
br_dev_delete(dev, NULL);
rtnl_unlock();
return ret;
......@@ -449,7 +450,7 @@ void __net_exit br_net_exit(struct net *net)
rtnl_lock();
for_each_netdev(net, dev)
if (dev->priv_flags & IFF_EBRIDGE)
del_br(netdev_priv(dev), &list);
br_dev_delete(dev, &list);
unregister_netdevice_many(&list);
rtnl_unlock();
......
......@@ -210,6 +210,7 @@ static struct rtnl_link_ops br_link_ops __read_mostly = {
.priv_size = sizeof(struct net_bridge),
.setup = br_dev_setup,
.validate = br_validate,
.dellink = br_dev_delete,
};
int __init br_netlink_init(void)
......
......@@ -294,6 +294,7 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
/* br_device.c */
extern void br_dev_setup(struct net_device *dev);
extern void br_dev_delete(struct net_device *dev, struct list_head *list);
extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
struct net_device *dev);
#ifdef CONFIG_NET_POLL_CONTROLLER
......
......@@ -475,8 +475,11 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
list_del_rcu(&rule->list);
if (rule->action == FR_ACT_GOTO)
if (rule->action == FR_ACT_GOTO) {
ops->nr_goto_rules--;
if (rtnl_dereference(rule->ctarget) == NULL)
ops->unresolved_rules--;
}
/*
* Check if this rule is a target to any of them. If so,
......
......@@ -328,6 +328,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
tw->tw_transparent = inet_sk(sk)->transparent;
tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale;
tcptw->tw_rcv_nxt = tp->rcv_nxt;
tcptw->tw_snd_nxt = tp->snd_nxt;
......
......@@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
headroom = NET_SKB_PAD + sizeof(struct iphdr) +
uhlen + hdr_len;
old_headroom = skb_headroom(skb);
if (skb_cow_head(skb, headroom))
if (skb_cow_head(skb, headroom)) {
dev_kfree_skb(skb);
goto abort;
}
new_headroom = skb_headroom(skb);
skb_orphan(skb);
......
......@@ -2283,6 +2283,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
struct ip_vs_service *svc;
struct ip_vs_dest_user *udest_compat;
struct ip_vs_dest_user_kern udest;
struct netns_ipvs *ipvs = net_ipvs(net);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
......@@ -2303,6 +2304,24 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
/* increase the module use count */
ip_vs_use_count_inc();
/* Handle daemons since they have another lock */
if (cmd == IP_VS_SO_SET_STARTDAEMON ||
cmd == IP_VS_SO_SET_STOPDAEMON) {
struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
if (mutex_lock_interruptible(&ipvs->sync_mutex)) {
ret = -ERESTARTSYS;
goto out_dec;
}
if (cmd == IP_VS_SO_SET_STARTDAEMON)
ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
dm->syncid);
else
ret = stop_sync_thread(net, dm->state);
mutex_unlock(&ipvs->sync_mutex);
goto out_dec;
}
if (mutex_lock_interruptible(&__ip_vs_mutex)) {
ret = -ERESTARTSYS;
goto out_dec;
......@@ -2316,15 +2335,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
/* Set timeout values for (tcp tcpfin udp) */
ret = ip_vs_set_timeout(net, (struct ip_vs_timeout_user *)arg);
goto out_unlock;
} else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
dm->syncid);
goto out_unlock;
} else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
ret = stop_sync_thread(net, dm->state);
goto out_unlock;
}
usvc_compat = (struct ip_vs_service_user *)arg;
......@@ -2584,6 +2594,33 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
if (copy_from_user(arg, user, copylen) != 0)
return -EFAULT;
/*
* Handle daemons first since it has its own locking
*/
if (cmd == IP_VS_SO_GET_DAEMON) {
struct ip_vs_daemon_user d[2];
memset(&d, 0, sizeof(d));
if (mutex_lock_interruptible(&ipvs->sync_mutex))
return -ERESTARTSYS;
if (ipvs->sync_state & IP_VS_STATE_MASTER) {
d[0].state = IP_VS_STATE_MASTER;
strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
sizeof(d[0].mcast_ifn));
d[0].syncid = ipvs->master_syncid;
}
if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
d[1].state = IP_VS_STATE_BACKUP;
strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
sizeof(d[1].mcast_ifn));
d[1].syncid = ipvs->backup_syncid;
}
if (copy_to_user(user, &d, sizeof(d)) != 0)
ret = -EFAULT;
mutex_unlock(&ipvs->sync_mutex);
return ret;
}
if (mutex_lock_interruptible(&__ip_vs_mutex))
return -ERESTARTSYS;
......@@ -2681,28 +2718,6 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
}
break;
case IP_VS_SO_GET_DAEMON:
{
struct ip_vs_daemon_user d[2];
memset(&d, 0, sizeof(d));
if (ipvs->sync_state & IP_VS_STATE_MASTER) {
d[0].state = IP_VS_STATE_MASTER;
strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
sizeof(d[0].mcast_ifn));
d[0].syncid = ipvs->master_syncid;
}
if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
d[1].state = IP_VS_STATE_BACKUP;
strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
sizeof(d[1].mcast_ifn));
d[1].syncid = ipvs->backup_syncid;
}
if (copy_to_user(user, &d, sizeof(d)) != 0)
ret = -EFAULT;
}
break;