summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/exthdrs.c5
-rw-r--r--net/ipv6/icmp.c15
-rw-r--r--net/ipv6/ioam6.c14
-rw-r--r--net/ipv6/ioam6_iptunnel.c10
-rw-r--r--net/ipv6/ip6_fib.c2
6 files changed, 29 insertions, 19 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 31ba677d0442..69be0a67a140 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -952,7 +952,7 @@ static int __net_init inet6_net_init(struct net *net)
int err = 0;
net->ipv6.sysctl.bindv6only = 0;
- net->ipv6.sysctl.icmpv6_time = 1*HZ;
+ net->ipv6.sysctl.icmpv6_time = HZ / 10;
net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 209fdf1b1aa9..5e3610a926cf 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -931,6 +931,11 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
if (hdr->opt_len < 2 + sizeof(*trace) + trace->remlen * 4)
goto drop;
+ /* Inconsistent Pre-allocated Trace header */
+ if (trace->nodelen !=
+ ioam6_trace_compute_nodelen(be32_to_cpu(trace->type_be32)))
+ goto drop;
+
/* Ignore if the IOAM namespace is unknown */
ns = ioam6_namespace(dev_net(skb->dev), trace->namespace_id);
if (!ns)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 375ecd779fda..813d2e9edb8b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -217,16 +217,15 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
} else if (dev && (dev->flags & IFF_LOOPBACK)) {
res = true;
} else {
- struct rt6_info *rt = dst_rt6_info(dst);
- int tmo = net->ipv6.sysctl.icmpv6_time;
+ int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time);
struct inet_peer *peer;
- /* Give more bandwidth to wider prefixes. */
- if (rt->rt6i_dst.plen < 128)
- tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
-
- peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
- res = inet_peer_xrlim_allow(peer, tmo);
+ if (!tmo) {
+ res = true;
+ } else {
+ peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
+ res = inet_peer_xrlim_allow(peer, tmo);
+ }
}
rcu_read_unlock();
if (!res)
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index 9553a3200081..08b7ac8c99b7 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -690,6 +690,20 @@ struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id)
return rhashtable_lookup_fast(&nsdata->namespaces, &id, rht_ns_params);
}
+#define IOAM6_MASK_SHORT_FIELDS 0xff1ffc00
+#define IOAM6_MASK_WIDE_FIELDS 0x00e00000
+
+u8 ioam6_trace_compute_nodelen(u32 trace_type)
+{
+ u8 nodelen = hweight32(trace_type & IOAM6_MASK_SHORT_FIELDS)
+ * (sizeof(__be32) / 4);
+
+ nodelen += hweight32(trace_type & IOAM6_MASK_WIDE_FIELDS)
+ * (sizeof(__be64) / 4);
+
+ return nodelen;
+}
+
static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_namespace *ns,
struct ioam6_trace_hdr *trace,
diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c
index 1fe7894f14dd..b9f6d892a566 100644
--- a/net/ipv6/ioam6_iptunnel.c
+++ b/net/ipv6/ioam6_iptunnel.c
@@ -22,9 +22,6 @@
#include <net/ip6_route.h>
#include <net/addrconf.h>
-#define IOAM6_MASK_SHORT_FIELDS 0xff100000
-#define IOAM6_MASK_WIDE_FIELDS 0xe00000
-
struct ioam6_lwt_encap {
struct ipv6_hopopt_hdr eh;
u8 pad[2]; /* 2-octet padding for 4n-alignment */
@@ -93,13 +90,8 @@ static bool ioam6_validate_trace_hdr(struct ioam6_trace_hdr *trace)
trace->type.bit21 | trace->type.bit23)
return false;
- trace->nodelen = 0;
fields = be32_to_cpu(trace->type_be32);
-
- trace->nodelen += hweight32(fields & IOAM6_MASK_SHORT_FIELDS)
- * (sizeof(__be32) / 4);
- trace->nodelen += hweight32(fields & IOAM6_MASK_WIDE_FIELDS)
- * (sizeof(__be64) / 4);
+ trace->nodelen = ioam6_trace_compute_nodelen(fields);
return true;
}
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 9880d608392b..56058e6de490 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
fib6_add_gc_list(iter);
}
if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) &&
- !iter->fib6_nh->fib_nh_gw_family) {
+ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) {
iter->fib6_flags &= ~RTF_ADDRCONF;
iter->fib6_flags &= ~RTF_PREFIX_RT;
}