diff options
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r-- | net/ipv4/icmp.c | 203 |
1 files changed, 121 insertions, 82 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 40508babad8c..f064031f2031 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -93,6 +93,7 @@ | |||
93 | #include <asm/uaccess.h> | 93 | #include <asm/uaccess.h> |
94 | #include <net/checksum.h> | 94 | #include <net/checksum.h> |
95 | #include <net/xfrm.h> | 95 | #include <net/xfrm.h> |
96 | #include <net/inet_common.h> | ||
96 | 97 | ||
97 | /* | 98 | /* |
98 | * Build xmit assembly blocks | 99 | * Build xmit assembly blocks |
@@ -188,29 +189,6 @@ struct icmp_err icmp_err_convert[] = { | |||
188 | }, | 189 | }, |
189 | }; | 190 | }; |
190 | 191 | ||
191 | /* Control parameters for ECHO replies. */ | ||
192 | int sysctl_icmp_echo_ignore_all __read_mostly; | ||
193 | int sysctl_icmp_echo_ignore_broadcasts __read_mostly = 1; | ||
194 | |||
195 | /* Control parameter - ignore bogus broadcast responses? */ | ||
196 | int sysctl_icmp_ignore_bogus_error_responses __read_mostly = 1; | ||
197 | |||
198 | /* | ||
199 | * Configurable global rate limit. | ||
200 | * | ||
201 | * ratelimit defines tokens/packet consumed for dst->rate_token bucket | ||
202 | * ratemask defines which icmp types are ratelimited by setting | ||
203 | * it's bit position. | ||
204 | * | ||
205 | * default: | ||
206 | * dest unreachable (3), source quench (4), | ||
207 | * time exceeded (11), parameter problem (12) | ||
208 | */ | ||
209 | |||
210 | int sysctl_icmp_ratelimit __read_mostly = 1 * HZ; | ||
211 | int sysctl_icmp_ratemask __read_mostly = 0x1818; | ||
212 | int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly; | ||
213 | |||
214 | /* | 192 | /* |
215 | * ICMP control array. This specifies what to do with each ICMP. | 193 | * ICMP control array. This specifies what to do with each ICMP. |
216 | */ | 194 | */ |
@@ -229,14 +207,16 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; | |||
229 | * | 207 | * |
230 | * On SMP we have one ICMP socket per-cpu. | 208 | * On SMP we have one ICMP socket per-cpu. |
231 | */ | 209 | */ |
232 | static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; | 210 | static struct sock *icmp_sk(struct net *net) |
233 | #define icmp_socket __get_cpu_var(__icmp_socket) | 211 | { |
212 | return net->ipv4.icmp_sk[smp_processor_id()]; | ||
213 | } | ||
234 | 214 | ||
235 | static inline int icmp_xmit_lock(void) | 215 | static inline int icmp_xmit_lock(struct sock *sk) |
236 | { | 216 | { |
237 | local_bh_disable(); | 217 | local_bh_disable(); |
238 | 218 | ||
239 | if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) { | 219 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { |
240 | /* This can happen if the output path signals a | 220 | /* This can happen if the output path signals a |
241 | * dst_link_failure() for an outgoing ICMP packet. | 221 | * dst_link_failure() for an outgoing ICMP packet. |
242 | */ | 222 | */ |
@@ -246,9 +226,9 @@ static inline int icmp_xmit_lock(void) | |||
246 | return 0; | 226 | return 0; |
247 | } | 227 | } |
248 | 228 | ||
249 | static inline void icmp_xmit_unlock(void) | 229 | static inline void icmp_xmit_unlock(struct sock *sk) |
250 | { | 230 | { |
251 | spin_unlock_bh(&icmp_socket->sk->sk_lock.slock); | 231 | spin_unlock_bh(&sk->sk_lock.slock); |
252 | } | 232 | } |
253 | 233 | ||
254 | /* | 234 | /* |
@@ -291,7 +271,8 @@ int xrlim_allow(struct dst_entry *dst, int timeout) | |||
291 | return rc; | 271 | return rc; |
292 | } | 272 | } |
293 | 273 | ||
294 | static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) | 274 | static inline int icmpv4_xrlim_allow(struct net *net, struct rtable *rt, |
275 | int type, int code) | ||
295 | { | 276 | { |
296 | struct dst_entry *dst = &rt->u.dst; | 277 | struct dst_entry *dst = &rt->u.dst; |
297 | int rc = 1; | 278 | int rc = 1; |
@@ -308,8 +289,8 @@ static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) | |||
308 | goto out; | 289 | goto out; |
309 | 290 | ||
310 | /* Limit if icmp type is enabled in ratemask. */ | 291 | /* Limit if icmp type is enabled in ratemask. */ |
311 | if ((1 << type) & sysctl_icmp_ratemask) | 292 | if ((1 << type) & net->ipv4.sysctl_icmp_ratemask) |
312 | rc = xrlim_allow(dst, sysctl_icmp_ratelimit); | 293 | rc = xrlim_allow(dst, net->ipv4.sysctl_icmp_ratelimit); |
313 | out: | 294 | out: |
314 | return rc; | 295 | return rc; |
315 | } | 296 | } |
@@ -346,19 +327,21 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, | |||
346 | static void icmp_push_reply(struct icmp_bxm *icmp_param, | 327 | static void icmp_push_reply(struct icmp_bxm *icmp_param, |
347 | struct ipcm_cookie *ipc, struct rtable *rt) | 328 | struct ipcm_cookie *ipc, struct rtable *rt) |
348 | { | 329 | { |
330 | struct sock *sk; | ||
349 | struct sk_buff *skb; | 331 | struct sk_buff *skb; |
350 | 332 | ||
351 | if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, | 333 | sk = icmp_sk(dev_net(rt->u.dst.dev)); |
334 | if (ip_append_data(sk, icmp_glue_bits, icmp_param, | ||
352 | icmp_param->data_len+icmp_param->head_len, | 335 | icmp_param->data_len+icmp_param->head_len, |
353 | icmp_param->head_len, | 336 | icmp_param->head_len, |
354 | ipc, rt, MSG_DONTWAIT) < 0) | 337 | ipc, rt, MSG_DONTWAIT) < 0) |
355 | ip_flush_pending_frames(icmp_socket->sk); | 338 | ip_flush_pending_frames(sk); |
356 | else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { | 339 | else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { |
357 | struct icmphdr *icmph = icmp_hdr(skb); | 340 | struct icmphdr *icmph = icmp_hdr(skb); |
358 | __wsum csum = 0; | 341 | __wsum csum = 0; |
359 | struct sk_buff *skb1; | 342 | struct sk_buff *skb1; |
360 | 343 | ||
361 | skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { | 344 | skb_queue_walk(&sk->sk_write_queue, skb1) { |
362 | csum = csum_add(csum, skb1->csum); | 345 | csum = csum_add(csum, skb1->csum); |
363 | } | 346 | } |
364 | csum = csum_partial_copy_nocheck((void *)&icmp_param->data, | 347 | csum = csum_partial_copy_nocheck((void *)&icmp_param->data, |
@@ -366,7 +349,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
366 | icmp_param->head_len, csum); | 349 | icmp_param->head_len, csum); |
367 | icmph->checksum = csum_fold(csum); | 350 | icmph->checksum = csum_fold(csum); |
368 | skb->ip_summed = CHECKSUM_NONE; | 351 | skb->ip_summed = CHECKSUM_NONE; |
369 | ip_push_pending_frames(icmp_socket->sk); | 352 | ip_push_pending_frames(sk); |
370 | } | 353 | } |
371 | } | 354 | } |
372 | 355 | ||
@@ -376,16 +359,17 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
376 | 359 | ||
377 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | 360 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) |
378 | { | 361 | { |
379 | struct sock *sk = icmp_socket->sk; | ||
380 | struct inet_sock *inet = inet_sk(sk); | ||
381 | struct ipcm_cookie ipc; | 362 | struct ipcm_cookie ipc; |
382 | struct rtable *rt = (struct rtable *)skb->dst; | 363 | struct rtable *rt = skb->rtable; |
364 | struct net *net = dev_net(rt->u.dst.dev); | ||
365 | struct sock *sk = icmp_sk(net); | ||
366 | struct inet_sock *inet = inet_sk(sk); | ||
383 | __be32 daddr; | 367 | __be32 daddr; |
384 | 368 | ||
385 | if (ip_options_echo(&icmp_param->replyopts, skb)) | 369 | if (ip_options_echo(&icmp_param->replyopts, skb)) |
386 | return; | 370 | return; |
387 | 371 | ||
388 | if (icmp_xmit_lock()) | 372 | if (icmp_xmit_lock(sk)) |
389 | return; | 373 | return; |
390 | 374 | ||
391 | icmp_param->data.icmph.checksum = 0; | 375 | icmp_param->data.icmph.checksum = 0; |
@@ -405,15 +389,15 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
405 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, | 389 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, |
406 | .proto = IPPROTO_ICMP }; | 390 | .proto = IPPROTO_ICMP }; |
407 | security_skb_classify_flow(skb, &fl); | 391 | security_skb_classify_flow(skb, &fl); |
408 | if (ip_route_output_key(rt->u.dst.dev->nd_net, &rt, &fl)) | 392 | if (ip_route_output_key(net, &rt, &fl)) |
409 | goto out_unlock; | 393 | goto out_unlock; |
410 | } | 394 | } |
411 | if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, | 395 | if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type, |
412 | icmp_param->data.icmph.code)) | 396 | icmp_param->data.icmph.code)) |
413 | icmp_push_reply(icmp_param, &ipc, rt); | 397 | icmp_push_reply(icmp_param, &ipc, rt); |
414 | ip_rt_put(rt); | 398 | ip_rt_put(rt); |
415 | out_unlock: | 399 | out_unlock: |
416 | icmp_xmit_unlock(); | 400 | icmp_xmit_unlock(sk); |
417 | } | 401 | } |
418 | 402 | ||
419 | 403 | ||
@@ -433,15 +417,17 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
433 | struct iphdr *iph; | 417 | struct iphdr *iph; |
434 | int room; | 418 | int room; |
435 | struct icmp_bxm icmp_param; | 419 | struct icmp_bxm icmp_param; |
436 | struct rtable *rt = (struct rtable *)skb_in->dst; | 420 | struct rtable *rt = skb_in->rtable; |
437 | struct ipcm_cookie ipc; | 421 | struct ipcm_cookie ipc; |
438 | __be32 saddr; | 422 | __be32 saddr; |
439 | u8 tos; | 423 | u8 tos; |
440 | struct net *net; | 424 | struct net *net; |
425 | struct sock *sk; | ||
441 | 426 | ||
442 | if (!rt) | 427 | if (!rt) |
443 | goto out; | 428 | goto out; |
444 | net = rt->u.dst.dev->nd_net; | 429 | net = dev_net(rt->u.dst.dev); |
430 | sk = icmp_sk(net); | ||
445 | 431 | ||
446 | /* | 432 | /* |
447 | * Find the original header. It is expected to be valid, of course. | 433 | * Find the original header. It is expected to be valid, of course. |
@@ -505,7 +491,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
505 | } | 491 | } |
506 | } | 492 | } |
507 | 493 | ||
508 | if (icmp_xmit_lock()) | 494 | if (icmp_xmit_lock(sk)) |
509 | return; | 495 | return; |
510 | 496 | ||
511 | /* | 497 | /* |
@@ -516,7 +502,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
516 | if (!(rt->rt_flags & RTCF_LOCAL)) { | 502 | if (!(rt->rt_flags & RTCF_LOCAL)) { |
517 | struct net_device *dev = NULL; | 503 | struct net_device *dev = NULL; |
518 | 504 | ||
519 | if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) | 505 | if (rt->fl.iif && |
506 | net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) | ||
520 | dev = dev_get_by_index(net, rt->fl.iif); | 507 | dev = dev_get_by_index(net, rt->fl.iif); |
521 | 508 | ||
522 | if (dev) { | 509 | if (dev) { |
@@ -544,7 +531,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
544 | icmp_param.data.icmph.checksum = 0; | 531 | icmp_param.data.icmph.checksum = 0; |
545 | icmp_param.skb = skb_in; | 532 | icmp_param.skb = skb_in; |
546 | icmp_param.offset = skb_network_offset(skb_in); | 533 | icmp_param.offset = skb_network_offset(skb_in); |
547 | inet_sk(icmp_socket->sk)->tos = tos; | 534 | inet_sk(sk)->tos = tos; |
548 | ipc.addr = iph->saddr; | 535 | ipc.addr = iph->saddr; |
549 | ipc.opt = &icmp_param.replyopts; | 536 | ipc.opt = &icmp_param.replyopts; |
550 | 537 | ||
@@ -609,7 +596,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
609 | RT_TOS(tos), rt2->u.dst.dev); | 596 | RT_TOS(tos), rt2->u.dst.dev); |
610 | 597 | ||
611 | dst_release(&rt2->u.dst); | 598 | dst_release(&rt2->u.dst); |
612 | rt2 = (struct rtable *)skb_in->dst; | 599 | rt2 = skb_in->rtable; |
613 | skb_in->dst = odst; | 600 | skb_in->dst = odst; |
614 | } | 601 | } |
615 | 602 | ||
@@ -634,7 +621,7 @@ relookup_failed: | |||
634 | } | 621 | } |
635 | 622 | ||
636 | route_done: | 623 | route_done: |
637 | if (!icmpv4_xrlim_allow(rt, type, code)) | 624 | if (!icmpv4_xrlim_allow(net, rt, type, code)) |
638 | goto ende; | 625 | goto ende; |
639 | 626 | ||
640 | /* RFC says return as much as we can without exceeding 576 bytes. */ | 627 | /* RFC says return as much as we can without exceeding 576 bytes. */ |
@@ -654,7 +641,7 @@ route_done: | |||
654 | ende: | 641 | ende: |
655 | ip_rt_put(rt); | 642 | ip_rt_put(rt); |
656 | out_unlock: | 643 | out_unlock: |
657 | icmp_xmit_unlock(); | 644 | icmp_xmit_unlock(sk); |
658 | out:; | 645 | out:; |
659 | } | 646 | } |
660 | 647 | ||
@@ -672,7 +659,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
672 | u32 info = 0; | 659 | u32 info = 0; |
673 | struct net *net; | 660 | struct net *net; |
674 | 661 | ||
675 | net = skb->dst->dev->nd_net; | 662 | net = dev_net(skb->dst->dev); |
676 | 663 | ||
677 | /* | 664 | /* |
678 | * Incomplete header ? | 665 | * Incomplete header ? |
@@ -698,7 +685,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
698 | break; | 685 | break; |
699 | case ICMP_FRAG_NEEDED: | 686 | case ICMP_FRAG_NEEDED: |
700 | if (ipv4_config.no_pmtu_disc) { | 687 | if (ipv4_config.no_pmtu_disc) { |
701 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: " | 688 | LIMIT_NETDEBUG(KERN_INFO "ICMP: " NIPQUAD_FMT ": " |
702 | "fragmentation needed " | 689 | "fragmentation needed " |
703 | "and DF set.\n", | 690 | "and DF set.\n", |
704 | NIPQUAD(iph->daddr)); | 691 | NIPQUAD(iph->daddr)); |
@@ -710,7 +697,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
710 | } | 697 | } |
711 | break; | 698 | break; |
712 | case ICMP_SR_FAILED: | 699 | case ICMP_SR_FAILED: |
713 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: Source " | 700 | LIMIT_NETDEBUG(KERN_INFO "ICMP: " NIPQUAD_FMT ": Source " |
714 | "Route Failed.\n", | 701 | "Route Failed.\n", |
715 | NIPQUAD(iph->daddr)); | 702 | NIPQUAD(iph->daddr)); |
716 | break; | 703 | break; |
@@ -740,12 +727,12 @@ static void icmp_unreach(struct sk_buff *skb) | |||
740 | * get the other vendor to fix their kit. | 727 | * get the other vendor to fix their kit. |
741 | */ | 728 | */ |
742 | 729 | ||
743 | if (!sysctl_icmp_ignore_bogus_error_responses && | 730 | if (!net->ipv4.sysctl_icmp_ignore_bogus_error_responses && |
744 | inet_addr_type(net, iph->daddr) == RTN_BROADCAST) { | 731 | inet_addr_type(net, iph->daddr) == RTN_BROADCAST) { |
745 | if (net_ratelimit()) | 732 | if (net_ratelimit()) |
746 | printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " | 733 | printk(KERN_WARNING NIPQUAD_FMT " sent an invalid ICMP " |
747 | "type %u, code %u " | 734 | "type %u, code %u " |
748 | "error to a broadcast: %u.%u.%u.%u on %s\n", | 735 | "error to a broadcast: " NIPQUAD_FMT " on %s\n", |
749 | NIPQUAD(ip_hdr(skb)->saddr), | 736 | NIPQUAD(ip_hdr(skb)->saddr), |
750 | icmph->type, icmph->code, | 737 | icmph->type, icmph->code, |
751 | NIPQUAD(iph->daddr), | 738 | NIPQUAD(iph->daddr), |
@@ -835,7 +822,10 @@ out_err: | |||
835 | 822 | ||
836 | static void icmp_echo(struct sk_buff *skb) | 823 | static void icmp_echo(struct sk_buff *skb) |
837 | { | 824 | { |
838 | if (!sysctl_icmp_echo_ignore_all) { | 825 | struct net *net; |
826 | |||
827 | net = dev_net(skb->dst->dev); | ||
828 | if (!net->ipv4.sysctl_icmp_echo_ignore_all) { | ||
839 | struct icmp_bxm icmp_param; | 829 | struct icmp_bxm icmp_param; |
840 | 830 | ||
841 | icmp_param.data.icmph = *icmp_hdr(skb); | 831 | icmp_param.data.icmph = *icmp_hdr(skb); |
@@ -938,7 +928,7 @@ static void icmp_address(struct sk_buff *skb) | |||
938 | 928 | ||
939 | static void icmp_address_reply(struct sk_buff *skb) | 929 | static void icmp_address_reply(struct sk_buff *skb) |
940 | { | 930 | { |
941 | struct rtable *rt = (struct rtable *)skb->dst; | 931 | struct rtable *rt = skb->rtable; |
942 | struct net_device *dev = skb->dev; | 932 | struct net_device *dev = skb->dev; |
943 | struct in_device *in_dev; | 933 | struct in_device *in_dev; |
944 | struct in_ifaddr *ifa; | 934 | struct in_ifaddr *ifa; |
@@ -963,8 +953,8 @@ static void icmp_address_reply(struct sk_buff *skb) | |||
963 | break; | 953 | break; |
964 | } | 954 | } |
965 | if (!ifa && net_ratelimit()) { | 955 | if (!ifa && net_ratelimit()) { |
966 | printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from " | 956 | printk(KERN_INFO "Wrong address mask " NIPQUAD_FMT " from " |
967 | "%s/%u.%u.%u.%u\n", | 957 | "%s/" NIPQUAD_FMT "\n", |
968 | NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src)); | 958 | NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src)); |
969 | } | 959 | } |
970 | } | 960 | } |
@@ -983,7 +973,7 @@ static void icmp_discard(struct sk_buff *skb) | |||
983 | int icmp_rcv(struct sk_buff *skb) | 973 | int icmp_rcv(struct sk_buff *skb) |
984 | { | 974 | { |
985 | struct icmphdr *icmph; | 975 | struct icmphdr *icmph; |
986 | struct rtable *rt = (struct rtable *)skb->dst; | 976 | struct rtable *rt = skb->rtable; |
987 | 977 | ||
988 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 978 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
989 | int nh; | 979 | int nh; |
@@ -1038,6 +1028,9 @@ int icmp_rcv(struct sk_buff *skb) | |||
1038 | */ | 1028 | */ |
1039 | 1029 | ||
1040 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { | 1030 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { |
1031 | struct net *net; | ||
1032 | |||
1033 | net = dev_net(rt->u.dst.dev); | ||
1041 | /* | 1034 | /* |
1042 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be | 1035 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be |
1043 | * silently ignored (we let user decide with a sysctl). | 1036 | * silently ignored (we let user decide with a sysctl). |
@@ -1046,7 +1039,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
1046 | */ | 1039 | */ |
1047 | if ((icmph->type == ICMP_ECHO || | 1040 | if ((icmph->type == ICMP_ECHO || |
1048 | icmph->type == ICMP_TIMESTAMP) && | 1041 | icmph->type == ICMP_TIMESTAMP) && |
1049 | sysctl_icmp_echo_ignore_broadcasts) { | 1042 | net->ipv4.sysctl_icmp_echo_ignore_broadcasts) { |
1050 | goto error; | 1043 | goto error; |
1051 | } | 1044 | } |
1052 | if (icmph->type != ICMP_ECHO && | 1045 | if (icmph->type != ICMP_ECHO && |
@@ -1141,38 +1134,84 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | |||
1141 | }, | 1134 | }, |
1142 | }; | 1135 | }; |
1143 | 1136 | ||
1144 | void __init icmp_init(struct net_proto_family *ops) | 1137 | static void __net_exit icmp_sk_exit(struct net *net) |
1145 | { | 1138 | { |
1146 | struct inet_sock *inet; | ||
1147 | int i; | 1139 | int i; |
1148 | 1140 | ||
1149 | for_each_possible_cpu(i) { | 1141 | for_each_possible_cpu(i) |
1150 | int err; | 1142 | inet_ctl_sock_destroy(net->ipv4.icmp_sk[i]); |
1143 | kfree(net->ipv4.icmp_sk); | ||
1144 | net->ipv4.icmp_sk = NULL; | ||
1145 | } | ||
1146 | |||
1147 | int __net_init icmp_sk_init(struct net *net) | ||
1148 | { | ||
1149 | int i, err; | ||
1151 | 1150 | ||
1152 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1151 | net->ipv4.icmp_sk = |
1153 | &per_cpu(__icmp_socket, i)); | 1152 | kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL); |
1153 | if (net->ipv4.icmp_sk == NULL) | ||
1154 | return -ENOMEM; | ||
1154 | 1155 | ||
1156 | for_each_possible_cpu(i) { | ||
1157 | struct sock *sk; | ||
1158 | |||
1159 | err = inet_ctl_sock_create(&sk, PF_INET, | ||
1160 | SOCK_RAW, IPPROTO_ICMP, net); | ||
1155 | if (err < 0) | 1161 | if (err < 0) |
1156 | panic("Failed to create the ICMP control socket.\n"); | 1162 | goto fail; |
1157 | 1163 | ||
1158 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; | 1164 | net->ipv4.icmp_sk[i] = sk; |
1159 | 1165 | ||
1160 | /* Enough space for 2 64K ICMP packets, including | 1166 | /* Enough space for 2 64K ICMP packets, including |
1161 | * sk_buff struct overhead. | 1167 | * sk_buff struct overhead. |
1162 | */ | 1168 | */ |
1163 | per_cpu(__icmp_socket, i)->sk->sk_sndbuf = | 1169 | sk->sk_sndbuf = |
1164 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | 1170 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); |
1165 | 1171 | ||
1166 | inet = inet_sk(per_cpu(__icmp_socket, i)->sk); | 1172 | inet_sk(sk)->pmtudisc = IP_PMTUDISC_DONT; |
1167 | inet->uc_ttl = -1; | ||
1168 | inet->pmtudisc = IP_PMTUDISC_DONT; | ||
1169 | |||
1170 | /* Unhash it so that IP input processing does not even | ||
1171 | * see it, we do not wish this socket to see incoming | ||
1172 | * packets. | ||
1173 | */ | ||
1174 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); | ||
1175 | } | 1173 | } |
1174 | |||
1175 | /* Control parameters for ECHO replies. */ | ||
1176 | net->ipv4.sysctl_icmp_echo_ignore_all = 0; | ||
1177 | net->ipv4.sysctl_icmp_echo_ignore_broadcasts = 1; | ||
1178 | |||
1179 | /* Control parameter - ignore bogus broadcast responses? */ | ||
1180 | net->ipv4.sysctl_icmp_ignore_bogus_error_responses = 1; | ||
1181 | |||
1182 | /* | ||
1183 | * Configurable global rate limit. | ||
1184 | * | ||
1185 | * ratelimit defines tokens/packet consumed for dst->rate_token | ||
1186 | * bucket ratemask defines which icmp types are ratelimited by | ||
1187 | * setting it's bit position. | ||
1188 | * | ||
1189 | * default: | ||
1190 | * dest unreachable (3), source quench (4), | ||
1191 | * time exceeded (11), parameter problem (12) | ||
1192 | */ | ||
1193 | |||
1194 | net->ipv4.sysctl_icmp_ratelimit = 1 * HZ; | ||
1195 | net->ipv4.sysctl_icmp_ratemask = 0x1818; | ||
1196 | net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0; | ||
1197 | |||
1198 | return 0; | ||
1199 | |||
1200 | fail: | ||
1201 | for_each_possible_cpu(i) | ||
1202 | inet_ctl_sock_destroy(net->ipv4.icmp_sk[i]); | ||
1203 | kfree(net->ipv4.icmp_sk); | ||
1204 | return err; | ||
1205 | } | ||
1206 | |||
1207 | static struct pernet_operations __net_initdata icmp_sk_ops = { | ||
1208 | .init = icmp_sk_init, | ||
1209 | .exit = icmp_sk_exit, | ||
1210 | }; | ||
1211 | |||
1212 | int __init icmp_init(void) | ||
1213 | { | ||
1214 | return register_pernet_device(&icmp_sk_ops); | ||
1176 | } | 1215 | } |
1177 | 1216 | ||
1178 | EXPORT_SYMBOL(icmp_err_convert); | 1217 | EXPORT_SYMBOL(icmp_err_convert); |