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

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (24 commits)
  usbnet: Remove over-broad module alias from zaurus.
  MAINTAINERS: drop Michael from bfin_mac driver
  net/can: activate bit-timing calculation and netlink based drivers by default
  rionet: fix NULL pointer dereference in rionet_remove
  net+crypto: Use vmalloc for zlib inflate buffers.
  netfilter: Fix ip_route_me_harder triggering ip_rt_bug
  ipv4: Fix IPsec slowpath fragmentation problem
  ipv4: Fix packet size calculation in __ip_append_data
  cxgb3: skb_record_rx_queue now records the queue index relative to the net_device.
  bridge: Only flood unregistered groups to routers
  qlge: Add maintainer.
  MAINTAINERS: mark socketcan-core lists as subscribers-only
  MAINTAINERS: Remove Sven Eckelmann from BATMAN ADVANCED
  r8169: fix wrong register use.
  net/usb/kalmia: signedness bug in kalmia_bind()
  net/usb: kalmia: Various fixes for better support of non-x86 architectures.
  rtl8192cu: Fix missing firmware load
  udp/recvmsg: Clear MSG_TRUNC flag when starting over for a new packet
  ipv6/udp: Use the correct variable to determine non-blocking condition
  netconsole: fix build when CONFIG_NETCONSOLE_DYNAMIC is turned on
  ...
This commit is contained in:
Linus Torvalds 2011-06-30 10:44:52 -07:00
commit 0e90ed0e8b
22 changed files with 155 additions and 134 deletions

View file

@ -1392,7 +1392,6 @@ F: include/linux/backlight.h
BATMAN ADVANCED
M: Marek Lindner <lindner_marek@yahoo.de>
M: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
M: Sven Eckelmann <sven@narfation.org>
L: b.a.t.m.a.n@lists.open-mesh.org
W: http://www.open-mesh.org/
S: Maintained
@ -1425,7 +1424,6 @@ S: Supported
F: arch/blackfin/
BLACKFIN EMAC DRIVER
M: Michael Hennerich <michael.hennerich@analog.com>
L: uclinux-dist-devel@blackfin.uclinux.org
W: http://blackfin.uclinux.org
S: Supported
@ -1641,7 +1639,7 @@ CAN NETWORK LAYER
M: Oliver Hartkopp <socketcan@hartkopp.net>
M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
M: Urs Thuermann <urs.thuermann@volkswagen.de>
L: socketcan-core@lists.berlios.de
L: socketcan-core@lists.berlios.de (subscribers-only)
L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/
S: Maintained
@ -1653,7 +1651,7 @@ F: include/linux/can/raw.h
CAN NETWORK DRIVERS
M: Wolfgang Grandegger <wg@grandegger.com>
L: socketcan-core@lists.berlios.de
L: socketcan-core@lists.berlios.de (subscribers-only)
L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/
S: Maintained
@ -5183,6 +5181,7 @@ S: Supported
F: drivers/net/qlcnic/
QLOGIC QLGE 10Gb ETHERNET DRIVER
M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
M: Ron Mercer <ron.mercer@qlogic.com>
M: linux-driver@qlogic.com
L: netdev@vger.kernel.org

View file

@ -32,7 +32,6 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/slab.h>
#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
#define DEFLATE_DEF_WINBITS 11
@ -73,7 +72,7 @@ static int deflate_decomp_init(struct deflate_ctx *ctx)
int ret = 0;
struct z_stream_s *stream = &ctx->decomp_stream;
stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
stream->workspace = vzalloc(zlib_inflate_workspacesize());
if (!stream->workspace) {
ret = -ENOMEM;
goto out;
@ -86,7 +85,7 @@ static int deflate_decomp_init(struct deflate_ctx *ctx)
out:
return ret;
out_free:
kfree(stream->workspace);
vfree(stream->workspace);
goto out;
}
@ -99,7 +98,7 @@ static void deflate_comp_exit(struct deflate_ctx *ctx)
static void deflate_decomp_exit(struct deflate_ctx *ctx)
{
zlib_inflateEnd(&ctx->decomp_stream);
kfree(ctx->decomp_stream.workspace);
vfree(ctx->decomp_stream.workspace);
}
static int deflate_init(struct crypto_tfm *tfm)

View file

@ -29,7 +29,6 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/slab.h>
#include <crypto/internal/compress.h>
@ -60,7 +59,7 @@ static void zlib_decomp_exit(struct zlib_ctx *ctx)
if (stream->workspace) {
zlib_inflateEnd(stream);
kfree(stream->workspace);
vfree(stream->workspace);
stream->workspace = NULL;
}
}
@ -228,13 +227,13 @@ static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
: DEF_WBITS;
stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
stream->workspace = vzalloc(zlib_inflate_workspacesize());
if (!stream->workspace)
return -ENOMEM;
ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
if (ret != Z_OK) {
kfree(stream->workspace);
vfree(stream->workspace);
stream->workspace = NULL;
return -EINVAL;
}

View file

@ -3416,7 +3416,8 @@ config NETCONSOLE
config NETCONSOLE_DYNAMIC
bool "Dynamic reconfiguration of logging targets"
depends on NETCONSOLE && SYSFS && CONFIGFS_FS
depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
!(NETCONSOLE=y && CONFIGFS_FS=m)
help
This option enables the ability to dynamically reconfigure target
parameters (interface, IP addresses, port numbers, MAC addresses)

View file

@ -49,6 +49,7 @@
#include <linux/zlib.h>
#include <linux/io.h>
#include <linux/stringify.h>
#include <linux/vmalloc.h>
#define BNX2X_MAIN
#include "bnx2x.h"
@ -4537,8 +4538,7 @@ static int bnx2x_gunzip_init(struct bnx2x *bp)
if (bp->strm == NULL)
goto gunzip_nomem2;
bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
GFP_KERNEL);
bp->strm->workspace = vmalloc(zlib_inflate_workspacesize());
if (bp->strm->workspace == NULL)
goto gunzip_nomem3;
@ -4562,7 +4562,7 @@ static int bnx2x_gunzip_init(struct bnx2x *bp)
static void bnx2x_gunzip_end(struct bnx2x *bp)
{
if (bp->strm) {
kfree(bp->strm->workspace);
vfree(bp->strm->workspace);
kfree(bp->strm);
bp->strm = NULL;
}

View file

@ -36,7 +36,7 @@ config CAN_SLCAN
config CAN_DEV
tristate "Platform CAN drivers with Netlink support"
depends on CAN
default Y
default y
---help---
Enables the common framework for platform CAN drivers with Netlink
support. This is the standard library for CAN drivers.
@ -45,7 +45,7 @@ config CAN_DEV
config CAN_CALC_BITTIMING
bool "CAN bit-timing calculation"
depends on CAN_DEV
default Y
default y
---help---
If enabled, CAN bit-timing parameters will be calculated for the
bit-rate specified via Netlink argument "bitrate" when the device

View file

@ -2026,7 +2026,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
skb_checksum_none_assert(skb);
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
if (unlikely(p->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
@ -2145,7 +2145,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
if (!complete)
return;
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
if (unlikely(cpl->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;

View file

@ -305,7 +305,7 @@ static void z_decomp_free(void *arg)
if (state) {
zlib_inflateEnd(&state->strm);
kfree(state->strm.workspace);
vfree(state->strm.workspace);
kfree(state);
}
}
@ -345,8 +345,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len)
state->w_size = w_size;
state->strm.next_out = NULL;
state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
GFP_KERNEL|__GFP_REPEAT);
state->strm.workspace = vmalloc(zlib_inflate_workspacesize());
if (state->strm.workspace == NULL)
goto out_free;

View file

@ -742,7 +742,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
msleep(2);
for (i = 0; i < 5; i++) {
udelay(100);
if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
break;
}

View file

@ -378,7 +378,7 @@ static int rionet_close(struct net_device *ndev)
static void rionet_remove(struct rio_dev *rdev)
{
struct net_device *ndev = NULL;
struct net_device *ndev = rio_get_drvdata(rdev);
struct rionet_peer *peer, *tmp;
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
@ -433,22 +433,12 @@ static const struct net_device_ops rionet_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
};
static int rionet_setup_netdev(struct rio_mport *mport)
static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
{
int rc = 0;
struct net_device *ndev = NULL;
struct rionet_private *rnet;
u16 device_id;
/* Allocate our net_device structure */
ndev = alloc_etherdev(sizeof(struct rionet_private));
if (ndev == NULL) {
printk(KERN_INFO "%s: could not allocate ethernet device.\n",
DRV_NAME);
rc = -ENOMEM;
goto out;
}
rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
if (!rionet_active) {
@ -504,11 +494,21 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
int rc = -ENODEV;
u32 lpef, lsrc_ops, ldst_ops;
struct rionet_peer *peer;
struct net_device *ndev = NULL;
/* If local device is not rionet capable, give up quickly */
if (!rionet_capable)
goto out;
/* Allocate our net_device structure */
ndev = alloc_etherdev(sizeof(struct rionet_private));
if (ndev == NULL) {
printk(KERN_INFO "%s: could not allocate ethernet device.\n",
DRV_NAME);
rc = -ENOMEM;
goto out;
}
/*
* First time through, make sure local device is rionet
* capable, setup netdev, and set flags so this is skipped
@ -529,7 +529,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
goto out;
}
rc = rionet_setup_netdev(rdev->net->hport);
rc = rionet_setup_netdev(rdev->net->hport, ndev);
rionet_check = 1;
}
@ -546,6 +546,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
list_add_tail(&peer->node, &rionet_peers);
}
rio_set_drvdata(rdev, ndev);
out:
return rc;
}

View file

@ -100,34 +100,42 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
static int
kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
{
char init_msg_1[] =
const static char init_msg_1[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00 };
char init_msg_2[] =
const static char init_msg_2[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
0x00, 0x00 };
char receive_buf[28];
const static int buflen = 28;
char *usb_buf;
int status;
status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1)
/ sizeof(init_msg_1[0]), receive_buf, 24);
usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL);
if (!usb_buf)
return -ENOMEM;
memcpy(usb_buf, init_msg_1, 12);
status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1)
/ sizeof(init_msg_1[0]), usb_buf, 24);
if (status != 0)
return status;
status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2)
/ sizeof(init_msg_2[0]), receive_buf, 28);
memcpy(usb_buf, init_msg_2, 12);
status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2)
/ sizeof(init_msg_2[0]), usb_buf, 28);
if (status != 0)
return status;
memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN);
memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN);
kfree(usb_buf);
return status;
}
static int
kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
{
u8 status;
int status;
u8 ethernet_addr[ETH_ALEN];
/* Don't bind to AT command interface */
@ -190,7 +198,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
dev_kfree_skb_any(skb);
skb = skb2;
done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
done:
header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
@ -201,9 +210,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
header_start[0] = 0x57;
header_start[1] = 0x44;
content_len = skb->len - KALMIA_HEADER_LENGTH;
header_start[2] = (content_len & 0xff); /* low byte */
header_start[3] = (content_len >> 8); /* high byte */
put_unaligned_le16(content_len, &header_start[2]);
header_start[4] = ether_type_1;
header_start[5] = ether_type_2;
@ -231,13 +239,13 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
* Our task here is to strip off framing, leaving skb with one
* data frame for the usbnet framework code to process.
*/
const u8 HEADER_END_OF_USB_PACKET[] =
const static u8 HEADER_END_OF_USB_PACKET[] =
{ 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
const u8 EXPECTED_UNKNOWN_HEADER_1[] =
const static u8 EXPECTED_UNKNOWN_HEADER_1[] =
{ 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
const u8 EXPECTED_UNKNOWN_HEADER_2[] =
const static u8 EXPECTED_UNKNOWN_HEADER_2[] =
{ 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
u8 i = 0;
int i = 0;
/* incomplete header? */
if (skb->len < KALMIA_HEADER_LENGTH)
@ -285,7 +293,7 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* subtract start header and end header */
usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
ether_packet_length = header_start[2] + (header_start[3] << 8);
ether_packet_length = get_unaligned_le16(&header_start[2]);
skb_pull(skb, KALMIA_HEADER_LENGTH);
/* Some small packets misses end marker */

View file

@ -331,17 +331,7 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO,
},
/* At least some of the newest PXA units have very different lies about
* their standards support: they claim to be cell phones offering
* direct access to their radios! (No, they don't conform to CDC MDLM.)
*/
{
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &bogus_mdlm_info,
}, {
/* Motorola MOTOMAGX phones */
USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),

View file

@ -1624,6 +1624,16 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
pci_read_config_byte(pdev, 0x8, &revisionid);
pci_read_config_word(pdev, 0x3C, &irqline);
/* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
* r8192e_pci, and RTL8192SE, which uses this driver. If the
* revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
* the correct driver is r8192e_pci, thus this routine should
* return false.
*/
if (deviceid == RTL_PCI_8192SE_DID &&
revisionid == RTL_PCI_REVISION_ID_8192PCIE)
return false;
if (deviceid == RTL_PCI_8192_DID ||
deviceid == RTL_PCI_0044_DID ||
deviceid == RTL_PCI_0047_DID ||
@ -1856,7 +1866,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
pci_write_config_byte(pdev, 0x04, 0x07);
/* find adapter */
_rtl_pci_find_adapter(pdev, hw);
if (!_rtl_pci_find_adapter(pdev, hw))
goto fail3;
/* Init IO handler */
_rtl_pci_io_handler_init(&pdev->dev, hw);

View file

@ -53,6 +53,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
const struct firmware *firmware;
int err;
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
@ -64,6 +66,24 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
("Can't alloc buffer for fw.\n"));
return 1;
}
/* request fw */
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
rtlpriv->io.dev);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Failed to request firmware!\n"));
return 1;
}
if (firmware->size > 0x4000) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Firmware is too big!\n"));
release_firmware(firmware);
return 1;
}
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
rtlpriv->rtlhal.fwsize = firmware->size;
release_firmware(firmware);
return 0;
}

View file

@ -608,11 +608,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
goto encrypt;
auth:
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;
hci_conn_auth(conn, sec_level, auth_type);
return 0;
if (!hci_conn_auth(conn, sec_level, auth_type))
return 0;
encrypt:
if (conn->link_mode & HCI_LM_ENCRYPT)

View file

@ -4002,21 +4002,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
}
} else if (sk->sk_state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
__u16 result;
__u16 res, stat;
if (!status) {
sk->sk_state = BT_CONFIG;
result = L2CAP_CR_SUCCESS;
if (bt_sk(sk)->defer_setup) {
struct sock *parent = bt_sk(sk)->parent;
res = L2CAP_CR_PEND;
stat = L2CAP_CS_AUTHOR_PEND;
parent->sk_data_ready(parent, 0);
} else {
sk->sk_state = BT_CONFIG;
res = L2CAP_CR_SUCCESS;
stat = L2CAP_CS_NO_INFO;
}
} else {
sk->sk_state = BT_DISCONN;
l2cap_sock_set_timer(sk, HZ / 10);
result = L2CAP_CR_SEC_BLOCK;
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
rsp.result = cpu_to_le16(res);
rsp.status = cpu_to_le16(stat);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
sizeof(rsp), &rsp);
}

View file

@ -1379,8 +1379,11 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
return -EINVAL;
if (iph->protocol != IPPROTO_IGMP)
if (iph->protocol != IPPROTO_IGMP) {
if ((iph->daddr & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP)
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
return 0;
}
len = ntohs(iph->tot_len);
if (skb->len < len || len < ip_hdrlen(skb))

View file

@ -802,8 +802,6 @@ static int __ip_append_data(struct sock *sk,
skb = skb_peek_tail(queue);
exthdrlen = !skb ? rt->dst.header_len : 0;
length += exthdrlen;
transhdrlen += exthdrlen;
mtu = cork->fragsize;
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@ -883,17 +881,16 @@ static int __ip_append_data(struct sock *sk,
else
alloclen = fraglen;
alloclen += exthdrlen;
/* The last fragment gets additional space at tail.
* Note, with MSG_MORE we overallocate on fragments,
* because we have no idea what fragment will be
* the last.
*/
if (datalen == length + fraggap) {
if (datalen == length + fraggap)
alloclen += rt->dst.trailer_len;
/* make sure mtu is not reached */
if (datalen > mtu - fragheaderlen - rt->dst.trailer_len)
datalen -= ALIGN(rt->dst.trailer_len, 8);
}
if (transhdrlen) {
skb = sock_alloc_send_skb(sk,
alloclen + hh_len + 15,
@ -926,11 +923,11 @@ static int __ip_append_data(struct sock *sk,
/*
* Find where to start putting bytes.
*/
data = skb_put(skb, fraglen);
data = skb_put(skb, fraglen + exthdrlen);
skb_set_network_header(skb, exthdrlen);
skb->transport_header = (skb->network_header +
fragheaderlen);
data += fragheaderlen;
data += fragheaderlen + exthdrlen;
if (fraggap) {
skb->csum = skb_copy_and_csum_bits(
@ -1064,7 +1061,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
*/
*rtp = NULL;
cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ?
rt->dst.dev->mtu : dst_mtu(rt->dst.path);
rt->dst.dev->mtu : dst_mtu(&rt->dst);
cork->dst = &rt->dst;
cork->length = 0;
cork->tx_flags = ipc->tx_flags;

View file

@ -17,51 +17,35 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
struct flowi4 fl4 = {};
unsigned long orefdst;
__be32 saddr = iph->saddr;
__u8 flags = 0;
unsigned int hh_len;
unsigned int type;
type = inet_addr_type(net, iph->saddr);
if (skb->sk && inet_sk(skb->sk)->transparent)
type = RTN_LOCAL;
if (addr_type == RTN_UNSPEC)
addr_type = type;
if (!skb->sk && addr_type != RTN_LOCAL) {
if (addr_type == RTN_UNSPEC)
addr_type = inet_addr_type(net, saddr);
if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
flags |= FLOWI_FLAG_ANYSRC;
else
saddr = 0;
}
/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
* packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
*/
if (addr_type == RTN_LOCAL) {
fl4.daddr = iph->daddr;
if (type == RTN_LOCAL)
fl4.saddr = iph->saddr;
fl4.flowi4_tos = RT_TOS(iph->tos);
fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl4.flowi4_mark = skb->mark;
fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt))
return -1;
fl4.daddr = iph->daddr;
fl4.saddr = saddr;
fl4.flowi4_tos = RT_TOS(iph->tos);
fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl4.flowi4_mark = skb->mark;
fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags;
rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt))
return -1;
/* Drop old route. */
skb_dst_drop(skb);
skb_dst_set(skb, &rt->dst);
} else {
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
fl4.daddr = iph->saddr;
rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt))
return -1;
orefdst = skb->_skb_refdst;
if (ip_route_input(skb, iph->daddr, iph->saddr,
RT_TOS(iph->tos), rt->dst.dev) != 0) {
dst_release(&rt->dst);
return -1;
}
dst_release(&rt->dst);
refdst_drop(orefdst);
}
/* Drop old route. */
skb_dst_drop(skb);
skb_dst_set(skb, &rt->dst);
if (skb_dst(skb)->error)
return -1;

View file

@ -40,7 +40,6 @@ static void send_reset(struct sk_buff *oldskb, int hook)
struct iphdr *niph;
const struct tcphdr *oth;
struct tcphdr _otcph, *tcph;
unsigned int addr_type;
/* IP header checks: fragment. */
if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook)
if (oth->rst)
return;
if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
return;
/* Check checksum */
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
return;
@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook)
nskb->csum_start = (unsigned char *)tcph - nskb->head;
nskb->csum_offset = offsetof(struct tcphdr, check);
addr_type = RTN_UNSPEC;
if (hook != NF_INET_FORWARD
#ifdef CONFIG_BRIDGE_NETFILTER
|| (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
#endif
)
addr_type = RTN_LOCAL;
/* ip_route_me_harder expects skb->dst to be set */
skb_dst_set_noref(nskb, skb_dst(oldskb));
nskb->protocol = htons(ETH_P_IP);
if (ip_route_me_harder(nskb, addr_type))
if (ip_route_me_harder(nskb, RTN_UNSPEC))
goto free_nskb;
niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));

View file

@ -1249,6 +1249,9 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (noblock)
return -EAGAIN;
/* starting over for a new packet */
msg->msg_flags &= ~MSG_TRUNC;
goto try_again;
}

View file

@ -453,8 +453,11 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
}
unlock_sock_fast(sk, slow);
if (flags & MSG_DONTWAIT)
if (noblock)
return -EAGAIN;
/* starting over for a new packet */
msg->msg_flags &= ~MSG_TRUNC;
goto try_again;
}