aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-02-29 14:14:50 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-29 14:14:50 -0500
commita5710d6582868a96cf0fe02eac11d34cfbc783c9 (patch)
tree8fcc3f4bc58436c1809602a98c9ce759c74f9410
parent9b0f976f27f00a81cf47643d90854659626795b4 (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.h2
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/icmp.c26
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;
48extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); 48extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
49extern int icmp_rcv(struct sk_buff *skb); 49extern int icmp_rcv(struct sk_buff *skb);
50extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); 50extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
51extern void icmp_init(void); 51extern int icmp_init(void);
52extern void icmp_out_count(unsigned char type); 52extern 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
1142void __init icmp_init(void) 1142static 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
1157int __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
1189fail:
1190 icmp_exit();
1191 return err;
1174} 1192}
1175 1193
1176EXPORT_SYMBOL(icmp_err_convert); 1194EXPORT_SYMBOL(icmp_err_convert);