mirror of https://gitee.com/openkylin/linux.git
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix memory leaks and other issues in mwifiex driver, from Amitkumar Karwar. 2) skb_segment() can choke on packets using frag lists, fix from Herbert Xu with help from Eric Dumazet and others. 3) IPv4 output cached route instantiation properly handles races involving two threads trying to install the same route, but we forgot to propagate this logic to input routes as well. Fix from Alexei Starovoitov. 4) Put protections in place to make sure that recvmsg() paths never accidently copy uninitialized memory back into userspace and also make sure that we never try to use more that sockaddr_storage for building the on-kernel-stack copy of a sockaddr. Fixes from Hannes Frederic Sowa. 5) R8152 driver transmit flow bug fixes from Hayes Wang. 6) Fix some minor fallouts from genetlink changes, from Johannes Berg and Michael Opdenacker. 7) AF_PACKET sendmsg path can race with netdevice unregister notifier, fix by using RCU to make sure the network device doesn't go away from under us. Fix from Daniel Borkmann. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (43 commits) gso: handle new frag_list of frags GRO packets genetlink: fix genl_set_err() group ID genetlink: fix genlmsg_multicast() bug packet: fix use after free race in send path when dev is released xen-netback: stop the VIF thread before unbinding IRQs wimax: remove dead code net/phy: Add the autocross feature for forced links on VSC82x4 net/phy: Add VSC8662 support net/phy: Add VSC8574 support net/phy: Add VSC8234 support net: add BUG_ON if kernel advertises msg_namelen > sizeof(struct sockaddr_storage) net: rework recvmsg handler msg_name and msg_namelen logic bridge: flush br's address entry in fdb when remove the net: core: Always propagate flag changes to interfaces ipv4: fix race in concurrent ip_route_input_slow() r8152: fix incorrect type in assignment r8152: support stopping/waking tx queue r8152: modify the tx flow r8152: fix tx/rx memory overflow netfilter: ebt_ip6: fix source and destination matching ...
This commit is contained in:
commit
d2c2ad54c4
|
@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
|
|||
else if (len < ds)
|
||||
msg->msg_flags |= MSG_TRUNC;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
lock_sock(sk);
|
||||
if (ctx->more) {
|
||||
ctx->more = 0;
|
||||
|
|
|
@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
|
|||
long copied = 0;
|
||||
|
||||
lock_sock(sk);
|
||||
msg->msg_namelen = 0;
|
||||
for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
|
||||
iovlen--, iov++) {
|
||||
unsigned long seglen = iov->iov_len;
|
||||
|
|
|
@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
struct sock *sk = sock->sk;
|
||||
struct sockaddr_mISDN *maddr;
|
||||
|
||||
int copied, err;
|
||||
|
||||
|
@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (!skb)
|
||||
return err;
|
||||
|
||||
if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
|
||||
msg->msg_namelen = sizeof(struct sockaddr_mISDN);
|
||||
maddr = (struct sockaddr_mISDN *)msg->msg_name;
|
||||
if (msg->msg_name) {
|
||||
struct sockaddr_mISDN *maddr = msg->msg_name;
|
||||
|
||||
maddr->family = AF_ISDN;
|
||||
maddr->dev = _pms(sk)->dev->id;
|
||||
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
|
||||
|
@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
maddr->sapi = _pms(sk)->ch.addr & 0xFF;
|
||||
maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
|
||||
}
|
||||
} else {
|
||||
if (msg->msg_namelen)
|
||||
printk(KERN_WARNING "%s: too small namelen %d\n",
|
||||
__func__, msg->msg_namelen);
|
||||
msg->msg_namelen = 0;
|
||||
msg->msg_namelen = sizeof(*maddr);
|
||||
}
|
||||
|
||||
copied = skb->len + MISDN_HEADER_LEN;
|
||||
|
|
|
@ -697,7 +697,7 @@ static int genphy_config_advert(struct phy_device *phydev)
|
|||
* to the values in phydev. Assumes that the values are valid.
|
||||
* Please see phy_sanitize_settings().
|
||||
*/
|
||||
static int genphy_setup_forced(struct phy_device *phydev)
|
||||
int genphy_setup_forced(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
int ctl = 0;
|
||||
|
@ -716,7 +716,7 @@ static int genphy_setup_forced(struct phy_device *phydev)
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(genphy_setup_forced);
|
||||
|
||||
/**
|
||||
* genphy_restart_aneg - Enable and Restart Autonegotiation
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Author: Kriston Carson
|
||||
*
|
||||
* Copyright (c) 2005, 2009 Freescale Semiconductor, Inc.
|
||||
* Copyright (c) 2005, 2009, 2011 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -18,6 +18,11 @@
|
|||
#include <linux/ethtool.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
/* Vitesse Extended Page Magic Register(s) */
|
||||
#define MII_VSC82X4_EXT_PAGE_16E 0x10
|
||||
#define MII_VSC82X4_EXT_PAGE_17E 0x11
|
||||
#define MII_VSC82X4_EXT_PAGE_18E 0x12
|
||||
|
||||
/* Vitesse Extended Control Register 1 */
|
||||
#define MII_VSC8244_EXT_CON1 0x17
|
||||
#define MII_VSC8244_EXTCON1_INIT 0x0000
|
||||
|
@ -54,7 +59,13 @@
|
|||
#define MII_VSC8221_AUXCONSTAT_INIT 0x0004 /* need to set this bit? */
|
||||
#define MII_VSC8221_AUXCONSTAT_RESERVED 0x0004
|
||||
|
||||
/* Vitesse Extended Page Access Register */
|
||||
#define MII_VSC82X4_EXT_PAGE_ACCESS 0x1f
|
||||
|
||||
#define PHY_ID_VSC8234 0x000fc620
|
||||
#define PHY_ID_VSC8244 0x000fc6c0
|
||||
#define PHY_ID_VSC8574 0x000704a0
|
||||
#define PHY_ID_VSC8662 0x00070660
|
||||
#define PHY_ID_VSC8221 0x000fc550
|
||||
#define PHY_ID_VSC8211 0x000fc4b0
|
||||
|
||||
|
@ -118,7 +129,9 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
|
|||
|
||||
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
||||
err = phy_write(phydev, MII_VSC8244_IMASK,
|
||||
phydev->drv->phy_id == PHY_ID_VSC8244 ?
|
||||
(phydev->drv->phy_id == PHY_ID_VSC8234 ||
|
||||
phydev->drv->phy_id == PHY_ID_VSC8244 ||
|
||||
phydev->drv->phy_id == PHY_ID_VSC8574) ?
|
||||
MII_VSC8244_IMASK_MASK :
|
||||
MII_VSC8221_IMASK_MASK);
|
||||
else {
|
||||
|
@ -149,16 +162,109 @@ static int vsc8221_config_init(struct phy_device *phydev)
|
|||
*/
|
||||
}
|
||||
|
||||
/* Vitesse 824x */
|
||||
/* vsc82x4_config_autocross_enable - Enable auto MDI/MDI-X for forced links
|
||||
* @phydev: target phy_device struct
|
||||
*
|
||||
* Enable auto MDI/MDI-X when in 10/100 forced link speeds by writing
|
||||
* special values in the VSC8234/VSC8244 extended reserved registers
|
||||
*/
|
||||
static int vsc82x4_config_autocross_enable(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed > SPEED_100)
|
||||
return 0;
|
||||
|
||||
/* map extended registers set 0x10 - 0x1e */
|
||||
ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x52b5);
|
||||
if (ret >= 0)
|
||||
ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_18E, 0x0012);
|
||||
if (ret >= 0)
|
||||
ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_17E, 0x2803);
|
||||
if (ret >= 0)
|
||||
ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_16E, 0x87fa);
|
||||
/* map standard registers set 0x10 - 0x1e */
|
||||
if (ret >= 0)
|
||||
ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
|
||||
else
|
||||
phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vsc82x4_config_aneg - restart auto-negotiation or write BMCR
|
||||
* @phydev: target phy_device struct
|
||||
*
|
||||
* Description: If auto-negotiation is enabled, we configure the
|
||||
* advertising, and then restart auto-negotiation. If it is not
|
||||
* enabled, then we write the BMCR and also start the auto
|
||||
* MDI/MDI-X feature
|
||||
*/
|
||||
static int vsc82x4_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Enable auto MDI/MDI-X when in 10/100 forced link speeds by
|
||||
* writing special values in the VSC8234 extended reserved registers
|
||||
*/
|
||||
if (phydev->autoneg != AUTONEG_ENABLE && phydev->speed <= SPEED_100) {
|
||||
ret = genphy_setup_forced(phydev);
|
||||
|
||||
if (ret < 0) /* error */
|
||||
return ret;
|
||||
|
||||
return vsc82x4_config_autocross_enable(phydev);
|
||||
}
|
||||
|
||||
return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
/* Vitesse 82xx */
|
||||
static struct phy_driver vsc82xx_driver[] = {
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8234,
|
||||
.name = "Vitesse VSC8234",
|
||||
.phy_id_mask = 0x000ffff0,
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &vsc824x_config_init,
|
||||
.config_aneg = &vsc82x4_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8244,
|
||||
.name = "Vitesse VSC8244",
|
||||
.phy_id_mask = 0x000fffc0,
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &vsc824x_config_init,
|
||||
.config_aneg = &genphy_config_aneg,
|
||||
.config_aneg = &vsc82x4_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8574,
|
||||
.name = "Vitesse VSC8574",
|
||||
.phy_id_mask = 0x000ffff0,
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &vsc824x_config_init,
|
||||
.config_aneg = &vsc82x4_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
.driver = { .owner = THIS_MODULE,},
|
||||
}, {
|
||||
.phy_id = PHY_ID_VSC8662,
|
||||
.name = "Vitesse VSC8662",
|
||||
.phy_id_mask = 0x000ffff0,
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &vsc824x_config_init,
|
||||
.config_aneg = &vsc82x4_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &vsc824x_ack_interrupt,
|
||||
.config_intr = &vsc82xx_config_intr,
|
||||
|
@ -207,7 +313,10 @@ module_init(vsc82xx_init);
|
|||
module_exit(vsc82xx_exit);
|
||||
|
||||
static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
|
||||
{ PHY_ID_VSC8234, 0x000ffff0 },
|
||||
{ PHY_ID_VSC8244, 0x000fffc0 },
|
||||
{ PHY_ID_VSC8574, 0x000ffff0 },
|
||||
{ PHY_ID_VSC8662, 0x000ffff0 },
|
||||
{ PHY_ID_VSC8221, 0x000ffff0 },
|
||||
{ PHY_ID_VSC8211, 0x000ffff0 },
|
||||
{ }
|
||||
|
|
|
@ -979,8 +979,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (error < 0)
|
||||
goto end;
|
||||
|
||||
m->msg_namelen = 0;
|
||||
|
||||
if (skb) {
|
||||
total_len = min_t(size_t, total_len, skb->len);
|
||||
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/ipv6.h>
|
||||
|
||||
/* Version Information */
|
||||
#define DRIVER_VERSION "v1.01.0 (2013/08/12)"
|
||||
#define DRIVER_VERSION "v1.02.0 (2013/10/28)"
|
||||
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
|
||||
#define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters"
|
||||
#define MODULENAME "r8152"
|
||||
|
@ -307,22 +307,22 @@ enum rtl8152_flags {
|
|||
#define MCU_TYPE_USB 0x0000
|
||||
|
||||
struct rx_desc {
|
||||
u32 opts1;
|
||||
__le32 opts1;
|
||||
#define RX_LEN_MASK 0x7fff
|
||||
u32 opts2;
|
||||
u32 opts3;
|
||||
u32 opts4;
|
||||
u32 opts5;
|
||||
u32 opts6;
|
||||
__le32 opts2;
|
||||
__le32 opts3;
|
||||
__le32 opts4;
|
||||
__le32 opts5;
|
||||
__le32 opts6;
|
||||
};
|
||||
|
||||
struct tx_desc {
|
||||
u32 opts1;
|
||||
__le32 opts1;
|
||||
#define TX_FS (1 << 31) /* First segment of a packet */
|
||||
#define TX_LS (1 << 30) /* Final segment of a packet */
|
||||
#define TX_LEN_MASK 0x3ffff
|
||||
|
||||
u32 opts2;
|
||||
__le32 opts2;
|
||||
#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */
|
||||
#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */
|
||||
#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */
|
||||
|
@ -365,6 +365,7 @@ struct r8152 {
|
|||
struct mii_if_info mii;
|
||||
int intr_interval;
|
||||
u32 msg_enable;
|
||||
u32 tx_qlen;
|
||||
u16 ocp_base;
|
||||
u8 *intr_buff;
|
||||
u8 version;
|
||||
|
@ -876,7 +877,7 @@ static void write_bulk_callback(struct urb *urb)
|
|||
static void intr_callback(struct urb *urb)
|
||||
{
|
||||
struct r8152 *tp;
|
||||
__u16 *d;
|
||||
__le16 *d;
|
||||
int status = urb->status;
|
||||
int res;
|
||||
|
||||
|
@ -1136,14 +1137,14 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
|
|||
|
||||
static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
|
||||
{
|
||||
u32 remain;
|
||||
int remain;
|
||||
u8 *tx_data;
|
||||
|
||||
tx_data = agg->head;
|
||||
agg->skb_num = agg->skb_len = 0;
|
||||
remain = rx_buf_sz - sizeof(struct tx_desc);
|
||||
remain = rx_buf_sz;
|
||||
|
||||
while (remain >= ETH_ZLEN) {
|
||||
while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) {
|
||||
struct tx_desc *tx_desc;
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
@ -1152,12 +1153,14 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
|
|||
if (!skb)
|
||||
break;
|
||||
|
||||
remain -= sizeof(*tx_desc);
|
||||
len = skb->len;
|
||||
if (remain < len) {
|
||||
skb_queue_head(&tp->tx_queue, skb);
|
||||
break;
|
||||
}
|
||||
|
||||
tx_data = tx_agg_align(tx_data);
|
||||
tx_desc = (struct tx_desc *)tx_data;
|
||||
tx_data += sizeof(*tx_desc);
|
||||
|
||||
|
@ -1167,11 +1170,18 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
|
|||
agg->skb_len += len;
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
tx_data = tx_agg_align(tx_data + len);
|
||||
remain = rx_buf_sz - sizeof(*tx_desc) -
|
||||
(u32)((void *)tx_data - agg->head);
|
||||
tx_data += len;
|
||||
remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
|
||||
}
|
||||
|
||||
netif_tx_lock(tp->netdev);
|
||||
|
||||
if (netif_queue_stopped(tp->netdev) &&
|
||||
skb_queue_len(&tp->tx_queue) < tp->tx_qlen)
|
||||
netif_wake_queue(tp->netdev);
|
||||
|
||||
netif_tx_unlock(tp->netdev);
|
||||
|
||||
usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
|
||||
agg->head, (int)(tx_data - (u8 *)agg->head),
|
||||
(usb_complete_t)write_bulk_callback, agg);
|
||||
|
@ -1188,7 +1198,6 @@ static void rx_bottom(struct r8152 *tp)
|
|||
list_for_each_safe(cursor, next, &tp->rx_done) {
|
||||
struct rx_desc *rx_desc;
|
||||
struct rx_agg *agg;
|
||||
unsigned pkt_len;
|
||||
int len_used = 0;
|
||||
struct urb *urb;
|
||||
u8 *rx_data;
|
||||
|
@ -1204,17 +1213,22 @@ static void rx_bottom(struct r8152 *tp)
|
|||
|
||||
rx_desc = agg->head;
|
||||
rx_data = agg->head;
|
||||
pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
|
||||
len_used += sizeof(struct rx_desc) + pkt_len;
|
||||
len_used += sizeof(struct rx_desc);
|
||||
|
||||
while (urb->actual_length >= len_used) {
|
||||
while (urb->actual_length > len_used) {
|
||||
struct net_device *netdev = tp->netdev;
|
||||
struct net_device_stats *stats;
|
||||
unsigned int pkt_len;
|
||||
struct sk_buff *skb;
|
||||
|
||||
pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
|
||||
if (pkt_len < ETH_ZLEN)
|
||||
break;
|
||||
|
||||
len_used += pkt_len;
|
||||
if (urb->actual_length < len_used)
|
||||
break;
|
||||
|
||||
stats = rtl8152_get_stats(netdev);
|
||||
|
||||
pkt_len -= 4; /* CRC */
|
||||
|
@ -1234,9 +1248,8 @@ static void rx_bottom(struct r8152 *tp)
|
|||
|
||||
rx_data = rx_agg_align(rx_data + pkt_len + 4);
|
||||
rx_desc = (struct rx_desc *)rx_data;
|
||||
pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
|
||||
len_used = (int)(rx_data - (u8 *)agg->head);
|
||||
len_used += sizeof(struct rx_desc) + pkt_len;
|
||||
len_used += sizeof(struct rx_desc);
|
||||
}
|
||||
|
||||
submit:
|
||||
|
@ -1384,53 +1397,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
|
|||
struct net_device *netdev)
|
||||
{
|
||||
struct r8152 *tp = netdev_priv(netdev);
|
||||
struct net_device_stats *stats = rtl8152_get_stats(netdev);
|
||||
unsigned long flags;
|
||||
struct tx_agg *agg = NULL;
|
||||
struct tx_desc *tx_desc;
|
||||
unsigned int len;
|
||||
u8 *tx_data;
|
||||
int res;
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
|
||||
/* If tx_queue is not empty, it means at least one previous packt */
|
||||
/* is waiting for sending. Don't send current one before it. */
|
||||
if (skb_queue_empty(&tp->tx_queue))
|
||||
agg = r8152_get_tx_agg(tp);
|
||||
|
||||
if (!agg) {
|
||||
skb_queue_tail(&tp->tx_queue, skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
tx_desc = (struct tx_desc *)agg->head;
|
||||
tx_data = agg->head + sizeof(*tx_desc);
|
||||
agg->skb_num = agg->skb_len = 0;
|
||||
if (list_empty(&tp->tx_free) &&
|
||||
skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
len = skb->len;
|
||||
r8152_tx_csum(tp, tx_desc, skb);
|
||||
memcpy(tx_data, skb->data, len);
|
||||
dev_kfree_skb_any(skb);
|
||||
agg->skb_num++;
|
||||
agg->skb_len += len;
|
||||
usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
|
||||
agg->head, len + sizeof(*tx_desc),
|
||||
(usb_complete_t)write_bulk_callback, agg);
|
||||
res = usb_submit_urb(agg->urb, GFP_ATOMIC);
|
||||
if (res) {
|
||||
/* Can we get/handle EPIPE here? */
|
||||
if (res == -ENODEV) {
|
||||
netif_device_detach(tp->netdev);
|
||||
} else {
|
||||
netif_warn(tp, tx_err, netdev,
|
||||
"failed tx_urb %d\n", res);
|
||||
stats->tx_dropped++;
|
||||
spin_lock_irqsave(&tp->tx_lock, flags);
|
||||
list_add_tail(&agg->list, &tp->tx_free);
|
||||
spin_unlock_irqrestore(&tp->tx_lock, flags);
|
||||
}
|
||||
}
|
||||
if (!list_empty(&tp->tx_free))
|
||||
tasklet_schedule(&tp->tl);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
@ -1459,6 +1436,14 @@ static void rtl8152_nic_reset(struct r8152 *tp)
|
|||
}
|
||||
}
|
||||
|
||||
static void set_tx_qlen(struct r8152 *tp)
|
||||
{
|
||||
struct net_device *netdev = tp->netdev;
|
||||
|
||||
tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN +
|
||||
sizeof(struct tx_desc));
|
||||
}
|
||||
|
||||
static inline u8 rtl8152_get_speed(struct r8152 *tp)
|
||||
{
|
||||
return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
|
||||
|
@ -1470,6 +1455,7 @@ static int rtl8152_enable(struct r8152 *tp)
|
|||
int i, ret;
|
||||
u8 speed;
|
||||
|
||||
set_tx_qlen(tp);
|
||||
speed = rtl8152_get_speed(tp);
|
||||
if (speed & _10bps) {
|
||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
|
||||
|
|
|
@ -701,6 +701,54 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ar9003_doubler_fix(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
|
||||
REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
|
||||
REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
|
||||
REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
|
||||
|
||||
udelay(200);
|
||||
|
||||
REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
|
||||
REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
|
||||
REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
|
||||
|
||||
udelay(1);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2,
|
||||
AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
|
||||
|
||||
udelay(200);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12,
|
||||
AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
|
||||
|
||||
REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
|
||||
REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
|
||||
REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0,
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
|
||||
1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
|
||||
}
|
||||
}
|
||||
|
||||
static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
|
@ -726,6 +774,8 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
|||
modesIndex);
|
||||
}
|
||||
|
||||
ar9003_doubler_fix(ah);
|
||||
|
||||
/*
|
||||
* RXGAIN initvals.
|
||||
*/
|
||||
|
|
|
@ -656,13 +656,24 @@
|
|||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00000001 : 0x00000002)
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0 : 1)
|
||||
#define AR_PHY_65NM_CH0_SYNTH7 0x16098
|
||||
#define AR_PHY_65NM_CH0_SYNTH12 0x160ac
|
||||
#define AR_PHY_65NM_CH0_BIAS1 0x160c0
|
||||
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
|
||||
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
|
||||
#define AR_PHY_65NM_CH0_RXTX2 0x16104
|
||||
#define AR_PHY_65NM_CH1_RXTX2 0x16504
|
||||
#define AR_PHY_65NM_CH2_RXTX2 0x16904
|
||||
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
|
||||
#define AR_PHY_65NM_CH1_RXTX4 0x1650c
|
||||
#define AR_PHY_65NM_CH2_RXTX4 0x1690c
|
||||
|
||||
#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000
|
||||
#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19
|
||||
#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004
|
||||
#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S 2
|
||||
#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK 0x00000008
|
||||
#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S 3
|
||||
|
||||
#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \
|
||||
(((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280)))
|
||||
#define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300)
|
||||
|
|
|
@ -361,7 +361,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
|
|||
{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
|
||||
{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
|
||||
{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
|
||||
{0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5},
|
||||
{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
|
||||
{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
|
||||
{0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
|
||||
|
@ -400,7 +400,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
|
|||
{0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
|
||||
{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
|
||||
{0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
|
||||
{0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa},
|
||||
{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
|
||||
};
|
||||
|
||||
|
@ -472,7 +472,7 @@ static const u32 ar9462_2p1_radio_postamble[][5] = {
|
|||
|
||||
static const u32 ar9462_2p1_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000040a4, 0x00a0c1c9},
|
||||
{0x000040a4, 0x00a0c9c9},
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000004c2},
|
||||
|
|
|
@ -362,7 +362,8 @@ static int __ath_reg_dyn_country(struct wiphy *wiphy,
|
|||
{
|
||||
u16 country_code;
|
||||
|
||||
if (!ath_is_world_regd(reg))
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
|
||||
!ath_is_world_regd(reg))
|
||||
return -EINVAL;
|
||||
|
||||
country_code = ath_regd_find_country_by_name(request->alpha2);
|
||||
|
|
|
@ -823,6 +823,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
|
|||
}
|
||||
err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state,
|
||||
action, P2PAPI_BSSCFG_DEVICE);
|
||||
kfree(chanspecs);
|
||||
}
|
||||
exit:
|
||||
if (err)
|
||||
|
|
|
@ -2210,8 +2210,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
priv->bss_started = 0;
|
||||
priv->bss_num = 0;
|
||||
|
||||
if (mwifiex_cfg80211_init_p2p_client(priv))
|
||||
return ERR_PTR(-EFAULT);
|
||||
if (mwifiex_cfg80211_init_p2p_client(priv)) {
|
||||
wdev = ERR_PTR(-EFAULT);
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -2224,7 +2226,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
if (!dev) {
|
||||
wiphy_err(wiphy, "no memory available for netdevice\n");
|
||||
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
wdev = ERR_PTR(-ENOMEM);
|
||||
goto done;
|
||||
}
|
||||
|
||||
mwifiex_init_priv_params(priv, dev);
|
||||
|
@ -2264,7 +2267,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
wiphy_err(wiphy, "cannot register virtual network device\n");
|
||||
free_netdev(dev);
|
||||
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
return ERR_PTR(-EFAULT);
|
||||
priv->netdev = NULL;
|
||||
wdev = ERR_PTR(-EFAULT);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sema_init(&priv->async_sem, 1);
|
||||
|
@ -2274,6 +2279,13 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||
#ifdef CONFIG_DEBUG_FS
|
||||
mwifiex_dev_debugfs_init(priv);
|
||||
#endif
|
||||
|
||||
done:
|
||||
if (IS_ERR(wdev)) {
|
||||
kfree(priv->wdev);
|
||||
priv->wdev = NULL;
|
||||
}
|
||||
|
||||
return wdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
|
||||
|
@ -2298,7 +2310,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
|||
unregister_netdevice(wdev->netdev);
|
||||
|
||||
/* Clear the priv in adapter */
|
||||
priv->netdev->ieee80211_ptr = NULL;
|
||||
priv->netdev = NULL;
|
||||
kfree(wdev);
|
||||
priv->wdev = NULL;
|
||||
|
||||
priv->media_connected = false;
|
||||
|
||||
|
|
|
@ -411,13 +411,14 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
|
|||
*/
|
||||
static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
char fmt[64];
|
||||
struct mwifiex_private *priv;
|
||||
struct mwifiex_adapter *adapter = context;
|
||||
struct mwifiex_fw_image fw;
|
||||
struct semaphore *sem = adapter->card_sem;
|
||||
bool init_failed = false;
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
if (!firmware) {
|
||||
dev_err(adapter->dev,
|
||||
|
@ -469,14 +470,16 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
|||
priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
|
||||
if (mwifiex_register_cfg80211(adapter)) {
|
||||
dev_err(adapter->dev, "cannot register with cfg80211\n");
|
||||
goto err_register_cfg80211;
|
||||
goto err_init_fw;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
/* Create station interface by default */
|
||||
if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
|
||||
NL80211_IFTYPE_STATION, NULL, NULL)) {
|
||||
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
|
||||
NL80211_IFTYPE_STATION, NULL, NULL);
|
||||
if (IS_ERR(wdev)) {
|
||||
dev_err(adapter->dev, "cannot create default STA interface\n");
|
||||
rtnl_unlock();
|
||||
goto err_add_intf;
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
@ -486,17 +489,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
|||
goto done;
|
||||
|
||||
err_add_intf:
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
|
||||
if (!priv)
|
||||
continue;
|
||||
|
||||
if (priv->wdev && priv->netdev)
|
||||
mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
|
||||
}
|
||||
rtnl_unlock();
|
||||
err_register_cfg80211:
|
||||
wiphy_unregister(adapter->wiphy);
|
||||
wiphy_free(adapter->wiphy);
|
||||
err_init_fw:
|
||||
|
@ -1006,12 +998,6 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
|
|||
wiphy_unregister(priv->wdev->wiphy);
|
||||
wiphy_free(priv->wdev->wiphy);
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv)
|
||||
kfree(priv->wdev);
|
||||
}
|
||||
|
||||
mwifiex_terminate_workqueue(adapter);
|
||||
|
||||
/* Unregister device */
|
||||
|
|
|
@ -232,7 +232,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
mwifiex_remove_card(card->adapter, &add_remove_card_sem);
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
|
||||
|
@ -2313,6 +2312,7 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
|
|||
pci_release_region(pdev, 0);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -196,7 +196,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
|
|||
}
|
||||
|
||||
mwifiex_remove_card(card->adapter, &add_remove_card_sem);
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1745,7 +1744,6 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
|
|||
sdio_claim_host(card->func);
|
||||
sdio_disable_func(card->func);
|
||||
sdio_release_host(card->func);
|
||||
sdio_set_drvdata(card->func, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1773,7 +1771,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
|
|||
return ret;
|
||||
}
|
||||
|
||||
sdio_set_drvdata(func, card);
|
||||
|
||||
adapter->dev = &func->dev;
|
||||
|
||||
|
@ -1801,6 +1798,8 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
|
|||
int ret;
|
||||
u8 sdio_ireg;
|
||||
|
||||
sdio_set_drvdata(card->func, card);
|
||||
|
||||
/*
|
||||
* Read the HOST_INT_STATUS_REG for ACK the first interrupt got
|
||||
* from the bootloader. If we don't do this we get a interrupt
|
||||
|
@ -1883,6 +1882,8 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
|
|||
kfree(card->mpa_rx.len_arr);
|
||||
kfree(card->mpa_tx.buf);
|
||||
kfree(card->mpa_rx.buf);
|
||||
sdio_set_drvdata(card->func, NULL);
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -350,7 +350,6 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
|
|||
|
||||
card->udev = udev;
|
||||
card->intf = intf;
|
||||
usb_card = card;
|
||||
|
||||
pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
|
||||
udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
|
||||
|
@ -525,25 +524,28 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
|
|||
static void mwifiex_usb_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_card_rec *card = usb_get_intfdata(intf);
|
||||
struct mwifiex_adapter *adapter;
|
||||
|
||||
if (!card || !card->adapter) {
|
||||
pr_err("%s: card or card->adapter is NULL\n", __func__);
|
||||
if (!card) {
|
||||
pr_err("%s: card is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = card->adapter;
|
||||
mwifiex_usb_free(card);
|
||||
|
||||
if (card->adapter) {
|
||||
struct mwifiex_adapter *adapter = card->adapter;
|
||||
|
||||
if (!adapter->priv_num)
|
||||
return;
|
||||
|
||||
mwifiex_usb_free(card);
|
||||
|
||||
dev_dbg(adapter->dev, "%s: removing card\n", __func__);
|
||||
mwifiex_remove_card(adapter, &add_remove_card_sem);
|
||||
}
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
usb_put_dev(interface_to_usbdev(intf));
|
||||
kfree(card);
|
||||
usb_card = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -754,6 +756,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
|
|||
card->adapter = adapter;
|
||||
adapter->dev = &card->udev->dev;
|
||||
strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
|
||||
usb_card = card;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -762,7 +765,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
|
|||
{
|
||||
struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
|
||||
|
||||
usb_set_intfdata(card->intf, NULL);
|
||||
card->adapter = NULL;
|
||||
}
|
||||
|
||||
static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
|
@ -1004,7 +1007,7 @@ static void mwifiex_usb_cleanup_module(void)
|
|||
if (!down_interruptible(&add_remove_card_sem))
|
||||
up(&add_remove_card_sem);
|
||||
|
||||
if (usb_card) {
|
||||
if (usb_card && usb_card->adapter) {
|
||||
struct mwifiex_adapter *adapter = usb_card->adapter;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
|
|||
static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ieee80211_tx_control control = {};
|
||||
struct rt2x00_dev *rt2x00dev = data;
|
||||
struct sk_buff *skb;
|
||||
|
||||
|
@ -195,7 +196,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
|
|||
*/
|
||||
skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
|
||||
while (skb) {
|
||||
rt2x00mac_tx(rt2x00dev->hw, NULL, skb);
|
||||
rt2x00mac_tx(rt2x00dev->hw, &control, skb);
|
||||
skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -769,7 +769,7 @@ static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
|
|||
|
||||
static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats,
|
||||
struct rx_desc_92c *pdesc,
|
||||
struct rx_desc_92c *p_desc,
|
||||
struct rx_fwinfo_92c *p_drvinfo,
|
||||
bool packet_match_bssid,
|
||||
bool packet_toself,
|
||||
|
@ -784,11 +784,11 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
|
|||
u32 rssi, total_rssi = 0;
|
||||
bool in_powersavemode = false;
|
||||
bool is_cck_rate;
|
||||
u8 *pdesc = (u8 *)p_desc;
|
||||
|
||||
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
|
||||
is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc);
|
||||
pstats->packet_matchbssid = packet_match_bssid;
|
||||
pstats->packet_toself = packet_toself;
|
||||
pstats->is_cck = is_cck_rate;
|
||||
pstats->packet_beacon = packet_beacon;
|
||||
pstats->is_cck = is_cck_rate;
|
||||
pstats->RX_SIGQ[0] = -1;
|
||||
|
|
|
@ -303,10 +303,10 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
|
|||
bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *p_desc, struct sk_buff *skb)
|
||||
u8 *pdesc, struct sk_buff *skb)
|
||||
{
|
||||
struct rx_fwinfo_92c *p_drvinfo;
|
||||
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
|
||||
struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc;
|
||||
u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc);
|
||||
|
||||
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
|
||||
|
@ -345,7 +345,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
|
|||
if (phystatus) {
|
||||
p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
|
||||
stats->rx_bufshift);
|
||||
rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
|
||||
rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc,
|
||||
p_drvinfo);
|
||||
}
|
||||
/*rx_status->qual = stats->signal; */
|
||||
|
|
|
@ -461,6 +461,9 @@ void xenvif_disconnect(struct xenvif *vif)
|
|||
if (netif_carrier_ok(vif->dev))
|
||||
xenvif_carrier_off(vif);
|
||||
|
||||
if (vif->task)
|
||||
kthread_stop(vif->task);
|
||||
|
||||
if (vif->tx_irq) {
|
||||
if (vif->tx_irq == vif->rx_irq)
|
||||
unbind_from_irqhandler(vif->tx_irq, vif);
|
||||
|
@ -471,9 +474,6 @@ void xenvif_disconnect(struct xenvif *vif)
|
|||
vif->tx_irq = 0;
|
||||
}
|
||||
|
||||
if (vif->task)
|
||||
kthread_stop(vif->task);
|
||||
|
||||
xenvif_unmap_frontend_rings(vif);
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,14 @@ struct proto_ops {
|
|||
#endif
|
||||
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
|
||||
struct msghdr *m, size_t total_len);
|
||||
/* Notes for implementing recvmsg:
|
||||
* ===============================
|
||||
* msg->msg_namelen should get updated by the recvmsg handlers
|
||||
* iff msg_name != NULL. It is by default 0 to prevent
|
||||
* returning uninitialized memory to user space. The recvfrom
|
||||
* handlers can assume that msg.msg_name is either NULL or has
|
||||
* a minimum size of sizeof(struct sockaddr_storage).
|
||||
*/
|
||||
int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
|
||||
struct msghdr *m, size_t total_len,
|
||||
int flags);
|
||||
|
|
|
@ -559,6 +559,7 @@ static inline int phy_read_status(struct phy_device *phydev) {
|
|||
return phydev->drv->read_status(phydev);
|
||||
}
|
||||
|
||||
int genphy_setup_forced(struct phy_device *phydev);
|
||||
int genphy_restart_aneg(struct phy_device *phydev);
|
||||
int genphy_config_aneg(struct phy_device *phydev);
|
||||
int genphy_update_link(struct phy_device *phydev);
|
||||
|
|
|
@ -265,7 +265,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
|
|||
struct net *net, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group, gfp_t flags)
|
||||
{
|
||||
if (group >= family->n_mcgrps)
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
|
||||
|
@ -283,9 +283,6 @@ static inline int genlmsg_multicast(struct genl_family *family,
|
|||
struct sk_buff *skb, u32 portid,
|
||||
unsigned int group, gfp_t flags)
|
||||
{
|
||||
if (group >= family->n_mcgrps)
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return genlmsg_multicast_netns(family, &init_net, skb,
|
||||
portid, group, flags);
|
||||
}
|
||||
|
@ -387,6 +384,9 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
|
|||
static inline int genl_set_err(struct genl_family *family, struct net *net,
|
||||
u32 portid, u32 group, int code)
|
||||
{
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return netlink_set_err(net->genl_sock, portid, group, code);
|
||||
}
|
||||
|
||||
|
|
|
@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
|
|||
size_t size, int flags)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
|
||||
struct ddpehdr *ddp;
|
||||
int copied = 0;
|
||||
int offset = 0;
|
||||
|
@ -1764,13 +1763,12 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
|
|||
}
|
||||
err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
|
||||
|
||||
if (!err) {
|
||||
if (sat) {
|
||||
if (!err && msg->msg_name) {
|
||||
struct sockaddr_at *sat = msg->msg_name;
|
||||
sat->sat_family = AF_APPLETALK;
|
||||
sat->sat_port = ddp->deh_sport;
|
||||
sat->sat_addr.s_node = ddp->deh_snode;
|
||||
sat->sat_addr.s_net = ddp->deh_snet;
|
||||
}
|
||||
msg->msg_namelen = sizeof(*sat);
|
||||
}
|
||||
|
||||
|
|
|
@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
|
|||
struct sk_buff *skb;
|
||||
int copied, error = -EINVAL;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
if (sock->state != SS_CONNECTED)
|
||||
return -ENOTCONN;
|
||||
|
||||
|
|
|
@ -1636,11 +1636,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
|
||||
|
||||
if (msg->msg_namelen != 0) {
|
||||
struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
|
||||
if (msg->msg_name) {
|
||||
ax25_digi digi;
|
||||
ax25_address src;
|
||||
const unsigned char *mac = skb_mac_header(skb);
|
||||
struct sockaddr_ax25 *sax = msg->msg_name;
|
||||
|
||||
memset(sax, 0, sizeof(struct full_sockaddr_ax25));
|
||||
ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
|
||||
|
|
|
@ -224,10 +224,9 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
skb = skb_recv_datagram(sk, flags, noblock, &err);
|
||||
if (!skb) {
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN) {
|
||||
msg->msg_namelen = 0;
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -245,8 +244,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (bt_sk(sk)->skb_msg_name)
|
||||
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
|
||||
&msg->msg_namelen);
|
||||
else
|
||||
msg->msg_namelen = 0;
|
||||
}
|
||||
|
||||
skb_free_datagram(sk, skb);
|
||||
|
@ -295,8 +292,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (flags & MSG_OOB)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
BT_DBG("sk %p size %zu", sk, size);
|
||||
|
||||
lock_sock(sk);
|
||||
|
|
|
@ -856,8 +856,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (!skb)
|
||||
return err;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
copied = skb->len;
|
||||
if (len < copied) {
|
||||
msg->msg_flags |= MSG_TRUNC;
|
||||
|
|
|
@ -2439,6 +2439,9 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
|
|||
int err;
|
||||
struct sk_buff_head seg_queue;
|
||||
|
||||
if (!chan->conn)
|
||||
return -ENOTCONN;
|
||||
|
||||
/* Connectionless channel */
|
||||
if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
|
||||
skb = l2cap_create_connless_pdu(chan, msg, len, priority);
|
||||
|
|
|
@ -694,6 +694,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
|
|||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = 0;
|
||||
addr.l2_cid = 0;
|
||||
addr.l2_bdaddr_type = BDADDR_BREDR;
|
||||
*err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (*err < 0)
|
||||
goto failed;
|
||||
|
@ -719,6 +720,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
|
|||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
|
||||
addr.l2_cid = 0;
|
||||
addr.l2_bdaddr_type = BDADDR_BREDR;
|
||||
*err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
|
||||
if (*err == 0 || *err == -EINPROGRESS)
|
||||
return s;
|
||||
|
@ -1983,6 +1985,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
|
|||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM);
|
||||
addr.l2_cid = 0;
|
||||
addr.l2_bdaddr_type = BDADDR_BREDR;
|
||||
err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (err < 0) {
|
||||
BT_ERR("Bind failed %d", err);
|
||||
|
|
|
@ -615,7 +615,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
|
||||
rfcomm_dlc_accept(d);
|
||||
msg->msg_namelen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -739,8 +738,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
|
|||
static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct sock *l2cap_sk;
|
||||
struct l2cap_conn *conn;
|
||||
struct rfcomm_conninfo cinfo;
|
||||
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
|
||||
int len, err = 0;
|
||||
u32 opt;
|
||||
|
||||
|
@ -783,6 +783,9 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
|
|||
break;
|
||||
}
|
||||
|
||||
l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
|
||||
conn = l2cap_pi(l2cap_sk)->chan->conn;
|
||||
|
||||
memset(&cinfo, 0, sizeof(cinfo));
|
||||
cinfo.hci_handle = conn->hcon->handle;
|
||||
memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
|
||||
|
|
|
@ -711,7 +711,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
||||
sco_conn_defer_accept(pi->conn->hcon, pi->setting);
|
||||
sk->sk_state = BT_CONFIG;
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
release_sock(sk);
|
||||
return 0;
|
||||
|
|
|
@ -742,6 +742,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
if (!(conn->hcon->link_mode & HCI_LM_MASTER))
|
||||
return SMP_CMD_NOTSUPP;
|
||||
|
||||
hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
|
||||
|
||||
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
|
||||
|
|
|
@ -172,6 +172,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
|
|||
del_nbp(p);
|
||||
}
|
||||
|
||||
br_fdb_delete_by_port(br, NULL, 1);
|
||||
|
||||
br_vlan_flush(br);
|
||||
del_timer_sync(&br->gc_timer);
|
||||
|
||||
|
|
|
@ -48,10 +48,12 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
if (info->bitmask & EBT_IP6_TCLASS &&
|
||||
FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
|
||||
return false;
|
||||
if (FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
|
||||
&info->saddr), EBT_IP6_SOURCE) ||
|
||||
if ((info->bitmask & EBT_IP6_SOURCE &&
|
||||
FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
|
||||
&info->saddr), EBT_IP6_SOURCE)) ||
|
||||
(info->bitmask & EBT_IP6_DEST &&
|
||||
FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk,
|
||||
&info->daddr), EBT_IP6_DEST))
|
||||
&info->daddr), EBT_IP6_DEST)))
|
||||
return false;
|
||||
if (info->bitmask & EBT_IP6_PROTO) {
|
||||
uint8_t nexthdr = ih6->nexthdr;
|
||||
|
|
|
@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (m->msg_flags&MSG_OOB)
|
||||
goto read_error;
|
||||
|
||||
m->msg_namelen = 0;
|
||||
|
||||
skb = skb_recv_datagram(sk, flags, 0 , &ret);
|
||||
if (!skb)
|
||||
goto read_error;
|
||||
|
@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (flags&MSG_OOB)
|
||||
goto out;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
/*
|
||||
* Lock the socket to prevent queue disordering
|
||||
* while sleeps in memcpy_tomsg
|
||||
|
|
|
@ -93,6 +93,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (kern_msg->msg_name)
|
||||
kern_msg->msg_name = kern_address;
|
||||
} else
|
||||
kern_msg->msg_name = NULL;
|
||||
|
|
|
@ -4996,7 +4996,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
|
|||
{
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
|
||||
if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
|
||||
if (ops->ndo_change_rx_flags)
|
||||
ops->ndo_change_rx_flags(dev, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (m->msg_name)
|
||||
m->msg_name = address;
|
||||
} else {
|
||||
m->msg_name = NULL;
|
||||
|
|
|
@ -2796,6 +2796,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
struct sk_buff *segs = NULL;
|
||||
struct sk_buff *tail = NULL;
|
||||
struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
|
||||
skb_frag_t *skb_frag = skb_shinfo(skb)->frags;
|
||||
unsigned int mss = skb_shinfo(skb)->gso_size;
|
||||
unsigned int doffset = skb->data - skb_mac_header(skb);
|
||||
unsigned int offset = doffset;
|
||||
|
@ -2835,16 +2836,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
if (hsize > len || !sg)
|
||||
hsize = len;
|
||||
|
||||
if (!hsize && i >= nfrags) {
|
||||
BUG_ON(fskb->len != len);
|
||||
if (!hsize && i >= nfrags && skb_headlen(fskb) &&
|
||||
(skb_headlen(fskb) == len || sg)) {
|
||||
BUG_ON(skb_headlen(fskb) > len);
|
||||
|
||||
i = 0;
|
||||
nfrags = skb_shinfo(fskb)->nr_frags;
|
||||
skb_frag = skb_shinfo(fskb)->frags;
|
||||
pos += skb_headlen(fskb);
|
||||
|
||||
while (pos < offset + len) {
|
||||
BUG_ON(i >= nfrags);
|
||||
|
||||
size = skb_frag_size(skb_frag);
|
||||
if (pos + size > offset + len)
|
||||
break;
|
||||
|
||||
i++;
|
||||
pos += size;
|
||||
skb_frag++;
|
||||
}
|
||||
|
||||
pos += len;
|
||||
nskb = skb_clone(fskb, GFP_ATOMIC);
|
||||
fskb = fskb->next;
|
||||
|
||||
if (unlikely(!nskb))
|
||||
goto err;
|
||||
|
||||
if (unlikely(pskb_trim(nskb, len))) {
|
||||
kfree_skb(nskb);
|
||||
goto err;
|
||||
}
|
||||
|
||||
hsize = skb_end_offset(nskb);
|
||||
if (skb_cow_head(nskb, doffset + headroom)) {
|
||||
kfree_skb(nskb);
|
||||
|
@ -2881,7 +2904,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
nskb->data - tnl_hlen,
|
||||
doffset + tnl_hlen);
|
||||
|
||||
if (fskb != skb_shinfo(skb)->frag_list)
|
||||
if (nskb->len == len + doffset)
|
||||
goto perform_csum_check;
|
||||
|
||||
if (!sg) {
|
||||
|
@ -2899,8 +2922,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
|
||||
skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
|
||||
|
||||
while (pos < offset + len && i < nfrags) {
|
||||
*frag = skb_shinfo(skb)->frags[i];
|
||||
while (pos < offset + len) {
|
||||
if (i >= nfrags) {
|
||||
BUG_ON(skb_headlen(fskb));
|
||||
|
||||
i = 0;
|
||||
nfrags = skb_shinfo(fskb)->nr_frags;
|
||||
skb_frag = skb_shinfo(fskb)->frags;
|
||||
|
||||
BUG_ON(!nfrags);
|
||||
|
||||
fskb = fskb->next;
|
||||
}
|
||||
|
||||
if (unlikely(skb_shinfo(nskb)->nr_frags >=
|
||||
MAX_SKB_FRAGS)) {
|
||||
net_warn_ratelimited(
|
||||
"skb_segment: too many frags: %u %u\n",
|
||||
pos, mss);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*frag = *skb_frag;
|
||||
__skb_frag_ref(frag);
|
||||
size = skb_frag_size(frag);
|
||||
|
||||
|
@ -2913,6 +2956,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
|
||||
if (pos + size <= offset + len) {
|
||||
i++;
|
||||
skb_frag++;
|
||||
pos += size;
|
||||
} else {
|
||||
skb_frag_size_sub(frag, pos + size - (offset + len));
|
||||
|
@ -2922,25 +2966,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
|
|||
frag++;
|
||||
}
|
||||
|
||||
if (pos < offset + len) {
|
||||
struct sk_buff *fskb2 = fskb;
|
||||
|
||||
BUG_ON(pos + fskb->len != offset + len);
|
||||
|
||||
pos += fskb->len;
|
||||
fskb = fskb->next;
|
||||
|
||||
if (fskb2->next) {
|
||||
fskb2 = skb_clone(fskb2, GFP_ATOMIC);
|
||||
if (!fskb2)
|
||||
goto err;
|
||||
} else
|
||||
skb_get(fskb2);
|
||||
|
||||
SKB_FRAG_ASSERT(nskb);
|
||||
skb_shinfo(nskb)->frag_list = fskb2;
|
||||
}
|
||||
|
||||
skip_fraglist:
|
||||
nskb->data_len = len - hsize;
|
||||
nskb->len += nskb->data_len;
|
||||
|
|
|
@ -244,6 +244,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet,
|
|||
|
||||
this_cpu_inc(snet->stats->cookie_valid);
|
||||
opts->mss = mss;
|
||||
opts->options |= XT_SYNPROXY_OPT_MSS;
|
||||
|
||||
if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP)
|
||||
synproxy_check_timestamp_cookie(opts);
|
||||
|
|
|
@ -1776,8 +1776,12 @@ out: return err;
|
|||
rth->dst.error= -err;
|
||||
rth->rt_flags &= ~RTCF_LOCAL;
|
||||
}
|
||||
if (do_cache)
|
||||
rt_cache_route(&FIB_RES_NH(res), rth);
|
||||
if (do_cache) {
|
||||
if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
|
||||
rth->dst.flags |= DST_NOCACHE;
|
||||
rt_add_uncached_list(rth);
|
||||
}
|
||||
}
|
||||
skb_dst_set(skb, &rth->dst);
|
||||
err = 0;
|
||||
goto out;
|
||||
|
|
|
@ -259,6 +259,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet,
|
|||
|
||||
this_cpu_inc(snet->stats->cookie_valid);
|
||||
opts->mss = mss;
|
||||
opts->options |= XT_SYNPROXY_OPT_MSS;
|
||||
|
||||
if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP)
|
||||
synproxy_check_timestamp_cookie(opts);
|
||||
|
|
|
@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (skb->tstamp.tv64)
|
||||
sk->sk_stamp = skb->tstamp;
|
||||
|
||||
msg->msg_namelen = sizeof(*sipx);
|
||||
|
||||
if (sipx) {
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_port = ipx->ipx_source.sock;
|
||||
|
@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net;
|
||||
sipx->sipx_type = ipx->ipx_type;
|
||||
sipx->sipx_zero = 0;
|
||||
msg->msg_namelen = sizeof(*sipx);
|
||||
}
|
||||
rc = copied;
|
||||
|
||||
|
|
|
@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
IRDA_DEBUG(4, "%s()\n", __func__);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
|
||||
flags & MSG_DONTWAIT, &err);
|
||||
if (!skb)
|
||||
|
@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
|
|||
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
|
||||
timeo = sock_rcvtimeo(sk, noblock);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
do {
|
||||
int chunk;
|
||||
struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
|
||||
|
|
|
@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
int err = 0;
|
||||
u32 offset;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
if ((sk->sk_state == IUCV_DISCONN) &&
|
||||
skb_queue_empty(&iucv->backlog_skb_q) &&
|
||||
skb_queue_empty(&sk->sk_receive_queue) &&
|
||||
|
|
|
@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
|
|||
if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
|
||||
goto out;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
|
||||
if (skb == NULL)
|
||||
goto out;
|
||||
|
|
|
@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (sk->sk_state & PPPOX_BOUND)
|
||||
goto end;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
err = 0;
|
||||
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
|
||||
flags & MSG_DONTWAIT, &err);
|
||||
|
|
|
@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
int target; /* Read at least this many bytes */
|
||||
long timeo;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
lock_sock(sk);
|
||||
copied = -ENOTCONN;
|
||||
if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
|
||||
|
|
|
@ -909,7 +909,7 @@ config NETFILTER_XT_MATCH_CONNLABEL
|
|||
connection simultaneously.
|
||||
|
||||
config NETFILTER_XT_MATCH_CONNLIMIT
|
||||
tristate '"connlimit" match support"'
|
||||
tristate '"connlimit" match support'
|
||||
depends on NF_CONNTRACK
|
||||
depends on NETFILTER_ADVANCED
|
||||
---help---
|
||||
|
|
|
@ -764,9 +764,10 @@ void nf_conntrack_free(struct nf_conn *ct)
|
|||
struct net *net = nf_ct_net(ct);
|
||||
|
||||
nf_ct_ext_destroy(ct);
|
||||
atomic_dec(&net->ct.count);
|
||||
nf_ct_ext_free(ct);
|
||||
kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
|
||||
smp_mb__before_atomic_dec();
|
||||
atomic_dec(&net->ct.count);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_free);
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
|
|||
spin_lock_bh(&ct->lock);
|
||||
this_way = &seqadj->seq[dir];
|
||||
if (this_way->offset_before == this_way->offset_after ||
|
||||
before(this_way->correction_pos, seq)) {
|
||||
this_way->correction_pos = seq;
|
||||
before(this_way->correction_pos, ntohl(seq))) {
|
||||
this_way->correction_pos = ntohl(seq);
|
||||
this_way->offset_before = this_way->offset_after;
|
||||
this_way->offset_after += off;
|
||||
}
|
||||
|
|
|
@ -151,9 +151,10 @@ void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info,
|
|||
opts->tsecr = opts->tsval;
|
||||
opts->tsval = tcp_time_stamp & ~0x3f;
|
||||
|
||||
if (opts->options & XT_SYNPROXY_OPT_WSCALE)
|
||||
opts->tsval |= info->wscale;
|
||||
else
|
||||
if (opts->options & XT_SYNPROXY_OPT_WSCALE) {
|
||||
opts->tsval |= opts->wscale;
|
||||
opts->wscale = info->wscale;
|
||||
} else
|
||||
opts->tsval |= 0xf;
|
||||
|
||||
if (opts->options & XT_SYNPROXY_OPT_SACK_PERM)
|
||||
|
|
|
@ -128,7 +128,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1]
|
|||
[NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static u8 nft_parse_compat(const struct nlattr *attr, bool *inv)
|
||||
static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv)
|
||||
{
|
||||
struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
|
||||
u32 flags;
|
||||
|
@ -148,7 +148,8 @@ static u8 nft_parse_compat(const struct nlattr *attr, bool *inv)
|
|||
if (flags & NFT_RULE_COMPAT_F_INV)
|
||||
*inv = true;
|
||||
|
||||
return ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
|
||||
*proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -166,8 +167,11 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
|||
|
||||
target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
|
||||
|
||||
if (ctx->nla[NFTA_RULE_COMPAT])
|
||||
proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv);
|
||||
if (ctx->nla[NFTA_RULE_COMPAT]) {
|
||||
ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
|
||||
|
||||
|
@ -356,8 +360,11 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
|||
|
||||
match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
|
||||
|
||||
if (ctx->nla[NFTA_RULE_COMPAT])
|
||||
proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv);
|
||||
if (ctx->nla[NFTA_RULE_COMPAT]) {
|
||||
ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
|
||||
|
||||
|
|
|
@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
|
|||
}
|
||||
#endif
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
copied = data_skb->len;
|
||||
if (len < copied) {
|
||||
msg->msg_flags |= MSG_TRUNC;
|
||||
|
|
|
@ -1045,7 +1045,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
|
|||
int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group, gfp_t flags)
|
||||
{
|
||||
if (group >= family->n_mcgrps)
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return genlmsg_mcast(skb, portid, group, flags);
|
||||
|
@ -1062,7 +1062,7 @@ void genl_notify(struct genl_family *family,
|
|||
if (nlh)
|
||||
report = nlmsg_report(nlh);
|
||||
|
||||
if (group >= family->n_mcgrps)
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return;
|
||||
group = family->mcgrp_offset + group;
|
||||
nlmsg_notify(sk, skb, portid, group, report, flags);
|
||||
|
|
|
@ -1179,9 +1179,8 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
sax->sax25_family = AF_NETROM;
|
||||
skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
|
||||
AX25_ADDR_LEN);
|
||||
}
|
||||
|
||||
msg->msg_namelen = sizeof(*sax);
|
||||
}
|
||||
|
||||
skb_free_datagram(sk, skb);
|
||||
|
||||
|
|
|
@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
pr_debug("%p %zu\n", sk, len);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state == LLCP_CLOSED &&
|
||||
|
|
|
@ -244,8 +244,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (!skb)
|
||||
return rc;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
copied = skb->len;
|
||||
if (len < copied) {
|
||||
msg->msg_flags |= MSG_TRUNC;
|
||||
|
|
|
@ -244,11 +244,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
|
|||
static void register_prot_hook(struct sock *sk)
|
||||
{
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
|
||||
if (!po->running) {
|
||||
if (po->fanout)
|
||||
if (po->fanout) {
|
||||
__fanout_link(sk, po);
|
||||
else
|
||||
} else {
|
||||
dev_add_pack(&po->prot_hook);
|
||||
rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
|
||||
}
|
||||
|
||||
sock_hold(sk);
|
||||
po->running = 1;
|
||||
}
|
||||
|
@ -266,10 +270,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
|
|||
struct packet_sock *po = pkt_sk(sk);
|
||||
|
||||
po->running = 0;
|
||||
if (po->fanout)
|
||||
if (po->fanout) {
|
||||
__fanout_unlink(sk, po);
|
||||
else
|
||||
} else {
|
||||
__dev_remove_pack(&po->prot_hook);
|
||||
RCU_INIT_POINTER(po->cached_dev, NULL);
|
||||
}
|
||||
|
||||
__sock_put(sk);
|
||||
|
||||
if (sync) {
|
||||
|
@ -2052,12 +2059,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
|
|||
return tp_len;
|
||||
}
|
||||
|
||||
static struct net_device *packet_cached_dev_get(struct packet_sock *po)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
rcu_read_lock();
|
||||
dev = rcu_dereference(po->cached_dev);
|
||||
if (dev)
|
||||
dev_hold(dev);
|
||||
rcu_read_unlock();
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct net_device *dev;
|
||||
__be16 proto;
|
||||
bool need_rls_dev = false;
|
||||
int err, reserve = 0;
|
||||
void *ph;
|
||||
struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
|
||||
|
@ -2070,7 +2089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
|||
mutex_lock(&po->pg_vec_lock);
|
||||
|
||||
if (saddr == NULL) {
|
||||
dev = po->prot_hook.dev;
|
||||
dev = packet_cached_dev_get(po);
|
||||
proto = po->num;
|
||||
addr = NULL;
|
||||
} else {
|
||||
|
@ -2084,19 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
|||
proto = saddr->sll_protocol;
|
||||
addr = saddr->sll_addr;
|
||||
dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
|
||||
need_rls_dev = true;
|
||||
}
|
||||
|
||||
err = -ENXIO;
|
||||
if (unlikely(dev == NULL))
|
||||
goto out;
|
||||
|
||||
reserve = dev->hard_header_len;
|
||||
|
||||
err = -ENETDOWN;
|
||||
if (unlikely(!(dev->flags & IFF_UP)))
|
||||
goto out_put;
|
||||
|
||||
reserve = dev->hard_header_len;
|
||||
|
||||
size_max = po->tx_ring.frame_size
|
||||
- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
|
||||
|
||||
|
@ -2173,7 +2190,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
|||
__packet_set_status(po, ph, status);
|
||||
kfree_skb(skb);
|
||||
out_put:
|
||||
if (need_rls_dev)
|
||||
dev_put(dev);
|
||||
out:
|
||||
mutex_unlock(&po->pg_vec_lock);
|
||||
|
@ -2212,7 +2228,6 @@ static int packet_snd(struct socket *sock,
|
|||
struct sk_buff *skb;
|
||||
struct net_device *dev;
|
||||
__be16 proto;
|
||||
bool need_rls_dev = false;
|
||||
unsigned char *addr;
|
||||
int err, reserve = 0;
|
||||
struct virtio_net_hdr vnet_hdr = { 0 };
|
||||
|
@ -2228,7 +2243,7 @@ static int packet_snd(struct socket *sock,
|
|||
*/
|
||||
|
||||
if (saddr == NULL) {
|
||||
dev = po->prot_hook.dev;
|
||||
dev = packet_cached_dev_get(po);
|
||||
proto = po->num;
|
||||
addr = NULL;
|
||||
} else {
|
||||
|
@ -2240,19 +2255,17 @@ static int packet_snd(struct socket *sock,
|
|||
proto = saddr->sll_protocol;
|
||||
addr = saddr->sll_addr;
|
||||
dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
|
||||
need_rls_dev = true;
|
||||
}
|
||||
|
||||
err = -ENXIO;
|
||||
if (dev == NULL)
|
||||
if (unlikely(dev == NULL))
|
||||
goto out_unlock;
|
||||
err = -ENETDOWN;
|
||||
if (unlikely(!(dev->flags & IFF_UP)))
|
||||
goto out_unlock;
|
||||
|
||||
if (sock->type == SOCK_RAW)
|
||||
reserve = dev->hard_header_len;
|
||||
|
||||
err = -ENETDOWN;
|
||||
if (!(dev->flags & IFF_UP))
|
||||
goto out_unlock;
|
||||
|
||||
if (po->has_vnet_hdr) {
|
||||
vnet_hdr_len = sizeof(vnet_hdr);
|
||||
|
||||
|
@ -2386,7 +2399,6 @@ static int packet_snd(struct socket *sock,
|
|||
if (err > 0 && (err = net_xmit_errno(err)) != 0)
|
||||
goto out_unlock;
|
||||
|
||||
if (need_rls_dev)
|
||||
dev_put(dev);
|
||||
|
||||
return len;
|
||||
|
@ -2394,7 +2406,7 @@ static int packet_snd(struct socket *sock,
|
|||
out_free:
|
||||
kfree_skb(skb);
|
||||
out_unlock:
|
||||
if (dev && need_rls_dev)
|
||||
if (dev)
|
||||
dev_put(dev);
|
||||
out:
|
||||
return err;
|
||||
|
@ -2614,6 +2626,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
|
|||
po = pkt_sk(sk);
|
||||
sk->sk_family = PF_PACKET;
|
||||
po->num = proto;
|
||||
RCU_INIT_POINTER(po->cached_dev, NULL);
|
||||
|
||||
sk->sk_destruct = packet_sock_destruct;
|
||||
sk_refcnt_debug_inc(sk);
|
||||
|
@ -2660,7 +2673,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
struct sock *sk = sock->sk;
|
||||
struct sk_buff *skb;
|
||||
int copied, err;
|
||||
struct sockaddr_ll *sll;
|
||||
int vnet_hdr_len = 0;
|
||||
|
||||
err = -EINVAL;
|
||||
|
@ -2744,22 +2756,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the address length field is there to be filled in, we fill
|
||||
* it in now.
|
||||
/* You lose any data beyond the buffer you gave. If it worries
|
||||
* a user program they can ask the device for its MTU
|
||||
* anyway.
|
||||
*/
|
||||
|
||||
sll = &PACKET_SKB_CB(skb)->sa.ll;
|
||||
if (sock->type == SOCK_PACKET)
|
||||
msg->msg_namelen = sizeof(struct sockaddr_pkt);
|
||||
else
|
||||
msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
|
||||
|
||||
/*
|
||||
* You lose any data beyond the buffer you gave. If it worries a
|
||||
* user program they can ask the device for its MTU anyway.
|
||||
*/
|
||||
|
||||
copied = skb->len;
|
||||
if (copied > len) {
|
||||
copied = len;
|
||||
|
@ -2772,9 +2772,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
sock_recv_ts_and_drops(msg, sk, skb);
|
||||
|
||||
if (msg->msg_name)
|
||||
if (msg->msg_name) {
|
||||
/* If the address length field is there to be filled
|
||||
* in, we fill it in now.
|
||||
*/
|
||||
if (sock->type == SOCK_PACKET) {
|
||||
msg->msg_namelen = sizeof(struct sockaddr_pkt);
|
||||
} else {
|
||||
struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
|
||||
msg->msg_namelen = sll->sll_halen +
|
||||
offsetof(struct sockaddr_ll, sll_addr);
|
||||
}
|
||||
memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
|
||||
msg->msg_namelen);
|
||||
}
|
||||
|
||||
if (pkt_sk(sk)->auxdata) {
|
||||
struct tpacket_auxdata aux;
|
||||
|
|
|
@ -113,6 +113,7 @@ struct packet_sock {
|
|||
unsigned int tp_loss:1;
|
||||
unsigned int tp_tx_has_off:1;
|
||||
unsigned int tp_tstamp;
|
||||
struct net_device __rcu *cached_dev;
|
||||
struct packet_type prot_hook ____cacheline_aligned_in_smp;
|
||||
};
|
||||
|
||||
|
|
|
@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
|
|||
|
||||
rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
if (msg_flags & MSG_OOB)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct rose_sock *rose = rose_sk(sk);
|
||||
struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
|
||||
size_t copied;
|
||||
unsigned char *asmptr;
|
||||
struct sk_buff *skb;
|
||||
|
@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
|
||||
|
||||
if (srose != NULL) {
|
||||
memset(srose, 0, msg->msg_namelen);
|
||||
if (msg->msg_name) {
|
||||
struct sockaddr_rose *srose;
|
||||
|
||||
memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
|
||||
srose = msg->msg_name;
|
||||
srose->srose_family = AF_ROSE;
|
||||
srose->srose_addr = rose->dest_addr;
|
||||
srose->srose_call = rose->dest_call;
|
||||
|
|
|
@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
/* copy the peer address and timestamp */
|
||||
if (!continue_call) {
|
||||
if (msg->msg_name && msg->msg_namelen > 0)
|
||||
if (msg->msg_name) {
|
||||
size_t len =
|
||||
sizeof(call->conn->trans->peer->srx);
|
||||
memcpy(msg->msg_name,
|
||||
&call->conn->trans->peer->srx,
|
||||
sizeof(call->conn->trans->peer->srx));
|
||||
&call->conn->trans->peer->srx, len);
|
||||
msg->msg_namelen = len;
|
||||
}
|
||||
sock_recv_ts_and_drops(msg, &rx->sk, skb);
|
||||
}
|
||||
|
||||
|
|
20
net/socket.c
20
net/socket.c
|
@ -221,12 +221,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
|
|||
int err;
|
||||
int len;
|
||||
|
||||
BUG_ON(klen > sizeof(struct sockaddr_storage));
|
||||
err = get_user(len, ulen);
|
||||
if (err)
|
||||
return err;
|
||||
if (len > klen)
|
||||
len = klen;
|
||||
if (len < 0 || len > sizeof(struct sockaddr_storage))
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
if (len) {
|
||||
if (audit_sockaddr(klen, kaddr))
|
||||
|
@ -1840,8 +1841,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
|
|||
msg.msg_iov = &iov;
|
||||
iov.iov_len = size;
|
||||
iov.iov_base = ubuf;
|
||||
msg.msg_name = (struct sockaddr *)&address;
|
||||
msg.msg_namelen = sizeof(address);
|
||||
/* Save some cycles and don't copy the address if not needed */
|
||||
msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
|
||||
/* We assume all kernel code knows the size of sockaddr_storage */
|
||||
msg.msg_namelen = 0;
|
||||
if (sock->file->f_flags & O_NONBLOCK)
|
||||
flags |= MSG_DONTWAIT;
|
||||
err = sock_recvmsg(sock, &msg, size, flags);
|
||||
|
@ -2221,16 +2224,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the user-mode address (verify_iovec will change the
|
||||
/* Save the user-mode address (verify_iovec will change the
|
||||
* kernel msghdr to use the kernel address space)
|
||||
*/
|
||||
|
||||
uaddr = (__force void __user *)msg_sys->msg_name;
|
||||
uaddr_len = COMPAT_NAMELEN(msg);
|
||||
if (MSG_CMSG_COMPAT & flags) {
|
||||
if (MSG_CMSG_COMPAT & flags)
|
||||
err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
|
||||
} else
|
||||
else
|
||||
err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
|
||||
if (err < 0)
|
||||
goto out_freeiov;
|
||||
|
@ -2239,6 +2240,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|||
cmsg_ptr = (unsigned long)msg_sys->msg_control;
|
||||
msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
|
||||
|
||||
/* We assume all kernel code knows the size of sockaddr_storage */
|
||||
msg_sys->msg_namelen = 0;
|
||||
|
||||
if (sock->file->f_flags & O_NONBLOCK)
|
||||
flags |= MSG_DONTWAIT;
|
||||
err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
|
||||
|
|
|
@ -980,9 +980,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* will be updated in set_orig_addr() if needed */
|
||||
m->msg_namelen = 0;
|
||||
|
||||
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
|
||||
restart:
|
||||
|
||||
|
@ -1091,9 +1088,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* will be updated in set_orig_addr() if needed */
|
||||
m->msg_namelen = 0;
|
||||
|
||||
target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
|
||||
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
|
||||
|
||||
|
|
|
@ -1754,7 +1754,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
|
|||
{
|
||||
struct unix_sock *u = unix_sk(sk);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
if (u->addr) {
|
||||
msg->msg_namelen = u->addr->len;
|
||||
memcpy(msg->msg_name, u->addr->name, u->addr->len);
|
||||
|
@ -1778,8 +1777,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (flags&MSG_OOB)
|
||||
goto out;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
err = mutex_lock_interruptible(&u->readlock);
|
||||
if (err) {
|
||||
err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
|
||||
|
@ -1924,8 +1921,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
|
||||
timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
/* Lock the socket to prevent queue disordering
|
||||
* while sleeps in memcpy_tomsg
|
||||
*/
|
||||
|
|
|
@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
|
|||
vsk = vsock_sk(sk);
|
||||
err = 0;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state != SS_CONNECTED) {
|
||||
|
|
|
@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
|
|||
if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
||||
/* Retrieve the head sk_buff from the socket's receive queue. */
|
||||
err = 0;
|
||||
skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
|
||||
|
|
|
@ -610,7 +610,6 @@ int __init wimax_subsys_init(void)
|
|||
d_fnend(4, NULL, "() = 0\n");
|
||||
return 0;
|
||||
|
||||
genl_unregister_family(&wimax_gnl_family);
|
||||
error_register_family:
|
||||
d_fnend(4, NULL, "() = %d\n", result);
|
||||
return result;
|
||||
|
|
|
@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (sx25) {
|
||||
sx25->sx25_family = AF_X25;
|
||||
sx25->sx25_addr = x25->dest_addr;
|
||||
msg->msg_namelen = sizeof(*sx25);
|
||||
}
|
||||
|
||||
msg->msg_namelen = sizeof(struct sockaddr_x25);
|
||||
|
||||
x25_check_rbuf(sk);
|
||||
rc = copied;
|
||||
out_free_dgram:
|
||||
|
|
Loading…
Reference in New Issue