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 /net | |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/af_inet.c | 3 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 26 |
2 files changed, 24 insertions, 5 deletions
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); |