Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
This commit is contained in:
@@ -3287,7 +3287,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||
&tvlv_tt_data,
|
||||
&tt_change,
|
||||
&tt_len);
|
||||
if (!tt_len)
|
||||
if (!tt_len || !tvlv_len)
|
||||
goto unlock;
|
||||
|
||||
/* Copy the last orig_node's OGM buffer */
|
||||
@@ -3305,7 +3305,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||
&tvlv_tt_data,
|
||||
&tt_change,
|
||||
&tt_len);
|
||||
if (!tt_len)
|
||||
if (!tt_len || !tvlv_len)
|
||||
goto out;
|
||||
|
||||
/* fill the rest of the tvlv with the real TT entries */
|
||||
|
@@ -938,6 +938,7 @@ int br_sysfs_addbr(struct net_device *dev)
|
||||
if (!br->ifobj) {
|
||||
pr_info("%s: can't add kobject (directory) %s/%s\n",
|
||||
__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
|
||||
err = -ENOMEM;
|
||||
goto out3;
|
||||
}
|
||||
return 0;
|
||||
|
@@ -1107,10 +1107,7 @@ static struct net_proto_family caif_family_ops = {
|
||||
|
||||
static int __init caif_sktinit_module(void)
|
||||
{
|
||||
int err = sock_register(&caif_family_ops);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
return sock_register(&caif_family_ops);
|
||||
}
|
||||
|
||||
static void __exit caif_sktexit_module(void)
|
||||
|
@@ -1353,6 +1353,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
|
||||
dcb_unlock:
|
||||
spin_unlock_bh(&dcb_lock);
|
||||
nla_put_failure:
|
||||
err = -EMSGSIZE;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@@ -808,6 +808,13 @@ static unsigned char update_suffix(struct key_vector *tn)
|
||||
{
|
||||
unsigned char slen = tn->pos;
|
||||
unsigned long stride, i;
|
||||
unsigned char slen_max;
|
||||
|
||||
/* only vector 0 can have a suffix length greater than or equal to
|
||||
* tn->pos + tn->bits, the second highest node will have a suffix
|
||||
* length at most of tn->pos + tn->bits - 1
|
||||
*/
|
||||
slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen);
|
||||
|
||||
/* search though the list of children looking for nodes that might
|
||||
* have a suffix greater than the one we currently have. This is
|
||||
@@ -825,12 +832,8 @@ static unsigned char update_suffix(struct key_vector *tn)
|
||||
slen = n->slen;
|
||||
i &= ~(stride - 1);
|
||||
|
||||
/* if slen covers all but the last bit we can stop here
|
||||
* there will be nothing longer than that since only node
|
||||
* 0 and 1 << (bits - 1) could have that as their suffix
|
||||
* length.
|
||||
*/
|
||||
if ((slen + 1) >= (tn->pos + tn->bits))
|
||||
/* stop searching if we have hit the maximum possible value */
|
||||
if (slen >= slen_max)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1002,39 +1005,27 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn)
|
||||
return collapse(t, tn);
|
||||
|
||||
/* update parent in case halve failed */
|
||||
tp = node_parent(tn);
|
||||
|
||||
/* Return if at least one deflate was run */
|
||||
if (max_work != MAX_WORK)
|
||||
return tp;
|
||||
|
||||
/* push the suffix length to the parent node */
|
||||
if (tn->slen > tn->pos) {
|
||||
unsigned char slen = update_suffix(tn);
|
||||
|
||||
if (slen > tp->slen)
|
||||
tp->slen = slen;
|
||||
}
|
||||
|
||||
return tp;
|
||||
return node_parent(tn);
|
||||
}
|
||||
|
||||
static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l)
|
||||
static void node_pull_suffix(struct key_vector *tn, unsigned char slen)
|
||||
{
|
||||
while ((tp->slen > tp->pos) && (tp->slen > l->slen)) {
|
||||
if (update_suffix(tp) > l->slen)
|
||||
unsigned char node_slen = tn->slen;
|
||||
|
||||
while ((node_slen > tn->pos) && (node_slen > slen)) {
|
||||
slen = update_suffix(tn);
|
||||
if (node_slen == slen)
|
||||
break;
|
||||
tp = node_parent(tp);
|
||||
|
||||
tn = node_parent(tn);
|
||||
node_slen = tn->slen;
|
||||
}
|
||||
}
|
||||
|
||||
static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l)
|
||||
static void node_push_suffix(struct key_vector *tn, unsigned char slen)
|
||||
{
|
||||
/* if this is a new leaf then tn will be NULL and we can sort
|
||||
* out parent suffix lengths as a part of trie_rebalance
|
||||
*/
|
||||
while (tn->slen < l->slen) {
|
||||
tn->slen = l->slen;
|
||||
while (tn->slen < slen) {
|
||||
tn->slen = slen;
|
||||
tn = node_parent(tn);
|
||||
}
|
||||
}
|
||||
@@ -1155,6 +1146,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp,
|
||||
}
|
||||
|
||||
/* Case 3: n is NULL, and will just insert a new leaf */
|
||||
node_push_suffix(tp, new->fa_slen);
|
||||
NODE_INIT_PARENT(l, tp);
|
||||
put_child_root(tp, key, l);
|
||||
trie_rebalance(t, tp);
|
||||
@@ -1196,7 +1188,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp,
|
||||
/* if we added to the tail node then we need to update slen */
|
||||
if (l->slen < new->fa_slen) {
|
||||
l->slen = new->fa_slen;
|
||||
leaf_push_suffix(tp, l);
|
||||
node_push_suffix(tp, new->fa_slen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1588,6 +1580,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
|
||||
* out parent suffix lengths as a part of trie_rebalance
|
||||
*/
|
||||
if (hlist_empty(&l->leaf)) {
|
||||
if (tp->slen == l->slen)
|
||||
node_pull_suffix(tp, tp->pos);
|
||||
put_child_root(tp, l->key, NULL);
|
||||
node_free(l);
|
||||
trie_rebalance(t, tp);
|
||||
@@ -1600,7 +1594,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
|
||||
|
||||
/* update the trie with the latest suffix length */
|
||||
l->slen = fa->fa_slen;
|
||||
leaf_pull_suffix(tp, l);
|
||||
node_pull_suffix(tp, fa->fa_slen);
|
||||
}
|
||||
|
||||
/* Caller must hold RTNL. */
|
||||
@@ -1872,6 +1866,10 @@ void fib_table_flush_external(struct fib_table *tb)
|
||||
if (IS_TRIE(pn))
|
||||
break;
|
||||
|
||||
/* update the suffix to address pulled leaves */
|
||||
if (pn->slen > pn->pos)
|
||||
update_suffix(pn);
|
||||
|
||||
/* resize completed node */
|
||||
pn = resize(t, pn);
|
||||
cindex = get_index(pkey, pn);
|
||||
@@ -1938,6 +1936,10 @@ int fib_table_flush(struct net *net, struct fib_table *tb)
|
||||
if (IS_TRIE(pn))
|
||||
break;
|
||||
|
||||
/* update the suffix to address pulled leaves */
|
||||
if (pn->slen > pn->pos)
|
||||
update_suffix(pn);
|
||||
|
||||
/* resize completed node */
|
||||
pn = resize(t, pn);
|
||||
cindex = get_index(pkey, pn);
|
||||
|
@@ -657,6 +657,10 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
|
||||
if (len > 0xFFFF)
|
||||
return -EMSGSIZE;
|
||||
|
||||
/* Must have at least a full ICMP header. */
|
||||
if (len < icmph_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Check the flags.
|
||||
*/
|
||||
|
@@ -129,6 +129,23 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
|
||||
#define REXMIT_LOST 1 /* retransmit packets marked lost */
|
||||
#define REXMIT_NEW 2 /* FRTO-style transmit of unsent/new packets */
|
||||
|
||||
static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb)
|
||||
{
|
||||
static bool __once __read_mostly;
|
||||
|
||||
if (!__once) {
|
||||
struct net_device *dev;
|
||||
|
||||
__once = true;
|
||||
|
||||
rcu_read_lock();
|
||||
dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
|
||||
pr_warn("%s: Driver has suspect GRO implementation, TCP performance may be compromised.\n",
|
||||
dev ? dev->name : "Unknown driver");
|
||||
rcu_read_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* Adapt the MSS value used to make delayed ack decision to the
|
||||
* real world.
|
||||
*/
|
||||
@@ -145,7 +162,10 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
|
||||
*/
|
||||
len = skb_shinfo(skb)->gso_size ? : skb->len;
|
||||
if (len >= icsk->icsk_ack.rcv_mss) {
|
||||
icsk->icsk_ack.rcv_mss = len;
|
||||
icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
|
||||
tcp_sk(sk)->advmss);
|
||||
if (unlikely(icsk->icsk_ack.rcv_mss != len))
|
||||
tcp_gro_dev_warn(sk, skb);
|
||||
} else {
|
||||
/* Otherwise, we make more careful check taking into account,
|
||||
* that SACKs block is variable.
|
||||
|
@@ -1252,7 +1252,7 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
if (!nla)
|
||||
continue;
|
||||
|
||||
switch(index) {
|
||||
switch (index) {
|
||||
case RTA_OIF:
|
||||
cfg->rc_ifindex = nla_get_u32(nla);
|
||||
break;
|
||||
|
@@ -322,11 +322,13 @@ static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
|
||||
sk_mem_charge(sk, skb->truesize);
|
||||
}
|
||||
|
||||
static void __netlink_sock_destruct(struct sock *sk)
|
||||
static void netlink_sock_destruct(struct sock *sk)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
|
||||
if (nlk->cb_running) {
|
||||
if (nlk->cb.done)
|
||||
nlk->cb.done(&nlk->cb);
|
||||
module_put(nlk->cb.module);
|
||||
kfree_skb(nlk->cb.skb);
|
||||
}
|
||||
@@ -348,21 +350,7 @@ static void netlink_sock_destruct_work(struct work_struct *work)
|
||||
struct netlink_sock *nlk = container_of(work, struct netlink_sock,
|
||||
work);
|
||||
|
||||
nlk->cb.done(&nlk->cb);
|
||||
__netlink_sock_destruct(&nlk->sk);
|
||||
}
|
||||
|
||||
static void netlink_sock_destruct(struct sock *sk)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
|
||||
if (nlk->cb_running && nlk->cb.done) {
|
||||
INIT_WORK(&nlk->work, netlink_sock_destruct_work);
|
||||
schedule_work(&nlk->work);
|
||||
return;
|
||||
}
|
||||
|
||||
__netlink_sock_destruct(sk);
|
||||
sk_free(&nlk->sk);
|
||||
}
|
||||
|
||||
/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
|
||||
@@ -667,8 +655,18 @@ out_module:
|
||||
static void deferred_put_nlk_sk(struct rcu_head *head)
|
||||
{
|
||||
struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
|
||||
struct sock *sk = &nlk->sk;
|
||||
|
||||
sock_put(&nlk->sk);
|
||||
if (!atomic_dec_and_test(&sk->sk_refcnt))
|
||||
return;
|
||||
|
||||
if (nlk->cb_running && nlk->cb.done) {
|
||||
INIT_WORK(&nlk->work, netlink_sock_destruct_work);
|
||||
schedule_work(&nlk->work);
|
||||
return;
|
||||
}
|
||||
|
||||
sk_free(sk);
|
||||
}
|
||||
|
||||
static int netlink_release(struct socket *sock)
|
||||
|
Reference in New Issue
Block a user