diff options
author | Denis V. Lunev <den@openvz.org> | 2008-02-29 14:14:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-29 14:14:50 -0500 |
commit | a5710d6582868a96cf0fe02eac11d34cfbc783c9 (patch) | |
tree | 8fcc3f4bc58436c1809602a98c9ce759c74f9410 | |
parent | 9b0f976f27f00a81cf47643d90854659626795b4 (diff) |
[ICMP]: Add return code to icmp_init.
icmp_init could fail and this is normal for namespace other than initial.
So, the panic should be triggered only on init_net initialization path.
Additionally create rollback path for icmp_init as a separate function.
It will also be used later during namespace destruction.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/icmp.h | 2 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 3 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 26 |
3 files changed, 25 insertions, 6 deletions
diff --git a/include/net/icmp.h b/include/net/icmp.h index 7bf714d9d7c7..faba64db8ff0 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
@@ -48,7 +48,7 @@ struct sk_buff; | |||
48 | extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); | 48 | extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); |
49 | extern int icmp_rcv(struct sk_buff *skb); | 49 | extern int icmp_rcv(struct sk_buff *skb); |
50 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); | 50 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
51 | extern void icmp_init(void); | 51 | extern int icmp_init(void); |
52 | extern void icmp_out_count(unsigned char type); | 52 | extern void icmp_out_count(unsigned char type); |
53 | 53 | ||
54 | /* Move into dst.h ? */ | 54 | /* Move into dst.h ? */ |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index a7a99ac856dc..4f539bd48718 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1430,7 +1430,8 @@ static int __init inet_init(void) | |||
1430 | * Set the ICMP layer up | 1430 | * Set the ICMP layer up |
1431 | */ | 1431 | */ |
1432 | 1432 | ||
1433 | icmp_init(); | 1433 | if (icmp_init() < 0) |
1434 | panic("Failed to create the ICMP control socket.\n"); | ||
1434 | 1435 | ||
1435 | /* | 1436 | /* |
1436 | * Initialise the multicast router | 1437 | * Initialise the multicast router |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 98372db66c66..b345b3d9bcaa 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -1139,19 +1139,32 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | |||
1139 | }, | 1139 | }, |
1140 | }; | 1140 | }; |
1141 | 1141 | ||
1142 | void __init icmp_init(void) | 1142 | static void __exit icmp_exit(void) |
1143 | { | 1143 | { |
1144 | struct inet_sock *inet; | ||
1145 | int i; | 1144 | int i; |
1146 | 1145 | ||
1147 | for_each_possible_cpu(i) { | 1146 | for_each_possible_cpu(i) { |
1148 | int err; | 1147 | struct socket *sock; |
1148 | |||
1149 | sock = per_cpu(__icmp_socket, i); | ||
1150 | if (sock == NULL) | ||
1151 | continue; | ||
1152 | per_cpu(__icmp_socket, i) = NULL; | ||
1153 | sock_release(sock); | ||
1154 | } | ||
1155 | } | ||
1149 | 1156 | ||
1157 | int __init icmp_init(void) | ||
1158 | { | ||
1159 | struct inet_sock *inet; | ||
1160 | int i, err; | ||
1161 | |||
1162 | for_each_possible_cpu(i) { | ||
1150 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1163 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, |
1151 | &per_cpu(__icmp_socket, i)); | 1164 | &per_cpu(__icmp_socket, i)); |
1152 | 1165 | ||
1153 | if (err < 0) | 1166 | if (err < 0) |
1154 | panic("Failed to create the ICMP control socket.\n"); | 1167 | goto fail; |
1155 | 1168 | ||
1156 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; | 1169 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; |
1157 | 1170 | ||
@@ -1171,6 +1184,11 @@ void __init icmp_init(void) | |||
1171 | */ | 1184 | */ |
1172 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); | 1185 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); |
1173 | } | 1186 | } |
1187 | return 0; | ||
1188 | |||
1189 | fail: | ||
1190 | icmp_exit(); | ||
1191 | return err; | ||
1174 | } | 1192 | } |
1175 | 1193 | ||
1176 | EXPORT_SYMBOL(icmp_err_convert); | 1194 | EXPORT_SYMBOL(icmp_err_convert); |