mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: arch/s390/net/bpf_jit_comp.c drivers/net/ethernet/ti/netcp_ethss.c net/bridge/br_multicast.c net/ipv4/ip_fragment.c All four conflicts were cases of simple overlapping changes. Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
commit
5510b3c2a1
417 changed files with 5237 additions and 2445 deletions
|
|
@ -1026,14 +1026,16 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
|
|||
|
||||
neigh = neigh_lookup(&arp_tbl, &ip, dev);
|
||||
if (neigh) {
|
||||
read_lock_bh(&neigh->lock);
|
||||
memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
|
||||
r->arp_flags = arp_state_to_flags(neigh);
|
||||
read_unlock_bh(&neigh->lock);
|
||||
r->arp_ha.sa_family = dev->type;
|
||||
strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
|
||||
if (!(neigh->nud_state & NUD_NOARP)) {
|
||||
read_lock_bh(&neigh->lock);
|
||||
memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
|
||||
r->arp_flags = arp_state_to_flags(neigh);
|
||||
read_unlock_bh(&neigh->lock);
|
||||
r->arp_ha.sa_family = dev->type;
|
||||
strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
|
||||
err = 0;
|
||||
}
|
||||
neigh_release(neigh);
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -882,7 +882,6 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
queue_delayed_work(system_power_efficient_wq,
|
||||
&check_lifetime_work, 0);
|
||||
rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
|
||||
blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ struct fib_alias {
|
|||
u8 fa_state;
|
||||
u8 fa_slen;
|
||||
u32 tb_id;
|
||||
s16 fa_default;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1297,23 +1297,40 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event)
|
|||
}
|
||||
|
||||
/* Must be invoked inside of an RCU protected region. */
|
||||
void fib_select_default(struct fib_result *res)
|
||||
void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
|
||||
{
|
||||
struct fib_info *fi = NULL, *last_resort = NULL;
|
||||
struct hlist_head *fa_head = res->fa_head;
|
||||
struct fib_table *tb = res->table;
|
||||
u8 slen = 32 - res->prefixlen;
|
||||
int order = -1, last_idx = -1;
|
||||
struct fib_alias *fa;
|
||||
struct fib_alias *fa, *fa1 = NULL;
|
||||
u32 last_prio = res->fi->fib_priority;
|
||||
u8 last_tos = 0;
|
||||
|
||||
hlist_for_each_entry_rcu(fa, fa_head, fa_list) {
|
||||
struct fib_info *next_fi = fa->fa_info;
|
||||
|
||||
if (fa->fa_slen != slen)
|
||||
continue;
|
||||
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
|
||||
continue;
|
||||
if (fa->tb_id != tb->tb_id)
|
||||
continue;
|
||||
if (next_fi->fib_priority > last_prio &&
|
||||
fa->fa_tos == last_tos) {
|
||||
if (last_tos)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (next_fi->fib_flags & RTNH_F_DEAD)
|
||||
continue;
|
||||
last_tos = fa->fa_tos;
|
||||
last_prio = next_fi->fib_priority;
|
||||
|
||||
if (next_fi->fib_scope != res->scope ||
|
||||
fa->fa_type != RTN_UNICAST)
|
||||
continue;
|
||||
|
||||
if (next_fi->fib_priority > res->fi->fib_priority)
|
||||
break;
|
||||
if (!next_fi->fib_nh[0].nh_gw ||
|
||||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
|
||||
continue;
|
||||
|
|
@ -1323,10 +1340,11 @@ void fib_select_default(struct fib_result *res)
|
|||
if (!fi) {
|
||||
if (next_fi != res->fi)
|
||||
break;
|
||||
fa1 = fa;
|
||||
} else if (!fib_detect_death(fi, order, &last_resort,
|
||||
&last_idx, tb->tb_default)) {
|
||||
&last_idx, fa1->fa_default)) {
|
||||
fib_result_assign(res, fi);
|
||||
tb->tb_default = order;
|
||||
fa1->fa_default = order;
|
||||
goto out;
|
||||
}
|
||||
fi = next_fi;
|
||||
|
|
@ -1334,20 +1352,21 @@ void fib_select_default(struct fib_result *res)
|
|||
}
|
||||
|
||||
if (order <= 0 || !fi) {
|
||||
tb->tb_default = -1;
|
||||
if (fa1)
|
||||
fa1->fa_default = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!fib_detect_death(fi, order, &last_resort, &last_idx,
|
||||
tb->tb_default)) {
|
||||
fa1->fa_default)) {
|
||||
fib_result_assign(res, fi);
|
||||
tb->tb_default = order;
|
||||
fa1->fa_default = order;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (last_idx >= 0)
|
||||
fib_result_assign(res, last_resort);
|
||||
tb->tb_default = last_idx;
|
||||
fa1->fa_default = last_idx;
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1171,6 +1171,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
|||
new_fa->fa_state = state & ~FA_S_ACCESSED;
|
||||
new_fa->fa_slen = fa->fa_slen;
|
||||
new_fa->tb_id = tb->tb_id;
|
||||
new_fa->fa_default = -1;
|
||||
|
||||
err = switchdev_fib_ipv4_add(key, plen, fi,
|
||||
new_fa->fa_tos,
|
||||
|
|
@ -1222,6 +1223,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
|||
new_fa->fa_state = 0;
|
||||
new_fa->fa_slen = slen;
|
||||
new_fa->tb_id = tb->tb_id;
|
||||
new_fa->fa_default = -1;
|
||||
|
||||
/* (Optionally) offload fib entry to switch hardware. */
|
||||
err = switchdev_fib_ipv4_add(key, plen, fi, tos, cfg->fc_type,
|
||||
|
|
@ -1791,8 +1793,6 @@ void fib_table_flush_external(struct fib_table *tb)
|
|||
if (hlist_empty(&n->leaf)) {
|
||||
put_child_root(pn, n->key, NULL);
|
||||
node_free(n);
|
||||
} else {
|
||||
leaf_pull_suffix(pn, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1862,8 +1862,6 @@ int fib_table_flush(struct fib_table *tb)
|
|||
if (hlist_empty(&n->leaf)) {
|
||||
put_child_root(pn, n->key, NULL);
|
||||
node_free(n);
|
||||
} else {
|
||||
leaf_pull_suffix(pn, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1990,7 +1988,6 @@ struct fib_table *fib_trie_table(u32 id, struct fib_table *alias)
|
|||
return NULL;
|
||||
|
||||
tb->tb_id = id;
|
||||
tb->tb_default = -1;
|
||||
tb->tb_num_default = 0;
|
||||
tb->tb_data = (alias ? alias->__data : tb->__data);
|
||||
|
||||
|
|
|
|||
|
|
@ -131,34 +131,22 @@ inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb)
|
|||
unsigned int evicted = 0;
|
||||
HLIST_HEAD(expired);
|
||||
|
||||
evict_again:
|
||||
spin_lock(&hb->chain_lock);
|
||||
|
||||
hlist_for_each_entry_safe(fq, n, &hb->chain, list) {
|
||||
if (!inet_fragq_should_evict(fq))
|
||||
continue;
|
||||
|
||||
if (!del_timer(&fq->timer)) {
|
||||
/* q expiring right now thus increment its refcount so
|
||||
* it won't be freed under us and wait until the timer
|
||||
* has finished executing then destroy it
|
||||
*/
|
||||
atomic_inc(&fq->refcnt);
|
||||
spin_unlock(&hb->chain_lock);
|
||||
del_timer_sync(&fq->timer);
|
||||
inet_frag_put(fq, f);
|
||||
goto evict_again;
|
||||
}
|
||||
if (!del_timer(&fq->timer))
|
||||
continue;
|
||||
|
||||
fq->flags |= INET_FRAG_EVICTED;
|
||||
hlist_del(&fq->list);
|
||||
hlist_add_head(&fq->list, &expired);
|
||||
hlist_add_head(&fq->list_evictor, &expired);
|
||||
++evicted;
|
||||
}
|
||||
|
||||
spin_unlock(&hb->chain_lock);
|
||||
|
||||
hlist_for_each_entry_safe(fq, n, &expired, list)
|
||||
hlist_for_each_entry_safe(fq, n, &expired, list_evictor)
|
||||
f->frag_expire((unsigned long) fq);
|
||||
|
||||
return evicted;
|
||||
|
|
@ -240,18 +228,20 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
|
|||
int i;
|
||||
|
||||
nf->low_thresh = 0;
|
||||
local_bh_disable();
|
||||
|
||||
evict_again:
|
||||
local_bh_disable();
|
||||
seq = read_seqbegin(&f->rnd_seqlock);
|
||||
|
||||
for (i = 0; i < INETFRAGS_HASHSZ ; i++)
|
||||
inet_evict_bucket(f, &f->hash[i]);
|
||||
|
||||
if (read_seqretry(&f->rnd_seqlock, seq))
|
||||
goto evict_again;
|
||||
|
||||
local_bh_enable();
|
||||
cond_resched();
|
||||
|
||||
if (read_seqretry(&f->rnd_seqlock, seq) ||
|
||||
percpu_counter_sum(&nf->mem))
|
||||
goto evict_again;
|
||||
|
||||
percpu_counter_destroy(&nf->mem);
|
||||
}
|
||||
|
|
@ -284,8 +274,8 @@ static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
|
|||
struct inet_frag_bucket *hb;
|
||||
|
||||
hb = get_frag_bucket_locked(fq, f);
|
||||
if (!(fq->flags & INET_FRAG_EVICTED))
|
||||
hlist_del(&fq->list);
|
||||
hlist_del(&fq->list);
|
||||
fq->flags |= INET_FRAG_COMPLETE;
|
||||
spin_unlock(&hb->chain_lock);
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +287,6 @@ void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
|
|||
if (!(fq->flags & INET_FRAG_COMPLETE)) {
|
||||
fq_unlink(fq, f);
|
||||
atomic_dec(&fq->refcnt);
|
||||
fq->flags |= INET_FRAG_COMPLETE;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_kill);
|
||||
|
|
@ -330,11 +319,12 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f)
|
|||
fp = xp;
|
||||
}
|
||||
sum = sum_truesize + f->qsize;
|
||||
sub_frag_mem_limit(q, sum);
|
||||
|
||||
if (f->destructor)
|
||||
f->destructor(q);
|
||||
kmem_cache_free(f->frags_cachep, q);
|
||||
|
||||
sub_frag_mem_limit(nf, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_destroy);
|
||||
|
||||
|
|
@ -390,7 +380,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
|
|||
|
||||
q->net = nf;
|
||||
f->constructor(q, arg);
|
||||
add_frag_mem_limit(q, f->qsize);
|
||||
add_frag_mem_limit(nf, f->qsize);
|
||||
|
||||
setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
|
||||
spin_lock_init(&q->lock);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ static void ip_expire(unsigned long arg)
|
|||
ipq_kill(qp);
|
||||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
|
||||
|
||||
if (!(qp->q.flags & INET_FRAG_EVICTED)) {
|
||||
if (!inet_frag_evicting(&qp->q)) {
|
||||
struct sk_buff *head = qp->q.fragments;
|
||||
const struct iphdr *iph;
|
||||
int err;
|
||||
|
|
@ -309,7 +309,7 @@ static int ip_frag_reinit(struct ipq *qp)
|
|||
kfree_skb(fp);
|
||||
fp = xp;
|
||||
} while (fp);
|
||||
sub_frag_mem_limit(&qp->q, sum_truesize);
|
||||
sub_frag_mem_limit(qp->q.net, sum_truesize);
|
||||
|
||||
qp->q.flags = 0;
|
||||
qp->q.len = 0;
|
||||
|
|
@ -455,7 +455,7 @@ found:
|
|||
qp->q.fragments = next;
|
||||
|
||||
qp->q.meat -= free_it->len;
|
||||
sub_frag_mem_limit(&qp->q, free_it->truesize);
|
||||
sub_frag_mem_limit(qp->q.net, free_it->truesize);
|
||||
kfree_skb(free_it);
|
||||
}
|
||||
}
|
||||
|
|
@ -479,7 +479,7 @@ found:
|
|||
qp->q.stamp = skb->tstamp;
|
||||
qp->q.meat += skb->len;
|
||||
qp->ecn |= ecn;
|
||||
add_frag_mem_limit(&qp->q, skb->truesize);
|
||||
add_frag_mem_limit(qp->q.net, skb->truesize);
|
||||
if (offset == 0)
|
||||
qp->q.flags |= INET_FRAG_FIRST_IN;
|
||||
|
||||
|
|
@ -586,7 +586,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
|||
head->len -= clone->len;
|
||||
clone->csum = 0;
|
||||
clone->ip_summed = head->ip_summed;
|
||||
add_frag_mem_limit(&qp->q, clone->truesize);
|
||||
add_frag_mem_limit(qp->q.net, clone->truesize);
|
||||
}
|
||||
|
||||
skb_shinfo(head)->frag_list = head->next;
|
||||
|
|
@ -601,7 +601,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
|||
head->csum = csum_add(head->csum, fp->csum);
|
||||
head->truesize += fp->truesize;
|
||||
}
|
||||
sub_frag_mem_limit(&qp->q, head->truesize);
|
||||
sub_frag_mem_limit(qp->q.net, head->truesize);
|
||||
|
||||
head->next = NULL;
|
||||
head->dev = dev;
|
||||
|
|
|
|||
|
|
@ -2194,7 +2194,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
|
|||
if (!res.prefixlen &&
|
||||
res.table->tb_num_default > 1 &&
|
||||
res.type == RTN_UNICAST && !fl4->flowi4_oif)
|
||||
fib_select_default(&res);
|
||||
fib_select_default(fl4, &res);
|
||||
|
||||
if (!fl4->saddr)
|
||||
fl4->saddr = FIB_RES_PREFSRC(net, res);
|
||||
|
|
|
|||
|
|
@ -780,7 +780,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
|
|||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
sk_wait_data(sk, &timeo);
|
||||
sk_wait_data(sk, &timeo, NULL);
|
||||
if (signal_pending(current)) {
|
||||
ret = sock_intr_errno(timeo);
|
||||
break;
|
||||
|
|
@ -1575,7 +1575,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
|||
int target; /* Read at least this many bytes */
|
||||
long timeo;
|
||||
struct task_struct *user_recv = NULL;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb, *last;
|
||||
u32 urg_hole = 0;
|
||||
|
||||
if (unlikely(flags & MSG_ERRQUEUE))
|
||||
|
|
@ -1635,7 +1635,9 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
|||
|
||||
/* Next get a buffer. */
|
||||
|
||||
last = skb_peek_tail(&sk->sk_receive_queue);
|
||||
skb_queue_walk(&sk->sk_receive_queue, skb) {
|
||||
last = skb;
|
||||
/* Now that we have two receive queues this
|
||||
* shouldn't happen.
|
||||
*/
|
||||
|
|
@ -1754,8 +1756,9 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
|
|||
/* Do not sleep, just process backlog. */
|
||||
release_sock(sk);
|
||||
lock_sock(sk);
|
||||
} else
|
||||
sk_wait_data(sk, &timeo);
|
||||
} else {
|
||||
sk_wait_data(sk, &timeo, last);
|
||||
}
|
||||
|
||||
if (user_recv) {
|
||||
int chunk;
|
||||
|
|
|
|||
Loading…
Reference in a new issue