diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 0d109504ed86..f2b5270efdaa 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -243,6 +243,23 @@ void build_ehash_secret(void) | |||
243 | } | 243 | } |
244 | EXPORT_SYMBOL(build_ehash_secret); | 244 | EXPORT_SYMBOL(build_ehash_secret); |
245 | 245 | ||
246 | static inline int inet_netns_ok(struct net *net, int protocol) | ||
247 | { | ||
248 | int hash; | ||
249 | struct net_protocol *ipprot; | ||
250 | |||
251 | if (net == &init_net) | ||
252 | return 1; | ||
253 | |||
254 | hash = protocol & (MAX_INET_PROTOS - 1); | ||
255 | ipprot = rcu_dereference(inet_protos[hash]); | ||
256 | |||
257 | if (ipprot == NULL) | ||
258 | /* raw IP is OK */ | ||
259 | return 1; | ||
260 | return ipprot->netns_ok; | ||
261 | } | ||
262 | |||
246 | /* | 263 | /* |
247 | * Create an inet socket. | 264 | * Create an inet socket. |
248 | */ | 265 | */ |
@@ -259,9 +276,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol) | |||
259 | int try_loading_module = 0; | 276 | int try_loading_module = 0; |
260 | int err; | 277 | int err; |
261 | 278 | ||
262 | if (net != &init_net) | ||
263 | return -EAFNOSUPPORT; | ||
264 | |||
265 | if (sock->type != SOCK_RAW && | 279 | if (sock->type != SOCK_RAW && |
266 | sock->type != SOCK_DGRAM && | 280 | sock->type != SOCK_DGRAM && |
267 | !inet_ehash_secret) | 281 | !inet_ehash_secret) |
@@ -320,6 +334,10 @@ lookup_protocol: | |||
320 | if (answer->capability > 0 && !capable(answer->capability)) | 334 | if (answer->capability > 0 && !capable(answer->capability)) |
321 | goto out_rcu_unlock; | 335 | goto out_rcu_unlock; |
322 | 336 | ||
337 | err = -EAFNOSUPPORT; | ||
338 | if (!inet_netns_ok(net, protocol)) | ||
339 | goto out_rcu_unlock; | ||
340 | |||
323 | sock->ops = answer->ops; | 341 | sock->ops = answer->ops; |
324 | answer_prot = answer->prot; | 342 | answer_prot = answer->prot; |
325 | answer_no_check = answer->no_check; | 343 | answer_no_check = answer->no_check; |
@@ -446,7 +464,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
446 | if (addr_len < sizeof(struct sockaddr_in)) | 464 | if (addr_len < sizeof(struct sockaddr_in)) |
447 | goto out; | 465 | goto out; |
448 | 466 | ||
449 | chk_addr_ret = inet_addr_type(&init_net, addr->sin_addr.s_addr); | 467 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
450 | 468 | ||
451 | /* Not specified by any standard per-se, however it breaks too | 469 | /* Not specified by any standard per-se, however it breaks too |
452 | * many applications when removed. It is unfortunate since | 470 | * many applications when removed. It is unfortunate since |
@@ -784,6 +802,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
784 | { | 802 | { |
785 | struct sock *sk = sock->sk; | 803 | struct sock *sk = sock->sk; |
786 | int err = 0; | 804 | int err = 0; |
805 | struct net *net = sock_net(sk); | ||
787 | 806 | ||
788 | switch (cmd) { | 807 | switch (cmd) { |
789 | case SIOCGSTAMP: | 808 | case SIOCGSTAMP: |
@@ -795,12 +814,12 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
795 | case SIOCADDRT: | 814 | case SIOCADDRT: |
796 | case SIOCDELRT: | 815 | case SIOCDELRT: |
797 | case SIOCRTMSG: | 816 | case SIOCRTMSG: |
798 | err = ip_rt_ioctl(sk->sk_net, cmd, (void __user *)arg); | 817 | err = ip_rt_ioctl(net, cmd, (void __user *)arg); |
799 | break; | 818 | break; |
800 | case SIOCDARP: | 819 | case SIOCDARP: |
801 | case SIOCGARP: | 820 | case SIOCGARP: |
802 | case SIOCSARP: | 821 | case SIOCSARP: |
803 | err = arp_ioctl(sk->sk_net, cmd, (void __user *)arg); | 822 | err = arp_ioctl(net, cmd, (void __user *)arg); |
804 | break; | 823 | break; |
805 | case SIOCGIFADDR: | 824 | case SIOCGIFADDR: |
806 | case SIOCSIFADDR: | 825 | case SIOCSIFADDR: |
@@ -813,7 +832,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
813 | case SIOCSIFPFLAGS: | 832 | case SIOCSIFPFLAGS: |
814 | case SIOCGIFPFLAGS: | 833 | case SIOCGIFPFLAGS: |
815 | case SIOCSIFFLAGS: | 834 | case SIOCSIFFLAGS: |
816 | err = devinet_ioctl(cmd, (void __user *)arg); | 835 | err = devinet_ioctl(net, cmd, (void __user *)arg); |
817 | break; | 836 | break; |
818 | default: | 837 | default: |
819 | if (sk->sk_prot->ioctl) | 838 | if (sk->sk_prot->ioctl) |
@@ -1058,8 +1077,8 @@ static int inet_sk_reselect_saddr(struct sock *sk) | |||
1058 | 1077 | ||
1059 | if (sysctl_ip_dynaddr > 1) { | 1078 | if (sysctl_ip_dynaddr > 1) { |
1060 | printk(KERN_INFO "%s(): shifting inet->" | 1079 | printk(KERN_INFO "%s(): shifting inet->" |
1061 | "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n", | 1080 | "saddr from " NIPQUAD_FMT " to " NIPQUAD_FMT "\n", |
1062 | __FUNCTION__, | 1081 | __func__, |
1063 | NIPQUAD(old_saddr), | 1082 | NIPQUAD(old_saddr), |
1064 | NIPQUAD(new_saddr)); | 1083 | NIPQUAD(new_saddr)); |
1065 | } | 1084 | } |
@@ -1113,7 +1132,7 @@ int inet_sk_rebuild_header(struct sock *sk) | |||
1113 | }; | 1132 | }; |
1114 | 1133 | ||
1115 | security_sk_classify_flow(sk, &fl); | 1134 | security_sk_classify_flow(sk, &fl); |
1116 | err = ip_route_output_flow(&init_net, &rt, &fl, sk, 0); | 1135 | err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0); |
1117 | } | 1136 | } |
1118 | if (!err) | 1137 | if (!err) |
1119 | sk_setup_caps(sk, &rt->u.dst); | 1138 | sk_setup_caps(sk, &rt->u.dst); |
@@ -1231,6 +1250,29 @@ out: | |||
1231 | return segs; | 1250 | return segs; |
1232 | } | 1251 | } |
1233 | 1252 | ||
1253 | int inet_ctl_sock_create(struct sock **sk, unsigned short family, | ||
1254 | unsigned short type, unsigned char protocol, | ||
1255 | struct net *net) | ||
1256 | { | ||
1257 | struct socket *sock; | ||
1258 | int rc = sock_create_kern(family, type, protocol, &sock); | ||
1259 | |||
1260 | if (rc == 0) { | ||
1261 | *sk = sock->sk; | ||
1262 | (*sk)->sk_allocation = GFP_ATOMIC; | ||
1263 | /* | ||
1264 | * Unhash it so that IP input processing does not even see it, | ||
1265 | * we do not wish this socket to see incoming packets. | ||
1266 | */ | ||
1267 | (*sk)->sk_prot->unhash(*sk); | ||
1268 | |||
1269 | sk_change_net(*sk, net); | ||
1270 | } | ||
1271 | return rc; | ||
1272 | } | ||
1273 | |||
1274 | EXPORT_SYMBOL_GPL(inet_ctl_sock_create); | ||
1275 | |||
1234 | unsigned long snmp_fold_field(void *mib[], int offt) | 1276 | unsigned long snmp_fold_field(void *mib[], int offt) |
1235 | { | 1277 | { |
1236 | unsigned long res = 0; | 1278 | unsigned long res = 0; |
@@ -1283,17 +1325,20 @@ static struct net_protocol tcp_protocol = { | |||
1283 | .gso_send_check = tcp_v4_gso_send_check, | 1325 | .gso_send_check = tcp_v4_gso_send_check, |
1284 | .gso_segment = tcp_tso_segment, | 1326 | .gso_segment = tcp_tso_segment, |
1285 | .no_policy = 1, | 1327 | .no_policy = 1, |
1328 | .netns_ok = 1, | ||
1286 | }; | 1329 | }; |
1287 | 1330 | ||
1288 | static struct net_protocol udp_protocol = { | 1331 | static struct net_protocol udp_protocol = { |
1289 | .handler = udp_rcv, | 1332 | .handler = udp_rcv, |
1290 | .err_handler = udp_err, | 1333 | .err_handler = udp_err, |
1291 | .no_policy = 1, | 1334 | .no_policy = 1, |
1335 | .netns_ok = 1, | ||
1292 | }; | 1336 | }; |
1293 | 1337 | ||
1294 | static struct net_protocol icmp_protocol = { | 1338 | static struct net_protocol icmp_protocol = { |
1295 | .handler = icmp_rcv, | 1339 | .handler = icmp_rcv, |
1296 | .no_policy = 1, | 1340 | .no_policy = 1, |
1341 | .netns_ok = 1, | ||
1297 | }; | 1342 | }; |
1298 | 1343 | ||
1299 | static int __init init_ipv4_mibs(void) | 1344 | static int __init init_ipv4_mibs(void) |
@@ -1414,7 +1459,7 @@ static int __init inet_init(void) | |||
1414 | 1459 | ||
1415 | ip_init(); | 1460 | ip_init(); |
1416 | 1461 | ||
1417 | tcp_v4_init(&inet_family_ops); | 1462 | tcp_v4_init(); |
1418 | 1463 | ||
1419 | /* Setup TCP slab cache for open requests. */ | 1464 | /* Setup TCP slab cache for open requests. */ |
1420 | tcp_init(); | 1465 | tcp_init(); |
@@ -1429,7 +1474,8 @@ static int __init inet_init(void) | |||
1429 | * Set the ICMP layer up | 1474 | * Set the ICMP layer up |
1430 | */ | 1475 | */ |
1431 | 1476 | ||
1432 | icmp_init(&inet_family_ops); | 1477 | if (icmp_init() < 0) |
1478 | panic("Failed to create the ICMP control socket.\n"); | ||
1433 | 1479 | ||
1434 | /* | 1480 | /* |
1435 | * Initialise the multicast router | 1481 | * Initialise the multicast router |