diff options
author | David S. Miller <davem@davemloft.net> | 2011-02-04 18:55:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-04 18:59:53 -0500 |
commit | 92d8682926342d2b6aa5b2ecc02221e00e1573a0 (patch) | |
tree | 7f70b9cc2975716ab60ddd632b9fecf0a51b828d /net/ipv6/icmp.c | |
parent | 0131ba451e20239c5dc701027c1a2edef95e1a6e (diff) |
inetpeer: Move ICMP rate limiting state into inet_peer entries.
Like metrics, the ICMP rate limiting bits are cached state about
a destination. So move it into the inet_peer entries.
If an inet_peer cannot be bound (the reason is memory allocation
failure or similar), the policy is to allow.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r-- | net/ipv6/icmp.c | 16 |
1 files changed, 9 insertions, 7 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 | */ |
160 | static inline int icmpv6_xrlim_allow(struct sock *sk, u8 type, | 160 | static 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; |