aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/icmp.c16
-rw-r--r--net/ipv6/ip6_output.c5
-rw-r--r--net/ipv6/ndisc.c4
3 files changed, 16 insertions, 9 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 03e62f94ff8e..a31d91b04c87 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,20 +157,20 @@ static int is_ineligible(struct sk_buff *skb)
157/* 157/*
158 * Check the ICMP output rate limit 158 * Check the ICMP output rate limit
159 */ 159 */
160static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type, 160static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
161 struct flowi *fl) 161 struct flowi *fl)
162{ 162{
163 struct dst_entry *dst; 163 struct dst_entry *dst;
164 struct net *net = sock_net(sk); 164 struct net *net = sock_net(sk);
165 int res = 0; 165 bool res = false;
166 166
167 /* Informational messages are not limited. */ 167 /* Informational messages are not limited. */
168 if (type & ICMPV6_INFOMSG_MASK) 168 if (type & ICMPV6_INFOMSG_MASK)
169 return 1; 169 return true;
170 170
171 /* Do not limit pmtu discovery, it would break it. */ 171 /* Do not limit pmtu discovery, it would break it. */
172 if (type == ICMPV6_PKT_TOOBIG) 172 if (type == ICMPV6_PKT_TOOBIG)
173 return 1; 173 return true;
174 174
175 /* 175 /*
176 * Look up the output route. 176 * Look up the output route.
@@ -182,7 +182,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type,
182 IP6_INC_STATS(net, ip6_dst_idev(dst), 182 IP6_INC_STATS(net, ip6_dst_idev(dst),
183 IPSTATS_MIB_OUTNOROUTES); 183 IPSTATS_MIB_OUTNOROUTES);
184 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { 184 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
185 res = 1; 185 res = true;
186 } else { 186 } else {
187 struct rt6_info *rt = (struct rt6_info *)dst; 187 struct rt6_info *rt = (struct rt6_info *)dst;
188 int tmo = net->ipv6.sysctl.icmpv6_time; 188 int tmo = net->ipv6.sysctl.icmpv6_time;
@@ -191,7 +191,9 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type,
191 if (rt->rt6i_dst.plen < 128) 191 if (rt->rt6i_dst.plen < 128)
192 tmo >>= ((128 - rt->rt6i_dst.plen)>>5); 192 tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
193 193
194 res = xrlim_allow(dst, tmo); 194 if (!rt->rt6i_peer)
195 rt6_bind_peer(rt, 1);
196 res = inet_peer_xrlim_allow(rt->rt6i_peer, tmo);
195 } 197 }
196 dst_release(dst); 198 dst_release(dst);
197 return res; 199 return res;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5f8d242be3f3..2600e2288724 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -479,10 +479,13 @@ int ip6_forward(struct sk_buff *skb)
479 else 479 else
480 target = &hdr->daddr; 480 target = &hdr->daddr;
481 481
482 if (!rt->rt6i_peer)
483 rt6_bind_peer(rt, 1);
484
482 /* Limit redirects both by destination (here) 485 /* Limit redirects both by destination (here)
483 and by source (inside ndisc_send_redirect) 486 and by source (inside ndisc_send_redirect)
484 */ 487 */
485 if (xrlim_allow(dst, 1*HZ)) 488 if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
486 ndisc_send_redirect(skb, n, target); 489 ndisc_send_redirect(skb, n, target);
487 } else { 490 } else {
488 int addrtype = ipv6_addr_type(&hdr->saddr); 491 int addrtype = ipv6_addr_type(&hdr->saddr);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2342545a5ee9..7254ce364006 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1553,7 +1553,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1553 "ICMPv6 Redirect: destination is not a neighbour.\n"); 1553 "ICMPv6 Redirect: destination is not a neighbour.\n");
1554 goto release; 1554 goto release;
1555 } 1555 }
1556 if (!xrlim_allow(dst, 1*HZ)) 1556 if (!rt->rt6i_peer)
1557 rt6_bind_peer(rt, 1);
1558 if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
1557 goto release; 1559 goto release;
1558 1560
1559 if (dev->addr_len) { 1561 if (dev->addr_len) {