diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 23 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 5 | ||||
-rw-r--r-- | net/ipv6/route.c | 2 |
3 files changed, 23 insertions, 7 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1eafcfc95e81..352690e2ab82 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -978,12 +978,27 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; case IPV6_UNICAST_HOPS: - val = np->hop_limit; - break; - case IPV6_MULTICAST_HOPS: - val = np->mcast_hops; + { + struct dst_entry *dst; + + if (optname == IPV6_UNICAST_HOPS) + val = np->hop_limit; + else + val = np->mcast_hops; + + dst = sk_dst_get(sk); + if (dst) { + if (val < 0) + val = dst_metric(dst, RTAX_HOPLIMIT); + if (val < 0) + val = ipv6_get_hoplimit(dst->dev); + dst_release(dst); + } + if (val < 0) + val = ipv6_devconf.hop_limit; break; + } case IPV6_MULTICAST_LOOP: val = np->mc_loop; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4eec4b3988b8..99502c5da4c4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -413,6 +413,7 @@ mark_source_chains(struct xt_table_info *newinfo, unsigned int pos = newinfo->hook_entry[hook]; struct ip6t_entry *e = (struct ip6t_entry *)(entry0 + pos); + int visited = e->comefrom & (1 << hook); if (!(valid_hooks & (1 << hook))) continue; @@ -433,11 +434,11 @@ mark_source_chains(struct xt_table_info *newinfo, |= ((1 << hook) | (1 << NF_IP6_NUMHOOKS)); /* Unconditional return/END. */ - if (e->target_offset == sizeof(struct ip6t_entry) + if ((e->target_offset == sizeof(struct ip6t_entry) && (strcmp(t->target.u.user.name, IP6T_STANDARD_TARGET) == 0) && t->verdict < 0 - && unconditional(&e->ipv6)) { + && unconditional(&e->ipv6)) || visited) { unsigned int oldpos, size; if (t->verdict < -NF_MAX_VERDICT - 1) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9f80518aacbd..8c3d56871b50 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -494,7 +494,7 @@ do { \ goto out; \ pn = fn->parent; \ if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \ - fn = fib6_lookup(pn->subtree, NULL, saddr); \ + fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \ else \ fn = pn; \ if (fn->fn_flags & RTN_RTINFO) \ |