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: (38 commits) ip_gre: include route header_len in max_headroom calculation if_tunnel.h: add missing ams/byteorder.h include ipv4: Don't drop redirected route cache entry unless PTMU actually expired net: suppress lockdep-RCU false positive in FIB trie. Bluetooth: Fix kernel crash on L2CAP stress tests Bluetooth: Convert debug files to actually use debugfs instead of sysfs Bluetooth: Fix potential bad memory access with sysfs files netfilter: ctnetlink: fix reliable event delivery if message building fails netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err() NET_DMA: free skbs periodically netlink: fix unaligned access in nla_get_be64() tcp: Fix tcp_mark_head_lost() with packets == 0 net: ipmr/ip6mr: fix potential out-of-bounds vif_table access KS8695: update ksp->next_rx_desc_read at the end of rx loop igb: Add support for 82576 ET2 Quad Port Server Adapter ixgbevf: Message formatting cleanups ixgbevf: Shorten up delay timer for watchdog task ixgbevf: Fix VF Stats accounting after reset ixgbe: Set IXGBE_RSC_CB(skb)->DMA field to zero after unmapping the address ixgbe: fix for real_num_tx_queues update issue ...
This commit is contained in:
@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
|
||||
if (netpoll_rx(skb))
|
||||
return NET_RX_DROP;
|
||||
|
||||
if (skb_bond_should_drop(skb))
|
||||
if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
|
||||
goto drop;
|
||||
|
||||
skb->skb_iif = skb->dev->ifindex;
|
||||
@@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
|
||||
{
|
||||
struct sk_buff *p;
|
||||
|
||||
if (skb_bond_should_drop(skb))
|
||||
if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
|
||||
goto drop;
|
||||
|
||||
skb->skb_iif = skb->dev->ifindex;
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
||||
struct class *bt_class = NULL;
|
||||
EXPORT_SYMBOL_GPL(bt_class);
|
||||
static struct class *bt_class;
|
||||
|
||||
struct dentry *bt_debugfs = NULL;
|
||||
EXPORT_SYMBOL_GPL(bt_debugfs);
|
||||
|
||||
+35
-13
@@ -40,6 +40,8 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/crc16.h>
|
||||
#include <net/sock.h>
|
||||
@@ -2830,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
||||
int len = cmd->len - sizeof(*rsp);
|
||||
char req[64];
|
||||
|
||||
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
|
||||
l2cap_send_disconn_req(conn, sk);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* throw out any old stored conf requests */
|
||||
result = L2CAP_CONF_SUCCESS;
|
||||
len = l2cap_parse_conf_rsp(sk, rsp->data,
|
||||
@@ -3937,31 +3944,42 @@ drop:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t l2cap_sysfs_show(struct class *dev,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
static int l2cap_debugfs_show(struct seq_file *f, void *p)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &l2cap_sk_list.head) {
|
||||
struct l2cap_pinfo *pi = l2cap_pi(sk);
|
||||
|
||||
str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
|
||||
pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
|
||||
seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src),
|
||||
batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, __le16_to_cpu(pi->psm),
|
||||
pi->scid, pi->dcid,
|
||||
pi->imtu, pi->omtu, pi->sec_level);
|
||||
}
|
||||
|
||||
read_unlock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
return str - buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
|
||||
static int l2cap_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, l2cap_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations l2cap_debugfs_fops = {
|
||||
.open = l2cap_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static struct dentry *l2cap_debugfs;
|
||||
|
||||
static const struct proto_ops l2cap_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
@@ -4021,8 +4039,12 @@ static int __init l2cap_init(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (class_create_file(bt_class, &class_attr_l2cap) < 0)
|
||||
BT_ERR("Failed to create L2CAP info file");
|
||||
if (bt_debugfs) {
|
||||
l2cap_debugfs = debugfs_create_file("l2cap", 0444,
|
||||
bt_debugfs, NULL, &l2cap_debugfs_fops);
|
||||
if (!l2cap_debugfs)
|
||||
BT_ERR("Failed to create L2CAP debug file");
|
||||
}
|
||||
|
||||
BT_INFO("L2CAP ver %s", VERSION);
|
||||
BT_INFO("L2CAP socket layer initialized");
|
||||
@@ -4036,7 +4058,7 @@ error:
|
||||
|
||||
static void __exit l2cap_exit(void)
|
||||
{
|
||||
class_remove_file(bt_class, &class_attr_l2cap);
|
||||
debugfs_remove(l2cap_debugfs);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
|
||||
BT_ERR("L2CAP socket unregistration failed");
|
||||
|
||||
+29
-12
@@ -33,6 +33,8 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/kthread.h>
|
||||
@@ -2098,13 +2100,10 @@ static struct hci_cb rfcomm_cb = {
|
||||
.security_cfm = rfcomm_security_cfm
|
||||
};
|
||||
|
||||
static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
|
||||
{
|
||||
struct rfcomm_session *s;
|
||||
struct list_head *pp, *p;
|
||||
char *str = buf;
|
||||
|
||||
rfcomm_lock();
|
||||
|
||||
@@ -2114,18 +2113,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
|
||||
struct sock *sk = s->sock->sk;
|
||||
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
|
||||
|
||||
str += sprintf(str, "%s %s %ld %d %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
|
||||
seq_printf(f, "%s %s %ld %d %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src),
|
||||
batostr(&bt_sk(sk)->dst),
|
||||
d->state, d->dlci, d->mtu,
|
||||
d->rx_credits, d->tx_credits);
|
||||
}
|
||||
}
|
||||
|
||||
rfcomm_unlock();
|
||||
|
||||
return (str - buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
|
||||
static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations rfcomm_dlc_debugfs_fops = {
|
||||
.open = rfcomm_dlc_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static struct dentry *rfcomm_dlc_debugfs;
|
||||
|
||||
/* ---- Initialization ---- */
|
||||
static int __init rfcomm_init(void)
|
||||
@@ -2142,8 +2155,12 @@ static int __init rfcomm_init(void)
|
||||
goto unregister;
|
||||
}
|
||||
|
||||
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
|
||||
BT_ERR("Failed to create RFCOMM info file");
|
||||
if (bt_debugfs) {
|
||||
rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
|
||||
bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
|
||||
if (!rfcomm_dlc_debugfs)
|
||||
BT_ERR("Failed to create RFCOMM debug file");
|
||||
}
|
||||
|
||||
err = rfcomm_init_ttys();
|
||||
if (err < 0)
|
||||
@@ -2171,7 +2188,7 @@ unregister:
|
||||
|
||||
static void __exit rfcomm_exit(void)
|
||||
{
|
||||
class_remove_file(bt_class, &class_attr_rfcomm_dlc);
|
||||
debugfs_remove(rfcomm_dlc_debugfs);
|
||||
|
||||
hci_unregister_cb(&rfcomm_cb);
|
||||
|
||||
|
||||
+27
-11
@@ -40,6 +40,8 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
@@ -1061,28 +1063,38 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t rfcomm_sock_sysfs_show(struct class *dev,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&rfcomm_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &rfcomm_sk_list.head) {
|
||||
str += sprintf(str, "%s %s %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
seq_printf(f, "%s %s %d %d\n",
|
||||
batostr(&bt_sk(sk)->src),
|
||||
batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, rfcomm_pi(sk)->channel);
|
||||
}
|
||||
|
||||
read_unlock_bh(&rfcomm_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
|
||||
static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations rfcomm_sock_debugfs_fops = {
|
||||
.open = rfcomm_sock_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static struct dentry *rfcomm_sock_debugfs;
|
||||
|
||||
static const struct proto_ops rfcomm_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
@@ -1122,8 +1134,12 @@ int __init rfcomm_init_sockets(void)
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
|
||||
BT_ERR("Failed to create RFCOMM info file");
|
||||
if (bt_debugfs) {
|
||||
rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
|
||||
bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
|
||||
if (!rfcomm_sock_debugfs)
|
||||
BT_ERR("Failed to create RFCOMM debug file");
|
||||
}
|
||||
|
||||
BT_INFO("RFCOMM socket layer initialized");
|
||||
|
||||
@@ -1137,7 +1153,7 @@ error:
|
||||
|
||||
void rfcomm_cleanup_sockets(void)
|
||||
{
|
||||
class_remove_file(bt_class, &class_attr_rfcomm);
|
||||
debugfs_remove(rfcomm_sock_debugfs);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
|
||||
BT_ERR("RFCOMM socket layer unregistration failed");
|
||||
|
||||
+26
-12
@@ -38,6 +38,8 @@
|
||||
#include <linux/socket.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/list.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
@@ -953,28 +955,36 @@ drop:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t sco_sysfs_show(struct class *dev,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
static int sco_debugfs_show(struct seq_file *f, void *p)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&sco_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &sco_sk_list.head) {
|
||||
str += sprintf(str, "%s %s %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state);
|
||||
seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
|
||||
batostr(&bt_sk(sk)->dst), sk->sk_state);
|
||||
}
|
||||
|
||||
read_unlock_bh(&sco_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
|
||||
static int sco_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, sco_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations sco_debugfs_fops = {
|
||||
.open = sco_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static struct dentry *sco_debugfs;
|
||||
|
||||
static const struct proto_ops sco_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
@@ -1032,8 +1042,12 @@ static int __init sco_init(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (class_create_file(bt_class, &class_attr_sco) < 0)
|
||||
BT_ERR("Failed to create SCO info file");
|
||||
if (bt_debugfs) {
|
||||
sco_debugfs = debugfs_create_file("sco", 0444,
|
||||
bt_debugfs, NULL, &sco_debugfs_fops);
|
||||
if (!sco_debugfs)
|
||||
BT_ERR("Failed to create SCO debug file");
|
||||
}
|
||||
|
||||
BT_INFO("SCO (Voice Link) ver %s", VERSION);
|
||||
BT_INFO("SCO socket layer initialized");
|
||||
@@ -1047,7 +1061,7 @@ error:
|
||||
|
||||
static void __exit sco_exit(void)
|
||||
{
|
||||
class_remove_file(bt_class, &class_attr_sco);
|
||||
debugfs_remove(sco_debugfs);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_SCO) < 0)
|
||||
BT_ERR("SCO socket unregistration failed");
|
||||
|
||||
+5
-3
@@ -2483,6 +2483,7 @@ int netif_receive_skb(struct sk_buff *skb)
|
||||
{
|
||||
struct packet_type *ptype, *pt_prev;
|
||||
struct net_device *orig_dev;
|
||||
struct net_device *master;
|
||||
struct net_device *null_or_orig;
|
||||
struct net_device *null_or_bond;
|
||||
int ret = NET_RX_DROP;
|
||||
@@ -2503,11 +2504,12 @@ int netif_receive_skb(struct sk_buff *skb)
|
||||
|
||||
null_or_orig = NULL;
|
||||
orig_dev = skb->dev;
|
||||
if (orig_dev->master) {
|
||||
if (skb_bond_should_drop(skb))
|
||||
master = ACCESS_ONCE(orig_dev->master);
|
||||
if (master) {
|
||||
if (skb_bond_should_drop(skb, master))
|
||||
null_or_orig = orig_dev; /* deliver only exact match */
|
||||
else
|
||||
skb->dev = orig_dev->master;
|
||||
skb->dev = master;
|
||||
}
|
||||
|
||||
__get_cpu_var(netdev_rx_stat).total++;
|
||||
|
||||
+3
-1
@@ -961,7 +961,9 @@ fib_find_node(struct trie *t, u32 key)
|
||||
struct node *n;
|
||||
|
||||
pos = 0;
|
||||
n = rcu_dereference(t->trie);
|
||||
n = rcu_dereference_check(t->trie,
|
||||
rcu_read_lock_held() ||
|
||||
lockdep_rtnl_is_held());
|
||||
|
||||
while (n != NULL && NODE_TYPE(n) == T_TNODE) {
|
||||
tn = (struct tnode *) n;
|
||||
|
||||
+3
-1
@@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||
tunnel->err_count = 0;
|
||||
}
|
||||
|
||||
max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
|
||||
max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len;
|
||||
|
||||
if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
|
||||
(skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
|
||||
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
|
||||
if (max_headroom > dev->needed_headroom)
|
||||
dev->needed_headroom = max_headroom;
|
||||
if (!new_skb) {
|
||||
ip_rt_put(rt);
|
||||
txq->tx_dropped++;
|
||||
|
||||
@@ -802,6 +802,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock)
|
||||
int line;
|
||||
struct mfc_cache *uc, *c, **cp;
|
||||
|
||||
if (mfc->mfcc_parent >= MAXVIFS)
|
||||
return -ENFILE;
|
||||
|
||||
line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
|
||||
|
||||
for (cp = &net->ipv4.mfc_cache_array[line];
|
||||
|
||||
+12
-5
@@ -1441,7 +1441,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
|
||||
dev_hold(rt->u.dst.dev);
|
||||
if (rt->idev)
|
||||
in_dev_hold(rt->idev);
|
||||
rt->u.dst.obsolete = 0;
|
||||
rt->u.dst.obsolete = -1;
|
||||
rt->u.dst.lastuse = jiffies;
|
||||
rt->u.dst.path = &rt->u.dst;
|
||||
rt->u.dst.neighbour = NULL;
|
||||
@@ -1506,11 +1506,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
||||
struct dst_entry *ret = dst;
|
||||
|
||||
if (rt) {
|
||||
if (dst->obsolete) {
|
||||
if (dst->obsolete > 0) {
|
||||
ip_rt_put(rt);
|
||||
ret = NULL;
|
||||
} else if ((rt->rt_flags & RTCF_REDIRECTED) ||
|
||||
rt->u.dst.expires) {
|
||||
(rt->u.dst.expires &&
|
||||
time_after_eq(jiffies, rt->u.dst.expires))) {
|
||||
unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
|
||||
rt->fl.oif,
|
||||
rt_genid(dev_net(dst->dev)));
|
||||
@@ -1726,7 +1727,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
|
||||
|
||||
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
|
||||
{
|
||||
return NULL;
|
||||
if (rt_is_expired((struct rtable *)dst))
|
||||
return NULL;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void ipv4_dst_destroy(struct dst_entry *dst)
|
||||
@@ -1888,7 +1891,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
||||
if (!rth)
|
||||
goto e_nobufs;
|
||||
|
||||
rth->u.dst.output= ip_rt_bug;
|
||||
rth->u.dst.output = ip_rt_bug;
|
||||
rth->u.dst.obsolete = -1;
|
||||
|
||||
atomic_set(&rth->u.dst.__refcnt, 1);
|
||||
rth->u.dst.flags= DST_HOST;
|
||||
@@ -2054,6 +2058,7 @@ static int __mkroute_input(struct sk_buff *skb,
|
||||
rth->fl.oif = 0;
|
||||
rth->rt_spec_dst= spec_dst;
|
||||
|
||||
rth->u.dst.obsolete = -1;
|
||||
rth->u.dst.input = ip_forward;
|
||||
rth->u.dst.output = ip_output;
|
||||
rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
|
||||
@@ -2218,6 +2223,7 @@ local_input:
|
||||
goto e_nobufs;
|
||||
|
||||
rth->u.dst.output= ip_rt_bug;
|
||||
rth->u.dst.obsolete = -1;
|
||||
rth->rt_genid = rt_genid(net);
|
||||
|
||||
atomic_set(&rth->u.dst.__refcnt, 1);
|
||||
@@ -2444,6 +2450,7 @@ static int __mkroute_output(struct rtable **result,
|
||||
rth->rt_spec_dst= fl->fl4_src;
|
||||
|
||||
rth->u.dst.output=ip_output;
|
||||
rth->u.dst.obsolete = -1;
|
||||
rth->rt_genid = rt_genid(dev_net(dev_out));
|
||||
|
||||
RT_CACHE_STAT_INC(out_slow_tot);
|
||||
|
||||
+44
-21
@@ -429,7 +429,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
|
||||
if (tp->urg_seq == tp->copied_seq &&
|
||||
!sock_flag(sk, SOCK_URGINLINE) &&
|
||||
tp->urg_data)
|
||||
target--;
|
||||
target++;
|
||||
|
||||
/* Potential race condition. If read of tp below will
|
||||
* escape above sk->sk_state, we can be illegally awaken
|
||||
@@ -1254,6 +1254,39 @@ static void tcp_prequeue_process(struct sock *sk)
|
||||
tp->ucopy.memory = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_DMA
|
||||
static void tcp_service_net_dma(struct sock *sk, bool wait)
|
||||
{
|
||||
dma_cookie_t done, used;
|
||||
dma_cookie_t last_issued;
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
if (!tp->ucopy.dma_chan)
|
||||
return;
|
||||
|
||||
last_issued = tp->ucopy.dma_cookie;
|
||||
dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
|
||||
|
||||
do {
|
||||
if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
|
||||
last_issued, &done,
|
||||
&used) == DMA_SUCCESS) {
|
||||
/* Safe to free early-copied skbs now */
|
||||
__skb_queue_purge(&sk->sk_async_wait_queue);
|
||||
break;
|
||||
} else {
|
||||
struct sk_buff *skb;
|
||||
while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
|
||||
(dma_async_is_complete(skb->dma_cookie, done,
|
||||
used) == DMA_SUCCESS)) {
|
||||
__skb_dequeue(&sk->sk_async_wait_queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
} while (wait);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -1546,6 +1579,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
/* __ Set realtime policy in scheduler __ */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_DMA
|
||||
if (tp->ucopy.dma_chan)
|
||||
dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
|
||||
#endif
|
||||
if (copied >= target) {
|
||||
/* Do not sleep, just process backlog. */
|
||||
release_sock(sk);
|
||||
@@ -1554,6 +1591,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
sk_wait_data(sk, &timeo);
|
||||
|
||||
#ifdef CONFIG_NET_DMA
|
||||
tcp_service_net_dma(sk, false); /* Don't block */
|
||||
tp->ucopy.wakeup = 0;
|
||||
#endif
|
||||
|
||||
@@ -1633,6 +1671,9 @@ do_prequeue:
|
||||
copied = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
|
||||
|
||||
if ((offset + used) == skb->len)
|
||||
copied_early = 1;
|
||||
|
||||
@@ -1702,27 +1743,9 @@ skip_copy:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_DMA
|
||||
if (tp->ucopy.dma_chan) {
|
||||
dma_cookie_t done, used;
|
||||
tcp_service_net_dma(sk, true); /* Wait for queue to drain */
|
||||
tp->ucopy.dma_chan = NULL;
|
||||
|
||||
dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
|
||||
|
||||
while (dma_async_memcpy_complete(tp->ucopy.dma_chan,
|
||||
tp->ucopy.dma_cookie, &done,
|
||||
&used) == DMA_IN_PROGRESS) {
|
||||
/* do partial cleanup of sk_async_wait_queue */
|
||||
while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
|
||||
(dma_async_is_complete(skb->dma_cookie, done,
|
||||
used) == DMA_SUCCESS)) {
|
||||
__skb_dequeue(&sk->sk_async_wait_queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Safe to free early-copied skbs now */
|
||||
__skb_queue_purge(&sk->sk_async_wait_queue);
|
||||
tp->ucopy.dma_chan = NULL;
|
||||
}
|
||||
if (tp->ucopy.pinned_list) {
|
||||
dma_unpin_iovec_pages(tp->ucopy.pinned_list);
|
||||
tp->ucopy.pinned_list = NULL;
|
||||
|
||||
@@ -2511,6 +2511,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
|
||||
int err;
|
||||
unsigned int mss;
|
||||
|
||||
if (packets == 0)
|
||||
return;
|
||||
|
||||
WARN_ON(packets > tp->packets_out);
|
||||
if (tp->lost_skb_hint) {
|
||||
skb = tp->lost_skb_hint;
|
||||
|
||||
@@ -370,6 +370,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
|
||||
if (sk->sk_state == TCP_CLOSE)
|
||||
goto out;
|
||||
|
||||
if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
|
||||
NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
icsk = inet_csk(sk);
|
||||
tp = tcp_sk(sk);
|
||||
seq = ntohl(th->seq);
|
||||
|
||||
@@ -1113,6 +1113,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
|
||||
unsigned char ttls[MAXMIFS];
|
||||
int i;
|
||||
|
||||
if (mfc->mf6cc_parent >= MAXMIFS)
|
||||
return -ENFILE;
|
||||
|
||||
memset(ttls, 255, MAXMIFS);
|
||||
for (i = 0; i < MAXMIFS; i++) {
|
||||
if (IF_ISSET(i, &mfc->mf6cc_ifset))
|
||||
|
||||
+1
-1
@@ -879,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
|
||||
|
||||
rt = (struct rt6_info *) dst;
|
||||
|
||||
if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
|
||||
if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
|
||||
return dst;
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -582,7 +582,9 @@ nla_put_failure:
|
||||
nlmsg_failure:
|
||||
kfree_skb(skb);
|
||||
errout:
|
||||
nfnetlink_set_err(net, 0, group, -ENOBUFS);
|
||||
if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
|
||||
return -ENOBUFS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NF_CONNTRACK_EVENTS */
|
||||
|
||||
@@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfnetlink_send);
|
||||
|
||||
void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
|
||||
int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
|
||||
{
|
||||
netlink_set_err(net->nfnl, pid, group, error);
|
||||
return netlink_set_err(net->nfnl, pid, group, error);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfnetlink_set_err);
|
||||
|
||||
|
||||
@@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct sock *sk,
|
||||
struct netlink_set_err_data *p)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
int ret = 0;
|
||||
|
||||
if (sk == p->exclude_sk)
|
||||
goto out;
|
||||
@@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct sock *sk,
|
||||
!test_bit(p->group - 1, nlk->groups))
|
||||
goto out;
|
||||
|
||||
if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sk->sk_err = p->code;
|
||||
sk->sk_error_report(sk);
|
||||
out:
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,12 +1122,16 @@ out:
|
||||
* @pid: the PID of a process that we want to skip (if any)
|
||||
* @groups: the broadcast group that will notice the error
|
||||
* @code: error code, must be negative (as usual in kernelspace)
|
||||
*
|
||||
* This function returns the number of broadcast listeners that have set the
|
||||
* NETLINK_RECV_NO_ENOBUFS socket option.
|
||||
*/
|
||||
void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
|
||||
int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
|
||||
{
|
||||
struct netlink_set_err_data info;
|
||||
struct hlist_node *node;
|
||||
struct sock *sk;
|
||||
int ret = 0;
|
||||
|
||||
info.exclude_sk = ssk;
|
||||
info.pid = pid;
|
||||
@@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
|
||||
read_lock(&nl_table_lock);
|
||||
|
||||
sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
|
||||
do_one_set_err(sk, &info);
|
||||
ret += do_one_set_err(sk, &info);
|
||||
|
||||
read_unlock(&nl_table_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_set_err);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user