diff options
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r-- | net/ipv4/icmp.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index d65e9215bcd7..a0d847c7cba5 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -181,6 +181,7 @@ const struct icmp_err icmp_err_convert[] = { | |||
181 | .fatal = 1, | 181 | .fatal = 1, |
182 | }, | 182 | }, |
183 | }; | 183 | }; |
184 | EXPORT_SYMBOL(icmp_err_convert); | ||
184 | 185 | ||
185 | /* | 186 | /* |
186 | * ICMP control array. This specifies what to do with each ICMP. | 187 | * ICMP control array. This specifies what to do with each ICMP. |
@@ -267,11 +268,12 @@ int xrlim_allow(struct dst_entry *dst, int timeout) | |||
267 | dst->rate_tokens = token; | 268 | dst->rate_tokens = token; |
268 | return rc; | 269 | return rc; |
269 | } | 270 | } |
271 | EXPORT_SYMBOL(xrlim_allow); | ||
270 | 272 | ||
271 | static inline int icmpv4_xrlim_allow(struct net *net, struct rtable *rt, | 273 | static inline int icmpv4_xrlim_allow(struct net *net, struct rtable *rt, |
272 | int type, int code) | 274 | int type, int code) |
273 | { | 275 | { |
274 | struct dst_entry *dst = &rt->u.dst; | 276 | struct dst_entry *dst = &rt->dst; |
275 | int rc = 1; | 277 | int rc = 1; |
276 | 278 | ||
277 | if (type > NR_ICMP_TYPES) | 279 | if (type > NR_ICMP_TYPES) |
@@ -327,7 +329,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
327 | struct sock *sk; | 329 | struct sock *sk; |
328 | struct sk_buff *skb; | 330 | struct sk_buff *skb; |
329 | 331 | ||
330 | sk = icmp_sk(dev_net((*rt)->u.dst.dev)); | 332 | sk = icmp_sk(dev_net((*rt)->dst.dev)); |
331 | if (ip_append_data(sk, icmp_glue_bits, icmp_param, | 333 | if (ip_append_data(sk, icmp_glue_bits, icmp_param, |
332 | icmp_param->data_len+icmp_param->head_len, | 334 | icmp_param->data_len+icmp_param->head_len, |
333 | icmp_param->head_len, | 335 | icmp_param->head_len, |
@@ -359,7 +361,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
359 | { | 361 | { |
360 | struct ipcm_cookie ipc; | 362 | struct ipcm_cookie ipc; |
361 | struct rtable *rt = skb_rtable(skb); | 363 | struct rtable *rt = skb_rtable(skb); |
362 | struct net *net = dev_net(rt->u.dst.dev); | 364 | struct net *net = dev_net(rt->dst.dev); |
363 | struct sock *sk; | 365 | struct sock *sk; |
364 | struct inet_sock *inet; | 366 | struct inet_sock *inet; |
365 | __be32 daddr; | 367 | __be32 daddr; |
@@ -427,7 +429,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
427 | 429 | ||
428 | if (!rt) | 430 | if (!rt) |
429 | goto out; | 431 | goto out; |
430 | net = dev_net(rt->u.dst.dev); | 432 | net = dev_net(rt->dst.dev); |
431 | 433 | ||
432 | /* | 434 | /* |
433 | * Find the original header. It is expected to be valid, of course. | 435 | * Find the original header. It is expected to be valid, of course. |
@@ -596,9 +598,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
596 | /* Ugh! */ | 598 | /* Ugh! */ |
597 | orefdst = skb_in->_skb_refdst; /* save old refdst */ | 599 | orefdst = skb_in->_skb_refdst; /* save old refdst */ |
598 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, | 600 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, |
599 | RT_TOS(tos), rt2->u.dst.dev); | 601 | RT_TOS(tos), rt2->dst.dev); |
600 | 602 | ||
601 | dst_release(&rt2->u.dst); | 603 | dst_release(&rt2->dst); |
602 | rt2 = skb_rtable(skb_in); | 604 | rt2 = skb_rtable(skb_in); |
603 | skb_in->_skb_refdst = orefdst; /* restore old refdst */ | 605 | skb_in->_skb_refdst = orefdst; /* restore old refdst */ |
604 | } | 606 | } |
@@ -610,7 +612,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
610 | XFRM_LOOKUP_ICMP); | 612 | XFRM_LOOKUP_ICMP); |
611 | switch (err) { | 613 | switch (err) { |
612 | case 0: | 614 | case 0: |
613 | dst_release(&rt->u.dst); | 615 | dst_release(&rt->dst); |
614 | rt = rt2; | 616 | rt = rt2; |
615 | break; | 617 | break; |
616 | case -EPERM: | 618 | case -EPERM: |
@@ -629,7 +631,7 @@ route_done: | |||
629 | 631 | ||
630 | /* RFC says return as much as we can without exceeding 576 bytes. */ | 632 | /* RFC says return as much as we can without exceeding 576 bytes. */ |
631 | 633 | ||
632 | room = dst_mtu(&rt->u.dst); | 634 | room = dst_mtu(&rt->dst); |
633 | if (room > 576) | 635 | if (room > 576) |
634 | room = 576; | 636 | room = 576; |
635 | room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; | 637 | room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; |
@@ -647,6 +649,7 @@ out_unlock: | |||
647 | icmp_xmit_unlock(sk); | 649 | icmp_xmit_unlock(sk); |
648 | out:; | 650 | out:; |
649 | } | 651 | } |
652 | EXPORT_SYMBOL(icmp_send); | ||
650 | 653 | ||
651 | 654 | ||
652 | /* | 655 | /* |
@@ -925,6 +928,7 @@ static void icmp_address(struct sk_buff *skb) | |||
925 | /* | 928 | /* |
926 | * RFC1812 (4.3.3.9). A router SHOULD listen all replies, and complain | 929 | * RFC1812 (4.3.3.9). A router SHOULD listen all replies, and complain |
927 | * loudly if an inconsistency is found. | 930 | * loudly if an inconsistency is found. |
931 | * called with rcu_read_lock() | ||
928 | */ | 932 | */ |
929 | 933 | ||
930 | static void icmp_address_reply(struct sk_buff *skb) | 934 | static void icmp_address_reply(struct sk_buff *skb) |
@@ -935,12 +939,12 @@ static void icmp_address_reply(struct sk_buff *skb) | |||
935 | struct in_ifaddr *ifa; | 939 | struct in_ifaddr *ifa; |
936 | 940 | ||
937 | if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) | 941 | if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) |
938 | goto out; | 942 | return; |
939 | 943 | ||
940 | in_dev = in_dev_get(dev); | 944 | in_dev = __in_dev_get_rcu(dev); |
941 | if (!in_dev) | 945 | if (!in_dev) |
942 | goto out; | 946 | return; |
943 | rcu_read_lock(); | 947 | |
944 | if (in_dev->ifa_list && | 948 | if (in_dev->ifa_list && |
945 | IN_DEV_LOG_MARTIANS(in_dev) && | 949 | IN_DEV_LOG_MARTIANS(in_dev) && |
946 | IN_DEV_FORWARD(in_dev)) { | 950 | IN_DEV_FORWARD(in_dev)) { |
@@ -958,9 +962,6 @@ static void icmp_address_reply(struct sk_buff *skb) | |||
958 | mp, dev->name, &rt->rt_src); | 962 | mp, dev->name, &rt->rt_src); |
959 | } | 963 | } |
960 | } | 964 | } |
961 | rcu_read_unlock(); | ||
962 | in_dev_put(in_dev); | ||
963 | out:; | ||
964 | } | 965 | } |
965 | 966 | ||
966 | static void icmp_discard(struct sk_buff *skb) | 967 | static void icmp_discard(struct sk_buff *skb) |
@@ -974,7 +975,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
974 | { | 975 | { |
975 | struct icmphdr *icmph; | 976 | struct icmphdr *icmph; |
976 | struct rtable *rt = skb_rtable(skb); | 977 | struct rtable *rt = skb_rtable(skb); |
977 | struct net *net = dev_net(rt->u.dst.dev); | 978 | struct net *net = dev_net(rt->dst.dev); |
978 | 979 | ||
979 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 980 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
980 | struct sec_path *sp = skb_sec_path(skb); | 981 | struct sec_path *sp = skb_sec_path(skb); |
@@ -1216,7 +1217,3 @@ int __init icmp_init(void) | |||
1216 | { | 1217 | { |
1217 | return register_pernet_subsys(&icmp_sk_ops); | 1218 | return register_pernet_subsys(&icmp_sk_ops); |
1218 | } | 1219 | } |
1219 | |||
1220 | EXPORT_SYMBOL(icmp_err_convert); | ||
1221 | EXPORT_SYMBOL(icmp_send); | ||
1222 | EXPORT_SYMBOL(xrlim_allow); | ||