Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Conflicts were all overlapping changes. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -1385,9 +1385,18 @@ static struct rt6_info *ip6_rt_pcpu_alloc(const struct fib6_result *res)
|
||||
}
|
||||
ip6_rt_copy_init(pcpu_rt, res);
|
||||
pcpu_rt->rt6i_flags |= RTF_PCPU;
|
||||
|
||||
if (f6i->nh)
|
||||
pcpu_rt->sernum = rt_genid_ipv6(dev_net(dev));
|
||||
|
||||
return pcpu_rt;
|
||||
}
|
||||
|
||||
static bool rt6_is_valid(const struct rt6_info *rt6)
|
||||
{
|
||||
return rt6->sernum == rt_genid_ipv6(dev_net(rt6->dst.dev));
|
||||
}
|
||||
|
||||
/* It should be called with rcu_read_lock() acquired */
|
||||
static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res)
|
||||
{
|
||||
@@ -1395,6 +1404,19 @@ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res)
|
||||
|
||||
pcpu_rt = this_cpu_read(*res->nh->rt6i_pcpu);
|
||||
|
||||
if (pcpu_rt && pcpu_rt->sernum && !rt6_is_valid(pcpu_rt)) {
|
||||
struct rt6_info *prev, **p;
|
||||
|
||||
p = this_cpu_ptr(res->nh->rt6i_pcpu);
|
||||
prev = xchg(p, NULL);
|
||||
if (prev) {
|
||||
dst_dev_put(&prev->dst);
|
||||
dst_release(&prev->dst);
|
||||
}
|
||||
|
||||
pcpu_rt = NULL;
|
||||
}
|
||||
|
||||
return pcpu_rt;
|
||||
}
|
||||
|
||||
@@ -2593,6 +2615,9 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
|
||||
|
||||
rt = container_of(dst, struct rt6_info, dst);
|
||||
|
||||
if (rt->sernum)
|
||||
return rt6_is_valid(rt) ? dst : NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* All IPV6 dsts are created with ->obsolete set to the value
|
||||
|
@@ -27,8 +27,9 @@
|
||||
|
||||
bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
|
||||
{
|
||||
int trailing;
|
||||
unsigned int tlv_offset;
|
||||
int max_last_entry;
|
||||
int trailing;
|
||||
|
||||
if (srh->type != IPV6_SRCRT_TYPE_4)
|
||||
return false;
|
||||
@@ -36,7 +37,12 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
|
||||
if (((srh->hdrlen + 1) << 3) != len)
|
||||
return false;
|
||||
|
||||
if (srh->segments_left > srh->first_segment)
|
||||
max_last_entry = (srh->hdrlen / 2) - 1;
|
||||
|
||||
if (srh->first_segment > max_last_entry)
|
||||
return false;
|
||||
|
||||
if (srh->segments_left > srh->first_segment + 1)
|
||||
return false;
|
||||
|
||||
tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4);
|
||||
|
Reference in New Issue
Block a user