diff options
Diffstat (limited to 'net/ipv4')
76 files changed, 1675 insertions, 1393 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 24eca23c2db3..dd919d84285f 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * PF_INET protocol family socket handler. | 6 | * PF_INET protocol family socket handler. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Florian La Roche, <flla@stud.uni-sb.de> | 10 | * Florian La Roche, <flla@stud.uni-sb.de> |
| @@ -112,12 +110,11 @@ | |||
| 112 | #include <net/ipip.h> | 110 | #include <net/ipip.h> |
| 113 | #include <net/inet_common.h> | 111 | #include <net/inet_common.h> |
| 114 | #include <net/xfrm.h> | 112 | #include <net/xfrm.h> |
| 113 | #include <net/net_namespace.h> | ||
| 115 | #ifdef CONFIG_IP_MROUTE | 114 | #ifdef CONFIG_IP_MROUTE |
| 116 | #include <linux/mroute.h> | 115 | #include <linux/mroute.h> |
| 117 | #endif | 116 | #endif |
| 118 | 117 | ||
| 119 | DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly; | ||
| 120 | |||
| 121 | extern void ip_mc_drop_socket(struct sock *sk); | 118 | extern void ip_mc_drop_socket(struct sock *sk); |
| 122 | 119 | ||
| 123 | /* The inetsw table contains everything that inet_create needs to | 120 | /* The inetsw table contains everything that inet_create needs to |
| @@ -1341,50 +1338,70 @@ static struct net_protocol icmp_protocol = { | |||
| 1341 | .netns_ok = 1, | 1338 | .netns_ok = 1, |
| 1342 | }; | 1339 | }; |
| 1343 | 1340 | ||
| 1344 | static int __init init_ipv4_mibs(void) | 1341 | static __net_init int ipv4_mib_init_net(struct net *net) |
| 1345 | { | 1342 | { |
| 1346 | if (snmp_mib_init((void **)net_statistics, | 1343 | if (snmp_mib_init((void **)net->mib.tcp_statistics, |
| 1347 | sizeof(struct linux_mib)) < 0) | ||
| 1348 | goto err_net_mib; | ||
| 1349 | if (snmp_mib_init((void **)ip_statistics, | ||
| 1350 | sizeof(struct ipstats_mib)) < 0) | ||
| 1351 | goto err_ip_mib; | ||
| 1352 | if (snmp_mib_init((void **)icmp_statistics, | ||
| 1353 | sizeof(struct icmp_mib)) < 0) | ||
| 1354 | goto err_icmp_mib; | ||
| 1355 | if (snmp_mib_init((void **)icmpmsg_statistics, | ||
| 1356 | sizeof(struct icmpmsg_mib)) < 0) | ||
| 1357 | goto err_icmpmsg_mib; | ||
| 1358 | if (snmp_mib_init((void **)tcp_statistics, | ||
| 1359 | sizeof(struct tcp_mib)) < 0) | 1344 | sizeof(struct tcp_mib)) < 0) |
| 1360 | goto err_tcp_mib; | 1345 | goto err_tcp_mib; |
| 1361 | if (snmp_mib_init((void **)udp_statistics, | 1346 | if (snmp_mib_init((void **)net->mib.ip_statistics, |
| 1347 | sizeof(struct ipstats_mib)) < 0) | ||
| 1348 | goto err_ip_mib; | ||
| 1349 | if (snmp_mib_init((void **)net->mib.net_statistics, | ||
| 1350 | sizeof(struct linux_mib)) < 0) | ||
| 1351 | goto err_net_mib; | ||
| 1352 | if (snmp_mib_init((void **)net->mib.udp_statistics, | ||
| 1362 | sizeof(struct udp_mib)) < 0) | 1353 | sizeof(struct udp_mib)) < 0) |
| 1363 | goto err_udp_mib; | 1354 | goto err_udp_mib; |
| 1364 | if (snmp_mib_init((void **)udplite_statistics, | 1355 | if (snmp_mib_init((void **)net->mib.udplite_statistics, |
| 1365 | sizeof(struct udp_mib)) < 0) | 1356 | sizeof(struct udp_mib)) < 0) |
| 1366 | goto err_udplite_mib; | 1357 | goto err_udplite_mib; |
| 1358 | if (snmp_mib_init((void **)net->mib.icmp_statistics, | ||
| 1359 | sizeof(struct icmp_mib)) < 0) | ||
| 1360 | goto err_icmp_mib; | ||
| 1361 | if (snmp_mib_init((void **)net->mib.icmpmsg_statistics, | ||
| 1362 | sizeof(struct icmpmsg_mib)) < 0) | ||
| 1363 | goto err_icmpmsg_mib; | ||
| 1367 | 1364 | ||
| 1368 | tcp_mib_init(); | 1365 | tcp_mib_init(net); |
| 1369 | |||
| 1370 | return 0; | 1366 | return 0; |
| 1371 | 1367 | ||
| 1372 | err_udplite_mib: | ||
| 1373 | snmp_mib_free((void **)udp_statistics); | ||
| 1374 | err_udp_mib: | ||
| 1375 | snmp_mib_free((void **)tcp_statistics); | ||
| 1376 | err_tcp_mib: | ||
| 1377 | snmp_mib_free((void **)icmpmsg_statistics); | ||
| 1378 | err_icmpmsg_mib: | 1368 | err_icmpmsg_mib: |
| 1379 | snmp_mib_free((void **)icmp_statistics); | 1369 | snmp_mib_free((void **)net->mib.icmp_statistics); |
| 1380 | err_icmp_mib: | 1370 | err_icmp_mib: |
| 1381 | snmp_mib_free((void **)ip_statistics); | 1371 | snmp_mib_free((void **)net->mib.udplite_statistics); |
| 1382 | err_ip_mib: | 1372 | err_udplite_mib: |
| 1383 | snmp_mib_free((void **)net_statistics); | 1373 | snmp_mib_free((void **)net->mib.udp_statistics); |
| 1374 | err_udp_mib: | ||
| 1375 | snmp_mib_free((void **)net->mib.net_statistics); | ||
| 1384 | err_net_mib: | 1376 | err_net_mib: |
| 1377 | snmp_mib_free((void **)net->mib.ip_statistics); | ||
| 1378 | err_ip_mib: | ||
| 1379 | snmp_mib_free((void **)net->mib.tcp_statistics); | ||
| 1380 | err_tcp_mib: | ||
| 1385 | return -ENOMEM; | 1381 | return -ENOMEM; |
| 1386 | } | 1382 | } |
| 1387 | 1383 | ||
| 1384 | static __net_exit void ipv4_mib_exit_net(struct net *net) | ||
| 1385 | { | ||
| 1386 | snmp_mib_free((void **)net->mib.icmpmsg_statistics); | ||
| 1387 | snmp_mib_free((void **)net->mib.icmp_statistics); | ||
| 1388 | snmp_mib_free((void **)net->mib.udplite_statistics); | ||
| 1389 | snmp_mib_free((void **)net->mib.udp_statistics); | ||
| 1390 | snmp_mib_free((void **)net->mib.net_statistics); | ||
| 1391 | snmp_mib_free((void **)net->mib.ip_statistics); | ||
| 1392 | snmp_mib_free((void **)net->mib.tcp_statistics); | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | static __net_initdata struct pernet_operations ipv4_mib_ops = { | ||
| 1396 | .init = ipv4_mib_init_net, | ||
| 1397 | .exit = ipv4_mib_exit_net, | ||
| 1398 | }; | ||
| 1399 | |||
| 1400 | static int __init init_ipv4_mibs(void) | ||
| 1401 | { | ||
| 1402 | return register_pernet_subsys(&ipv4_mib_ops); | ||
| 1403 | } | ||
| 1404 | |||
| 1388 | static int ipv4_proc_init(void); | 1405 | static int ipv4_proc_init(void); |
| 1389 | 1406 | ||
| 1390 | /* | 1407 | /* |
| @@ -1481,14 +1498,15 @@ static int __init inet_init(void) | |||
| 1481 | * Initialise the multicast router | 1498 | * Initialise the multicast router |
| 1482 | */ | 1499 | */ |
| 1483 | #if defined(CONFIG_IP_MROUTE) | 1500 | #if defined(CONFIG_IP_MROUTE) |
| 1484 | ip_mr_init(); | 1501 | if (ip_mr_init()) |
| 1502 | printk(KERN_CRIT "inet_init: Cannot init ipv4 mroute\n"); | ||
| 1485 | #endif | 1503 | #endif |
| 1486 | /* | 1504 | /* |
| 1487 | * Initialise per-cpu ipv4 mibs | 1505 | * Initialise per-cpu ipv4 mibs |
| 1488 | */ | 1506 | */ |
| 1489 | 1507 | ||
| 1490 | if (init_ipv4_mibs()) | 1508 | if (init_ipv4_mibs()) |
| 1491 | printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ; | 1509 | printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); |
| 1492 | 1510 | ||
| 1493 | ipv4_proc_init(); | 1511 | ipv4_proc_init(); |
| 1494 | 1512 | ||
| @@ -1560,5 +1578,4 @@ EXPORT_SYMBOL(inet_sock_destruct); | |||
| 1560 | EXPORT_SYMBOL(inet_stream_connect); | 1578 | EXPORT_SYMBOL(inet_stream_connect); |
| 1561 | EXPORT_SYMBOL(inet_stream_ops); | 1579 | EXPORT_SYMBOL(inet_stream_ops); |
| 1562 | EXPORT_SYMBOL(inet_unregister_protosw); | 1580 | EXPORT_SYMBOL(inet_unregister_protosw); |
| 1563 | EXPORT_SYMBOL(net_statistics); | ||
| 1564 | EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); | 1581 | EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 9b539fa9fe18..b043eda60b04 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
| @@ -1,7 +1,5 @@ | |||
| 1 | /* linux/net/ipv4/arp.c | 1 | /* linux/net/ipv4/arp.c |
| 2 | * | 2 | * |
| 3 | * Version: $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $ | ||
| 4 | * | ||
| 5 | * Copyright (C) 1994 by Florian La Roche | 3 | * Copyright (C) 1994 by Florian La Roche |
| 6 | * | 4 | * |
| 7 | * This module implements the Address Resolution Protocol ARP (RFC 826), | 5 | * This module implements the Address Resolution Protocol ARP (RFC 826), |
| @@ -423,11 +421,12 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) | |||
| 423 | struct rtable *rt; | 421 | struct rtable *rt; |
| 424 | int flag = 0; | 422 | int flag = 0; |
| 425 | /*unsigned long now; */ | 423 | /*unsigned long now; */ |
| 424 | struct net *net = dev_net(dev); | ||
| 426 | 425 | ||
| 427 | if (ip_route_output_key(dev_net(dev), &rt, &fl) < 0) | 426 | if (ip_route_output_key(net, &rt, &fl) < 0) |
| 428 | return 1; | 427 | return 1; |
| 429 | if (rt->u.dst.dev != dev) { | 428 | if (rt->u.dst.dev != dev) { |
| 430 | NET_INC_STATS_BH(LINUX_MIB_ARPFILTER); | 429 | NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); |
| 431 | flag = 1; | 430 | flag = 1; |
| 432 | } | 431 | } |
| 433 | ip_rt_put(rt); | 432 | ip_rt_put(rt); |
| @@ -1199,7 +1198,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo | |||
| 1199 | switch (event) { | 1198 | switch (event) { |
| 1200 | case NETDEV_CHANGEADDR: | 1199 | case NETDEV_CHANGEADDR: |
| 1201 | neigh_changeaddr(&arp_tbl, dev); | 1200 | neigh_changeaddr(&arp_tbl, dev); |
| 1202 | rt_cache_flush(0); | 1201 | rt_cache_flush(dev_net(dev), 0); |
| 1203 | break; | 1202 | break; |
| 1204 | default: | 1203 | default: |
| 1205 | break; | 1204 | break; |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 0c0c73f368ce..5e6c5a0f3fde 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
| @@ -52,7 +52,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 52 | inet->sport, usin->sin_port, sk, 1); | 52 | inet->sport, usin->sin_port, sk, 1); |
| 53 | if (err) { | 53 | if (err) { |
| 54 | if (err == -ENETUNREACH) | 54 | if (err == -ENETUNREACH) |
| 55 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 55 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
| 56 | return err; | 56 | return err; |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 79a7ef6209ff..2e667e2f90df 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * NET3 IP device support routines. | 2 | * NET3 IP device support routines. |
| 3 | * | 3 | * |
| 4 | * Version: $Id: devinet.c,v 1.44 2001/10/31 21:55:54 davem Exp $ | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
| @@ -170,6 +168,8 @@ static struct in_device *inetdev_init(struct net_device *dev) | |||
| 170 | in_dev->dev = dev; | 168 | in_dev->dev = dev; |
| 171 | if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) | 169 | if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) |
| 172 | goto out_kfree; | 170 | goto out_kfree; |
| 171 | if (IPV4_DEVCONF(in_dev->cnf, FORWARDING)) | ||
| 172 | dev_disable_lro(dev); | ||
| 173 | /* Reference in_dev->dev */ | 173 | /* Reference in_dev->dev */ |
| 174 | dev_hold(dev); | 174 | dev_hold(dev); |
| 175 | /* Account for reference dev->ip_ptr (below) */ | 175 | /* Account for reference dev->ip_ptr (below) */ |
| @@ -1013,7 +1013,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) | |||
| 1013 | memcpy(old, ifa->ifa_label, IFNAMSIZ); | 1013 | memcpy(old, ifa->ifa_label, IFNAMSIZ); |
| 1014 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); | 1014 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); |
| 1015 | if (named++ == 0) | 1015 | if (named++ == 0) |
| 1016 | continue; | 1016 | goto skip; |
| 1017 | dot = strchr(old, ':'); | 1017 | dot = strchr(old, ':'); |
| 1018 | if (dot == NULL) { | 1018 | if (dot == NULL) { |
| 1019 | sprintf(old, ":%d", named); | 1019 | sprintf(old, ":%d", named); |
| @@ -1024,6 +1024,8 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) | |||
| 1024 | } else { | 1024 | } else { |
| 1025 | strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); | 1025 | strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); |
| 1026 | } | 1026 | } |
| 1027 | skip: | ||
| 1028 | rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); | ||
| 1027 | } | 1029 | } |
| 1028 | } | 1030 | } |
| 1029 | 1031 | ||
| @@ -1241,6 +1243,8 @@ static void inet_forward_change(struct net *net) | |||
| 1241 | read_lock(&dev_base_lock); | 1243 | read_lock(&dev_base_lock); |
| 1242 | for_each_netdev(net, dev) { | 1244 | for_each_netdev(net, dev) { |
| 1243 | struct in_device *in_dev; | 1245 | struct in_device *in_dev; |
| 1246 | if (on) | ||
| 1247 | dev_disable_lro(dev); | ||
| 1244 | rcu_read_lock(); | 1248 | rcu_read_lock(); |
| 1245 | in_dev = __in_dev_get_rcu(dev); | 1249 | in_dev = __in_dev_get_rcu(dev); |
| 1246 | if (in_dev) | 1250 | if (in_dev) |
| @@ -1248,8 +1252,6 @@ static void inet_forward_change(struct net *net) | |||
| 1248 | rcu_read_unlock(); | 1252 | rcu_read_unlock(); |
| 1249 | } | 1253 | } |
| 1250 | read_unlock(&dev_base_lock); | 1254 | read_unlock(&dev_base_lock); |
| 1251 | |||
| 1252 | rt_cache_flush(0); | ||
| 1253 | } | 1255 | } |
| 1254 | 1256 | ||
| 1255 | static int devinet_conf_proc(ctl_table *ctl, int write, | 1257 | static int devinet_conf_proc(ctl_table *ctl, int write, |
| @@ -1335,10 +1337,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, | |||
| 1335 | if (write && *valp != val) { | 1337 | if (write && *valp != val) { |
| 1336 | struct net *net = ctl->extra2; | 1338 | struct net *net = ctl->extra2; |
| 1337 | 1339 | ||
| 1338 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) | 1340 | if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) { |
| 1339 | inet_forward_change(net); | 1341 | rtnl_lock(); |
| 1340 | else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) | 1342 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { |
| 1341 | rt_cache_flush(0); | 1343 | inet_forward_change(net); |
| 1344 | } else if (*valp) { | ||
| 1345 | struct ipv4_devconf *cnf = ctl->extra1; | ||
| 1346 | struct in_device *idev = | ||
| 1347 | container_of(cnf, struct in_device, cnf); | ||
| 1348 | dev_disable_lro(idev->dev); | ||
| 1349 | } | ||
| 1350 | rtnl_unlock(); | ||
| 1351 | rt_cache_flush(net, 0); | ||
| 1352 | } | ||
| 1342 | } | 1353 | } |
| 1343 | 1354 | ||
| 1344 | return ret; | 1355 | return ret; |
| @@ -1351,9 +1362,10 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write, | |||
| 1351 | int *valp = ctl->data; | 1362 | int *valp = ctl->data; |
| 1352 | int val = *valp; | 1363 | int val = *valp; |
| 1353 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 1364 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
| 1365 | struct net *net = ctl->extra2; | ||
| 1354 | 1366 | ||
| 1355 | if (write && *valp != val) | 1367 | if (write && *valp != val) |
| 1356 | rt_cache_flush(0); | 1368 | rt_cache_flush(net, 0); |
| 1357 | 1369 | ||
| 1358 | return ret; | 1370 | return ret; |
| 1359 | } | 1371 | } |
| @@ -1364,9 +1376,10 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, | |||
| 1364 | { | 1376 | { |
| 1365 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, | 1377 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, |
| 1366 | newval, newlen); | 1378 | newval, newlen); |
| 1379 | struct net *net = table->extra2; | ||
| 1367 | 1380 | ||
| 1368 | if (ret == 1) | 1381 | if (ret == 1) |
| 1369 | rt_cache_flush(0); | 1382 | rt_cache_flush(net, 0); |
| 1370 | 1383 | ||
| 1371 | return ret; | 1384 | return ret; |
| 1372 | } | 1385 | } |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 0b2ac6a3d903..65c1503f8cc8 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * IPv4 Forwarding Information Base: FIB frontend. | 6 | * IPv4 Forwarding Information Base: FIB frontend. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: fib_frontend.c,v 1.26 2001/10/31 21:55:54 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | 8 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 11 | * | 9 | * |
| 12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| @@ -146,7 +144,7 @@ static void fib_flush(struct net *net) | |||
| 146 | } | 144 | } |
| 147 | 145 | ||
| 148 | if (flushed) | 146 | if (flushed) |
| 149 | rt_cache_flush(-1); | 147 | rt_cache_flush(net, -1); |
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | /* | 150 | /* |
| @@ -899,21 +897,22 @@ static void fib_disable_ip(struct net_device *dev, int force) | |||
| 899 | { | 897 | { |
| 900 | if (fib_sync_down_dev(dev, force)) | 898 | if (fib_sync_down_dev(dev, force)) |
| 901 | fib_flush(dev_net(dev)); | 899 | fib_flush(dev_net(dev)); |
| 902 | rt_cache_flush(0); | 900 | rt_cache_flush(dev_net(dev), 0); |
| 903 | arp_ifdown(dev); | 901 | arp_ifdown(dev); |
| 904 | } | 902 | } |
| 905 | 903 | ||
| 906 | static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) | 904 | static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 907 | { | 905 | { |
| 908 | struct in_ifaddr *ifa = (struct in_ifaddr*)ptr; | 906 | struct in_ifaddr *ifa = (struct in_ifaddr*)ptr; |
| 907 | struct net_device *dev = ifa->ifa_dev->dev; | ||
| 909 | 908 | ||
| 910 | switch (event) { | 909 | switch (event) { |
| 911 | case NETDEV_UP: | 910 | case NETDEV_UP: |
| 912 | fib_add_ifaddr(ifa); | 911 | fib_add_ifaddr(ifa); |
| 913 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 912 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
| 914 | fib_sync_up(ifa->ifa_dev->dev); | 913 | fib_sync_up(dev); |
| 915 | #endif | 914 | #endif |
| 916 | rt_cache_flush(-1); | 915 | rt_cache_flush(dev_net(dev), -1); |
| 917 | break; | 916 | break; |
| 918 | case NETDEV_DOWN: | 917 | case NETDEV_DOWN: |
| 919 | fib_del_ifaddr(ifa); | 918 | fib_del_ifaddr(ifa); |
| @@ -921,9 +920,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
| 921 | /* Last address was deleted from this interface. | 920 | /* Last address was deleted from this interface. |
| 922 | Disable IP. | 921 | Disable IP. |
| 923 | */ | 922 | */ |
| 924 | fib_disable_ip(ifa->ifa_dev->dev, 1); | 923 | fib_disable_ip(dev, 1); |
| 925 | } else { | 924 | } else { |
| 926 | rt_cache_flush(-1); | 925 | rt_cache_flush(dev_net(dev), -1); |
| 927 | } | 926 | } |
| 928 | break; | 927 | break; |
| 929 | } | 928 | } |
| @@ -951,14 +950,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo | |||
| 951 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 950 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
| 952 | fib_sync_up(dev); | 951 | fib_sync_up(dev); |
| 953 | #endif | 952 | #endif |
| 954 | rt_cache_flush(-1); | 953 | rt_cache_flush(dev_net(dev), -1); |
| 955 | break; | 954 | break; |
| 956 | case NETDEV_DOWN: | 955 | case NETDEV_DOWN: |
| 957 | fib_disable_ip(dev, 0); | 956 | fib_disable_ip(dev, 0); |
| 958 | break; | 957 | break; |
| 959 | case NETDEV_CHANGEMTU: | 958 | case NETDEV_CHANGEMTU: |
| 960 | case NETDEV_CHANGE: | 959 | case NETDEV_CHANGE: |
| 961 | rt_cache_flush(0); | 960 | rt_cache_flush(dev_net(dev), 0); |
| 962 | break; | 961 | break; |
| 963 | } | 962 | } |
| 964 | return NOTIFY_DONE; | 963 | return NOTIFY_DONE; |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 2e2fc3376ac9..c8cac6c7f881 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * IPv4 FIB: lookup engine and maintenance routines. | 6 | * IPv4 FIB: lookup engine and maintenance routines. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: fib_hash.c,v 1.13 2001/10/31 21:55:54 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | 8 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 11 | * | 9 | * |
| 12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| @@ -474,7 +472,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 474 | 472 | ||
| 475 | fib_release_info(fi_drop); | 473 | fib_release_info(fi_drop); |
| 476 | if (state & FA_S_ACCESSED) | 474 | if (state & FA_S_ACCESSED) |
| 477 | rt_cache_flush(-1); | 475 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 478 | rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id, | 476 | rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id, |
| 479 | &cfg->fc_nlinfo, NLM_F_REPLACE); | 477 | &cfg->fc_nlinfo, NLM_F_REPLACE); |
| 480 | return 0; | 478 | return 0; |
| @@ -534,7 +532,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 534 | 532 | ||
| 535 | if (new_f) | 533 | if (new_f) |
| 536 | fz->fz_nent++; | 534 | fz->fz_nent++; |
| 537 | rt_cache_flush(-1); | 535 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 538 | 536 | ||
| 539 | rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id, | 537 | rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id, |
| 540 | &cfg->fc_nlinfo, 0); | 538 | &cfg->fc_nlinfo, 0); |
| @@ -616,7 +614,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg) | |||
| 616 | write_unlock_bh(&fib_hash_lock); | 614 | write_unlock_bh(&fib_hash_lock); |
| 617 | 615 | ||
| 618 | if (fa->fa_state & FA_S_ACCESSED) | 616 | if (fa->fa_state & FA_S_ACCESSED) |
| 619 | rt_cache_flush(-1); | 617 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 620 | fn_free_alias(fa, f); | 618 | fn_free_alias(fa, f); |
| 621 | if (kill_fn) { | 619 | if (kill_fn) { |
| 622 | fn_free_node(f); | 620 | fn_free_node(f); |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 1fb56876be54..6080d7120821 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -258,9 +258,9 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) | |||
| 258 | + nla_total_size(4); /* flow */ | 258 | + nla_total_size(4); /* flow */ |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static void fib4_rule_flush_cache(void) | 261 | static void fib4_rule_flush_cache(struct fib_rules_ops *ops) |
| 262 | { | 262 | { |
| 263 | rt_cache_flush(-1); | 263 | rt_cache_flush(ops->fro_net, -1); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static struct fib_rules_ops fib4_rules_ops_template = { | 266 | static struct fib_rules_ops fib4_rules_ops_template = { |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0d4d72827e4b..ded2ae34eab1 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * IPv4 Forwarding Information Base: semantics. | 6 | * IPv4 Forwarding Information Base: semantics. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: fib_semantics.c,v 1.19 2002/01/12 07:54:56 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | 8 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 11 | * | 9 | * |
| 12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index e1600ad8fb0e..5cb72786a8af 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson | 22 | * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson |
| 23 | * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 | 23 | * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 |
| 24 | * | 24 | * |
| 25 | * Version: $Id: fib_trie.c,v 1.3 2005/06/08 14:20:01 robert Exp $ | ||
| 26 | * | ||
| 27 | * | 25 | * |
| 28 | * Code from fib_hash has been reused which includes the following header: | 26 | * Code from fib_hash has been reused which includes the following header: |
| 29 | * | 27 | * |
| @@ -1273,7 +1271,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 1273 | 1271 | ||
| 1274 | fib_release_info(fi_drop); | 1272 | fib_release_info(fi_drop); |
| 1275 | if (state & FA_S_ACCESSED) | 1273 | if (state & FA_S_ACCESSED) |
| 1276 | rt_cache_flush(-1); | 1274 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 1277 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, | 1275 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, |
| 1278 | tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE); | 1276 | tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE); |
| 1279 | 1277 | ||
| @@ -1318,7 +1316,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
| 1318 | list_add_tail_rcu(&new_fa->fa_list, | 1316 | list_add_tail_rcu(&new_fa->fa_list, |
| 1319 | (fa ? &fa->fa_list : fa_head)); | 1317 | (fa ? &fa->fa_list : fa_head)); |
| 1320 | 1318 | ||
| 1321 | rt_cache_flush(-1); | 1319 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 1322 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, | 1320 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, |
| 1323 | &cfg->fc_nlinfo, 0); | 1321 | &cfg->fc_nlinfo, 0); |
| 1324 | succeeded: | 1322 | succeeded: |
| @@ -1661,7 +1659,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) | |||
| 1661 | trie_leaf_remove(t, l); | 1659 | trie_leaf_remove(t, l); |
| 1662 | 1660 | ||
| 1663 | if (fa->fa_state & FA_S_ACCESSED) | 1661 | if (fa->fa_state & FA_S_ACCESSED) |
| 1664 | rt_cache_flush(-1); | 1662 | rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); |
| 1665 | 1663 | ||
| 1666 | fib_release_info(fa->fa_info); | 1664 | fib_release_info(fa->fa_info); |
| 1667 | alias_free_mem_rcu(fa); | 1665 | alias_free_mem_rcu(fa); |
| @@ -2253,25 +2251,7 @@ static int fib_triestat_seq_show(struct seq_file *seq, void *v) | |||
| 2253 | 2251 | ||
| 2254 | static int fib_triestat_seq_open(struct inode *inode, struct file *file) | 2252 | static int fib_triestat_seq_open(struct inode *inode, struct file *file) |
| 2255 | { | 2253 | { |
| 2256 | int err; | 2254 | return single_open_net(inode, file, fib_triestat_seq_show); |
| 2257 | struct net *net; | ||
| 2258 | |||
| 2259 | net = get_proc_net(inode); | ||
| 2260 | if (net == NULL) | ||
| 2261 | return -ENXIO; | ||
| 2262 | err = single_open(file, fib_triestat_seq_show, net); | ||
| 2263 | if (err < 0) { | ||
| 2264 | put_net(net); | ||
| 2265 | return err; | ||
| 2266 | } | ||
| 2267 | return 0; | ||
| 2268 | } | ||
| 2269 | |||
| 2270 | static int fib_triestat_seq_release(struct inode *ino, struct file *f) | ||
| 2271 | { | ||
| 2272 | struct seq_file *seq = f->private_data; | ||
| 2273 | put_net(seq->private); | ||
| 2274 | return single_release(ino, f); | ||
| 2275 | } | 2255 | } |
| 2276 | 2256 | ||
| 2277 | static const struct file_operations fib_triestat_fops = { | 2257 | static const struct file_operations fib_triestat_fops = { |
| @@ -2279,7 +2259,7 @@ static const struct file_operations fib_triestat_fops = { | |||
| 2279 | .open = fib_triestat_seq_open, | 2259 | .open = fib_triestat_seq_open, |
| 2280 | .read = seq_read, | 2260 | .read = seq_read, |
| 2281 | .llseek = seq_lseek, | 2261 | .llseek = seq_lseek, |
| 2282 | .release = fib_triestat_seq_release, | 2262 | .release = single_release_net, |
| 2283 | }; | 2263 | }; |
| 2284 | 2264 | ||
| 2285 | static struct node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) | 2265 | static struct node *fib_trie_get_idx(struct seq_file *seq, loff_t pos) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 87397351ddac..860558633b2c 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -3,8 +3,6 @@ | |||
| 3 | * | 3 | * |
| 4 | * Alan Cox, <alan@redhat.com> | 4 | * Alan Cox, <alan@redhat.com> |
| 5 | * | 5 | * |
| 6 | * Version: $Id: icmp.c,v 1.85 2002/02/01 22:01:03 davem Exp $ | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| 10 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
| @@ -113,12 +111,6 @@ struct icmp_bxm { | |||
| 113 | unsigned char optbuf[40]; | 111 | unsigned char optbuf[40]; |
| 114 | }; | 112 | }; |
| 115 | 113 | ||
| 116 | /* | ||
| 117 | * Statistics | ||
| 118 | */ | ||
| 119 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; | ||
| 120 | DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics) __read_mostly; | ||
| 121 | |||
| 122 | /* An array of errno for error messages from dest unreach. */ | 114 | /* An array of errno for error messages from dest unreach. */ |
| 123 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ | 115 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ |
| 124 | 116 | ||
| @@ -298,10 +290,10 @@ out: | |||
| 298 | /* | 290 | /* |
| 299 | * Maintain the counters used in the SNMP statistics for outgoing ICMP | 291 | * Maintain the counters used in the SNMP statistics for outgoing ICMP |
| 300 | */ | 292 | */ |
| 301 | void icmp_out_count(unsigned char type) | 293 | void icmp_out_count(struct net *net, unsigned char type) |
| 302 | { | 294 | { |
| 303 | ICMPMSGOUT_INC_STATS(type); | 295 | ICMPMSGOUT_INC_STATS(net, type); |
| 304 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); | 296 | ICMP_INC_STATS(net, ICMP_MIB_OUTMSGS); |
| 305 | } | 297 | } |
| 306 | 298 | ||
| 307 | /* | 299 | /* |
| @@ -765,7 +757,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
| 765 | out: | 757 | out: |
| 766 | return; | 758 | return; |
| 767 | out_err: | 759 | out_err: |
| 768 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 760 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
| 769 | goto out; | 761 | goto out; |
| 770 | } | 762 | } |
| 771 | 763 | ||
| @@ -805,7 +797,7 @@ static void icmp_redirect(struct sk_buff *skb) | |||
| 805 | out: | 797 | out: |
| 806 | return; | 798 | return; |
| 807 | out_err: | 799 | out_err: |
| 808 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 800 | ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS); |
| 809 | goto out; | 801 | goto out; |
| 810 | } | 802 | } |
| 811 | 803 | ||
| @@ -876,7 +868,7 @@ static void icmp_timestamp(struct sk_buff *skb) | |||
| 876 | out: | 868 | out: |
| 877 | return; | 869 | return; |
| 878 | out_err: | 870 | out_err: |
| 879 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 871 | ICMP_INC_STATS_BH(dev_net(skb->dst->dev), ICMP_MIB_INERRORS); |
| 880 | goto out; | 872 | goto out; |
| 881 | } | 873 | } |
| 882 | 874 | ||
| @@ -975,6 +967,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
| 975 | { | 967 | { |
| 976 | struct icmphdr *icmph; | 968 | struct icmphdr *icmph; |
| 977 | struct rtable *rt = skb->rtable; | 969 | struct rtable *rt = skb->rtable; |
| 970 | struct net *net = dev_net(rt->u.dst.dev); | ||
| 978 | 971 | ||
| 979 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 972 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
| 980 | int nh; | 973 | int nh; |
| @@ -995,7 +988,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
| 995 | skb_set_network_header(skb, nh); | 988 | skb_set_network_header(skb, nh); |
| 996 | } | 989 | } |
| 997 | 990 | ||
| 998 | ICMP_INC_STATS_BH(ICMP_MIB_INMSGS); | 991 | ICMP_INC_STATS_BH(net, ICMP_MIB_INMSGS); |
| 999 | 992 | ||
| 1000 | switch (skb->ip_summed) { | 993 | switch (skb->ip_summed) { |
| 1001 | case CHECKSUM_COMPLETE: | 994 | case CHECKSUM_COMPLETE: |
| @@ -1013,7 +1006,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
| 1013 | 1006 | ||
| 1014 | icmph = icmp_hdr(skb); | 1007 | icmph = icmp_hdr(skb); |
| 1015 | 1008 | ||
| 1016 | ICMPMSGIN_INC_STATS_BH(icmph->type); | 1009 | ICMPMSGIN_INC_STATS_BH(net, icmph->type); |
| 1017 | /* | 1010 | /* |
| 1018 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 1011 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
| 1019 | * | 1012 | * |
| @@ -1029,9 +1022,6 @@ int icmp_rcv(struct sk_buff *skb) | |||
| 1029 | */ | 1022 | */ |
| 1030 | 1023 | ||
| 1031 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { | 1024 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { |
| 1032 | struct net *net; | ||
| 1033 | |||
| 1034 | net = dev_net(rt->u.dst.dev); | ||
| 1035 | /* | 1025 | /* |
| 1036 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be | 1026 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be |
| 1037 | * silently ignored (we let user decide with a sysctl). | 1027 | * silently ignored (we let user decide with a sysctl). |
| @@ -1057,7 +1047,7 @@ drop: | |||
| 1057 | kfree_skb(skb); | 1047 | kfree_skb(skb); |
| 1058 | return 0; | 1048 | return 0; |
| 1059 | error: | 1049 | error: |
| 1060 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 1050 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
| 1061 | goto drop; | 1051 | goto drop; |
| 1062 | } | 1052 | } |
| 1063 | 1053 | ||
| @@ -1217,5 +1207,4 @@ int __init icmp_init(void) | |||
| 1217 | 1207 | ||
| 1218 | EXPORT_SYMBOL(icmp_err_convert); | 1208 | EXPORT_SYMBOL(icmp_err_convert); |
| 1219 | EXPORT_SYMBOL(icmp_send); | 1209 | EXPORT_SYMBOL(icmp_send); |
| 1220 | EXPORT_SYMBOL(icmp_statistics); | ||
| 1221 | EXPORT_SYMBOL(xrlim_allow); | 1210 | EXPORT_SYMBOL(xrlim_allow); |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2769dc4a4c84..6203ece53606 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -8,8 +8,6 @@ | |||
| 8 | * the older version didn't come out right using gcc 2.5.8, the newer one | 8 | * the older version didn't come out right using gcc 2.5.8, the newer one |
| 9 | * seems to fall out with gcc 2.6.2. | 9 | * seems to fall out with gcc 2.6.2. |
| 10 | * | 10 | * |
| 11 | * Version: $Id: igmp.c,v 1.47 2002/02/01 22:01:03 davem Exp $ | ||
| 12 | * | ||
| 13 | * Authors: | 11 | * Authors: |
| 14 | * Alan Cox <Alan.Cox@linux.org> | 12 | * Alan Cox <Alan.Cox@linux.org> |
| 15 | * | 13 | * |
| @@ -1198,7 +1196,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) | |||
| 1198 | 1196 | ||
| 1199 | ASSERT_RTNL(); | 1197 | ASSERT_RTNL(); |
| 1200 | 1198 | ||
| 1201 | if (dev_net(in_dev->dev) != &init_net) | 1199 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1202 | return; | 1200 | return; |
| 1203 | 1201 | ||
| 1204 | for (im=in_dev->mc_list; im; im=im->next) { | 1202 | for (im=in_dev->mc_list; im; im=im->next) { |
| @@ -1280,7 +1278,7 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) | |||
| 1280 | 1278 | ||
| 1281 | ASSERT_RTNL(); | 1279 | ASSERT_RTNL(); |
| 1282 | 1280 | ||
| 1283 | if (dev_net(in_dev->dev) != &init_net) | 1281 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1284 | return; | 1282 | return; |
| 1285 | 1283 | ||
| 1286 | for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { | 1284 | for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { |
| @@ -1310,7 +1308,7 @@ void ip_mc_down(struct in_device *in_dev) | |||
| 1310 | 1308 | ||
| 1311 | ASSERT_RTNL(); | 1309 | ASSERT_RTNL(); |
| 1312 | 1310 | ||
| 1313 | if (dev_net(in_dev->dev) != &init_net) | 1311 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1314 | return; | 1312 | return; |
| 1315 | 1313 | ||
| 1316 | for (i=in_dev->mc_list; i; i=i->next) | 1314 | for (i=in_dev->mc_list; i; i=i->next) |
| @@ -1333,7 +1331,7 @@ void ip_mc_init_dev(struct in_device *in_dev) | |||
| 1333 | { | 1331 | { |
| 1334 | ASSERT_RTNL(); | 1332 | ASSERT_RTNL(); |
| 1335 | 1333 | ||
| 1336 | if (dev_net(in_dev->dev) != &init_net) | 1334 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1337 | return; | 1335 | return; |
| 1338 | 1336 | ||
| 1339 | in_dev->mc_tomb = NULL; | 1337 | in_dev->mc_tomb = NULL; |
| @@ -1359,7 +1357,7 @@ void ip_mc_up(struct in_device *in_dev) | |||
| 1359 | 1357 | ||
| 1360 | ASSERT_RTNL(); | 1358 | ASSERT_RTNL(); |
| 1361 | 1359 | ||
| 1362 | if (dev_net(in_dev->dev) != &init_net) | 1360 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1363 | return; | 1361 | return; |
| 1364 | 1362 | ||
| 1365 | ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); | 1363 | ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); |
| @@ -1378,7 +1376,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev) | |||
| 1378 | 1376 | ||
| 1379 | ASSERT_RTNL(); | 1377 | ASSERT_RTNL(); |
| 1380 | 1378 | ||
| 1381 | if (dev_net(in_dev->dev) != &init_net) | 1379 | if (!net_eq(dev_net(in_dev->dev), &init_net)) |
| 1382 | return; | 1380 | return; |
| 1383 | 1381 | ||
| 1384 | /* Deactivate timers */ | 1382 | /* Deactivate timers */ |
| @@ -1762,7 +1760,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) | |||
| 1762 | if (!ipv4_is_multicast(addr)) | 1760 | if (!ipv4_is_multicast(addr)) |
| 1763 | return -EINVAL; | 1761 | return -EINVAL; |
| 1764 | 1762 | ||
| 1765 | if (sock_net(sk) != &init_net) | 1763 | if (!net_eq(sock_net(sk), &init_net)) |
| 1766 | return -EPROTONOSUPPORT; | 1764 | return -EPROTONOSUPPORT; |
| 1767 | 1765 | ||
| 1768 | rtnl_lock(); | 1766 | rtnl_lock(); |
| @@ -1833,7 +1831,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
| 1833 | u32 ifindex; | 1831 | u32 ifindex; |
| 1834 | int ret = -EADDRNOTAVAIL; | 1832 | int ret = -EADDRNOTAVAIL; |
| 1835 | 1833 | ||
| 1836 | if (sock_net(sk) != &init_net) | 1834 | if (!net_eq(sock_net(sk), &init_net)) |
| 1837 | return -EPROTONOSUPPORT; | 1835 | return -EPROTONOSUPPORT; |
| 1838 | 1836 | ||
| 1839 | rtnl_lock(); | 1837 | rtnl_lock(); |
| @@ -1881,7 +1879,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct | |||
| 1881 | if (!ipv4_is_multicast(addr)) | 1879 | if (!ipv4_is_multicast(addr)) |
| 1882 | return -EINVAL; | 1880 | return -EINVAL; |
| 1883 | 1881 | ||
| 1884 | if (sock_net(sk) != &init_net) | 1882 | if (!net_eq(sock_net(sk), &init_net)) |
| 1885 | return -EPROTONOSUPPORT; | 1883 | return -EPROTONOSUPPORT; |
| 1886 | 1884 | ||
| 1887 | rtnl_lock(); | 1885 | rtnl_lock(); |
| @@ -2017,7 +2015,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) | |||
| 2017 | msf->imsf_fmode != MCAST_EXCLUDE) | 2015 | msf->imsf_fmode != MCAST_EXCLUDE) |
| 2018 | return -EINVAL; | 2016 | return -EINVAL; |
| 2019 | 2017 | ||
| 2020 | if (sock_net(sk) != &init_net) | 2018 | if (!net_eq(sock_net(sk), &init_net)) |
| 2021 | return -EPROTONOSUPPORT; | 2019 | return -EPROTONOSUPPORT; |
| 2022 | 2020 | ||
| 2023 | rtnl_lock(); | 2021 | rtnl_lock(); |
| @@ -2100,7 +2098,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, | |||
| 2100 | if (!ipv4_is_multicast(addr)) | 2098 | if (!ipv4_is_multicast(addr)) |
| 2101 | return -EINVAL; | 2099 | return -EINVAL; |
| 2102 | 2100 | ||
| 2103 | if (sock_net(sk) != &init_net) | 2101 | if (!net_eq(sock_net(sk), &init_net)) |
| 2104 | return -EPROTONOSUPPORT; | 2102 | return -EPROTONOSUPPORT; |
| 2105 | 2103 | ||
| 2106 | rtnl_lock(); | 2104 | rtnl_lock(); |
| @@ -2165,7 +2163,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, | |||
| 2165 | if (!ipv4_is_multicast(addr)) | 2163 | if (!ipv4_is_multicast(addr)) |
| 2166 | return -EINVAL; | 2164 | return -EINVAL; |
| 2167 | 2165 | ||
| 2168 | if (sock_net(sk) != &init_net) | 2166 | if (!net_eq(sock_net(sk), &init_net)) |
| 2169 | return -EPROTONOSUPPORT; | 2167 | return -EPROTONOSUPPORT; |
| 2170 | 2168 | ||
| 2171 | rtnl_lock(); | 2169 | rtnl_lock(); |
| @@ -2252,7 +2250,7 @@ void ip_mc_drop_socket(struct sock *sk) | |||
| 2252 | if (inet->mc_list == NULL) | 2250 | if (inet->mc_list == NULL) |
| 2253 | return; | 2251 | return; |
| 2254 | 2252 | ||
| 2255 | if (sock_net(sk) != &init_net) | 2253 | if (!net_eq(sock_net(sk), &init_net)) |
| 2256 | return; | 2254 | return; |
| 2257 | 2255 | ||
| 2258 | rtnl_lock(); | 2256 | rtnl_lock(); |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index ec834480abe7..bb81c958b744 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -103,7 +103,8 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) | |||
| 103 | rover = net_random() % remaining + low; | 103 | rover = net_random() % remaining + low; |
| 104 | 104 | ||
| 105 | do { | 105 | do { |
| 106 | head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)]; | 106 | head = &hashinfo->bhash[inet_bhashfn(net, rover, |
| 107 | hashinfo->bhash_size)]; | ||
| 107 | spin_lock(&head->lock); | 108 | spin_lock(&head->lock); |
| 108 | inet_bind_bucket_for_each(tb, node, &head->chain) | 109 | inet_bind_bucket_for_each(tb, node, &head->chain) |
| 109 | if (tb->ib_net == net && tb->port == rover) | 110 | if (tb->ib_net == net && tb->port == rover) |
| @@ -130,7 +131,8 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) | |||
| 130 | */ | 131 | */ |
| 131 | snum = rover; | 132 | snum = rover; |
| 132 | } else { | 133 | } else { |
| 133 | head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)]; | 134 | head = &hashinfo->bhash[inet_bhashfn(net, snum, |
| 135 | hashinfo->bhash_size)]; | ||
| 134 | spin_lock(&head->lock); | 136 | spin_lock(&head->lock); |
| 135 | inet_bind_bucket_for_each(tb, node, &head->chain) | 137 | inet_bind_bucket_for_each(tb, node, &head->chain) |
| 136 | if (tb->ib_net == net && tb->port == snum) | 138 | if (tb->ib_net == net && tb->port == snum) |
| @@ -336,15 +338,16 @@ struct dst_entry* inet_csk_route_req(struct sock *sk, | |||
| 336 | .uli_u = { .ports = | 338 | .uli_u = { .ports = |
| 337 | { .sport = inet_sk(sk)->sport, | 339 | { .sport = inet_sk(sk)->sport, |
| 338 | .dport = ireq->rmt_port } } }; | 340 | .dport = ireq->rmt_port } } }; |
| 341 | struct net *net = sock_net(sk); | ||
| 339 | 342 | ||
| 340 | security_req_classify_flow(req, &fl); | 343 | security_req_classify_flow(req, &fl); |
| 341 | if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) { | 344 | if (ip_route_output_flow(net, &rt, &fl, sk, 0)) { |
| 342 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 345 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
| 343 | return NULL; | 346 | return NULL; |
| 344 | } | 347 | } |
| 345 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { | 348 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { |
| 346 | ip_rt_put(rt); | 349 | ip_rt_put(rt); |
| 347 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 350 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
| 348 | return NULL; | 351 | return NULL; |
| 349 | } | 352 | } |
| 350 | return &rt->u.dst; | 353 | return &rt->u.dst; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index da97695e7096..c10036e7a463 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * inet_diag.c Module for monitoring INET transport protocols sockets. | 2 | * inet_diag.c Module for monitoring INET transport protocols sockets. |
| 3 | * | 3 | * |
| 4 | * Version: $Id: inet_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | 4 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 2023d37b2708..115f53722d20 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
| @@ -70,7 +70,8 @@ void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | |||
| 70 | static void __inet_put_port(struct sock *sk) | 70 | static void __inet_put_port(struct sock *sk) |
| 71 | { | 71 | { |
| 72 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; | 72 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; |
| 73 | const int bhash = inet_bhashfn(inet_sk(sk)->num, hashinfo->bhash_size); | 73 | const int bhash = inet_bhashfn(sock_net(sk), inet_sk(sk)->num, |
| 74 | hashinfo->bhash_size); | ||
| 74 | struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; | 75 | struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; |
| 75 | struct inet_bind_bucket *tb; | 76 | struct inet_bind_bucket *tb; |
| 76 | 77 | ||
| @@ -95,7 +96,8 @@ EXPORT_SYMBOL(inet_put_port); | |||
| 95 | void __inet_inherit_port(struct sock *sk, struct sock *child) | 96 | void __inet_inherit_port(struct sock *sk, struct sock *child) |
| 96 | { | 97 | { |
| 97 | struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; | 98 | struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; |
| 98 | const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size); | 99 | const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->num, |
| 100 | table->bhash_size); | ||
| 99 | struct inet_bind_hashbucket *head = &table->bhash[bhash]; | 101 | struct inet_bind_hashbucket *head = &table->bhash[bhash]; |
| 100 | struct inet_bind_bucket *tb; | 102 | struct inet_bind_bucket *tb; |
| 101 | 103 | ||
| @@ -192,7 +194,7 @@ struct sock *__inet_lookup_listener(struct net *net, | |||
| 192 | const struct hlist_head *head; | 194 | const struct hlist_head *head; |
| 193 | 195 | ||
| 194 | read_lock(&hashinfo->lhash_lock); | 196 | read_lock(&hashinfo->lhash_lock); |
| 195 | head = &hashinfo->listening_hash[inet_lhashfn(hnum)]; | 197 | head = &hashinfo->listening_hash[inet_lhashfn(net, hnum)]; |
| 196 | if (!hlist_empty(head)) { | 198 | if (!hlist_empty(head)) { |
| 197 | const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); | 199 | const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); |
| 198 | 200 | ||
| @@ -225,7 +227,7 @@ struct sock * __inet_lookup_established(struct net *net, | |||
| 225 | /* Optimize here for direct hit, only listening connections can | 227 | /* Optimize here for direct hit, only listening connections can |
| 226 | * have wildcards anyways. | 228 | * have wildcards anyways. |
| 227 | */ | 229 | */ |
| 228 | unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); | 230 | unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport); |
| 229 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | 231 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); |
| 230 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | 232 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); |
| 231 | 233 | ||
| @@ -265,13 +267,13 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
| 265 | int dif = sk->sk_bound_dev_if; | 267 | int dif = sk->sk_bound_dev_if; |
| 266 | INET_ADDR_COOKIE(acookie, saddr, daddr) | 268 | INET_ADDR_COOKIE(acookie, saddr, daddr) |
| 267 | const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); | 269 | const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); |
| 268 | unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport); | 270 | struct net *net = sock_net(sk); |
| 271 | unsigned int hash = inet_ehashfn(net, daddr, lport, saddr, inet->dport); | ||
| 269 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); | 272 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); |
| 270 | rwlock_t *lock = inet_ehash_lockp(hinfo, hash); | 273 | rwlock_t *lock = inet_ehash_lockp(hinfo, hash); |
| 271 | struct sock *sk2; | 274 | struct sock *sk2; |
| 272 | const struct hlist_node *node; | 275 | const struct hlist_node *node; |
| 273 | struct inet_timewait_sock *tw; | 276 | struct inet_timewait_sock *tw; |
| 274 | struct net *net = sock_net(sk); | ||
| 275 | 277 | ||
| 276 | prefetch(head->chain.first); | 278 | prefetch(head->chain.first); |
| 277 | write_lock(lock); | 279 | write_lock(lock); |
| @@ -310,11 +312,11 @@ unique: | |||
| 310 | 312 | ||
| 311 | if (twp) { | 313 | if (twp) { |
| 312 | *twp = tw; | 314 | *twp = tw; |
| 313 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | 315 | NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); |
| 314 | } else if (tw) { | 316 | } else if (tw) { |
| 315 | /* Silly. Should hash-dance instead... */ | 317 | /* Silly. Should hash-dance instead... */ |
| 316 | inet_twsk_deschedule(tw, death_row); | 318 | inet_twsk_deschedule(tw, death_row); |
| 317 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | 319 | NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); |
| 318 | 320 | ||
| 319 | inet_twsk_put(tw); | 321 | inet_twsk_put(tw); |
| 320 | } | 322 | } |
| @@ -438,7 +440,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, | |||
| 438 | local_bh_disable(); | 440 | local_bh_disable(); |
| 439 | for (i = 1; i <= remaining; i++) { | 441 | for (i = 1; i <= remaining; i++) { |
| 440 | port = low + (i + offset) % remaining; | 442 | port = low + (i + offset) % remaining; |
| 441 | head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; | 443 | head = &hinfo->bhash[inet_bhashfn(net, port, |
| 444 | hinfo->bhash_size)]; | ||
| 442 | spin_lock(&head->lock); | 445 | spin_lock(&head->lock); |
| 443 | 446 | ||
| 444 | /* Does not bother with rcv_saddr checks, | 447 | /* Does not bother with rcv_saddr checks, |
| @@ -493,7 +496,7 @@ ok: | |||
| 493 | goto out; | 496 | goto out; |
| 494 | } | 497 | } |
| 495 | 498 | ||
| 496 | head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)]; | 499 | head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)]; |
| 497 | tb = inet_csk(sk)->icsk_bind_hash; | 500 | tb = inet_csk(sk)->icsk_bind_hash; |
| 498 | spin_lock_bh(&head->lock); | 501 | spin_lock_bh(&head->lock); |
| 499 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 502 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index ce16e9ac24c1..75c2def8f9a0 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
| @@ -32,7 +32,8 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw, | |||
| 32 | write_unlock(lock); | 32 | write_unlock(lock); |
| 33 | 33 | ||
| 34 | /* Disassociate with bind bucket. */ | 34 | /* Disassociate with bind bucket. */ |
| 35 | bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)]; | 35 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num, |
| 36 | hashinfo->bhash_size)]; | ||
| 36 | spin_lock(&bhead->lock); | 37 | spin_lock(&bhead->lock); |
| 37 | tb = tw->tw_tb; | 38 | tb = tw->tw_tb; |
| 38 | __hlist_del(&tw->tw_bind_node); | 39 | __hlist_del(&tw->tw_bind_node); |
| @@ -81,7 +82,8 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
| 81 | Note, that any socket with inet->num != 0 MUST be bound in | 82 | Note, that any socket with inet->num != 0 MUST be bound in |
| 82 | binding cache, even if it is closed. | 83 | binding cache, even if it is closed. |
| 83 | */ | 84 | */ |
| 84 | bhead = &hashinfo->bhash[inet_bhashfn(inet->num, hashinfo->bhash_size)]; | 85 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->num, |
| 86 | hashinfo->bhash_size)]; | ||
| 85 | spin_lock(&bhead->lock); | 87 | spin_lock(&bhead->lock); |
| 86 | tw->tw_tb = icsk->icsk_bind_hash; | 88 | tw->tw_tb = icsk->icsk_bind_hash; |
| 87 | BUG_TRAP(icsk->icsk_bind_hash); | 89 | BUG_TRAP(icsk->icsk_bind_hash); |
| @@ -158,6 +160,9 @@ rescan: | |||
| 158 | __inet_twsk_del_dead_node(tw); | 160 | __inet_twsk_del_dead_node(tw); |
| 159 | spin_unlock(&twdr->death_lock); | 161 | spin_unlock(&twdr->death_lock); |
| 160 | __inet_twsk_kill(tw, twdr->hashinfo); | 162 | __inet_twsk_kill(tw, twdr->hashinfo); |
| 163 | #ifdef CONFIG_NET_NS | ||
| 164 | NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITED); | ||
| 165 | #endif | ||
| 161 | inet_twsk_put(tw); | 166 | inet_twsk_put(tw); |
| 162 | killed++; | 167 | killed++; |
| 163 | spin_lock(&twdr->death_lock); | 168 | spin_lock(&twdr->death_lock); |
| @@ -176,8 +181,9 @@ rescan: | |||
| 176 | } | 181 | } |
| 177 | 182 | ||
| 178 | twdr->tw_count -= killed; | 183 | twdr->tw_count -= killed; |
| 179 | NET_ADD_STATS_BH(LINUX_MIB_TIMEWAITED, killed); | 184 | #ifndef CONFIG_NET_NS |
| 180 | 185 | NET_ADD_STATS_BH(&init_net, LINUX_MIB_TIMEWAITED, killed); | |
| 186 | #endif | ||
| 181 | return ret; | 187 | return ret; |
| 182 | } | 188 | } |
| 183 | 189 | ||
| @@ -370,6 +376,9 @@ void inet_twdr_twcal_tick(unsigned long data) | |||
| 370 | &twdr->twcal_row[slot]) { | 376 | &twdr->twcal_row[slot]) { |
| 371 | __inet_twsk_del_dead_node(tw); | 377 | __inet_twsk_del_dead_node(tw); |
| 372 | __inet_twsk_kill(tw, twdr->hashinfo); | 378 | __inet_twsk_kill(tw, twdr->hashinfo); |
| 379 | #ifdef CONFIG_NET_NS | ||
| 380 | NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITKILLED); | ||
| 381 | #endif | ||
| 373 | inet_twsk_put(tw); | 382 | inet_twsk_put(tw); |
| 374 | killed++; | 383 | killed++; |
| 375 | } | 384 | } |
| @@ -393,7 +402,9 @@ void inet_twdr_twcal_tick(unsigned long data) | |||
| 393 | out: | 402 | out: |
| 394 | if ((twdr->tw_count -= killed) == 0) | 403 | if ((twdr->tw_count -= killed) == 0) |
| 395 | del_timer(&twdr->tw_timer); | 404 | del_timer(&twdr->tw_timer); |
| 396 | NET_ADD_STATS_BH(LINUX_MIB_TIMEWAITKILLED, killed); | 405 | #ifndef CONFIG_NET_NS |
| 406 | NET_ADD_STATS_BH(&init_net, LINUX_MIB_TIMEWAITKILLED, killed); | ||
| 407 | #endif | ||
| 397 | spin_unlock(&twdr->death_lock); | 408 | spin_unlock(&twdr->death_lock); |
| 398 | } | 409 | } |
| 399 | 410 | ||
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index af995198f643..a456ceeac3f2 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
| @@ -3,8 +3,6 @@ | |||
| 3 | * | 3 | * |
| 4 | * This source is covered by the GNU GPL, the same as all kernel sources. | 4 | * This source is covered by the GNU GPL, the same as all kernel sources. |
| 5 | * | 5 | * |
| 6 | * Version: $Id: inetpeer.c,v 1.7 2001/09/20 21:22:50 davem Exp $ | ||
| 7 | * | ||
| 8 | * Authors: Andrey V. Savochkin <saw@msu.ru> | 6 | * Authors: Andrey V. Savochkin <saw@msu.ru> |
| 9 | */ | 7 | */ |
| 10 | 8 | ||
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 4813c39b438b..450016b89a18 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The IP forwarding functionality. | 6 | * The IP forwarding functionality. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_forward.c,v 1.48 2000/12/13 18:31:48 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: see ip.c | 8 | * Authors: see ip.c |
| 11 | * | 9 | * |
| 12 | * Fixes: | 10 | * Fixes: |
| @@ -44,7 +42,7 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
| 44 | { | 42 | { |
| 45 | struct ip_options * opt = &(IPCB(skb)->opt); | 43 | struct ip_options * opt = &(IPCB(skb)->opt); |
| 46 | 44 | ||
| 47 | IP_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); | 45 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 48 | 46 | ||
| 49 | if (unlikely(opt->optlen)) | 47 | if (unlikely(opt->optlen)) |
| 50 | ip_forward_options(skb); | 48 | ip_forward_options(skb); |
| @@ -58,6 +56,9 @@ int ip_forward(struct sk_buff *skb) | |||
| 58 | struct rtable *rt; /* Route we use */ | 56 | struct rtable *rt; /* Route we use */ |
| 59 | struct ip_options * opt = &(IPCB(skb)->opt); | 57 | struct ip_options * opt = &(IPCB(skb)->opt); |
| 60 | 58 | ||
| 59 | if (skb_warn_if_lro(skb)) | ||
| 60 | goto drop; | ||
| 61 | |||
| 61 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb)) | 62 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb)) |
| 62 | goto drop; | 63 | goto drop; |
| 63 | 64 | ||
| @@ -87,7 +88,7 @@ int ip_forward(struct sk_buff *skb) | |||
| 87 | 88 | ||
| 88 | if (unlikely(skb->len > dst_mtu(&rt->u.dst) && !skb_is_gso(skb) && | 89 | if (unlikely(skb->len > dst_mtu(&rt->u.dst) && !skb_is_gso(skb) && |
| 89 | (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { | 90 | (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { |
| 90 | IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 91 | IP_INC_STATS(dev_net(rt->u.dst.dev), IPSTATS_MIB_FRAGFAILS); |
| 91 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 92 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
| 92 | htonl(dst_mtu(&rt->u.dst))); | 93 | htonl(dst_mtu(&rt->u.dst))); |
| 93 | goto drop; | 94 | goto drop; |
| @@ -122,7 +123,7 @@ sr_failed: | |||
| 122 | 123 | ||
| 123 | too_many_hops: | 124 | too_many_hops: |
| 124 | /* Tell the sender its packet died... */ | 125 | /* Tell the sender its packet died... */ |
| 125 | IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 126 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_INHDRERRORS); |
| 126 | icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); | 127 | icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); |
| 127 | drop: | 128 | drop: |
| 128 | kfree_skb(skb); | 129 | kfree_skb(skb); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 37221f659159..38d38f058018 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The IP fragmentation functionality. | 6 | * The IP fragmentation functionality. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_fragment.c,v 1.59 2002/01/12 07:54:56 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> | 8 | * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> |
| 11 | * Alan Cox <Alan.Cox@linux.org> | 9 | * Alan Cox <Alan.Cox@linux.org> |
| 12 | * | 10 | * |
| @@ -180,7 +178,7 @@ static void ip_evictor(struct net *net) | |||
| 180 | 178 | ||
| 181 | evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags); | 179 | evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags); |
| 182 | if (evicted) | 180 | if (evicted) |
| 183 | IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted); | 181 | IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted); |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | /* | 184 | /* |
| @@ -189,8 +187,10 @@ static void ip_evictor(struct net *net) | |||
| 189 | static void ip_expire(unsigned long arg) | 187 | static void ip_expire(unsigned long arg) |
| 190 | { | 188 | { |
| 191 | struct ipq *qp; | 189 | struct ipq *qp; |
| 190 | struct net *net; | ||
| 192 | 191 | ||
| 193 | qp = container_of((struct inet_frag_queue *) arg, struct ipq, q); | 192 | qp = container_of((struct inet_frag_queue *) arg, struct ipq, q); |
| 193 | net = container_of(qp->q.net, struct net, ipv4.frags); | ||
| 194 | 194 | ||
| 195 | spin_lock(&qp->q.lock); | 195 | spin_lock(&qp->q.lock); |
| 196 | 196 | ||
| @@ -199,14 +199,12 @@ static void ip_expire(unsigned long arg) | |||
| 199 | 199 | ||
| 200 | ipq_kill(qp); | 200 | ipq_kill(qp); |
| 201 | 201 | ||
| 202 | IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); | 202 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT); |
| 203 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | 203 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
| 204 | 204 | ||
| 205 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { | 205 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { |
| 206 | struct sk_buff *head = qp->q.fragments; | 206 | struct sk_buff *head = qp->q.fragments; |
| 207 | struct net *net; | ||
| 208 | 207 | ||
| 209 | net = container_of(qp->q.net, struct net, ipv4.frags); | ||
| 210 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ | 208 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ |
| 211 | if ((head->dev = dev_get_by_index(net, qp->iif)) != NULL) { | 209 | if ((head->dev = dev_get_by_index(net, qp->iif)) != NULL) { |
| 212 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); | 210 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); |
| @@ -263,7 +261,10 @@ static inline int ip_frag_too_far(struct ipq *qp) | |||
| 263 | rc = qp->q.fragments && (end - start) > max; | 261 | rc = qp->q.fragments && (end - start) > max; |
| 264 | 262 | ||
| 265 | if (rc) { | 263 | if (rc) { |
| 266 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | 264 | struct net *net; |
| 265 | |||
| 266 | net = container_of(qp->q.net, struct net, ipv4.frags); | ||
| 267 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); | ||
| 267 | } | 268 | } |
| 268 | 269 | ||
| 269 | return rc; | 270 | return rc; |
| @@ -547,7 +548,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
| 547 | iph = ip_hdr(head); | 548 | iph = ip_hdr(head); |
| 548 | iph->frag_off = 0; | 549 | iph->frag_off = 0; |
| 549 | iph->tot_len = htons(len); | 550 | iph->tot_len = htons(len); |
| 550 | IP_INC_STATS_BH(IPSTATS_MIB_REASMOKS); | 551 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMOKS); |
| 551 | qp->q.fragments = NULL; | 552 | qp->q.fragments = NULL; |
| 552 | return 0; | 553 | return 0; |
| 553 | 554 | ||
| @@ -562,7 +563,7 @@ out_oversize: | |||
| 562 | "Oversized IP packet from " NIPQUAD_FMT ".\n", | 563 | "Oversized IP packet from " NIPQUAD_FMT ".\n", |
| 563 | NIPQUAD(qp->saddr)); | 564 | NIPQUAD(qp->saddr)); |
| 564 | out_fail: | 565 | out_fail: |
| 565 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | 566 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS); |
| 566 | return err; | 567 | return err; |
| 567 | } | 568 | } |
| 568 | 569 | ||
| @@ -572,9 +573,9 @@ int ip_defrag(struct sk_buff *skb, u32 user) | |||
| 572 | struct ipq *qp; | 573 | struct ipq *qp; |
| 573 | struct net *net; | 574 | struct net *net; |
| 574 | 575 | ||
| 575 | IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS); | ||
| 576 | |||
| 577 | net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev); | 576 | net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev); |
| 577 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); | ||
| 578 | |||
| 578 | /* Start by cleaning up the memory. */ | 579 | /* Start by cleaning up the memory. */ |
| 579 | if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh) | 580 | if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh) |
| 580 | ip_evictor(net); | 581 | ip_evictor(net); |
| @@ -592,7 +593,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) | |||
| 592 | return ret; | 593 | return ret; |
| 593 | } | 594 | } |
| 594 | 595 | ||
| 595 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | 596 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
| 596 | kfree_skb(skb); | 597 | kfree_skb(skb); |
| 597 | return -ENOMEM; | 598 | return -ENOMEM; |
| 598 | } | 599 | } |
| @@ -600,7 +601,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) | |||
| 600 | #ifdef CONFIG_SYSCTL | 601 | #ifdef CONFIG_SYSCTL |
| 601 | static int zero; | 602 | static int zero; |
| 602 | 603 | ||
| 603 | static struct ctl_table ip4_frags_ctl_table[] = { | 604 | static struct ctl_table ip4_frags_ns_ctl_table[] = { |
| 604 | { | 605 | { |
| 605 | .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, | 606 | .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, |
| 606 | .procname = "ipfrag_high_thresh", | 607 | .procname = "ipfrag_high_thresh", |
| @@ -626,6 +627,10 @@ static struct ctl_table ip4_frags_ctl_table[] = { | |||
| 626 | .proc_handler = &proc_dointvec_jiffies, | 627 | .proc_handler = &proc_dointvec_jiffies, |
| 627 | .strategy = &sysctl_jiffies | 628 | .strategy = &sysctl_jiffies |
| 628 | }, | 629 | }, |
| 630 | { } | ||
| 631 | }; | ||
| 632 | |||
| 633 | static struct ctl_table ip4_frags_ctl_table[] = { | ||
| 629 | { | 634 | { |
| 630 | .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, | 635 | .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, |
| 631 | .procname = "ipfrag_secret_interval", | 636 | .procname = "ipfrag_secret_interval", |
| @@ -646,22 +651,20 @@ static struct ctl_table ip4_frags_ctl_table[] = { | |||
| 646 | { } | 651 | { } |
| 647 | }; | 652 | }; |
| 648 | 653 | ||
| 649 | static int ip4_frags_ctl_register(struct net *net) | 654 | static int ip4_frags_ns_ctl_register(struct net *net) |
| 650 | { | 655 | { |
| 651 | struct ctl_table *table; | 656 | struct ctl_table *table; |
| 652 | struct ctl_table_header *hdr; | 657 | struct ctl_table_header *hdr; |
| 653 | 658 | ||
| 654 | table = ip4_frags_ctl_table; | 659 | table = ip4_frags_ns_ctl_table; |
| 655 | if (net != &init_net) { | 660 | if (net != &init_net) { |
| 656 | table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL); | 661 | table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL); |
| 657 | if (table == NULL) | 662 | if (table == NULL) |
| 658 | goto err_alloc; | 663 | goto err_alloc; |
| 659 | 664 | ||
| 660 | table[0].data = &net->ipv4.frags.high_thresh; | 665 | table[0].data = &net->ipv4.frags.high_thresh; |
| 661 | table[1].data = &net->ipv4.frags.low_thresh; | 666 | table[1].data = &net->ipv4.frags.low_thresh; |
| 662 | table[2].data = &net->ipv4.frags.timeout; | 667 | table[2].data = &net->ipv4.frags.timeout; |
| 663 | table[3].mode &= ~0222; | ||
| 664 | table[4].mode &= ~0222; | ||
| 665 | } | 668 | } |
| 666 | 669 | ||
| 667 | hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table); | 670 | hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table); |
| @@ -678,7 +681,7 @@ err_alloc: | |||
| 678 | return -ENOMEM; | 681 | return -ENOMEM; |
| 679 | } | 682 | } |
| 680 | 683 | ||
| 681 | static void ip4_frags_ctl_unregister(struct net *net) | 684 | static void ip4_frags_ns_ctl_unregister(struct net *net) |
| 682 | { | 685 | { |
| 683 | struct ctl_table *table; | 686 | struct ctl_table *table; |
| 684 | 687 | ||
| @@ -686,13 +689,22 @@ static void ip4_frags_ctl_unregister(struct net *net) | |||
| 686 | unregister_net_sysctl_table(net->ipv4.frags_hdr); | 689 | unregister_net_sysctl_table(net->ipv4.frags_hdr); |
| 687 | kfree(table); | 690 | kfree(table); |
| 688 | } | 691 | } |
| 692 | |||
| 693 | static void ip4_frags_ctl_register(void) | ||
| 694 | { | ||
| 695 | register_net_sysctl_rotable(net_ipv4_ctl_path, ip4_frags_ctl_table); | ||
| 696 | } | ||
| 689 | #else | 697 | #else |
| 690 | static inline int ip4_frags_ctl_register(struct net *net) | 698 | static inline int ip4_frags_ns_ctl_register(struct net *net) |
| 691 | { | 699 | { |
| 692 | return 0; | 700 | return 0; |
| 693 | } | 701 | } |
| 694 | 702 | ||
| 695 | static inline void ip4_frags_ctl_unregister(struct net *net) | 703 | static inline void ip4_frags_ns_ctl_unregister(struct net *net) |
| 704 | { | ||
| 705 | } | ||
| 706 | |||
| 707 | static inline void ip4_frags_ctl_register(void) | ||
| 696 | { | 708 | { |
| 697 | } | 709 | } |
| 698 | #endif | 710 | #endif |
| @@ -716,12 +728,12 @@ static int ipv4_frags_init_net(struct net *net) | |||
| 716 | 728 | ||
| 717 | inet_frags_init_net(&net->ipv4.frags); | 729 | inet_frags_init_net(&net->ipv4.frags); |
| 718 | 730 | ||
| 719 | return ip4_frags_ctl_register(net); | 731 | return ip4_frags_ns_ctl_register(net); |
| 720 | } | 732 | } |
| 721 | 733 | ||
| 722 | static void ipv4_frags_exit_net(struct net *net) | 734 | static void ipv4_frags_exit_net(struct net *net) |
| 723 | { | 735 | { |
| 724 | ip4_frags_ctl_unregister(net); | 736 | ip4_frags_ns_ctl_unregister(net); |
| 725 | inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); | 737 | inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); |
| 726 | } | 738 | } |
| 727 | 739 | ||
| @@ -732,6 +744,7 @@ static struct pernet_operations ip4_frags_ops = { | |||
| 732 | 744 | ||
| 733 | void __init ipfrag_init(void) | 745 | void __init ipfrag_init(void) |
| 734 | { | 746 | { |
| 747 | ip4_frags_ctl_register(); | ||
| 735 | register_pernet_subsys(&ip4_frags_ops); | 748 | register_pernet_subsys(&ip4_frags_ops); |
| 736 | ip4_frags.hashfn = ip4_hashfn; | 749 | ip4_frags.hashfn = ip4_hashfn; |
| 737 | ip4_frags.constructor = ip4_frag_init; | 750 | ip4_frags.constructor = ip4_frag_init; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4342cba4ff82..2a61158ea722 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -473,6 +473,8 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
| 473 | read_lock(&ipgre_lock); | 473 | read_lock(&ipgre_lock); |
| 474 | if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), | 474 | if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), |
| 475 | iph->saddr, iph->daddr, key)) != NULL) { | 475 | iph->saddr, iph->daddr, key)) != NULL) { |
| 476 | struct net_device_stats *stats = &tunnel->dev->stats; | ||
| 477 | |||
| 476 | secpath_reset(skb); | 478 | secpath_reset(skb); |
| 477 | 479 | ||
| 478 | skb->protocol = *(__be16*)(h + 2); | 480 | skb->protocol = *(__be16*)(h + 2); |
| @@ -497,28 +499,28 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
| 497 | /* Looped back packet, drop it! */ | 499 | /* Looped back packet, drop it! */ |
| 498 | if (skb->rtable->fl.iif == 0) | 500 | if (skb->rtable->fl.iif == 0) |
| 499 | goto drop; | 501 | goto drop; |
| 500 | tunnel->stat.multicast++; | 502 | stats->multicast++; |
| 501 | skb->pkt_type = PACKET_BROADCAST; | 503 | skb->pkt_type = PACKET_BROADCAST; |
| 502 | } | 504 | } |
| 503 | #endif | 505 | #endif |
| 504 | 506 | ||
| 505 | if (((flags&GRE_CSUM) && csum) || | 507 | if (((flags&GRE_CSUM) && csum) || |
| 506 | (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { | 508 | (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { |
| 507 | tunnel->stat.rx_crc_errors++; | 509 | stats->rx_crc_errors++; |
| 508 | tunnel->stat.rx_errors++; | 510 | stats->rx_errors++; |
| 509 | goto drop; | 511 | goto drop; |
| 510 | } | 512 | } |
| 511 | if (tunnel->parms.i_flags&GRE_SEQ) { | 513 | if (tunnel->parms.i_flags&GRE_SEQ) { |
| 512 | if (!(flags&GRE_SEQ) || | 514 | if (!(flags&GRE_SEQ) || |
| 513 | (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { | 515 | (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { |
| 514 | tunnel->stat.rx_fifo_errors++; | 516 | stats->rx_fifo_errors++; |
| 515 | tunnel->stat.rx_errors++; | 517 | stats->rx_errors++; |
| 516 | goto drop; | 518 | goto drop; |
| 517 | } | 519 | } |
| 518 | tunnel->i_seqno = seqno + 1; | 520 | tunnel->i_seqno = seqno + 1; |
| 519 | } | 521 | } |
| 520 | tunnel->stat.rx_packets++; | 522 | stats->rx_packets++; |
| 521 | tunnel->stat.rx_bytes += skb->len; | 523 | stats->rx_bytes += skb->len; |
| 522 | skb->dev = tunnel->dev; | 524 | skb->dev = tunnel->dev; |
| 523 | dst_release(skb->dst); | 525 | dst_release(skb->dst); |
| 524 | skb->dst = NULL; | 526 | skb->dst = NULL; |
| @@ -540,7 +542,7 @@ drop_nolock: | |||
| 540 | static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | 542 | static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
| 541 | { | 543 | { |
| 542 | struct ip_tunnel *tunnel = netdev_priv(dev); | 544 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 543 | struct net_device_stats *stats = &tunnel->stat; | 545 | struct net_device_stats *stats = &tunnel->dev->stats; |
| 544 | struct iphdr *old_iph = ip_hdr(skb); | 546 | struct iphdr *old_iph = ip_hdr(skb); |
| 545 | struct iphdr *tiph; | 547 | struct iphdr *tiph; |
| 546 | u8 tos; | 548 | u8 tos; |
| @@ -554,7 +556,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 554 | int mtu; | 556 | int mtu; |
| 555 | 557 | ||
| 556 | if (tunnel->recursion++) { | 558 | if (tunnel->recursion++) { |
| 557 | tunnel->stat.collisions++; | 559 | stats->collisions++; |
| 558 | goto tx_error; | 560 | goto tx_error; |
| 559 | } | 561 | } |
| 560 | 562 | ||
| @@ -570,7 +572,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 570 | /* NBMA tunnel */ | 572 | /* NBMA tunnel */ |
| 571 | 573 | ||
| 572 | if (skb->dst == NULL) { | 574 | if (skb->dst == NULL) { |
| 573 | tunnel->stat.tx_fifo_errors++; | 575 | stats->tx_fifo_errors++; |
| 574 | goto tx_error; | 576 | goto tx_error; |
| 575 | } | 577 | } |
| 576 | 578 | ||
| @@ -621,7 +623,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 621 | .tos = RT_TOS(tos) } }, | 623 | .tos = RT_TOS(tos) } }, |
| 622 | .proto = IPPROTO_GRE }; | 624 | .proto = IPPROTO_GRE }; |
| 623 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | 625 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { |
| 624 | tunnel->stat.tx_carrier_errors++; | 626 | stats->tx_carrier_errors++; |
| 625 | goto tx_error; | 627 | goto tx_error; |
| 626 | } | 628 | } |
| 627 | } | 629 | } |
| @@ -629,7 +631,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 629 | 631 | ||
| 630 | if (tdev == dev) { | 632 | if (tdev == dev) { |
| 631 | ip_rt_put(rt); | 633 | ip_rt_put(rt); |
| 632 | tunnel->stat.collisions++; | 634 | stats->collisions++; |
| 633 | goto tx_error; | 635 | goto tx_error; |
| 634 | } | 636 | } |
| 635 | 637 | ||
| @@ -954,11 +956,6 @@ done: | |||
| 954 | return err; | 956 | return err; |
| 955 | } | 957 | } |
| 956 | 958 | ||
| 957 | static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev) | ||
| 958 | { | ||
| 959 | return &(((struct ip_tunnel*)netdev_priv(dev))->stat); | ||
| 960 | } | ||
| 961 | |||
| 962 | static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) | 959 | static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) |
| 963 | { | 960 | { |
| 964 | struct ip_tunnel *tunnel = netdev_priv(dev); | 961 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| @@ -1084,7 +1081,6 @@ static void ipgre_tunnel_setup(struct net_device *dev) | |||
| 1084 | dev->uninit = ipgre_tunnel_uninit; | 1081 | dev->uninit = ipgre_tunnel_uninit; |
| 1085 | dev->destructor = free_netdev; | 1082 | dev->destructor = free_netdev; |
| 1086 | dev->hard_start_xmit = ipgre_tunnel_xmit; | 1083 | dev->hard_start_xmit = ipgre_tunnel_xmit; |
| 1087 | dev->get_stats = ipgre_tunnel_get_stats; | ||
| 1088 | dev->do_ioctl = ipgre_tunnel_ioctl; | 1084 | dev->do_ioctl = ipgre_tunnel_ioctl; |
| 1089 | dev->change_mtu = ipgre_tunnel_change_mtu; | 1085 | dev->change_mtu = ipgre_tunnel_change_mtu; |
| 1090 | 1086 | ||
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index ff77a4a7f9ec..e0bed56c51f1 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The Internet Protocol (IP) module. | 6 | * The Internet Protocol (IP) module. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Donald Becker, <becker@super.org> | 10 | * Donald Becker, <becker@super.org> |
| @@ -147,12 +145,6 @@ | |||
| 147 | #include <linux/netlink.h> | 145 | #include <linux/netlink.h> |
| 148 | 146 | ||
| 149 | /* | 147 | /* |
| 150 | * SNMP management statistics | ||
| 151 | */ | ||
| 152 | |||
| 153 | DEFINE_SNMP_STAT(struct ipstats_mib, ip_statistics) __read_mostly; | ||
| 154 | |||
| 155 | /* | ||
| 156 | * Process Router Attention IP option | 148 | * Process Router Attention IP option |
| 157 | */ | 149 | */ |
| 158 | int ip_call_ra_chain(struct sk_buff *skb) | 150 | int ip_call_ra_chain(struct sk_buff *skb) |
| @@ -232,16 +224,16 @@ static int ip_local_deliver_finish(struct sk_buff *skb) | |||
| 232 | protocol = -ret; | 224 | protocol = -ret; |
| 233 | goto resubmit; | 225 | goto resubmit; |
| 234 | } | 226 | } |
| 235 | IP_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); | 227 | IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); |
| 236 | } else { | 228 | } else { |
| 237 | if (!raw) { | 229 | if (!raw) { |
| 238 | if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 230 | if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
| 239 | IP_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); | 231 | IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS); |
| 240 | icmp_send(skb, ICMP_DEST_UNREACH, | 232 | icmp_send(skb, ICMP_DEST_UNREACH, |
| 241 | ICMP_PROT_UNREACH, 0); | 233 | ICMP_PROT_UNREACH, 0); |
| 242 | } | 234 | } |
| 243 | } else | 235 | } else |
| 244 | IP_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); | 236 | IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); |
| 245 | kfree_skb(skb); | 237 | kfree_skb(skb); |
| 246 | } | 238 | } |
| 247 | } | 239 | } |
| @@ -283,7 +275,7 @@ static inline int ip_rcv_options(struct sk_buff *skb) | |||
| 283 | --ANK (980813) | 275 | --ANK (980813) |
| 284 | */ | 276 | */ |
| 285 | if (skb_cow(skb, skb_headroom(skb))) { | 277 | if (skb_cow(skb, skb_headroom(skb))) { |
| 286 | IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); | 278 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); |
| 287 | goto drop; | 279 | goto drop; |
| 288 | } | 280 | } |
| 289 | 281 | ||
| @@ -292,7 +284,7 @@ static inline int ip_rcv_options(struct sk_buff *skb) | |||
| 292 | opt->optlen = iph->ihl*4 - sizeof(struct iphdr); | 284 | opt->optlen = iph->ihl*4 - sizeof(struct iphdr); |
| 293 | 285 | ||
| 294 | if (ip_options_compile(dev_net(dev), opt, skb)) { | 286 | if (ip_options_compile(dev_net(dev), opt, skb)) { |
| 295 | IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 287 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS); |
| 296 | goto drop; | 288 | goto drop; |
| 297 | } | 289 | } |
| 298 | 290 | ||
| @@ -336,9 +328,11 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
| 336 | skb->dev); | 328 | skb->dev); |
| 337 | if (unlikely(err)) { | 329 | if (unlikely(err)) { |
| 338 | if (err == -EHOSTUNREACH) | 330 | if (err == -EHOSTUNREACH) |
| 339 | IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); | 331 | IP_INC_STATS_BH(dev_net(skb->dev), |
| 332 | IPSTATS_MIB_INADDRERRORS); | ||
| 340 | else if (err == -ENETUNREACH) | 333 | else if (err == -ENETUNREACH) |
| 341 | IP_INC_STATS_BH(IPSTATS_MIB_INNOROUTES); | 334 | IP_INC_STATS_BH(dev_net(skb->dev), |
| 335 | IPSTATS_MIB_INNOROUTES); | ||
| 342 | goto drop; | 336 | goto drop; |
| 343 | } | 337 | } |
| 344 | } | 338 | } |
| @@ -359,9 +353,9 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
| 359 | 353 | ||
| 360 | rt = skb->rtable; | 354 | rt = skb->rtable; |
| 361 | if (rt->rt_type == RTN_MULTICAST) | 355 | if (rt->rt_type == RTN_MULTICAST) |
| 362 | IP_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); | 356 | IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS); |
| 363 | else if (rt->rt_type == RTN_BROADCAST) | 357 | else if (rt->rt_type == RTN_BROADCAST) |
| 364 | IP_INC_STATS_BH(IPSTATS_MIB_INBCASTPKTS); | 358 | IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS); |
| 365 | 359 | ||
| 366 | return dst_input(skb); | 360 | return dst_input(skb); |
| 367 | 361 | ||
| @@ -384,10 +378,10 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
| 384 | if (skb->pkt_type == PACKET_OTHERHOST) | 378 | if (skb->pkt_type == PACKET_OTHERHOST) |
| 385 | goto drop; | 379 | goto drop; |
| 386 | 380 | ||
| 387 | IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); | 381 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES); |
| 388 | 382 | ||
| 389 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 383 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
| 390 | IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); | 384 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); |
| 391 | goto out; | 385 | goto out; |
| 392 | } | 386 | } |
| 393 | 387 | ||
| @@ -420,7 +414,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
| 420 | 414 | ||
| 421 | len = ntohs(iph->tot_len); | 415 | len = ntohs(iph->tot_len); |
| 422 | if (skb->len < len) { | 416 | if (skb->len < len) { |
| 423 | IP_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); | 417 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS); |
| 424 | goto drop; | 418 | goto drop; |
| 425 | } else if (len < (iph->ihl*4)) | 419 | } else if (len < (iph->ihl*4)) |
| 426 | goto inhdr_error; | 420 | goto inhdr_error; |
| @@ -430,7 +424,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
| 430 | * Note this now means skb->len holds ntohs(iph->tot_len). | 424 | * Note this now means skb->len holds ntohs(iph->tot_len). |
| 431 | */ | 425 | */ |
| 432 | if (pskb_trim_rcsum(skb, len)) { | 426 | if (pskb_trim_rcsum(skb, len)) { |
| 433 | IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); | 427 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); |
| 434 | goto drop; | 428 | goto drop; |
| 435 | } | 429 | } |
| 436 | 430 | ||
| @@ -441,11 +435,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
| 441 | ip_rcv_finish); | 435 | ip_rcv_finish); |
| 442 | 436 | ||
| 443 | inhdr_error: | 437 | inhdr_error: |
| 444 | IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 438 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS); |
| 445 | drop: | 439 | drop: |
| 446 | kfree_skb(skb); | 440 | kfree_skb(skb); |
| 447 | out: | 441 | out: |
| 448 | return NET_RX_DROP; | 442 | return NET_RX_DROP; |
| 449 | } | 443 | } |
| 450 | |||
| 451 | EXPORT_SYMBOL(ip_statistics); | ||
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 33126ad2cfdc..be3f18a7a40e 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The options processing module for ip.c | 6 | * The options processing module for ip.c |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_options.c,v 1.21 2001/09/01 00:31:50 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: A.N.Kuznetsov | 8 | * Authors: A.N.Kuznetsov |
| 11 | * | 9 | * |
| 12 | */ | 10 | */ |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e527628f56cf..465544f6281a 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The Internet Protocol (IP) output module. | 6 | * The Internet Protocol (IP) output module. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Donald Becker, <becker@super.org> | 10 | * Donald Becker, <becker@super.org> |
| @@ -184,9 +182,9 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
| 184 | unsigned int hh_len = LL_RESERVED_SPACE(dev); | 182 | unsigned int hh_len = LL_RESERVED_SPACE(dev); |
| 185 | 183 | ||
| 186 | if (rt->rt_type == RTN_MULTICAST) | 184 | if (rt->rt_type == RTN_MULTICAST) |
| 187 | IP_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); | 185 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS); |
| 188 | else if (rt->rt_type == RTN_BROADCAST) | 186 | else if (rt->rt_type == RTN_BROADCAST) |
| 189 | IP_INC_STATS(IPSTATS_MIB_OUTBCASTPKTS); | 187 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS); |
| 190 | 188 | ||
| 191 | /* Be paranoid, rather than too clever. */ | 189 | /* Be paranoid, rather than too clever. */ |
| 192 | if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { | 190 | if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { |
| @@ -246,7 +244,7 @@ int ip_mc_output(struct sk_buff *skb) | |||
| 246 | /* | 244 | /* |
| 247 | * If the indicated interface is up and running, send the packet. | 245 | * If the indicated interface is up and running, send the packet. |
| 248 | */ | 246 | */ |
| 249 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 247 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); |
| 250 | 248 | ||
| 251 | skb->dev = dev; | 249 | skb->dev = dev; |
| 252 | skb->protocol = htons(ETH_P_IP); | 250 | skb->protocol = htons(ETH_P_IP); |
| @@ -300,7 +298,7 @@ int ip_output(struct sk_buff *skb) | |||
| 300 | { | 298 | { |
| 301 | struct net_device *dev = skb->dst->dev; | 299 | struct net_device *dev = skb->dst->dev; |
| 302 | 300 | ||
| 303 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 301 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); |
| 304 | 302 | ||
| 305 | skb->dev = dev; | 303 | skb->dev = dev; |
| 306 | skb->protocol = htons(ETH_P_IP); | 304 | skb->protocol = htons(ETH_P_IP); |
| @@ -391,7 +389,7 @@ packet_routed: | |||
| 391 | return ip_local_out(skb); | 389 | return ip_local_out(skb); |
| 392 | 390 | ||
| 393 | no_route: | 391 | no_route: |
| 394 | IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES); | 392 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
| 395 | kfree_skb(skb); | 393 | kfree_skb(skb); |
| 396 | return -EHOSTUNREACH; | 394 | return -EHOSTUNREACH; |
| 397 | } | 395 | } |
| @@ -453,7 +451,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
| 453 | iph = ip_hdr(skb); | 451 | iph = ip_hdr(skb); |
| 454 | 452 | ||
| 455 | if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) { | 453 | if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) { |
| 456 | IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 454 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
| 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 455 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
| 458 | htonl(ip_skb_dst_mtu(skb))); | 456 | htonl(ip_skb_dst_mtu(skb))); |
| 459 | kfree_skb(skb); | 457 | kfree_skb(skb); |
| @@ -544,7 +542,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
| 544 | err = output(skb); | 542 | err = output(skb); |
| 545 | 543 | ||
| 546 | if (!err) | 544 | if (!err) |
| 547 | IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); | 545 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGCREATES); |
| 548 | if (err || !frag) | 546 | if (err || !frag) |
| 549 | break; | 547 | break; |
| 550 | 548 | ||
| @@ -554,7 +552,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
| 554 | } | 552 | } |
| 555 | 553 | ||
| 556 | if (err == 0) { | 554 | if (err == 0) { |
| 557 | IP_INC_STATS(IPSTATS_MIB_FRAGOKS); | 555 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGOKS); |
| 558 | return 0; | 556 | return 0; |
| 559 | } | 557 | } |
| 560 | 558 | ||
| @@ -563,7 +561,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
| 563 | kfree_skb(frag); | 561 | kfree_skb(frag); |
| 564 | frag = skb; | 562 | frag = skb; |
| 565 | } | 563 | } |
| 566 | IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 564 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
| 567 | return err; | 565 | return err; |
| 568 | } | 566 | } |
| 569 | 567 | ||
| @@ -675,15 +673,15 @@ slow_path: | |||
| 675 | if (err) | 673 | if (err) |
| 676 | goto fail; | 674 | goto fail; |
| 677 | 675 | ||
| 678 | IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); | 676 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGCREATES); |
| 679 | } | 677 | } |
| 680 | kfree_skb(skb); | 678 | kfree_skb(skb); |
| 681 | IP_INC_STATS(IPSTATS_MIB_FRAGOKS); | 679 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGOKS); |
| 682 | return err; | 680 | return err; |
| 683 | 681 | ||
| 684 | fail: | 682 | fail: |
| 685 | kfree_skb(skb); | 683 | kfree_skb(skb); |
| 686 | IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 684 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
| 687 | return err; | 685 | return err; |
| 688 | } | 686 | } |
| 689 | 687 | ||
| @@ -1049,7 +1047,7 @@ alloc_new_skb: | |||
| 1049 | 1047 | ||
| 1050 | error: | 1048 | error: |
| 1051 | inet->cork.length -= length; | 1049 | inet->cork.length -= length; |
| 1052 | IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 1050 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS); |
| 1053 | return err; | 1051 | return err; |
| 1054 | } | 1052 | } |
| 1055 | 1053 | ||
| @@ -1191,7 +1189,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, | |||
| 1191 | 1189 | ||
| 1192 | error: | 1190 | error: |
| 1193 | inet->cork.length -= size; | 1191 | inet->cork.length -= size; |
| 1194 | IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 1192 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS); |
| 1195 | return err; | 1193 | return err; |
| 1196 | } | 1194 | } |
| 1197 | 1195 | ||
| @@ -1213,6 +1211,7 @@ int ip_push_pending_frames(struct sock *sk) | |||
| 1213 | struct sk_buff *skb, *tmp_skb; | 1211 | struct sk_buff *skb, *tmp_skb; |
| 1214 | struct sk_buff **tail_skb; | 1212 | struct sk_buff **tail_skb; |
| 1215 | struct inet_sock *inet = inet_sk(sk); | 1213 | struct inet_sock *inet = inet_sk(sk); |
| 1214 | struct net *net = sock_net(sk); | ||
| 1216 | struct ip_options *opt = NULL; | 1215 | struct ip_options *opt = NULL; |
| 1217 | struct rtable *rt = (struct rtable *)inet->cork.dst; | 1216 | struct rtable *rt = (struct rtable *)inet->cork.dst; |
| 1218 | struct iphdr *iph; | 1217 | struct iphdr *iph; |
| @@ -1282,7 +1281,7 @@ int ip_push_pending_frames(struct sock *sk) | |||
| 1282 | skb->dst = dst_clone(&rt->u.dst); | 1281 | skb->dst = dst_clone(&rt->u.dst); |
| 1283 | 1282 | ||
| 1284 | if (iph->protocol == IPPROTO_ICMP) | 1283 | if (iph->protocol == IPPROTO_ICMP) |
| 1285 | icmp_out_count(((struct icmphdr *) | 1284 | icmp_out_count(net, ((struct icmphdr *) |
| 1286 | skb_transport_header(skb))->type); | 1285 | skb_transport_header(skb))->type); |
| 1287 | 1286 | ||
| 1288 | /* Netfilter gets whole the not fragmented skb. */ | 1287 | /* Netfilter gets whole the not fragmented skb. */ |
| @@ -1299,7 +1298,7 @@ out: | |||
| 1299 | return err; | 1298 | return err; |
| 1300 | 1299 | ||
| 1301 | error: | 1300 | error: |
| 1302 | IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 1301 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |
| 1303 | goto out; | 1302 | goto out; |
| 1304 | } | 1303 | } |
| 1305 | 1304 | ||
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index e0514e82308e..105d92a039b9 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The IP to API glue. | 6 | * The IP to API glue. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_sockglue.c,v 1.62 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: see ip.c | 8 | * Authors: see ip.c |
| 11 | * | 9 | * |
| 12 | * Fixes: | 10 | * Fixes: |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index ed45037ce9be..42065fff46c4 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $ | ||
| 3 | * | ||
| 4 | * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or | 2 | * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or |
| 5 | * user-supplied information to configure own IP address and routes. | 3 | * user-supplied information to configure own IP address and routes. |
| 6 | * | 4 | * |
| @@ -434,7 +432,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
| 434 | unsigned char *sha, *tha; /* s for "source", t for "target" */ | 432 | unsigned char *sha, *tha; /* s for "source", t for "target" */ |
| 435 | struct ic_device *d; | 433 | struct ic_device *d; |
| 436 | 434 | ||
| 437 | if (dev_net(dev) != &init_net) | 435 | if (!net_eq(dev_net(dev), &init_net)) |
| 438 | goto drop; | 436 | goto drop; |
| 439 | 437 | ||
| 440 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) | 438 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) |
| @@ -854,7 +852,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str | |||
| 854 | struct ic_device *d; | 852 | struct ic_device *d; |
| 855 | int len, ext_len; | 853 | int len, ext_len; |
| 856 | 854 | ||
| 857 | if (dev_net(dev) != &init_net) | 855 | if (!net_eq(dev_net(dev), &init_net)) |
| 858 | goto drop; | 856 | goto drop; |
| 859 | 857 | ||
| 860 | /* Perform verifications before taking the lock. */ | 858 | /* Perform verifications before taking the lock. */ |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index af5cb53da5cc..4c6d2caf9203 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux NET3: IP/IP protocol decoder. | 2 | * Linux NET3: IP/IP protocol decoder. |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ipip.c,v 1.50 2001/10/02 02:22:36 davem Exp $ | ||
| 5 | * | ||
| 6 | * Authors: | 4 | * Authors: |
| 7 | * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 | 5 | * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 |
| 8 | * | 6 | * |
| @@ -368,8 +366,8 @@ static int ipip_rcv(struct sk_buff *skb) | |||
| 368 | skb->protocol = htons(ETH_P_IP); | 366 | skb->protocol = htons(ETH_P_IP); |
| 369 | skb->pkt_type = PACKET_HOST; | 367 | skb->pkt_type = PACKET_HOST; |
| 370 | 368 | ||
| 371 | tunnel->stat.rx_packets++; | 369 | tunnel->dev->stats.rx_packets++; |
| 372 | tunnel->stat.rx_bytes += skb->len; | 370 | tunnel->dev->stats.rx_bytes += skb->len; |
| 373 | skb->dev = tunnel->dev; | 371 | skb->dev = tunnel->dev; |
| 374 | dst_release(skb->dst); | 372 | dst_release(skb->dst); |
| 375 | skb->dst = NULL; | 373 | skb->dst = NULL; |
| @@ -392,7 +390,7 @@ static int ipip_rcv(struct sk_buff *skb) | |||
| 392 | static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | 390 | static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
| 393 | { | 391 | { |
| 394 | struct ip_tunnel *tunnel = netdev_priv(dev); | 392 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 395 | struct net_device_stats *stats = &tunnel->stat; | 393 | struct net_device_stats *stats = &tunnel->dev->stats; |
| 396 | struct iphdr *tiph = &tunnel->parms.iph; | 394 | struct iphdr *tiph = &tunnel->parms.iph; |
| 397 | u8 tos = tunnel->parms.iph.tos; | 395 | u8 tos = tunnel->parms.iph.tos; |
| 398 | __be16 df = tiph->frag_off; | 396 | __be16 df = tiph->frag_off; |
| @@ -405,7 +403,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 405 | int mtu; | 403 | int mtu; |
| 406 | 404 | ||
| 407 | if (tunnel->recursion++) { | 405 | if (tunnel->recursion++) { |
| 408 | tunnel->stat.collisions++; | 406 | stats->collisions++; |
| 409 | goto tx_error; | 407 | goto tx_error; |
| 410 | } | 408 | } |
| 411 | 409 | ||
| @@ -418,7 +416,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 418 | if (!dst) { | 416 | if (!dst) { |
| 419 | /* NBMA tunnel */ | 417 | /* NBMA tunnel */ |
| 420 | if ((rt = skb->rtable) == NULL) { | 418 | if ((rt = skb->rtable) == NULL) { |
| 421 | tunnel->stat.tx_fifo_errors++; | 419 | stats->tx_fifo_errors++; |
| 422 | goto tx_error; | 420 | goto tx_error; |
| 423 | } | 421 | } |
| 424 | if ((dst = rt->rt_gateway) == 0) | 422 | if ((dst = rt->rt_gateway) == 0) |
| @@ -433,7 +431,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 433 | .tos = RT_TOS(tos) } }, | 431 | .tos = RT_TOS(tos) } }, |
| 434 | .proto = IPPROTO_IPIP }; | 432 | .proto = IPPROTO_IPIP }; |
| 435 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | 433 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { |
| 436 | tunnel->stat.tx_carrier_errors++; | 434 | stats->tx_carrier_errors++; |
| 437 | goto tx_error_icmp; | 435 | goto tx_error_icmp; |
| 438 | } | 436 | } |
| 439 | } | 437 | } |
| @@ -441,7 +439,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 441 | 439 | ||
| 442 | if (tdev == dev) { | 440 | if (tdev == dev) { |
| 443 | ip_rt_put(rt); | 441 | ip_rt_put(rt); |
| 444 | tunnel->stat.collisions++; | 442 | stats->collisions++; |
| 445 | goto tx_error; | 443 | goto tx_error; |
| 446 | } | 444 | } |
| 447 | 445 | ||
| @@ -451,7 +449,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 451 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; | 449 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; |
| 452 | 450 | ||
| 453 | if (mtu < 68) { | 451 | if (mtu < 68) { |
| 454 | tunnel->stat.collisions++; | 452 | stats->collisions++; |
| 455 | ip_rt_put(rt); | 453 | ip_rt_put(rt); |
| 456 | goto tx_error; | 454 | goto tx_error; |
| 457 | } | 455 | } |
| @@ -685,11 +683,6 @@ done: | |||
| 685 | return err; | 683 | return err; |
| 686 | } | 684 | } |
| 687 | 685 | ||
| 688 | static struct net_device_stats *ipip_tunnel_get_stats(struct net_device *dev) | ||
| 689 | { | ||
| 690 | return &(((struct ip_tunnel*)netdev_priv(dev))->stat); | ||
| 691 | } | ||
| 692 | |||
| 693 | static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu) | 686 | static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu) |
| 694 | { | 687 | { |
| 695 | if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr)) | 688 | if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr)) |
| @@ -702,7 +695,6 @@ static void ipip_tunnel_setup(struct net_device *dev) | |||
| 702 | { | 695 | { |
| 703 | dev->uninit = ipip_tunnel_uninit; | 696 | dev->uninit = ipip_tunnel_uninit; |
| 704 | dev->hard_start_xmit = ipip_tunnel_xmit; | 697 | dev->hard_start_xmit = ipip_tunnel_xmit; |
| 705 | dev->get_stats = ipip_tunnel_get_stats; | ||
| 706 | dev->do_ioctl = ipip_tunnel_ioctl; | 698 | dev->do_ioctl = ipip_tunnel_ioctl; |
| 707 | dev->change_mtu = ipip_tunnel_change_mtu; | 699 | dev->change_mtu = ipip_tunnel_change_mtu; |
| 708 | dev->destructor = free_netdev; | 700 | dev->destructor = free_netdev; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 11700a4dcd95..c519b8d30eee 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -9,8 +9,6 @@ | |||
| 9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | * | 11 | * |
| 12 | * Version: $Id: ipmr.c,v 1.65 2001/10/31 21:55:54 davem Exp $ | ||
| 13 | * | ||
| 14 | * Fixes: | 12 | * Fixes: |
| 15 | * Michael Chastain : Incorrect size of copying. | 13 | * Michael Chastain : Incorrect size of copying. |
| 16 | * Alan Cox : Added the cache manager code | 14 | * Alan Cox : Added the cache manager code |
| @@ -120,6 +118,31 @@ static struct timer_list ipmr_expire_timer; | |||
| 120 | 118 | ||
| 121 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ | 119 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ |
| 122 | 120 | ||
| 121 | static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) | ||
| 122 | { | ||
| 123 | dev_close(dev); | ||
| 124 | |||
| 125 | dev = __dev_get_by_name(&init_net, "tunl0"); | ||
| 126 | if (dev) { | ||
| 127 | struct ifreq ifr; | ||
| 128 | mm_segment_t oldfs; | ||
| 129 | struct ip_tunnel_parm p; | ||
| 130 | |||
| 131 | memset(&p, 0, sizeof(p)); | ||
| 132 | p.iph.daddr = v->vifc_rmt_addr.s_addr; | ||
| 133 | p.iph.saddr = v->vifc_lcl_addr.s_addr; | ||
| 134 | p.iph.version = 4; | ||
| 135 | p.iph.ihl = 5; | ||
| 136 | p.iph.protocol = IPPROTO_IPIP; | ||
| 137 | sprintf(p.name, "dvmrp%d", v->vifc_vifi); | ||
| 138 | ifr.ifr_ifru.ifru_data = (__force void __user *)&p; | ||
| 139 | |||
| 140 | oldfs = get_fs(); set_fs(KERNEL_DS); | ||
| 141 | dev->do_ioctl(dev, &ifr, SIOCDELTUNNEL); | ||
| 142 | set_fs(oldfs); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 123 | static | 146 | static |
| 124 | struct net_device *ipmr_new_tunnel(struct vifctl *v) | 147 | struct net_device *ipmr_new_tunnel(struct vifctl *v) |
| 125 | { | 148 | { |
| @@ -161,6 +184,7 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) | |||
| 161 | 184 | ||
| 162 | if (dev_open(dev)) | 185 | if (dev_open(dev)) |
| 163 | goto failure; | 186 | goto failure; |
| 187 | dev_hold(dev); | ||
| 164 | } | 188 | } |
| 165 | } | 189 | } |
| 166 | return dev; | 190 | return dev; |
| @@ -181,26 +205,20 @@ static int reg_vif_num = -1; | |||
| 181 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | 205 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) |
| 182 | { | 206 | { |
| 183 | read_lock(&mrt_lock); | 207 | read_lock(&mrt_lock); |
| 184 | ((struct net_device_stats*)netdev_priv(dev))->tx_bytes += skb->len; | 208 | dev->stats.tx_bytes += skb->len; |
| 185 | ((struct net_device_stats*)netdev_priv(dev))->tx_packets++; | 209 | dev->stats.tx_packets++; |
| 186 | ipmr_cache_report(skb, reg_vif_num, IGMPMSG_WHOLEPKT); | 210 | ipmr_cache_report(skb, reg_vif_num, IGMPMSG_WHOLEPKT); |
| 187 | read_unlock(&mrt_lock); | 211 | read_unlock(&mrt_lock); |
| 188 | kfree_skb(skb); | 212 | kfree_skb(skb); |
| 189 | return 0; | 213 | return 0; |
| 190 | } | 214 | } |
| 191 | 215 | ||
| 192 | static struct net_device_stats *reg_vif_get_stats(struct net_device *dev) | ||
| 193 | { | ||
| 194 | return (struct net_device_stats*)netdev_priv(dev); | ||
| 195 | } | ||
| 196 | |||
| 197 | static void reg_vif_setup(struct net_device *dev) | 216 | static void reg_vif_setup(struct net_device *dev) |
| 198 | { | 217 | { |
| 199 | dev->type = ARPHRD_PIMREG; | 218 | dev->type = ARPHRD_PIMREG; |
| 200 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; | 219 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; |
| 201 | dev->flags = IFF_NOARP; | 220 | dev->flags = IFF_NOARP; |
| 202 | dev->hard_start_xmit = reg_vif_xmit; | 221 | dev->hard_start_xmit = reg_vif_xmit; |
| 203 | dev->get_stats = reg_vif_get_stats; | ||
| 204 | dev->destructor = free_netdev; | 222 | dev->destructor = free_netdev; |
| 205 | } | 223 | } |
| 206 | 224 | ||
| @@ -209,8 +227,7 @@ static struct net_device *ipmr_reg_vif(void) | |||
| 209 | struct net_device *dev; | 227 | struct net_device *dev; |
| 210 | struct in_device *in_dev; | 228 | struct in_device *in_dev; |
| 211 | 229 | ||
| 212 | dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg", | 230 | dev = alloc_netdev(0, "pimreg", reg_vif_setup); |
| 213 | reg_vif_setup); | ||
| 214 | 231 | ||
| 215 | if (dev == NULL) | 232 | if (dev == NULL) |
| 216 | return NULL; | 233 | return NULL; |
| @@ -234,6 +251,8 @@ static struct net_device *ipmr_reg_vif(void) | |||
| 234 | if (dev_open(dev)) | 251 | if (dev_open(dev)) |
| 235 | goto failure; | 252 | goto failure; |
| 236 | 253 | ||
| 254 | dev_hold(dev); | ||
| 255 | |||
| 237 | return dev; | 256 | return dev; |
| 238 | 257 | ||
| 239 | failure: | 258 | failure: |
| @@ -248,9 +267,10 @@ failure: | |||
| 248 | 267 | ||
| 249 | /* | 268 | /* |
| 250 | * Delete a VIF entry | 269 | * Delete a VIF entry |
| 270 | * @notify: Set to 1, if the caller is a notifier_call | ||
| 251 | */ | 271 | */ |
| 252 | 272 | ||
| 253 | static int vif_delete(int vifi) | 273 | static int vif_delete(int vifi, int notify) |
| 254 | { | 274 | { |
| 255 | struct vif_device *v; | 275 | struct vif_device *v; |
| 256 | struct net_device *dev; | 276 | struct net_device *dev; |
| @@ -293,7 +313,7 @@ static int vif_delete(int vifi) | |||
| 293 | ip_rt_multicast_event(in_dev); | 313 | ip_rt_multicast_event(in_dev); |
| 294 | } | 314 | } |
| 295 | 315 | ||
| 296 | if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) | 316 | if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER) && !notify) |
| 297 | unregister_netdevice(dev); | 317 | unregister_netdevice(dev); |
| 298 | 318 | ||
| 299 | dev_put(dev); | 319 | dev_put(dev); |
| @@ -398,6 +418,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
| 398 | struct vif_device *v = &vif_table[vifi]; | 418 | struct vif_device *v = &vif_table[vifi]; |
| 399 | struct net_device *dev; | 419 | struct net_device *dev; |
| 400 | struct in_device *in_dev; | 420 | struct in_device *in_dev; |
| 421 | int err; | ||
| 401 | 422 | ||
| 402 | /* Is vif busy ? */ | 423 | /* Is vif busy ? */ |
| 403 | if (VIF_EXISTS(vifi)) | 424 | if (VIF_EXISTS(vifi)) |
| @@ -415,18 +436,34 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
| 415 | dev = ipmr_reg_vif(); | 436 | dev = ipmr_reg_vif(); |
| 416 | if (!dev) | 437 | if (!dev) |
| 417 | return -ENOBUFS; | 438 | return -ENOBUFS; |
| 439 | err = dev_set_allmulti(dev, 1); | ||
| 440 | if (err) { | ||
| 441 | unregister_netdevice(dev); | ||
| 442 | dev_put(dev); | ||
| 443 | return err; | ||
| 444 | } | ||
| 418 | break; | 445 | break; |
| 419 | #endif | 446 | #endif |
| 420 | case VIFF_TUNNEL: | 447 | case VIFF_TUNNEL: |
| 421 | dev = ipmr_new_tunnel(vifc); | 448 | dev = ipmr_new_tunnel(vifc); |
| 422 | if (!dev) | 449 | if (!dev) |
| 423 | return -ENOBUFS; | 450 | return -ENOBUFS; |
| 451 | err = dev_set_allmulti(dev, 1); | ||
| 452 | if (err) { | ||
| 453 | ipmr_del_tunnel(dev, vifc); | ||
| 454 | dev_put(dev); | ||
| 455 | return err; | ||
| 456 | } | ||
| 424 | break; | 457 | break; |
| 425 | case 0: | 458 | case 0: |
| 426 | dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr); | 459 | dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr); |
| 427 | if (!dev) | 460 | if (!dev) |
| 428 | return -EADDRNOTAVAIL; | 461 | return -EADDRNOTAVAIL; |
| 429 | dev_put(dev); | 462 | err = dev_set_allmulti(dev, 1); |
| 463 | if (err) { | ||
| 464 | dev_put(dev); | ||
| 465 | return err; | ||
| 466 | } | ||
| 430 | break; | 467 | break; |
| 431 | default: | 468 | default: |
| 432 | return -EINVAL; | 469 | return -EINVAL; |
| @@ -435,7 +472,6 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
| 435 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 472 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) |
| 436 | return -EADDRNOTAVAIL; | 473 | return -EADDRNOTAVAIL; |
| 437 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; | 474 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
| 438 | dev_set_allmulti(dev, +1); | ||
| 439 | ip_rt_multicast_event(in_dev); | 475 | ip_rt_multicast_event(in_dev); |
| 440 | 476 | ||
| 441 | /* | 477 | /* |
| @@ -458,7 +494,6 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
| 458 | 494 | ||
| 459 | /* And finish update writing critical data */ | 495 | /* And finish update writing critical data */ |
| 460 | write_lock_bh(&mrt_lock); | 496 | write_lock_bh(&mrt_lock); |
| 461 | dev_hold(dev); | ||
| 462 | v->dev=dev; | 497 | v->dev=dev; |
| 463 | #ifdef CONFIG_IP_PIMSM | 498 | #ifdef CONFIG_IP_PIMSM |
| 464 | if (v->flags&VIFF_REGISTER) | 499 | if (v->flags&VIFF_REGISTER) |
| @@ -805,7 +840,7 @@ static void mroute_clean_tables(struct sock *sk) | |||
| 805 | */ | 840 | */ |
| 806 | for (i=0; i<maxvif; i++) { | 841 | for (i=0; i<maxvif; i++) { |
| 807 | if (!(vif_table[i].flags&VIFF_STATIC)) | 842 | if (!(vif_table[i].flags&VIFF_STATIC)) |
| 808 | vif_delete(i); | 843 | vif_delete(i, 0); |
| 809 | } | 844 | } |
| 810 | 845 | ||
| 811 | /* | 846 | /* |
| @@ -918,7 +953,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt | |||
| 918 | if (optname==MRT_ADD_VIF) { | 953 | if (optname==MRT_ADD_VIF) { |
| 919 | ret = vif_add(&vif, sk==mroute_socket); | 954 | ret = vif_add(&vif, sk==mroute_socket); |
| 920 | } else { | 955 | } else { |
| 921 | ret = vif_delete(vif.vifc_vifi); | 956 | ret = vif_delete(vif.vifc_vifi, 0); |
| 922 | } | 957 | } |
| 923 | rtnl_unlock(); | 958 | rtnl_unlock(); |
| 924 | return ret; | 959 | return ret; |
| @@ -1089,7 +1124,7 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v | |||
| 1089 | struct vif_device *v; | 1124 | struct vif_device *v; |
| 1090 | int ct; | 1125 | int ct; |
| 1091 | 1126 | ||
| 1092 | if (dev_net(dev) != &init_net) | 1127 | if (!net_eq(dev_net(dev), &init_net)) |
| 1093 | return NOTIFY_DONE; | 1128 | return NOTIFY_DONE; |
| 1094 | 1129 | ||
| 1095 | if (event != NETDEV_UNREGISTER) | 1130 | if (event != NETDEV_UNREGISTER) |
| @@ -1097,7 +1132,7 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v | |||
| 1097 | v=&vif_table[0]; | 1132 | v=&vif_table[0]; |
| 1098 | for (ct=0;ct<maxvif;ct++,v++) { | 1133 | for (ct=0;ct<maxvif;ct++,v++) { |
| 1099 | if (v->dev==dev) | 1134 | if (v->dev==dev) |
| 1100 | vif_delete(ct); | 1135 | vif_delete(ct, 1); |
| 1101 | } | 1136 | } |
| 1102 | return NOTIFY_DONE; | 1137 | return NOTIFY_DONE; |
| 1103 | } | 1138 | } |
| @@ -1143,7 +1178,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
| 1143 | { | 1178 | { |
| 1144 | struct ip_options * opt = &(IPCB(skb)->opt); | 1179 | struct ip_options * opt = &(IPCB(skb)->opt); |
| 1145 | 1180 | ||
| 1146 | IP_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); | 1181 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 1147 | 1182 | ||
| 1148 | if (unlikely(opt->optlen)) | 1183 | if (unlikely(opt->optlen)) |
| 1149 | ip_forward_options(skb); | 1184 | ip_forward_options(skb); |
| @@ -1170,8 +1205,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
| 1170 | if (vif->flags & VIFF_REGISTER) { | 1205 | if (vif->flags & VIFF_REGISTER) { |
| 1171 | vif->pkt_out++; | 1206 | vif->pkt_out++; |
| 1172 | vif->bytes_out+=skb->len; | 1207 | vif->bytes_out+=skb->len; |
| 1173 | ((struct net_device_stats*)netdev_priv(vif->dev))->tx_bytes += skb->len; | 1208 | vif->dev->stats.tx_bytes += skb->len; |
| 1174 | ((struct net_device_stats*)netdev_priv(vif->dev))->tx_packets++; | 1209 | vif->dev->stats.tx_packets++; |
| 1175 | ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT); | 1210 | ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT); |
| 1176 | kfree_skb(skb); | 1211 | kfree_skb(skb); |
| 1177 | return; | 1212 | return; |
| @@ -1206,7 +1241,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
| 1206 | to blackhole. | 1241 | to blackhole. |
| 1207 | */ | 1242 | */ |
| 1208 | 1243 | ||
| 1209 | IP_INC_STATS_BH(IPSTATS_MIB_FRAGFAILS); | 1244 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
| 1210 | ip_rt_put(rt); | 1245 | ip_rt_put(rt); |
| 1211 | goto out_free; | 1246 | goto out_free; |
| 1212 | } | 1247 | } |
| @@ -1230,8 +1265,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
| 1230 | if (vif->flags & VIFF_TUNNEL) { | 1265 | if (vif->flags & VIFF_TUNNEL) { |
| 1231 | ip_encap(skb, vif->local, vif->remote); | 1266 | ip_encap(skb, vif->local, vif->remote); |
| 1232 | /* FIXME: extra output firewall step used to be here. --RR */ | 1267 | /* FIXME: extra output firewall step used to be here. --RR */ |
| 1233 | ((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_packets++; | 1268 | vif->dev->stats.tx_packets++; |
| 1234 | ((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_bytes+=skb->len; | 1269 | vif->dev->stats.tx_bytes += skb->len; |
| 1235 | } | 1270 | } |
| 1236 | 1271 | ||
| 1237 | IPCB(skb)->flags |= IPSKB_FORWARDED; | 1272 | IPCB(skb)->flags |= IPSKB_FORWARDED; |
| @@ -1487,8 +1522,8 @@ int pim_rcv_v1(struct sk_buff * skb) | |||
| 1487 | skb->pkt_type = PACKET_HOST; | 1522 | skb->pkt_type = PACKET_HOST; |
| 1488 | dst_release(skb->dst); | 1523 | dst_release(skb->dst); |
| 1489 | skb->dst = NULL; | 1524 | skb->dst = NULL; |
| 1490 | ((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len; | 1525 | reg_dev->stats.rx_bytes += skb->len; |
| 1491 | ((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++; | 1526 | reg_dev->stats.rx_packets++; |
| 1492 | nf_reset(skb); | 1527 | nf_reset(skb); |
| 1493 | netif_rx(skb); | 1528 | netif_rx(skb); |
| 1494 | dev_put(reg_dev); | 1529 | dev_put(reg_dev); |
| @@ -1542,8 +1577,8 @@ static int pim_rcv(struct sk_buff * skb) | |||
| 1542 | skb->ip_summed = 0; | 1577 | skb->ip_summed = 0; |
| 1543 | skb->pkt_type = PACKET_HOST; | 1578 | skb->pkt_type = PACKET_HOST; |
| 1544 | dst_release(skb->dst); | 1579 | dst_release(skb->dst); |
| 1545 | ((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len; | 1580 | reg_dev->stats.rx_bytes += skb->len; |
| 1546 | ((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++; | 1581 | reg_dev->stats.rx_packets++; |
| 1547 | skb->dst = NULL; | 1582 | skb->dst = NULL; |
| 1548 | nf_reset(skb); | 1583 | nf_reset(skb); |
| 1549 | netif_rx(skb); | 1584 | netif_rx(skb); |
| @@ -1887,16 +1922,36 @@ static struct net_protocol pim_protocol = { | |||
| 1887 | * Setup for IP multicast routing | 1922 | * Setup for IP multicast routing |
| 1888 | */ | 1923 | */ |
| 1889 | 1924 | ||
| 1890 | void __init ip_mr_init(void) | 1925 | int __init ip_mr_init(void) |
| 1891 | { | 1926 | { |
| 1927 | int err; | ||
| 1928 | |||
| 1892 | mrt_cachep = kmem_cache_create("ip_mrt_cache", | 1929 | mrt_cachep = kmem_cache_create("ip_mrt_cache", |
| 1893 | sizeof(struct mfc_cache), | 1930 | sizeof(struct mfc_cache), |
| 1894 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, | 1931 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
| 1895 | NULL); | 1932 | NULL); |
| 1933 | if (!mrt_cachep) | ||
| 1934 | return -ENOMEM; | ||
| 1935 | |||
| 1896 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); | 1936 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); |
| 1897 | register_netdevice_notifier(&ip_mr_notifier); | 1937 | err = register_netdevice_notifier(&ip_mr_notifier); |
| 1938 | if (err) | ||
| 1939 | goto reg_notif_fail; | ||
| 1898 | #ifdef CONFIG_PROC_FS | 1940 | #ifdef CONFIG_PROC_FS |
| 1899 | proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops); | 1941 | err = -ENOMEM; |
| 1900 | proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops); | 1942 | if (!proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops)) |
| 1943 | goto proc_vif_fail; | ||
| 1944 | if (!proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops)) | ||
| 1945 | goto proc_cache_fail; | ||
| 1901 | #endif | 1946 | #endif |
| 1947 | return 0; | ||
| 1948 | reg_notif_fail: | ||
| 1949 | kmem_cache_destroy(mrt_cachep); | ||
| 1950 | #ifdef CONFIG_PROC_FS | ||
| 1951 | proc_vif_fail: | ||
| 1952 | unregister_netdevice_notifier(&ip_mr_notifier); | ||
| 1953 | proc_cache_fail: | ||
| 1954 | proc_net_remove(&init_net, "ip_mr_vif"); | ||
| 1955 | #endif | ||
| 1956 | return err; | ||
| 1902 | } | 1957 | } |
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c index 535abe0c45e7..1f1897a1a702 100644 --- a/net/ipv4/ipvs/ip_vs_app.c +++ b/net/ipv4/ipvs/ip_vs_app.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_app.c: Application module support for IPVS | 2 | * ip_vs_app.c: Application module support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_app.c,v 1.17 2003/03/22 06:31:21 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index 65f1ba112752..f8bdae47a77f 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * high-performance and highly available server based on a | 5 | * high-performance and highly available server based on a |
| 6 | * cluster of servers. | 6 | * cluster of servers. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_vs_conn.c,v 1.31 2003/04/18 09:03:16 wensong Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 8 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 11 | * Peter Kese <peter.kese@ijs.si> | 9 | * Peter Kese <peter.kese@ijs.si> |
| 12 | * Julian Anastasov <ja@ssi.bg> | 10 | * Julian Anastasov <ja@ssi.bg> |
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 963981a9d501..a7879eafc3b5 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * high-performance and highly available server based on a | 5 | * high-performance and highly available server based on a |
| 6 | * cluster of servers. | 6 | * cluster of servers. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_vs_core.c,v 1.34 2003/05/10 03:05:23 wensong Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 8 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 11 | * Peter Kese <peter.kese@ijs.si> | 9 | * Peter Kese <peter.kese@ijs.si> |
| 12 | * Julian Anastasov <ja@ssi.bg> | 10 | * Julian Anastasov <ja@ssi.bg> |
| @@ -993,7 +991,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, | |||
| 993 | == sysctl_ip_vs_sync_threshold[0])) || | 991 | == sysctl_ip_vs_sync_threshold[0])) || |
| 994 | ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && | 992 | ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && |
| 995 | ((cp->state == IP_VS_TCP_S_FIN_WAIT) || | 993 | ((cp->state == IP_VS_TCP_S_FIN_WAIT) || |
| 996 | (cp->state == IP_VS_TCP_S_CLOSE))))) | 994 | (cp->state == IP_VS_TCP_S_CLOSE_WAIT) || |
| 995 | (cp->state == IP_VS_TCP_S_TIME_WAIT))))) | ||
| 997 | ip_vs_sync_conn(cp); | 996 | ip_vs_sync_conn(cp); |
| 998 | cp->old_state = cp->state; | 997 | cp->old_state = cp->state; |
| 999 | 998 | ||
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 94c5767c8e01..9a5ace0b4dd6 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * high-performance and highly available server based on a | 5 | * high-performance and highly available server based on a |
| 6 | * cluster of servers. | 6 | * cluster of servers. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_vs_ctl.c,v 1.36 2003/06/08 09:31:19 wensong Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 8 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 11 | * Peter Kese <peter.kese@ijs.si> | 9 | * Peter Kese <peter.kese@ijs.si> |
| 12 | * Julian Anastasov <ja@ssi.bg> | 10 | * Julian Anastasov <ja@ssi.bg> |
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c index dcf5d46aaa5e..8afc1503ed20 100644 --- a/net/ipv4/ipvs/ip_vs_dh.c +++ b/net/ipv4/ipvs/ip_vs_dh.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Destination Hashing scheduling module | 2 | * IPVS: Destination Hashing scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_dh.c,v 1.5 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@gnuchina.org> | 4 | * Authors: Wensong Zhang <wensong@gnuchina.org> |
| 7 | * | 5 | * |
| 8 | * Inspired by the consistent hashing scheduler patch from | 6 | * Inspired by the consistent hashing scheduler patch from |
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c index dfa0d713c801..bc04eedd6dbb 100644 --- a/net/ipv4/ipvs/ip_vs_est.c +++ b/net/ipv4/ipvs/ip_vs_est.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_est.c: simple rate estimator for IPVS | 2 | * ip_vs_est.c: simple rate estimator for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_est.c,v 1.4 2002/11/30 01:50:35 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c index 59aa166b7678..c1c758e4f733 100644 --- a/net/ipv4/ipvs/ip_vs_ftp.c +++ b/net/ipv4/ipvs/ip_vs_ftp.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_ftp.c: IPVS ftp application module | 2 | * ip_vs_ftp.c: IPVS ftp application module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_ftp.c,v 1.13 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * Changes: | 6 | * Changes: |
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c index 3888642706ad..0efa3db4b180 100644 --- a/net/ipv4/ipvs/ip_vs_lblc.c +++ b/net/ipv4/ipvs/ip_vs_lblc.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Locality-Based Least-Connection scheduling module | 2 | * IPVS: Locality-Based Least-Connection scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_lblc.c,v 1.10 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@gnuchina.org> | 4 | * Authors: Wensong Zhang <wensong@gnuchina.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c index daa260eb21cf..8e3bbeb45138 100644 --- a/net/ipv4/ipvs/ip_vs_lblcr.c +++ b/net/ipv4/ipvs/ip_vs_lblcr.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Locality-Based Least-Connection with Replication scheduler | 2 | * IPVS: Locality-Based Least-Connection with Replication scheduler |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_lblcr.c,v 1.11 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@gnuchina.org> | 4 | * Authors: Wensong Zhang <wensong@gnuchina.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_lc.c b/net/ipv4/ipvs/ip_vs_lc.c index d88fef90a641..ac9f08e065d5 100644 --- a/net/ipv4/ipvs/ip_vs_lc.c +++ b/net/ipv4/ipvs/ip_vs_lc.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Least-Connection Scheduling module | 2 | * IPVS: Least-Connection Scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_lc.c,v 1.10 2003/04/18 09:03:16 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_nq.c b/net/ipv4/ipvs/ip_vs_nq.c index bc2a9e5f2a7b..a46bf258d420 100644 --- a/net/ipv4/ipvs/ip_vs_nq.c +++ b/net/ipv4/ipvs/ip_vs_nq.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Never Queue scheduling module | 2 | * IPVS: Never Queue scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_nq.c,v 1.2 2003/06/08 09:31:19 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c index 4b1c16cbb16b..876714f23d65 100644 --- a/net/ipv4/ipvs/ip_vs_proto.c +++ b/net/ipv4/ipvs/ip_vs_proto.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_proto.c: transport protocol load balancing support for IPVS | 2 | * ip_vs_proto.c: transport protocol load balancing support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_proto.c,v 1.2 2003/04/18 09:03:16 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Julian Anastasov <ja@ssi.bg> | 5 | * Julian Anastasov <ja@ssi.bg> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c index 4bf835e1d86d..73e0ea87c1f5 100644 --- a/net/ipv4/ipvs/ip_vs_proto_ah.c +++ b/net/ipv4/ipvs/ip_vs_proto_ah.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_proto_ah.c: AH IPSec load balancing support for IPVS | 2 | * ip_vs_proto_ah.c: AH IPSec load balancing support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_proto_ah.c,v 1.1 2003/07/04 15:04:37 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 | 4 | * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 |
| 7 | * Wensong Zhang <wensong@linuxvirtualserver.org> | 5 | * Wensong Zhang <wensong@linuxvirtualserver.org> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c index db6a6b7b1a0b..21d70c8ffa54 100644 --- a/net/ipv4/ipvs/ip_vs_proto_esp.c +++ b/net/ipv4/ipvs/ip_vs_proto_esp.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_proto_esp.c: ESP IPSec load balancing support for IPVS | 2 | * ip_vs_proto_esp.c: ESP IPSec load balancing support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_proto_esp.c,v 1.1 2003/07/04 15:04:37 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 | 4 | * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 |
| 7 | * Wensong Zhang <wensong@linuxvirtualserver.org> | 5 | * Wensong Zhang <wensong@linuxvirtualserver.org> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index b83dc14b0a4d..d0ea467986a0 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_proto_tcp.c: TCP load balancing support for IPVS | 2 | * ip_vs_proto_tcp.c: TCP load balancing support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_proto_tcp.c,v 1.3 2002/11/30 01:50:35 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Julian Anastasov <ja@ssi.bg> | 5 | * Julian Anastasov <ja@ssi.bg> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 75771cb3cd6f..c6be5d56823f 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_proto_udp.c: UDP load balancing support for IPVS | 2 | * ip_vs_proto_udp.c: UDP load balancing support for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_proto_udp.c,v 1.3 2002/11/30 01:50:35 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Julian Anastasov <ja@ssi.bg> | 5 | * Julian Anastasov <ja@ssi.bg> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_rr.c b/net/ipv4/ipvs/ip_vs_rr.c index 433f8a947924..c8db12d39e61 100644 --- a/net/ipv4/ipvs/ip_vs_rr.c +++ b/net/ipv4/ipvs/ip_vs_rr.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Round-Robin Scheduling module | 2 | * IPVS: Round-Robin Scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_rr.c,v 1.9 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Peter Kese <peter.kese@ijs.si> | 5 | * Peter Kese <peter.kese@ijs.si> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c index 121a32b1b756..b64767309855 100644 --- a/net/ipv4/ipvs/ip_vs_sched.c +++ b/net/ipv4/ipvs/ip_vs_sched.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * high-performance and highly available server based on a | 5 | * high-performance and highly available server based on a |
| 6 | * cluster of servers. | 6 | * cluster of servers. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_vs_sched.c,v 1.13 2003/05/10 03:05:23 wensong Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 8 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 11 | * Peter Kese <peter.kese@ijs.si> | 9 | * Peter Kese <peter.kese@ijs.si> |
| 12 | * | 10 | * |
diff --git a/net/ipv4/ipvs/ip_vs_sed.c b/net/ipv4/ipvs/ip_vs_sed.c index dd7c128f9db3..2a7d31358181 100644 --- a/net/ipv4/ipvs/ip_vs_sed.c +++ b/net/ipv4/ipvs/ip_vs_sed.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Shortest Expected Delay scheduling module | 2 | * IPVS: Shortest Expected Delay scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_sed.c,v 1.1 2003/05/10 03:06:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c index 1b25b00ef1e1..b8fdfac65001 100644 --- a/net/ipv4/ipvs/ip_vs_sh.c +++ b/net/ipv4/ipvs/ip_vs_sh.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Source Hashing scheduling module | 2 | * IPVS: Source Hashing scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_sh.c,v 1.5 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@gnuchina.org> | 4 | * Authors: Wensong Zhang <wensong@gnuchina.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index eff54efe0351..45e9bd96c286 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * high-performance and highly available server based on a | 5 | * high-performance and highly available server based on a |
| 6 | * cluster of servers. | 6 | * cluster of servers. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: ip_vs_sync.c,v 1.13 2003/06/08 09:31:19 wensong Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 8 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 11 | * | 9 | * |
| 12 | * ip_vs_sync: sync connection info from master load balancer to backups | 10 | * ip_vs_sync: sync connection info from master load balancer to backups |
| @@ -29,10 +27,12 @@ | |||
| 29 | #include <linux/in.h> | 27 | #include <linux/in.h> |
| 30 | #include <linux/igmp.h> /* for ip_mc_join_group */ | 28 | #include <linux/igmp.h> /* for ip_mc_join_group */ |
| 31 | #include <linux/udp.h> | 29 | #include <linux/udp.h> |
| 30 | #include <linux/err.h> | ||
| 31 | #include <linux/kthread.h> | ||
| 32 | #include <linux/wait.h> | ||
| 32 | 33 | ||
| 33 | #include <net/ip.h> | 34 | #include <net/ip.h> |
| 34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
| 35 | #include <asm/uaccess.h> /* for get_fs and set_fs */ | ||
| 36 | 36 | ||
| 37 | #include <net/ip_vs.h> | 37 | #include <net/ip_vs.h> |
| 38 | 38 | ||
| @@ -68,8 +68,8 @@ struct ip_vs_sync_conn_options { | |||
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | struct ip_vs_sync_thread_data { | 70 | struct ip_vs_sync_thread_data { |
| 71 | struct completion *startup; | 71 | struct socket *sock; |
| 72 | int state; | 72 | char *buf; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) | 75 | #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) |
| @@ -140,18 +140,19 @@ volatile int ip_vs_backup_syncid = 0; | |||
| 140 | char ip_vs_master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; | 140 | char ip_vs_master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; |
| 141 | char ip_vs_backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; | 141 | char ip_vs_backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; |
| 142 | 142 | ||
| 143 | /* sync daemon tasks */ | ||
| 144 | static struct task_struct *sync_master_thread; | ||
| 145 | static struct task_struct *sync_backup_thread; | ||
| 146 | |||
| 143 | /* multicast addr */ | 147 | /* multicast addr */ |
| 144 | static struct sockaddr_in mcast_addr; | 148 | static struct sockaddr_in mcast_addr = { |
| 149 | .sin_family = AF_INET, | ||
| 150 | .sin_port = __constant_htons(IP_VS_SYNC_PORT), | ||
| 151 | .sin_addr.s_addr = __constant_htonl(IP_VS_SYNC_GROUP), | ||
| 152 | }; | ||
| 145 | 153 | ||
| 146 | 154 | ||
| 147 | static inline void sb_queue_tail(struct ip_vs_sync_buff *sb) | 155 | static inline struct ip_vs_sync_buff *sb_dequeue(void) |
| 148 | { | ||
| 149 | spin_lock(&ip_vs_sync_lock); | ||
| 150 | list_add_tail(&sb->list, &ip_vs_sync_queue); | ||
| 151 | spin_unlock(&ip_vs_sync_lock); | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline struct ip_vs_sync_buff * sb_dequeue(void) | ||
| 155 | { | 156 | { |
| 156 | struct ip_vs_sync_buff *sb; | 157 | struct ip_vs_sync_buff *sb; |
| 157 | 158 | ||
| @@ -195,6 +196,16 @@ static inline void ip_vs_sync_buff_release(struct ip_vs_sync_buff *sb) | |||
| 195 | kfree(sb); | 196 | kfree(sb); |
| 196 | } | 197 | } |
| 197 | 198 | ||
| 199 | static inline void sb_queue_tail(struct ip_vs_sync_buff *sb) | ||
| 200 | { | ||
| 201 | spin_lock(&ip_vs_sync_lock); | ||
| 202 | if (ip_vs_sync_state & IP_VS_STATE_MASTER) | ||
| 203 | list_add_tail(&sb->list, &ip_vs_sync_queue); | ||
| 204 | else | ||
| 205 | ip_vs_sync_buff_release(sb); | ||
| 206 | spin_unlock(&ip_vs_sync_lock); | ||
| 207 | } | ||
| 208 | |||
| 198 | /* | 209 | /* |
| 199 | * Get the current sync buffer if it has been created for more | 210 | * Get the current sync buffer if it has been created for more |
| 200 | * than the specified time or the specified time is zero. | 211 | * than the specified time or the specified time is zero. |
| @@ -574,14 +585,17 @@ static int bind_mcastif_addr(struct socket *sock, char *ifname) | |||
| 574 | static struct socket * make_send_sock(void) | 585 | static struct socket * make_send_sock(void) |
| 575 | { | 586 | { |
| 576 | struct socket *sock; | 587 | struct socket *sock; |
| 588 | int result; | ||
| 577 | 589 | ||
| 578 | /* First create a socket */ | 590 | /* First create a socket */ |
| 579 | if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) { | 591 | result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
| 592 | if (result < 0) { | ||
| 580 | IP_VS_ERR("Error during creation of socket; terminating\n"); | 593 | IP_VS_ERR("Error during creation of socket; terminating\n"); |
| 581 | return NULL; | 594 | return ERR_PTR(result); |
| 582 | } | 595 | } |
| 583 | 596 | ||
| 584 | if (set_mcast_if(sock->sk, ip_vs_master_mcast_ifn) < 0) { | 597 | result = set_mcast_if(sock->sk, ip_vs_master_mcast_ifn); |
| 598 | if (result < 0) { | ||
| 585 | IP_VS_ERR("Error setting outbound mcast interface\n"); | 599 | IP_VS_ERR("Error setting outbound mcast interface\n"); |
| 586 | goto error; | 600 | goto error; |
| 587 | } | 601 | } |
| @@ -589,14 +603,15 @@ static struct socket * make_send_sock(void) | |||
| 589 | set_mcast_loop(sock->sk, 0); | 603 | set_mcast_loop(sock->sk, 0); |
| 590 | set_mcast_ttl(sock->sk, 1); | 604 | set_mcast_ttl(sock->sk, 1); |
| 591 | 605 | ||
| 592 | if (bind_mcastif_addr(sock, ip_vs_master_mcast_ifn) < 0) { | 606 | result = bind_mcastif_addr(sock, ip_vs_master_mcast_ifn); |
| 607 | if (result < 0) { | ||
| 593 | IP_VS_ERR("Error binding address of the mcast interface\n"); | 608 | IP_VS_ERR("Error binding address of the mcast interface\n"); |
| 594 | goto error; | 609 | goto error; |
| 595 | } | 610 | } |
| 596 | 611 | ||
| 597 | if (sock->ops->connect(sock, | 612 | result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr, |
| 598 | (struct sockaddr*)&mcast_addr, | 613 | sizeof(struct sockaddr), 0); |
| 599 | sizeof(struct sockaddr), 0) < 0) { | 614 | if (result < 0) { |
| 600 | IP_VS_ERR("Error connecting to the multicast addr\n"); | 615 | IP_VS_ERR("Error connecting to the multicast addr\n"); |
| 601 | goto error; | 616 | goto error; |
| 602 | } | 617 | } |
| @@ -605,7 +620,7 @@ static struct socket * make_send_sock(void) | |||
| 605 | 620 | ||
| 606 | error: | 621 | error: |
| 607 | sock_release(sock); | 622 | sock_release(sock); |
| 608 | return NULL; | 623 | return ERR_PTR(result); |
| 609 | } | 624 | } |
| 610 | 625 | ||
| 611 | 626 | ||
| @@ -615,27 +630,30 @@ static struct socket * make_send_sock(void) | |||
| 615 | static struct socket * make_receive_sock(void) | 630 | static struct socket * make_receive_sock(void) |
| 616 | { | 631 | { |
| 617 | struct socket *sock; | 632 | struct socket *sock; |
| 633 | int result; | ||
| 618 | 634 | ||
| 619 | /* First create a socket */ | 635 | /* First create a socket */ |
| 620 | if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) { | 636 | result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
| 637 | if (result < 0) { | ||
| 621 | IP_VS_ERR("Error during creation of socket; terminating\n"); | 638 | IP_VS_ERR("Error during creation of socket; terminating\n"); |
| 622 | return NULL; | 639 | return ERR_PTR(result); |
| 623 | } | 640 | } |
| 624 | 641 | ||
| 625 | /* it is equivalent to the REUSEADDR option in user-space */ | 642 | /* it is equivalent to the REUSEADDR option in user-space */ |
| 626 | sock->sk->sk_reuse = 1; | 643 | sock->sk->sk_reuse = 1; |
| 627 | 644 | ||
| 628 | if (sock->ops->bind(sock, | 645 | result = sock->ops->bind(sock, (struct sockaddr *) &mcast_addr, |
| 629 | (struct sockaddr*)&mcast_addr, | 646 | sizeof(struct sockaddr)); |
| 630 | sizeof(struct sockaddr)) < 0) { | 647 | if (result < 0) { |
| 631 | IP_VS_ERR("Error binding to the multicast addr\n"); | 648 | IP_VS_ERR("Error binding to the multicast addr\n"); |
| 632 | goto error; | 649 | goto error; |
| 633 | } | 650 | } |
| 634 | 651 | ||
| 635 | /* join the multicast group */ | 652 | /* join the multicast group */ |
| 636 | if (join_mcast_group(sock->sk, | 653 | result = join_mcast_group(sock->sk, |
| 637 | (struct in_addr*)&mcast_addr.sin_addr, | 654 | (struct in_addr *) &mcast_addr.sin_addr, |
| 638 | ip_vs_backup_mcast_ifn) < 0) { | 655 | ip_vs_backup_mcast_ifn); |
| 656 | if (result < 0) { | ||
| 639 | IP_VS_ERR("Error joining to the multicast group\n"); | 657 | IP_VS_ERR("Error joining to the multicast group\n"); |
| 640 | goto error; | 658 | goto error; |
| 641 | } | 659 | } |
| @@ -644,7 +662,7 @@ static struct socket * make_receive_sock(void) | |||
| 644 | 662 | ||
| 645 | error: | 663 | error: |
| 646 | sock_release(sock); | 664 | sock_release(sock); |
| 647 | return NULL; | 665 | return ERR_PTR(result); |
| 648 | } | 666 | } |
| 649 | 667 | ||
| 650 | 668 | ||
| @@ -702,44 +720,29 @@ ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen) | |||
| 702 | } | 720 | } |
| 703 | 721 | ||
| 704 | 722 | ||
| 705 | static DECLARE_WAIT_QUEUE_HEAD(sync_wait); | 723 | static int sync_thread_master(void *data) |
| 706 | static pid_t sync_master_pid = 0; | ||
| 707 | static pid_t sync_backup_pid = 0; | ||
| 708 | |||
| 709 | static DECLARE_WAIT_QUEUE_HEAD(stop_sync_wait); | ||
| 710 | static int stop_master_sync = 0; | ||
| 711 | static int stop_backup_sync = 0; | ||
| 712 | |||
| 713 | static void sync_master_loop(void) | ||
| 714 | { | 724 | { |
| 715 | struct socket *sock; | 725 | struct ip_vs_sync_thread_data *tinfo = data; |
| 716 | struct ip_vs_sync_buff *sb; | 726 | struct ip_vs_sync_buff *sb; |
| 717 | 727 | ||
| 718 | /* create the sending multicast socket */ | ||
| 719 | sock = make_send_sock(); | ||
| 720 | if (!sock) | ||
| 721 | return; | ||
| 722 | |||
| 723 | IP_VS_INFO("sync thread started: state = MASTER, mcast_ifn = %s, " | 728 | IP_VS_INFO("sync thread started: state = MASTER, mcast_ifn = %s, " |
| 724 | "syncid = %d\n", | 729 | "syncid = %d\n", |
| 725 | ip_vs_master_mcast_ifn, ip_vs_master_syncid); | 730 | ip_vs_master_mcast_ifn, ip_vs_master_syncid); |
| 726 | 731 | ||
| 727 | for (;;) { | 732 | while (!kthread_should_stop()) { |
| 728 | while ((sb=sb_dequeue())) { | 733 | while ((sb = sb_dequeue())) { |
| 729 | ip_vs_send_sync_msg(sock, sb->mesg); | 734 | ip_vs_send_sync_msg(tinfo->sock, sb->mesg); |
| 730 | ip_vs_sync_buff_release(sb); | 735 | ip_vs_sync_buff_release(sb); |
| 731 | } | 736 | } |
| 732 | 737 | ||
| 733 | /* check if entries stay in curr_sb for 2 seconds */ | 738 | /* check if entries stay in curr_sb for 2 seconds */ |
| 734 | if ((sb = get_curr_sync_buff(2*HZ))) { | 739 | sb = get_curr_sync_buff(2 * HZ); |
| 735 | ip_vs_send_sync_msg(sock, sb->mesg); | 740 | if (sb) { |
| 741 | ip_vs_send_sync_msg(tinfo->sock, sb->mesg); | ||
| 736 | ip_vs_sync_buff_release(sb); | 742 | ip_vs_sync_buff_release(sb); |
| 737 | } | 743 | } |
| 738 | 744 | ||
| 739 | if (stop_master_sync) | 745 | schedule_timeout_interruptible(HZ); |
| 740 | break; | ||
| 741 | |||
| 742 | msleep_interruptible(1000); | ||
| 743 | } | 746 | } |
| 744 | 747 | ||
| 745 | /* clean up the sync_buff queue */ | 748 | /* clean up the sync_buff queue */ |
| @@ -753,267 +756,175 @@ static void sync_master_loop(void) | |||
| 753 | } | 756 | } |
| 754 | 757 | ||
| 755 | /* release the sending multicast socket */ | 758 | /* release the sending multicast socket */ |
| 756 | sock_release(sock); | 759 | sock_release(tinfo->sock); |
| 760 | kfree(tinfo); | ||
| 761 | |||
| 762 | return 0; | ||
| 757 | } | 763 | } |
| 758 | 764 | ||
| 759 | 765 | ||
| 760 | static void sync_backup_loop(void) | 766 | static int sync_thread_backup(void *data) |
| 761 | { | 767 | { |
| 762 | struct socket *sock; | 768 | struct ip_vs_sync_thread_data *tinfo = data; |
| 763 | char *buf; | ||
| 764 | int len; | 769 | int len; |
| 765 | 770 | ||
| 766 | if (!(buf = kmalloc(sync_recv_mesg_maxlen, GFP_ATOMIC))) { | ||
| 767 | IP_VS_ERR("sync_backup_loop: kmalloc error\n"); | ||
| 768 | return; | ||
| 769 | } | ||
| 770 | |||
| 771 | /* create the receiving multicast socket */ | ||
| 772 | sock = make_receive_sock(); | ||
| 773 | if (!sock) | ||
| 774 | goto out; | ||
| 775 | |||
| 776 | IP_VS_INFO("sync thread started: state = BACKUP, mcast_ifn = %s, " | 771 | IP_VS_INFO("sync thread started: state = BACKUP, mcast_ifn = %s, " |
| 777 | "syncid = %d\n", | 772 | "syncid = %d\n", |
| 778 | ip_vs_backup_mcast_ifn, ip_vs_backup_syncid); | 773 | ip_vs_backup_mcast_ifn, ip_vs_backup_syncid); |
| 779 | 774 | ||
| 780 | for (;;) { | 775 | while (!kthread_should_stop()) { |
| 781 | /* do you have data now? */ | 776 | wait_event_interruptible(*tinfo->sock->sk->sk_sleep, |
| 782 | while (!skb_queue_empty(&(sock->sk->sk_receive_queue))) { | 777 | !skb_queue_empty(&tinfo->sock->sk->sk_receive_queue) |
| 783 | if ((len = | 778 | || kthread_should_stop()); |
| 784 | ip_vs_receive(sock, buf, | 779 | |
| 785 | sync_recv_mesg_maxlen)) <= 0) { | 780 | /* do we have data now? */ |
| 781 | while (!skb_queue_empty(&(tinfo->sock->sk->sk_receive_queue))) { | ||
| 782 | len = ip_vs_receive(tinfo->sock, tinfo->buf, | ||
| 783 | sync_recv_mesg_maxlen); | ||
| 784 | if (len <= 0) { | ||
| 786 | IP_VS_ERR("receiving message error\n"); | 785 | IP_VS_ERR("receiving message error\n"); |
| 787 | break; | 786 | break; |
| 788 | } | 787 | } |
| 789 | /* disable bottom half, because it accessed the data | 788 | |
| 789 | /* disable bottom half, because it accesses the data | ||
| 790 | shared by softirq while getting/creating conns */ | 790 | shared by softirq while getting/creating conns */ |
| 791 | local_bh_disable(); | 791 | local_bh_disable(); |
| 792 | ip_vs_process_message(buf, len); | 792 | ip_vs_process_message(tinfo->buf, len); |
| 793 | local_bh_enable(); | 793 | local_bh_enable(); |
| 794 | } | 794 | } |
| 795 | |||
| 796 | if (stop_backup_sync) | ||
| 797 | break; | ||
| 798 | |||
| 799 | msleep_interruptible(1000); | ||
| 800 | } | 795 | } |
| 801 | 796 | ||
| 802 | /* release the sending multicast socket */ | 797 | /* release the sending multicast socket */ |
| 803 | sock_release(sock); | 798 | sock_release(tinfo->sock); |
| 799 | kfree(tinfo->buf); | ||
| 800 | kfree(tinfo); | ||
| 804 | 801 | ||
| 805 | out: | 802 | return 0; |
| 806 | kfree(buf); | ||
| 807 | } | 803 | } |
| 808 | 804 | ||
| 809 | 805 | ||
| 810 | static void set_sync_pid(int sync_state, pid_t sync_pid) | 806 | int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) |
| 811 | { | ||
| 812 | if (sync_state == IP_VS_STATE_MASTER) | ||
| 813 | sync_master_pid = sync_pid; | ||
| 814 | else if (sync_state == IP_VS_STATE_BACKUP) | ||
| 815 | sync_backup_pid = sync_pid; | ||
| 816 | } | ||
| 817 | |||
| 818 | static void set_stop_sync(int sync_state, int set) | ||
| 819 | { | 807 | { |
| 820 | if (sync_state == IP_VS_STATE_MASTER) | 808 | struct ip_vs_sync_thread_data *tinfo; |
| 821 | stop_master_sync = set; | 809 | struct task_struct **realtask, *task; |
| 822 | else if (sync_state == IP_VS_STATE_BACKUP) | 810 | struct socket *sock; |
| 823 | stop_backup_sync = set; | 811 | char *name, *buf = NULL; |
| 824 | else { | 812 | int (*threadfn)(void *data); |
| 825 | stop_master_sync = set; | 813 | int result = -ENOMEM; |
| 826 | stop_backup_sync = set; | ||
| 827 | } | ||
| 828 | } | ||
| 829 | 814 | ||
| 830 | static int sync_thread(void *startup) | 815 | IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current)); |
| 831 | { | 816 | IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n", |
| 832 | DECLARE_WAITQUEUE(wait, current); | 817 | sizeof(struct ip_vs_sync_conn)); |
| 833 | mm_segment_t oldmm; | ||
| 834 | int state; | ||
| 835 | const char *name; | ||
| 836 | struct ip_vs_sync_thread_data *tinfo = startup; | ||
| 837 | 818 | ||
| 838 | /* increase the module use count */ | 819 | if (state == IP_VS_STATE_MASTER) { |
| 839 | ip_vs_use_count_inc(); | 820 | if (sync_master_thread) |
| 821 | return -EEXIST; | ||
| 840 | 822 | ||
| 841 | if (ip_vs_sync_state & IP_VS_STATE_MASTER && !sync_master_pid) { | 823 | strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, |
| 842 | state = IP_VS_STATE_MASTER; | 824 | sizeof(ip_vs_master_mcast_ifn)); |
| 825 | ip_vs_master_syncid = syncid; | ||
| 826 | realtask = &sync_master_thread; | ||
| 843 | name = "ipvs_syncmaster"; | 827 | name = "ipvs_syncmaster"; |
| 844 | } else if (ip_vs_sync_state & IP_VS_STATE_BACKUP && !sync_backup_pid) { | 828 | threadfn = sync_thread_master; |
| 845 | state = IP_VS_STATE_BACKUP; | 829 | sock = make_send_sock(); |
| 830 | } else if (state == IP_VS_STATE_BACKUP) { | ||
| 831 | if (sync_backup_thread) | ||
| 832 | return -EEXIST; | ||
| 833 | |||
| 834 | strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, | ||
| 835 | sizeof(ip_vs_backup_mcast_ifn)); | ||
| 836 | ip_vs_backup_syncid = syncid; | ||
| 837 | realtask = &sync_backup_thread; | ||
| 846 | name = "ipvs_syncbackup"; | 838 | name = "ipvs_syncbackup"; |
| 839 | threadfn = sync_thread_backup; | ||
| 840 | sock = make_receive_sock(); | ||
| 847 | } else { | 841 | } else { |
| 848 | IP_VS_BUG(); | ||
| 849 | ip_vs_use_count_dec(); | ||
| 850 | return -EINVAL; | 842 | return -EINVAL; |
| 851 | } | 843 | } |
| 852 | 844 | ||
| 853 | daemonize(name); | 845 | if (IS_ERR(sock)) { |
| 854 | 846 | result = PTR_ERR(sock); | |
| 855 | oldmm = get_fs(); | 847 | goto out; |
| 856 | set_fs(KERNEL_DS); | 848 | } |
| 857 | |||
| 858 | /* Block all signals */ | ||
| 859 | spin_lock_irq(¤t->sighand->siglock); | ||
| 860 | siginitsetinv(¤t->blocked, 0); | ||
| 861 | recalc_sigpending(); | ||
| 862 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 863 | 849 | ||
| 864 | /* set the maximum length of sync message */ | ||
| 865 | set_sync_mesg_maxlen(state); | 850 | set_sync_mesg_maxlen(state); |
| 851 | if (state == IP_VS_STATE_BACKUP) { | ||
| 852 | buf = kmalloc(sync_recv_mesg_maxlen, GFP_KERNEL); | ||
| 853 | if (!buf) | ||
| 854 | goto outsocket; | ||
| 855 | } | ||
| 866 | 856 | ||
| 867 | /* set up multicast address */ | 857 | tinfo = kmalloc(sizeof(*tinfo), GFP_KERNEL); |
| 868 | mcast_addr.sin_family = AF_INET; | 858 | if (!tinfo) |
| 869 | mcast_addr.sin_port = htons(IP_VS_SYNC_PORT); | 859 | goto outbuf; |
| 870 | mcast_addr.sin_addr.s_addr = htonl(IP_VS_SYNC_GROUP); | ||
| 871 | |||
| 872 | add_wait_queue(&sync_wait, &wait); | ||
| 873 | |||
| 874 | set_sync_pid(state, task_pid_nr(current)); | ||
| 875 | complete(tinfo->startup); | ||
| 876 | |||
| 877 | /* | ||
| 878 | * once we call the completion queue above, we should | ||
| 879 | * null out that reference, since its allocated on the | ||
| 880 | * stack of the creating kernel thread | ||
| 881 | */ | ||
| 882 | tinfo->startup = NULL; | ||
| 883 | |||
| 884 | /* processing master/backup loop here */ | ||
| 885 | if (state == IP_VS_STATE_MASTER) | ||
| 886 | sync_master_loop(); | ||
| 887 | else if (state == IP_VS_STATE_BACKUP) | ||
| 888 | sync_backup_loop(); | ||
| 889 | else IP_VS_BUG(); | ||
| 890 | |||
| 891 | remove_wait_queue(&sync_wait, &wait); | ||
| 892 | |||
| 893 | /* thread exits */ | ||
| 894 | |||
| 895 | /* | ||
| 896 | * If we weren't explicitly stopped, then we | ||
| 897 | * exited in error, and should undo our state | ||
| 898 | */ | ||
| 899 | if ((!stop_master_sync) && (!stop_backup_sync)) | ||
| 900 | ip_vs_sync_state -= tinfo->state; | ||
| 901 | 860 | ||
| 902 | set_sync_pid(state, 0); | 861 | tinfo->sock = sock; |
| 903 | IP_VS_INFO("sync thread stopped!\n"); | 862 | tinfo->buf = buf; |
| 904 | 863 | ||
| 905 | set_fs(oldmm); | 864 | task = kthread_run(threadfn, tinfo, name); |
| 865 | if (IS_ERR(task)) { | ||
| 866 | result = PTR_ERR(task); | ||
| 867 | goto outtinfo; | ||
| 868 | } | ||
| 906 | 869 | ||
| 907 | /* decrease the module use count */ | 870 | /* mark as active */ |
| 908 | ip_vs_use_count_dec(); | 871 | *realtask = task; |
| 872 | ip_vs_sync_state |= state; | ||
| 909 | 873 | ||
| 910 | set_stop_sync(state, 0); | 874 | /* increase the module use count */ |
| 911 | wake_up(&stop_sync_wait); | 875 | ip_vs_use_count_inc(); |
| 912 | 876 | ||
| 913 | /* | ||
| 914 | * we need to free the structure that was allocated | ||
| 915 | * for us in start_sync_thread | ||
| 916 | */ | ||
| 917 | kfree(tinfo); | ||
| 918 | return 0; | 877 | return 0; |
| 919 | } | ||
| 920 | |||
| 921 | |||
| 922 | static int fork_sync_thread(void *startup) | ||
| 923 | { | ||
| 924 | pid_t pid; | ||
| 925 | |||
| 926 | /* fork the sync thread here, then the parent process of the | ||
| 927 | sync thread is the init process after this thread exits. */ | ||
| 928 | repeat: | ||
| 929 | if ((pid = kernel_thread(sync_thread, startup, 0)) < 0) { | ||
| 930 | IP_VS_ERR("could not create sync_thread due to %d... " | ||
| 931 | "retrying.\n", pid); | ||
| 932 | msleep_interruptible(1000); | ||
| 933 | goto repeat; | ||
| 934 | } | ||
| 935 | 878 | ||
| 936 | return 0; | 879 | outtinfo: |
| 880 | kfree(tinfo); | ||
| 881 | outbuf: | ||
| 882 | kfree(buf); | ||
| 883 | outsocket: | ||
| 884 | sock_release(sock); | ||
| 885 | out: | ||
| 886 | return result; | ||
| 937 | } | 887 | } |
| 938 | 888 | ||
| 939 | 889 | ||
| 940 | int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) | 890 | int stop_sync_thread(int state) |
| 941 | { | 891 | { |
| 942 | DECLARE_COMPLETION_ONSTACK(startup); | ||
| 943 | pid_t pid; | ||
| 944 | struct ip_vs_sync_thread_data *tinfo; | ||
| 945 | |||
| 946 | if ((state == IP_VS_STATE_MASTER && sync_master_pid) || | ||
| 947 | (state == IP_VS_STATE_BACKUP && sync_backup_pid)) | ||
| 948 | return -EEXIST; | ||
| 949 | |||
| 950 | /* | ||
| 951 | * Note that tinfo will be freed in sync_thread on exit | ||
| 952 | */ | ||
| 953 | tinfo = kmalloc(sizeof(struct ip_vs_sync_thread_data), GFP_KERNEL); | ||
| 954 | if (!tinfo) | ||
| 955 | return -ENOMEM; | ||
| 956 | |||
| 957 | IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current)); | 892 | IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current)); |
| 958 | IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", | ||
| 959 | sizeof(struct ip_vs_sync_conn)); | ||
| 960 | 893 | ||
| 961 | ip_vs_sync_state |= state; | ||
| 962 | if (state == IP_VS_STATE_MASTER) { | 894 | if (state == IP_VS_STATE_MASTER) { |
| 963 | strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, | 895 | if (!sync_master_thread) |
| 964 | sizeof(ip_vs_master_mcast_ifn)); | 896 | return -ESRCH; |
| 965 | ip_vs_master_syncid = syncid; | ||
| 966 | } else { | ||
| 967 | strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, | ||
| 968 | sizeof(ip_vs_backup_mcast_ifn)); | ||
| 969 | ip_vs_backup_syncid = syncid; | ||
| 970 | } | ||
| 971 | |||
| 972 | tinfo->state = state; | ||
| 973 | tinfo->startup = &startup; | ||
| 974 | |||
| 975 | repeat: | ||
| 976 | if ((pid = kernel_thread(fork_sync_thread, tinfo, 0)) < 0) { | ||
| 977 | IP_VS_ERR("could not create fork_sync_thread due to %d... " | ||
| 978 | "retrying.\n", pid); | ||
| 979 | msleep_interruptible(1000); | ||
| 980 | goto repeat; | ||
| 981 | } | ||
| 982 | |||
| 983 | wait_for_completion(&startup); | ||
| 984 | |||
| 985 | return 0; | ||
| 986 | } | ||
| 987 | 897 | ||
| 898 | IP_VS_INFO("stopping master sync thread %d ...\n", | ||
| 899 | task_pid_nr(sync_master_thread)); | ||
| 988 | 900 | ||
| 989 | int stop_sync_thread(int state) | 901 | /* |
| 990 | { | 902 | * The lock synchronizes with sb_queue_tail(), so that we don't |
| 991 | DECLARE_WAITQUEUE(wait, current); | 903 | * add sync buffers to the queue, when we are already in |
| 904 | * progress of stopping the master sync daemon. | ||
| 905 | */ | ||
| 992 | 906 | ||
| 993 | if ((state == IP_VS_STATE_MASTER && !sync_master_pid) || | 907 | spin_lock(&ip_vs_sync_lock); |
| 994 | (state == IP_VS_STATE_BACKUP && !sync_backup_pid)) | 908 | ip_vs_sync_state &= ~IP_VS_STATE_MASTER; |
| 995 | return -ESRCH; | 909 | spin_unlock(&ip_vs_sync_lock); |
| 910 | kthread_stop(sync_master_thread); | ||
| 911 | sync_master_thread = NULL; | ||
| 912 | } else if (state == IP_VS_STATE_BACKUP) { | ||
| 913 | if (!sync_backup_thread) | ||
| 914 | return -ESRCH; | ||
| 915 | |||
| 916 | IP_VS_INFO("stopping backup sync thread %d ...\n", | ||
| 917 | task_pid_nr(sync_backup_thread)); | ||
| 918 | |||
| 919 | ip_vs_sync_state &= ~IP_VS_STATE_BACKUP; | ||
| 920 | kthread_stop(sync_backup_thread); | ||
| 921 | sync_backup_thread = NULL; | ||
| 922 | } else { | ||
| 923 | return -EINVAL; | ||
| 924 | } | ||
| 996 | 925 | ||
| 997 | IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current)); | 926 | /* decrease the module use count */ |
| 998 | IP_VS_INFO("stopping sync thread %d ...\n", | 927 | ip_vs_use_count_dec(); |
| 999 | (state == IP_VS_STATE_MASTER) ? | ||
| 1000 | sync_master_pid : sync_backup_pid); | ||
| 1001 | |||
| 1002 | __set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 1003 | add_wait_queue(&stop_sync_wait, &wait); | ||
| 1004 | set_stop_sync(state, 1); | ||
| 1005 | ip_vs_sync_state -= state; | ||
| 1006 | wake_up(&sync_wait); | ||
| 1007 | schedule(); | ||
| 1008 | __set_current_state(TASK_RUNNING); | ||
| 1009 | remove_wait_queue(&stop_sync_wait, &wait); | ||
| 1010 | |||
| 1011 | /* Note: no need to reap the sync thread, because its parent | ||
| 1012 | process is the init process */ | ||
| 1013 | |||
| 1014 | if ((state == IP_VS_STATE_MASTER && stop_master_sync) || | ||
| 1015 | (state == IP_VS_STATE_BACKUP && stop_backup_sync)) | ||
| 1016 | IP_VS_BUG(); | ||
| 1017 | 928 | ||
| 1018 | return 0; | 929 | return 0; |
| 1019 | } | 930 | } |
diff --git a/net/ipv4/ipvs/ip_vs_wlc.c b/net/ipv4/ipvs/ip_vs_wlc.c index 8a9d913261d8..772c3cb4eca1 100644 --- a/net/ipv4/ipvs/ip_vs_wlc.c +++ b/net/ipv4/ipvs/ip_vs_wlc.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Weighted Least-Connection Scheduling module | 2 | * IPVS: Weighted Least-Connection Scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_wlc.c,v 1.13 2003/04/18 09:03:16 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Peter Kese <peter.kese@ijs.si> | 5 | * Peter Kese <peter.kese@ijs.si> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/ipvs/ip_vs_wrr.c b/net/ipv4/ipvs/ip_vs_wrr.c index 85c680add6df..1d6932d7dc97 100644 --- a/net/ipv4/ipvs/ip_vs_wrr.c +++ b/net/ipv4/ipvs/ip_vs_wrr.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IPVS: Weighted Round-Robin Scheduling module | 2 | * IPVS: Weighted Round-Robin Scheduling module |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_wrr.c,v 1.12 2002/09/15 08:14:08 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index f63006caea03..9892d4aca42e 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ip_vs_xmit.c: various packet transmitters for IPVS | 2 | * ip_vs_xmit.c: various packet transmitters for IPVS |
| 3 | * | 3 | * |
| 4 | * Version: $Id: ip_vs_xmit.c,v 1.2 2002/11/30 01:50:35 wensong Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> | 4 | * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> |
| 7 | * Julian Anastasov <ja@ssi.bg> | 5 | * Julian Anastasov <ja@ssi.bg> |
| 8 | * | 6 | * |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 2767841a8cef..f23e60c93ef9 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
| @@ -213,8 +213,7 @@ config IP_NF_TARGET_NETMAP | |||
| 213 | help | 213 | help |
| 214 | NETMAP is an implementation of static 1:1 NAT mapping of network | 214 | NETMAP is an implementation of static 1:1 NAT mapping of network |
| 215 | addresses. It maps the network address part, while keeping the host | 215 | addresses. It maps the network address part, while keeping the host |
| 216 | address part intact. It is similar to Fast NAT, except that | 216 | address part intact. |
| 217 | Netfilter's connection tracking doesn't work well with Fast NAT. | ||
| 218 | 217 | ||
| 219 | To compile it as a module, choose M here. If unsure, say N. | 218 | To compile it as a module, choose M here. If unsure, say N. |
| 220 | 219 | ||
| @@ -365,6 +364,18 @@ config IP_NF_RAW | |||
| 365 | If you want to compile it as a module, say M here and read | 364 | If you want to compile it as a module, say M here and read |
| 366 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. | 365 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
| 367 | 366 | ||
| 367 | # security table for MAC policy | ||
| 368 | config IP_NF_SECURITY | ||
| 369 | tristate "Security table" | ||
| 370 | depends on IP_NF_IPTABLES | ||
| 371 | depends on SECURITY | ||
| 372 | default m if NETFILTER_ADVANCED=n | ||
| 373 | help | ||
| 374 | This option adds a `security' table to iptables, for use | ||
| 375 | with Mandatory Access Control (MAC) policy. | ||
| 376 | |||
| 377 | If unsure, say N. | ||
| 378 | |||
| 368 | # ARP tables | 379 | # ARP tables |
| 369 | config IP_NF_ARPTABLES | 380 | config IP_NF_ARPTABLES |
| 370 | tristate "ARP tables support" | 381 | tristate "ARP tables support" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index d9b92fbf5579..3f31291f37ce 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
| @@ -42,6 +42,7 @@ obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o | |||
| 42 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o | 42 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o |
| 43 | obj-$(CONFIG_NF_NAT) += iptable_nat.o | 43 | obj-$(CONFIG_NF_NAT) += iptable_nat.o |
| 44 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | 44 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o |
| 45 | obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | ||
| 45 | 46 | ||
| 46 | # matches | 47 | # matches |
| 47 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 48 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 26a37cedcf2e..432ce9d1c11c 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -156,7 +156,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 156 | case IPQ_COPY_META: | 156 | case IPQ_COPY_META: |
| 157 | case IPQ_COPY_NONE: | 157 | case IPQ_COPY_NONE: |
| 158 | size = NLMSG_SPACE(sizeof(*pmsg)); | 158 | size = NLMSG_SPACE(sizeof(*pmsg)); |
| 159 | data_len = 0; | ||
| 160 | break; | 159 | break; |
| 161 | 160 | ||
| 162 | case IPQ_COPY_PACKET: | 161 | case IPQ_COPY_PACKET: |
| @@ -224,8 +223,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 224 | return skb; | 223 | return skb; |
| 225 | 224 | ||
| 226 | nlmsg_failure: | 225 | nlmsg_failure: |
| 227 | if (skb) | ||
| 228 | kfree_skb(skb); | ||
| 229 | *errp = -EINVAL; | 226 | *errp = -EINVAL; |
| 230 | printk(KERN_ERR "ip_queue: error creating packet message\n"); | 227 | printk(KERN_ERR "ip_queue: error creating packet message\n"); |
| 231 | return NULL; | 228 | return NULL; |
| @@ -480,7 +477,7 @@ ipq_rcv_dev_event(struct notifier_block *this, | |||
| 480 | { | 477 | { |
| 481 | struct net_device *dev = ptr; | 478 | struct net_device *dev = ptr; |
| 482 | 479 | ||
| 483 | if (dev_net(dev) != &init_net) | 480 | if (!net_eq(dev_net(dev), &init_net)) |
| 484 | return NOTIFY_DONE; | 481 | return NOTIFY_DONE; |
| 485 | 482 | ||
| 486 | /* Drop any packets associated with the downed device */ | 483 | /* Drop any packets associated with the downed device */ |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 84c26dd27d81..0841aefaa503 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
| @@ -120,7 +120,7 @@ static int masq_device_event(struct notifier_block *this, | |||
| 120 | { | 120 | { |
| 121 | const struct net_device *dev = ptr; | 121 | const struct net_device *dev = ptr; |
| 122 | 122 | ||
| 123 | if (dev_net(dev) != &init_net) | 123 | if (!net_eq(dev_net(dev), &init_net)) |
| 124 | return NOTIFY_DONE; | 124 | return NOTIFY_DONE; |
| 125 | 125 | ||
| 126 | if (event == NETDEV_DOWN) { | 126 | if (event == NETDEV_DOWN) { |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c new file mode 100644 index 000000000000..2b472ac2263a --- /dev/null +++ b/net/ipv4/netfilter/iptable_security.c | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | /* | ||
| 2 | * "security" table | ||
| 3 | * | ||
| 4 | * This is for use by Mandatory Access Control (MAC) security models, | ||
| 5 | * which need to be able to manage security policy in separate context | ||
| 6 | * to DAC. | ||
| 7 | * | ||
| 8 | * Based on iptable_mangle.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | ||
| 11 | * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org> | ||
| 12 | * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com> | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify | ||
| 15 | * it under the terms of the GNU General Public License version 2 as | ||
| 16 | * published by the Free Software Foundation. | ||
| 17 | */ | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
| 20 | #include <net/ip.h> | ||
| 21 | |||
| 22 | MODULE_LICENSE("GPL"); | ||
| 23 | MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); | ||
| 24 | MODULE_DESCRIPTION("iptables security table, for MAC rules"); | ||
| 25 | |||
| 26 | #define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \ | ||
| 27 | (1 << NF_INET_FORWARD) | \ | ||
| 28 | (1 << NF_INET_LOCAL_OUT) | ||
| 29 | |||
| 30 | static struct | ||
| 31 | { | ||
| 32 | struct ipt_replace repl; | ||
| 33 | struct ipt_standard entries[3]; | ||
| 34 | struct ipt_error term; | ||
| 35 | } initial_table __initdata = { | ||
| 36 | .repl = { | ||
| 37 | .name = "security", | ||
| 38 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
| 39 | .num_entries = 4, | ||
| 40 | .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), | ||
| 41 | .hook_entry = { | ||
| 42 | [NF_INET_LOCAL_IN] = 0, | ||
| 43 | [NF_INET_FORWARD] = sizeof(struct ipt_standard), | ||
| 44 | [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, | ||
| 45 | }, | ||
| 46 | .underflow = { | ||
| 47 | [NF_INET_LOCAL_IN] = 0, | ||
| 48 | [NF_INET_FORWARD] = sizeof(struct ipt_standard), | ||
| 49 | [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, | ||
| 50 | }, | ||
| 51 | }, | ||
| 52 | .entries = { | ||
| 53 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ | ||
| 54 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ | ||
| 55 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ | ||
| 56 | }, | ||
| 57 | .term = IPT_ERROR_INIT, /* ERROR */ | ||
| 58 | }; | ||
| 59 | |||
| 60 | static struct xt_table security_table = { | ||
| 61 | .name = "security", | ||
| 62 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
| 63 | .lock = __RW_LOCK_UNLOCKED(security_table.lock), | ||
| 64 | .me = THIS_MODULE, | ||
| 65 | .af = AF_INET, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static unsigned int | ||
| 69 | ipt_local_in_hook(unsigned int hook, | ||
| 70 | struct sk_buff *skb, | ||
| 71 | const struct net_device *in, | ||
| 72 | const struct net_device *out, | ||
| 73 | int (*okfn)(struct sk_buff *)) | ||
| 74 | { | ||
| 75 | return ipt_do_table(skb, hook, in, out, | ||
| 76 | nf_local_in_net(in, out)->ipv4.iptable_security); | ||
| 77 | } | ||
| 78 | |||
| 79 | static unsigned int | ||
| 80 | ipt_forward_hook(unsigned int hook, | ||
| 81 | struct sk_buff *skb, | ||
| 82 | const struct net_device *in, | ||
| 83 | const struct net_device *out, | ||
| 84 | int (*okfn)(struct sk_buff *)) | ||
| 85 | { | ||
| 86 | return ipt_do_table(skb, hook, in, out, | ||
| 87 | nf_forward_net(in, out)->ipv4.iptable_security); | ||
| 88 | } | ||
| 89 | |||
| 90 | static unsigned int | ||
| 91 | ipt_local_out_hook(unsigned int hook, | ||
| 92 | struct sk_buff *skb, | ||
| 93 | const struct net_device *in, | ||
| 94 | const struct net_device *out, | ||
| 95 | int (*okfn)(struct sk_buff *)) | ||
| 96 | { | ||
| 97 | /* Somebody is playing with raw sockets. */ | ||
| 98 | if (skb->len < sizeof(struct iphdr) | ||
| 99 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | ||
| 100 | if (net_ratelimit()) | ||
| 101 | printk(KERN_INFO "iptable_security: ignoring short " | ||
| 102 | "SOCK_RAW packet.\n"); | ||
| 103 | return NF_ACCEPT; | ||
| 104 | } | ||
| 105 | return ipt_do_table(skb, hook, in, out, | ||
| 106 | nf_local_out_net(in, out)->ipv4.iptable_security); | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | ||
| 110 | { | ||
| 111 | .hook = ipt_local_in_hook, | ||
| 112 | .owner = THIS_MODULE, | ||
| 113 | .pf = PF_INET, | ||
| 114 | .hooknum = NF_INET_LOCAL_IN, | ||
| 115 | .priority = NF_IP_PRI_SECURITY, | ||
| 116 | }, | ||
| 117 | { | ||
| 118 | .hook = ipt_forward_hook, | ||
| 119 | .owner = THIS_MODULE, | ||
| 120 | .pf = PF_INET, | ||
| 121 | .hooknum = NF_INET_FORWARD, | ||
| 122 | .priority = NF_IP_PRI_SECURITY, | ||
| 123 | }, | ||
| 124 | { | ||
| 125 | .hook = ipt_local_out_hook, | ||
| 126 | .owner = THIS_MODULE, | ||
| 127 | .pf = PF_INET, | ||
| 128 | .hooknum = NF_INET_LOCAL_OUT, | ||
| 129 | .priority = NF_IP_PRI_SECURITY, | ||
| 130 | }, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int __net_init iptable_security_net_init(struct net *net) | ||
| 134 | { | ||
| 135 | net->ipv4.iptable_security = | ||
| 136 | ipt_register_table(net, &security_table, &initial_table.repl); | ||
| 137 | |||
| 138 | if (IS_ERR(net->ipv4.iptable_security)) | ||
| 139 | return PTR_ERR(net->ipv4.iptable_security); | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | static void __net_exit iptable_security_net_exit(struct net *net) | ||
| 145 | { | ||
| 146 | ipt_unregister_table(net->ipv4.iptable_security); | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct pernet_operations iptable_security_net_ops = { | ||
| 150 | .init = iptable_security_net_init, | ||
| 151 | .exit = iptable_security_net_exit, | ||
| 152 | }; | ||
| 153 | |||
| 154 | static int __init iptable_security_init(void) | ||
| 155 | { | ||
| 156 | int ret; | ||
| 157 | |||
| 158 | ret = register_pernet_subsys(&iptable_security_net_ops); | ||
| 159 | if (ret < 0) | ||
| 160 | return ret; | ||
| 161 | |||
| 162 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | ||
| 163 | if (ret < 0) | ||
| 164 | goto cleanup_table; | ||
| 165 | |||
| 166 | return ret; | ||
| 167 | |||
| 168 | cleanup_table: | ||
| 169 | unregister_pernet_subsys(&iptable_security_net_ops); | ||
| 170 | return ret; | ||
| 171 | } | ||
| 172 | |||
| 173 | static void __exit iptable_security_fini(void) | ||
| 174 | { | ||
| 175 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | ||
| 176 | unregister_pernet_subsys(&iptable_security_net_ops); | ||
| 177 | } | ||
| 178 | |||
| 179 | module_init(iptable_security_init); | ||
| 180 | module_exit(iptable_security_fini); | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 40a46d482490..3a020720e40b 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
| @@ -18,19 +18,7 @@ | |||
| 18 | #include <net/netfilter/nf_conntrack_l3proto.h> | 18 | #include <net/netfilter/nf_conntrack_l3proto.h> |
| 19 | #include <net/netfilter/nf_conntrack_l4proto.h> | 19 | #include <net/netfilter/nf_conntrack_l4proto.h> |
| 20 | #include <net/netfilter/nf_conntrack_expect.h> | 20 | #include <net/netfilter/nf_conntrack_expect.h> |
| 21 | 21 | #include <net/netfilter/nf_conntrack_acct.h> | |
| 22 | #ifdef CONFIG_NF_CT_ACCT | ||
| 23 | static unsigned int | ||
| 24 | seq_print_counters(struct seq_file *s, | ||
| 25 | const struct ip_conntrack_counter *counter) | ||
| 26 | { | ||
| 27 | return seq_printf(s, "packets=%llu bytes=%llu ", | ||
| 28 | (unsigned long long)counter->packets, | ||
| 29 | (unsigned long long)counter->bytes); | ||
| 30 | } | ||
| 31 | #else | ||
| 32 | #define seq_print_counters(x, y) 0 | ||
| 33 | #endif | ||
| 34 | 22 | ||
| 35 | struct ct_iter_state { | 23 | struct ct_iter_state { |
| 36 | unsigned int bucket; | 24 | unsigned int bucket; |
| @@ -127,7 +115,7 @@ static int ct_seq_show(struct seq_file *s, void *v) | |||
| 127 | l3proto, l4proto)) | 115 | l3proto, l4proto)) |
| 128 | return -ENOSPC; | 116 | return -ENOSPC; |
| 129 | 117 | ||
| 130 | if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL])) | 118 | if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) |
| 131 | return -ENOSPC; | 119 | return -ENOSPC; |
| 132 | 120 | ||
| 133 | if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) | 121 | if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) |
| @@ -138,7 +126,7 @@ static int ct_seq_show(struct seq_file *s, void *v) | |||
| 138 | l3proto, l4proto)) | 126 | l3proto, l4proto)) |
| 139 | return -ENOSPC; | 127 | return -ENOSPC; |
| 140 | 128 | ||
| 141 | if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY])) | 129 | if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) |
| 142 | return -ENOSPC; | 130 | return -ENOSPC; |
| 143 | 131 | ||
| 144 | if (test_bit(IPS_ASSURED_BIT, &ct->status)) | 132 | if (test_bit(IPS_ASSURED_BIT, &ct->status)) |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 78ab19accace..97791048fa9b 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
| @@ -87,9 +87,8 @@ static int icmp_packet(struct nf_conn *ct, | |||
| 87 | means this will only run once even if count hits zero twice | 87 | means this will only run once even if count hits zero twice |
| 88 | (theoretically possible with SMP) */ | 88 | (theoretically possible with SMP) */ |
| 89 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { | 89 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { |
| 90 | if (atomic_dec_and_test(&ct->proto.icmp.count) | 90 | if (atomic_dec_and_test(&ct->proto.icmp.count)) |
| 91 | && del_timer(&ct->timeout)) | 91 | nf_ct_kill_acct(ct, ctinfo, skb); |
| 92 | ct->timeout.function((unsigned long)ct); | ||
| 93 | } else { | 92 | } else { |
| 94 | atomic_inc(&ct->proto.icmp.count); | 93 | atomic_inc(&ct->proto.icmp.count); |
| 95 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); | 94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index d2a887fc8d9b..6c6a3cba8d50 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
| @@ -240,12 +240,12 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
| 240 | This is only required for source (ie. NAT/masq) mappings. | 240 | This is only required for source (ie. NAT/masq) mappings. |
| 241 | So far, we don't do local source mappings, so multiple | 241 | So far, we don't do local source mappings, so multiple |
| 242 | manips not an issue. */ | 242 | manips not an issue. */ |
| 243 | if (maniptype == IP_NAT_MANIP_SRC) { | 243 | if (maniptype == IP_NAT_MANIP_SRC && |
| 244 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { | ||
| 244 | if (find_appropriate_src(orig_tuple, tuple, range)) { | 245 | if (find_appropriate_src(orig_tuple, tuple, range)) { |
| 245 | pr_debug("get_unique_tuple: Found current src map\n"); | 246 | pr_debug("get_unique_tuple: Found current src map\n"); |
| 246 | if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) | 247 | if (!nf_nat_used_tuple(tuple, ct)) |
| 247 | if (!nf_nat_used_tuple(tuple, ct)) | 248 | return; |
| 248 | return; | ||
| 249 | } | 249 | } |
| 250 | } | 250 | } |
| 251 | 251 | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c index 82e4c0e286b8..65e470bc6123 100644 --- a/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c | |||
| @@ -36,7 +36,7 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
| 36 | sctp_sctphdr_t *hdr; | 36 | sctp_sctphdr_t *hdr; |
| 37 | unsigned int hdroff = iphdroff + iph->ihl*4; | 37 | unsigned int hdroff = iphdroff + iph->ihl*4; |
| 38 | __be32 oldip, newip; | 38 | __be32 oldip, newip; |
| 39 | u32 crc32; | 39 | __be32 crc32; |
| 40 | 40 | ||
| 41 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) | 41 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) |
| 42 | return false; | 42 | return false; |
| @@ -61,7 +61,7 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
| 61 | crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), | 61 | crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), |
| 62 | crc32); | 62 | crc32); |
| 63 | crc32 = sctp_end_cksum(crc32); | 63 | crc32 = sctp_end_cksum(crc32); |
| 64 | hdr->checksum = htonl(crc32); | 64 | hdr->checksum = crc32; |
| 65 | 65 | ||
| 66 | return true; | 66 | return true; |
| 67 | } | 67 | } |
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 4334d5cabc5b..14544320c545 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c | |||
| @@ -318,11 +318,11 @@ static int mangle_content_len(struct sk_buff *skb, | |||
| 318 | buffer, buflen); | 318 | buffer, buflen); |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr, | 321 | static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr, |
| 322 | unsigned int dataoff, unsigned int *datalen, | 322 | unsigned int dataoff, unsigned int *datalen, |
| 323 | enum sdp_header_types type, | 323 | enum sdp_header_types type, |
| 324 | enum sdp_header_types term, | 324 | enum sdp_header_types term, |
| 325 | char *buffer, int buflen) | 325 | char *buffer, int buflen) |
| 326 | { | 326 | { |
| 327 | enum ip_conntrack_info ctinfo; | 327 | enum ip_conntrack_info ctinfo; |
| 328 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | 328 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); |
| @@ -330,9 +330,9 @@ static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr, | |||
| 330 | 330 | ||
| 331 | if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term, | 331 | if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term, |
| 332 | &matchoff, &matchlen) <= 0) | 332 | &matchoff, &matchlen) <= 0) |
| 333 | return 0; | 333 | return -ENOENT; |
| 334 | return mangle_packet(skb, dptr, datalen, matchoff, matchlen, | 334 | return mangle_packet(skb, dptr, datalen, matchoff, matchlen, |
| 335 | buffer, buflen); | 335 | buffer, buflen) ? 0 : -EINVAL; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, | 338 | static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, |
| @@ -346,8 +346,8 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, | |||
| 346 | unsigned int buflen; | 346 | unsigned int buflen; |
| 347 | 347 | ||
| 348 | buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip)); | 348 | buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip)); |
| 349 | if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term, | 349 | if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term, |
| 350 | buffer, buflen)) | 350 | buffer, buflen)) |
| 351 | return 0; | 351 | return 0; |
| 352 | 352 | ||
| 353 | return mangle_content_len(skb, dptr, datalen); | 353 | return mangle_content_len(skb, dptr, datalen); |
| @@ -381,15 +381,27 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr, | |||
| 381 | 381 | ||
| 382 | /* Mangle session description owner and contact addresses */ | 382 | /* Mangle session description owner and contact addresses */ |
| 383 | buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip)); | 383 | buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip)); |
| 384 | if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, | 384 | if (mangle_sdp_packet(skb, dptr, dataoff, datalen, |
| 385 | SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA, | 385 | SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA, |
| 386 | buffer, buflen)) | 386 | buffer, buflen)) |
| 387 | return 0; | 387 | return 0; |
| 388 | 388 | ||
| 389 | if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, | 389 | switch (mangle_sdp_packet(skb, dptr, dataoff, datalen, |
| 390 | SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA, | 390 | SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA, |
| 391 | buffer, buflen)) | 391 | buffer, buflen)) { |
| 392 | case 0: | ||
| 393 | /* | ||
| 394 | * RFC 2327: | ||
| 395 | * | ||
| 396 | * Session description | ||
| 397 | * | ||
| 398 | * c=* (connection information - not required if included in all media) | ||
| 399 | */ | ||
| 400 | case -ENOENT: | ||
| 401 | break; | ||
| 402 | default: | ||
| 392 | return 0; | 403 | return 0; |
| 404 | } | ||
| 393 | 405 | ||
| 394 | return mangle_content_len(skb, dptr, datalen); | 406 | return mangle_content_len(skb, dptr, datalen); |
| 395 | } | 407 | } |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 552169b41b16..834356ea99df 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -7,8 +7,6 @@ | |||
| 7 | * PROC file system. It is mainly used for debugging and | 7 | * PROC file system. It is mainly used for debugging and |
| 8 | * statistics. | 8 | * statistics. |
| 9 | * | 9 | * |
| 10 | * Version: $Id: proc.c,v 1.45 2001/05/16 16:45:35 davem Exp $ | ||
| 11 | * | ||
| 12 | * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 10 | * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 13 | * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> | 11 | * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> |
| 14 | * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> | 12 | * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> |
| @@ -73,32 +71,7 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) | |||
| 73 | 71 | ||
| 74 | static int sockstat_seq_open(struct inode *inode, struct file *file) | 72 | static int sockstat_seq_open(struct inode *inode, struct file *file) |
| 75 | { | 73 | { |
| 76 | int err; | 74 | return single_open_net(inode, file, sockstat_seq_show); |
| 77 | struct net *net; | ||
| 78 | |||
| 79 | err = -ENXIO; | ||
| 80 | net = get_proc_net(inode); | ||
| 81 | if (net == NULL) | ||
| 82 | goto err_net; | ||
| 83 | |||
| 84 | err = single_open(file, sockstat_seq_show, net); | ||
| 85 | if (err < 0) | ||
| 86 | goto err_open; | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | |||
| 90 | err_open: | ||
| 91 | put_net(net); | ||
| 92 | err_net: | ||
| 93 | return err; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int sockstat_seq_release(struct inode *inode, struct file *file) | ||
| 97 | { | ||
| 98 | struct net *net = ((struct seq_file *)file->private_data)->private; | ||
| 99 | |||
| 100 | put_net(net); | ||
| 101 | return single_release(inode, file); | ||
| 102 | } | 75 | } |
| 103 | 76 | ||
| 104 | static const struct file_operations sockstat_seq_fops = { | 77 | static const struct file_operations sockstat_seq_fops = { |
| @@ -106,7 +79,7 @@ static const struct file_operations sockstat_seq_fops = { | |||
| 106 | .open = sockstat_seq_open, | 79 | .open = sockstat_seq_open, |
| 107 | .read = seq_read, | 80 | .read = seq_read, |
| 108 | .llseek = seq_lseek, | 81 | .llseek = seq_lseek, |
| 109 | .release = sockstat_seq_release, | 82 | .release = single_release_net, |
| 110 | }; | 83 | }; |
| 111 | 84 | ||
| 112 | /* snmp items */ | 85 | /* snmp items */ |
| @@ -268,11 +241,12 @@ static void icmpmsg_put(struct seq_file *seq) | |||
| 268 | 241 | ||
| 269 | int j, i, count; | 242 | int j, i, count; |
| 270 | static int out[PERLINE]; | 243 | static int out[PERLINE]; |
| 244 | struct net *net = seq->private; | ||
| 271 | 245 | ||
| 272 | count = 0; | 246 | count = 0; |
| 273 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { | 247 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
| 274 | 248 | ||
| 275 | if (snmp_fold_field((void **) icmpmsg_statistics, i)) | 249 | if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i)) |
| 276 | out[count++] = i; | 250 | out[count++] = i; |
| 277 | if (count < PERLINE) | 251 | if (count < PERLINE) |
| 278 | continue; | 252 | continue; |
| @@ -284,7 +258,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
| 284 | seq_printf(seq, "\nIcmpMsg: "); | 258 | seq_printf(seq, "\nIcmpMsg: "); |
| 285 | for (j = 0; j < PERLINE; ++j) | 259 | for (j = 0; j < PERLINE; ++j) |
| 286 | seq_printf(seq, " %lu", | 260 | seq_printf(seq, " %lu", |
| 287 | snmp_fold_field((void **) icmpmsg_statistics, | 261 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
| 288 | out[j])); | 262 | out[j])); |
| 289 | seq_putc(seq, '\n'); | 263 | seq_putc(seq, '\n'); |
| 290 | } | 264 | } |
| @@ -296,7 +270,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
| 296 | seq_printf(seq, "\nIcmpMsg:"); | 270 | seq_printf(seq, "\nIcmpMsg:"); |
| 297 | for (j = 0; j < count; ++j) | 271 | for (j = 0; j < count; ++j) |
| 298 | seq_printf(seq, " %lu", snmp_fold_field((void **) | 272 | seq_printf(seq, " %lu", snmp_fold_field((void **) |
| 299 | icmpmsg_statistics, out[j])); | 273 | net->mib.icmpmsg_statistics, out[j])); |
| 300 | } | 274 | } |
| 301 | 275 | ||
| 302 | #undef PERLINE | 276 | #undef PERLINE |
| @@ -305,6 +279,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
| 305 | static void icmp_put(struct seq_file *seq) | 279 | static void icmp_put(struct seq_file *seq) |
| 306 | { | 280 | { |
| 307 | int i; | 281 | int i; |
| 282 | struct net *net = seq->private; | ||
| 308 | 283 | ||
| 309 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); | 284 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); |
| 310 | for (i=0; icmpmibmap[i].name != NULL; i++) | 285 | for (i=0; icmpmibmap[i].name != NULL; i++) |
| @@ -313,18 +288,18 @@ static void icmp_put(struct seq_file *seq) | |||
| 313 | for (i=0; icmpmibmap[i].name != NULL; i++) | 288 | for (i=0; icmpmibmap[i].name != NULL; i++) |
| 314 | seq_printf(seq, " Out%s", icmpmibmap[i].name); | 289 | seq_printf(seq, " Out%s", icmpmibmap[i].name); |
| 315 | seq_printf(seq, "\nIcmp: %lu %lu", | 290 | seq_printf(seq, "\nIcmp: %lu %lu", |
| 316 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INMSGS), | 291 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INMSGS), |
| 317 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INERRORS)); | 292 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INERRORS)); |
| 318 | for (i=0; icmpmibmap[i].name != NULL; i++) | 293 | for (i=0; icmpmibmap[i].name != NULL; i++) |
| 319 | seq_printf(seq, " %lu", | 294 | seq_printf(seq, " %lu", |
| 320 | snmp_fold_field((void **) icmpmsg_statistics, | 295 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
| 321 | icmpmibmap[i].index)); | 296 | icmpmibmap[i].index)); |
| 322 | seq_printf(seq, " %lu %lu", | 297 | seq_printf(seq, " %lu %lu", |
| 323 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTMSGS), | 298 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS), |
| 324 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTERRORS)); | 299 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS)); |
| 325 | for (i=0; icmpmibmap[i].name != NULL; i++) | 300 | for (i=0; icmpmibmap[i].name != NULL; i++) |
| 326 | seq_printf(seq, " %lu", | 301 | seq_printf(seq, " %lu", |
| 327 | snmp_fold_field((void **) icmpmsg_statistics, | 302 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
| 328 | icmpmibmap[i].index | 0x100)); | 303 | icmpmibmap[i].index | 0x100)); |
| 329 | } | 304 | } |
| 330 | 305 | ||
| @@ -334,6 +309,7 @@ static void icmp_put(struct seq_file *seq) | |||
| 334 | static int snmp_seq_show(struct seq_file *seq, void *v) | 309 | static int snmp_seq_show(struct seq_file *seq, void *v) |
| 335 | { | 310 | { |
| 336 | int i; | 311 | int i; |
| 312 | struct net *net = seq->private; | ||
| 337 | 313 | ||
| 338 | seq_puts(seq, "Ip: Forwarding DefaultTTL"); | 314 | seq_puts(seq, "Ip: Forwarding DefaultTTL"); |
| 339 | 315 | ||
| @@ -341,12 +317,12 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 341 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); | 317 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); |
| 342 | 318 | ||
| 343 | seq_printf(seq, "\nIp: %d %d", | 319 | seq_printf(seq, "\nIp: %d %d", |
| 344 | IPV4_DEVCONF_ALL(&init_net, FORWARDING) ? 1 : 2, | 320 | IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2, |
| 345 | sysctl_ip_default_ttl); | 321 | sysctl_ip_default_ttl); |
| 346 | 322 | ||
| 347 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) | 323 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) |
| 348 | seq_printf(seq, " %lu", | 324 | seq_printf(seq, " %lu", |
| 349 | snmp_fold_field((void **)ip_statistics, | 325 | snmp_fold_field((void **)net->mib.ip_statistics, |
| 350 | snmp4_ipstats_list[i].entry)); | 326 | snmp4_ipstats_list[i].entry)); |
| 351 | 327 | ||
| 352 | icmp_put(seq); /* RFC 2011 compatibility */ | 328 | icmp_put(seq); /* RFC 2011 compatibility */ |
| @@ -361,11 +337,11 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 361 | /* MaxConn field is signed, RFC 2012 */ | 337 | /* MaxConn field is signed, RFC 2012 */ |
| 362 | if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) | 338 | if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) |
| 363 | seq_printf(seq, " %ld", | 339 | seq_printf(seq, " %ld", |
| 364 | snmp_fold_field((void **)tcp_statistics, | 340 | snmp_fold_field((void **)net->mib.tcp_statistics, |
| 365 | snmp4_tcp_list[i].entry)); | 341 | snmp4_tcp_list[i].entry)); |
| 366 | else | 342 | else |
| 367 | seq_printf(seq, " %lu", | 343 | seq_printf(seq, " %lu", |
| 368 | snmp_fold_field((void **)tcp_statistics, | 344 | snmp_fold_field((void **)net->mib.tcp_statistics, |
| 369 | snmp4_tcp_list[i].entry)); | 345 | snmp4_tcp_list[i].entry)); |
| 370 | } | 346 | } |
| 371 | 347 | ||
| @@ -376,7 +352,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 376 | seq_puts(seq, "\nUdp:"); | 352 | seq_puts(seq, "\nUdp:"); |
| 377 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) | 353 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) |
| 378 | seq_printf(seq, " %lu", | 354 | seq_printf(seq, " %lu", |
| 379 | snmp_fold_field((void **)udp_statistics, | 355 | snmp_fold_field((void **)net->mib.udp_statistics, |
| 380 | snmp4_udp_list[i].entry)); | 356 | snmp4_udp_list[i].entry)); |
| 381 | 357 | ||
| 382 | /* the UDP and UDP-Lite MIBs are the same */ | 358 | /* the UDP and UDP-Lite MIBs are the same */ |
| @@ -387,7 +363,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 387 | seq_puts(seq, "\nUdpLite:"); | 363 | seq_puts(seq, "\nUdpLite:"); |
| 388 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) | 364 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) |
| 389 | seq_printf(seq, " %lu", | 365 | seq_printf(seq, " %lu", |
| 390 | snmp_fold_field((void **)udplite_statistics, | 366 | snmp_fold_field((void **)net->mib.udplite_statistics, |
| 391 | snmp4_udp_list[i].entry)); | 367 | snmp4_udp_list[i].entry)); |
| 392 | 368 | ||
| 393 | seq_putc(seq, '\n'); | 369 | seq_putc(seq, '\n'); |
| @@ -396,7 +372,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
| 396 | 372 | ||
| 397 | static int snmp_seq_open(struct inode *inode, struct file *file) | 373 | static int snmp_seq_open(struct inode *inode, struct file *file) |
| 398 | { | 374 | { |
| 399 | return single_open(file, snmp_seq_show, NULL); | 375 | return single_open_net(inode, file, snmp_seq_show); |
| 400 | } | 376 | } |
| 401 | 377 | ||
| 402 | static const struct file_operations snmp_seq_fops = { | 378 | static const struct file_operations snmp_seq_fops = { |
| @@ -404,7 +380,7 @@ static const struct file_operations snmp_seq_fops = { | |||
| 404 | .open = snmp_seq_open, | 380 | .open = snmp_seq_open, |
| 405 | .read = seq_read, | 381 | .read = seq_read, |
| 406 | .llseek = seq_lseek, | 382 | .llseek = seq_lseek, |
| 407 | .release = single_release, | 383 | .release = single_release_net, |
| 408 | }; | 384 | }; |
| 409 | 385 | ||
| 410 | 386 | ||
| @@ -415,6 +391,7 @@ static const struct file_operations snmp_seq_fops = { | |||
| 415 | static int netstat_seq_show(struct seq_file *seq, void *v) | 391 | static int netstat_seq_show(struct seq_file *seq, void *v) |
| 416 | { | 392 | { |
| 417 | int i; | 393 | int i; |
| 394 | struct net *net = seq->private; | ||
| 418 | 395 | ||
| 419 | seq_puts(seq, "TcpExt:"); | 396 | seq_puts(seq, "TcpExt:"); |
| 420 | for (i = 0; snmp4_net_list[i].name != NULL; i++) | 397 | for (i = 0; snmp4_net_list[i].name != NULL; i++) |
| @@ -423,7 +400,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
| 423 | seq_puts(seq, "\nTcpExt:"); | 400 | seq_puts(seq, "\nTcpExt:"); |
| 424 | for (i = 0; snmp4_net_list[i].name != NULL; i++) | 401 | for (i = 0; snmp4_net_list[i].name != NULL; i++) |
| 425 | seq_printf(seq, " %lu", | 402 | seq_printf(seq, " %lu", |
| 426 | snmp_fold_field((void **)net_statistics, | 403 | snmp_fold_field((void **)net->mib.net_statistics, |
| 427 | snmp4_net_list[i].entry)); | 404 | snmp4_net_list[i].entry)); |
| 428 | 405 | ||
| 429 | seq_puts(seq, "\nIpExt:"); | 406 | seq_puts(seq, "\nIpExt:"); |
| @@ -433,7 +410,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
| 433 | seq_puts(seq, "\nIpExt:"); | 410 | seq_puts(seq, "\nIpExt:"); |
| 434 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) | 411 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) |
| 435 | seq_printf(seq, " %lu", | 412 | seq_printf(seq, " %lu", |
| 436 | snmp_fold_field((void **)ip_statistics, | 413 | snmp_fold_field((void **)net->mib.ip_statistics, |
| 437 | snmp4_ipextstats_list[i].entry)); | 414 | snmp4_ipextstats_list[i].entry)); |
| 438 | 415 | ||
| 439 | seq_putc(seq, '\n'); | 416 | seq_putc(seq, '\n'); |
| @@ -442,7 +419,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
| 442 | 419 | ||
| 443 | static int netstat_seq_open(struct inode *inode, struct file *file) | 420 | static int netstat_seq_open(struct inode *inode, struct file *file) |
| 444 | { | 421 | { |
| 445 | return single_open(file, netstat_seq_show, NULL); | 422 | return single_open_net(inode, file, netstat_seq_show); |
| 446 | } | 423 | } |
| 447 | 424 | ||
| 448 | static const struct file_operations netstat_seq_fops = { | 425 | static const struct file_operations netstat_seq_fops = { |
| @@ -450,18 +427,32 @@ static const struct file_operations netstat_seq_fops = { | |||
| 450 | .open = netstat_seq_open, | 427 | .open = netstat_seq_open, |
| 451 | .read = seq_read, | 428 | .read = seq_read, |
| 452 | .llseek = seq_lseek, | 429 | .llseek = seq_lseek, |
| 453 | .release = single_release, | 430 | .release = single_release_net, |
| 454 | }; | 431 | }; |
| 455 | 432 | ||
| 456 | static __net_init int ip_proc_init_net(struct net *net) | 433 | static __net_init int ip_proc_init_net(struct net *net) |
| 457 | { | 434 | { |
| 458 | if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) | 435 | if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) |
| 459 | return -ENOMEM; | 436 | goto out_sockstat; |
| 437 | if (!proc_net_fops_create(net, "netstat", S_IRUGO, &netstat_seq_fops)) | ||
| 438 | goto out_netstat; | ||
| 439 | if (!proc_net_fops_create(net, "snmp", S_IRUGO, &snmp_seq_fops)) | ||
| 440 | goto out_snmp; | ||
| 441 | |||
| 460 | return 0; | 442 | return 0; |
| 443 | |||
| 444 | out_snmp: | ||
| 445 | proc_net_remove(net, "netstat"); | ||
| 446 | out_netstat: | ||
| 447 | proc_net_remove(net, "sockstat"); | ||
| 448 | out_sockstat: | ||
| 449 | return -ENOMEM; | ||
| 461 | } | 450 | } |
| 462 | 451 | ||
| 463 | static __net_exit void ip_proc_exit_net(struct net *net) | 452 | static __net_exit void ip_proc_exit_net(struct net *net) |
| 464 | { | 453 | { |
| 454 | proc_net_remove(net, "snmp"); | ||
| 455 | proc_net_remove(net, "netstat"); | ||
| 465 | proc_net_remove(net, "sockstat"); | 456 | proc_net_remove(net, "sockstat"); |
| 466 | } | 457 | } |
| 467 | 458 | ||
| @@ -472,24 +463,6 @@ static __net_initdata struct pernet_operations ip_proc_ops = { | |||
| 472 | 463 | ||
| 473 | int __init ip_misc_proc_init(void) | 464 | int __init ip_misc_proc_init(void) |
| 474 | { | 465 | { |
| 475 | int rc = 0; | 466 | return register_pernet_subsys(&ip_proc_ops); |
| 476 | |||
| 477 | if (register_pernet_subsys(&ip_proc_ops)) | ||
| 478 | goto out_pernet; | ||
| 479 | |||
| 480 | if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops)) | ||
| 481 | goto out_netstat; | ||
| 482 | |||
| 483 | if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) | ||
| 484 | goto out_snmp; | ||
| 485 | out: | ||
| 486 | return rc; | ||
| 487 | out_snmp: | ||
| 488 | proc_net_remove(&init_net, "netstat"); | ||
| 489 | out_netstat: | ||
| 490 | unregister_pernet_subsys(&ip_proc_ops); | ||
| 491 | out_pernet: | ||
| 492 | rc = -ENOMEM; | ||
| 493 | goto out; | ||
| 494 | } | 467 | } |
| 495 | 468 | ||
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index 971ab9356e51..ea50da0649fd 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * INET protocol dispatch tables. | 6 | * INET protocol dispatch tables. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * | 10 | * |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 37a1ecd9d600..cd975743bcd2 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * RAW - implementation of IP "raw" sockets. | 6 | * RAW - implementation of IP "raw" sockets. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * | 10 | * |
| @@ -322,6 +320,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 322 | unsigned int flags) | 320 | unsigned int flags) |
| 323 | { | 321 | { |
| 324 | struct inet_sock *inet = inet_sk(sk); | 322 | struct inet_sock *inet = inet_sk(sk); |
| 323 | struct net *net = sock_net(sk); | ||
| 325 | struct iphdr *iph; | 324 | struct iphdr *iph; |
| 326 | struct sk_buff *skb; | 325 | struct sk_buff *skb; |
| 327 | unsigned int iphlen; | 326 | unsigned int iphlen; |
| @@ -370,7 +369,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 370 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); | 369 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); |
| 371 | } | 370 | } |
| 372 | if (iph->protocol == IPPROTO_ICMP) | 371 | if (iph->protocol == IPPROTO_ICMP) |
| 373 | icmp_out_count(((struct icmphdr *) | 372 | icmp_out_count(net, ((struct icmphdr *) |
| 374 | skb_transport_header(skb))->type); | 373 | skb_transport_header(skb))->type); |
| 375 | 374 | ||
| 376 | err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, | 375 | err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, |
| @@ -386,7 +385,7 @@ error_fault: | |||
| 386 | err = -EFAULT; | 385 | err = -EFAULT; |
| 387 | kfree_skb(skb); | 386 | kfree_skb(skb); |
| 388 | error: | 387 | error: |
| 389 | IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 388 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |
| 390 | return err; | 389 | return err; |
| 391 | } | 390 | } |
| 392 | 391 | ||
| @@ -608,12 +607,11 @@ static void raw_close(struct sock *sk, long timeout) | |||
| 608 | sk_common_release(sk); | 607 | sk_common_release(sk); |
| 609 | } | 608 | } |
| 610 | 609 | ||
| 611 | static int raw_destroy(struct sock *sk) | 610 | static void raw_destroy(struct sock *sk) |
| 612 | { | 611 | { |
| 613 | lock_sock(sk); | 612 | lock_sock(sk); |
| 614 | ip_flush_pending_frames(sk); | 613 | ip_flush_pending_frames(sk); |
| 615 | release_sock(sk); | 614 | release_sock(sk); |
| 616 | return 0; | ||
| 617 | } | 615 | } |
| 618 | 616 | ||
| 619 | /* This gets rid of all the nasties in af_inet. -DaveM */ | 617 | /* This gets rid of all the nasties in af_inet. -DaveM */ |
| @@ -947,7 +945,7 @@ static int raw_seq_show(struct seq_file *seq, void *v) | |||
| 947 | if (v == SEQ_START_TOKEN) | 945 | if (v == SEQ_START_TOKEN) |
| 948 | seq_printf(seq, " sl local_address rem_address st tx_queue " | 946 | seq_printf(seq, " sl local_address rem_address st tx_queue " |
| 949 | "rx_queue tr tm->when retrnsmt uid timeout " | 947 | "rx_queue tr tm->when retrnsmt uid timeout " |
| 950 | "inode drops\n"); | 948 | "inode ref pointer drops\n"); |
| 951 | else | 949 | else |
| 952 | raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket); | 950 | raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket); |
| 953 | return 0; | 951 | return 0; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 96be336064fb..e4ab0ac94f92 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * ROUTE - implementation of the IP router. | 6 | * ROUTE - implementation of the IP router. |
| 7 | * | 7 | * |
| 8 | * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 10 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
| @@ -134,7 +132,6 @@ static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; | |||
| 134 | 132 | ||
| 135 | static void rt_worker_func(struct work_struct *work); | 133 | static void rt_worker_func(struct work_struct *work); |
| 136 | static DECLARE_DELAYED_WORK(expires_work, rt_worker_func); | 134 | static DECLARE_DELAYED_WORK(expires_work, rt_worker_func); |
| 137 | static struct timer_list rt_secret_timer; | ||
| 138 | 135 | ||
| 139 | /* | 136 | /* |
| 140 | * Interface to generic destination cache. | 137 | * Interface to generic destination cache. |
| @@ -253,20 +250,25 @@ static inline void rt_hash_lock_init(void) | |||
| 253 | static struct rt_hash_bucket *rt_hash_table __read_mostly; | 250 | static struct rt_hash_bucket *rt_hash_table __read_mostly; |
| 254 | static unsigned rt_hash_mask __read_mostly; | 251 | static unsigned rt_hash_mask __read_mostly; |
| 255 | static unsigned int rt_hash_log __read_mostly; | 252 | static unsigned int rt_hash_log __read_mostly; |
| 256 | static atomic_t rt_genid __read_mostly; | ||
| 257 | 253 | ||
| 258 | static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); | 254 | static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); |
| 259 | #define RT_CACHE_STAT_INC(field) \ | 255 | #define RT_CACHE_STAT_INC(field) \ |
| 260 | (__raw_get_cpu_var(rt_cache_stat).field++) | 256 | (__raw_get_cpu_var(rt_cache_stat).field++) |
| 261 | 257 | ||
| 262 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx) | 258 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx, |
| 259 | int genid) | ||
| 263 | { | 260 | { |
| 264 | return jhash_3words((__force u32)(__be32)(daddr), | 261 | return jhash_3words((__force u32)(__be32)(daddr), |
| 265 | (__force u32)(__be32)(saddr), | 262 | (__force u32)(__be32)(saddr), |
| 266 | idx, atomic_read(&rt_genid)) | 263 | idx, genid) |
| 267 | & rt_hash_mask; | 264 | & rt_hash_mask; |
| 268 | } | 265 | } |
| 269 | 266 | ||
| 267 | static inline int rt_genid(struct net *net) | ||
| 268 | { | ||
| 269 | return atomic_read(&net->ipv4.rt_genid); | ||
| 270 | } | ||
| 271 | |||
| 270 | #ifdef CONFIG_PROC_FS | 272 | #ifdef CONFIG_PROC_FS |
| 271 | struct rt_cache_iter_state { | 273 | struct rt_cache_iter_state { |
| 272 | struct seq_net_private p; | 274 | struct seq_net_private p; |
| @@ -336,7 +338,7 @@ static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos) | |||
| 336 | struct rt_cache_iter_state *st = seq->private; | 338 | struct rt_cache_iter_state *st = seq->private; |
| 337 | if (*pos) | 339 | if (*pos) |
| 338 | return rt_cache_get_idx(seq, *pos - 1); | 340 | return rt_cache_get_idx(seq, *pos - 1); |
| 339 | st->genid = atomic_read(&rt_genid); | 341 | st->genid = rt_genid(seq_file_net(seq)); |
| 340 | return SEQ_START_TOKEN; | 342 | return SEQ_START_TOKEN; |
| 341 | } | 343 | } |
| 342 | 344 | ||
| @@ -683,6 +685,11 @@ static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | |||
| 683 | return dev_net(rt1->u.dst.dev) == dev_net(rt2->u.dst.dev); | 685 | return dev_net(rt1->u.dst.dev) == dev_net(rt2->u.dst.dev); |
| 684 | } | 686 | } |
| 685 | 687 | ||
| 688 | static inline int rt_is_expired(struct rtable *rth) | ||
| 689 | { | ||
| 690 | return rth->rt_genid != rt_genid(dev_net(rth->u.dst.dev)); | ||
| 691 | } | ||
| 692 | |||
| 686 | /* | 693 | /* |
| 687 | * Perform a full scan of hash table and free all entries. | 694 | * Perform a full scan of hash table and free all entries. |
| 688 | * Can be called by a softirq or a process. | 695 | * Can be called by a softirq or a process. |
| @@ -692,6 +699,7 @@ static void rt_do_flush(int process_context) | |||
| 692 | { | 699 | { |
| 693 | unsigned int i; | 700 | unsigned int i; |
| 694 | struct rtable *rth, *next; | 701 | struct rtable *rth, *next; |
| 702 | struct rtable * tail; | ||
| 695 | 703 | ||
| 696 | for (i = 0; i <= rt_hash_mask; i++) { | 704 | for (i = 0; i <= rt_hash_mask; i++) { |
| 697 | if (process_context && need_resched()) | 705 | if (process_context && need_resched()) |
| @@ -701,11 +709,39 @@ static void rt_do_flush(int process_context) | |||
| 701 | continue; | 709 | continue; |
| 702 | 710 | ||
| 703 | spin_lock_bh(rt_hash_lock_addr(i)); | 711 | spin_lock_bh(rt_hash_lock_addr(i)); |
| 712 | #ifdef CONFIG_NET_NS | ||
| 713 | { | ||
| 714 | struct rtable ** prev, * p; | ||
| 715 | |||
| 716 | rth = rt_hash_table[i].chain; | ||
| 717 | |||
| 718 | /* defer releasing the head of the list after spin_unlock */ | ||
| 719 | for (tail = rth; tail; tail = tail->u.dst.rt_next) | ||
| 720 | if (!rt_is_expired(tail)) | ||
| 721 | break; | ||
| 722 | if (rth != tail) | ||
| 723 | rt_hash_table[i].chain = tail; | ||
| 724 | |||
| 725 | /* call rt_free on entries after the tail requiring flush */ | ||
| 726 | prev = &rt_hash_table[i].chain; | ||
| 727 | for (p = *prev; p; p = next) { | ||
| 728 | next = p->u.dst.rt_next; | ||
| 729 | if (!rt_is_expired(p)) { | ||
| 730 | prev = &p->u.dst.rt_next; | ||
| 731 | } else { | ||
| 732 | *prev = next; | ||
| 733 | rt_free(p); | ||
| 734 | } | ||
| 735 | } | ||
| 736 | } | ||
| 737 | #else | ||
| 704 | rth = rt_hash_table[i].chain; | 738 | rth = rt_hash_table[i].chain; |
| 705 | rt_hash_table[i].chain = NULL; | 739 | rt_hash_table[i].chain = NULL; |
| 740 | tail = NULL; | ||
| 741 | #endif | ||
| 706 | spin_unlock_bh(rt_hash_lock_addr(i)); | 742 | spin_unlock_bh(rt_hash_lock_addr(i)); |
| 707 | 743 | ||
| 708 | for (; rth; rth = next) { | 744 | for (; rth != tail; rth = next) { |
| 709 | next = rth->u.dst.rt_next; | 745 | next = rth->u.dst.rt_next; |
| 710 | rt_free(rth); | 746 | rt_free(rth); |
| 711 | } | 747 | } |
| @@ -738,7 +774,7 @@ static void rt_check_expire(void) | |||
| 738 | continue; | 774 | continue; |
| 739 | spin_lock_bh(rt_hash_lock_addr(i)); | 775 | spin_lock_bh(rt_hash_lock_addr(i)); |
| 740 | while ((rth = *rthp) != NULL) { | 776 | while ((rth = *rthp) != NULL) { |
| 741 | if (rth->rt_genid != atomic_read(&rt_genid)) { | 777 | if (rt_is_expired(rth)) { |
| 742 | *rthp = rth->u.dst.rt_next; | 778 | *rthp = rth->u.dst.rt_next; |
| 743 | rt_free(rth); | 779 | rt_free(rth); |
| 744 | continue; | 780 | continue; |
| @@ -781,21 +817,21 @@ static void rt_worker_func(struct work_struct *work) | |||
| 781 | * many times (2^24) without giving recent rt_genid. | 817 | * many times (2^24) without giving recent rt_genid. |
| 782 | * Jenkins hash is strong enough that litle changes of rt_genid are OK. | 818 | * Jenkins hash is strong enough that litle changes of rt_genid are OK. |
| 783 | */ | 819 | */ |
| 784 | static void rt_cache_invalidate(void) | 820 | static void rt_cache_invalidate(struct net *net) |
| 785 | { | 821 | { |
| 786 | unsigned char shuffle; | 822 | unsigned char shuffle; |
| 787 | 823 | ||
| 788 | get_random_bytes(&shuffle, sizeof(shuffle)); | 824 | get_random_bytes(&shuffle, sizeof(shuffle)); |
| 789 | atomic_add(shuffle + 1U, &rt_genid); | 825 | atomic_add(shuffle + 1U, &net->ipv4.rt_genid); |
| 790 | } | 826 | } |
| 791 | 827 | ||
| 792 | /* | 828 | /* |
| 793 | * delay < 0 : invalidate cache (fast : entries will be deleted later) | 829 | * delay < 0 : invalidate cache (fast : entries will be deleted later) |
| 794 | * delay >= 0 : invalidate & flush cache (can be long) | 830 | * delay >= 0 : invalidate & flush cache (can be long) |
| 795 | */ | 831 | */ |
| 796 | void rt_cache_flush(int delay) | 832 | void rt_cache_flush(struct net *net, int delay) |
| 797 | { | 833 | { |
| 798 | rt_cache_invalidate(); | 834 | rt_cache_invalidate(net); |
| 799 | if (delay >= 0) | 835 | if (delay >= 0) |
| 800 | rt_do_flush(!in_softirq()); | 836 | rt_do_flush(!in_softirq()); |
| 801 | } | 837 | } |
| @@ -803,10 +839,11 @@ void rt_cache_flush(int delay) | |||
| 803 | /* | 839 | /* |
| 804 | * We change rt_genid and let gc do the cleanup | 840 | * We change rt_genid and let gc do the cleanup |
| 805 | */ | 841 | */ |
| 806 | static void rt_secret_rebuild(unsigned long dummy) | 842 | static void rt_secret_rebuild(unsigned long __net) |
| 807 | { | 843 | { |
| 808 | rt_cache_invalidate(); | 844 | struct net *net = (struct net *)__net; |
| 809 | mod_timer(&rt_secret_timer, jiffies + ip_rt_secret_interval); | 845 | rt_cache_invalidate(net); |
| 846 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); | ||
| 810 | } | 847 | } |
| 811 | 848 | ||
| 812 | /* | 849 | /* |
| @@ -882,7 +919,7 @@ static int rt_garbage_collect(struct dst_ops *ops) | |||
| 882 | rthp = &rt_hash_table[k].chain; | 919 | rthp = &rt_hash_table[k].chain; |
| 883 | spin_lock_bh(rt_hash_lock_addr(k)); | 920 | spin_lock_bh(rt_hash_lock_addr(k)); |
| 884 | while ((rth = *rthp) != NULL) { | 921 | while ((rth = *rthp) != NULL) { |
| 885 | if (rth->rt_genid == atomic_read(&rt_genid) && | 922 | if (!rt_is_expired(rth) && |
| 886 | !rt_may_expire(rth, tmo, expire)) { | 923 | !rt_may_expire(rth, tmo, expire)) { |
| 887 | tmo >>= 1; | 924 | tmo >>= 1; |
| 888 | rthp = &rth->u.dst.rt_next; | 925 | rthp = &rth->u.dst.rt_next; |
| @@ -964,7 +1001,7 @@ restart: | |||
| 964 | 1001 | ||
| 965 | spin_lock_bh(rt_hash_lock_addr(hash)); | 1002 | spin_lock_bh(rt_hash_lock_addr(hash)); |
| 966 | while ((rth = *rthp) != NULL) { | 1003 | while ((rth = *rthp) != NULL) { |
| 967 | if (rth->rt_genid != atomic_read(&rt_genid)) { | 1004 | if (rt_is_expired(rth)) { |
| 968 | *rthp = rth->u.dst.rt_next; | 1005 | *rthp = rth->u.dst.rt_next; |
| 969 | rt_free(rth); | 1006 | rt_free(rth); |
| 970 | continue; | 1007 | continue; |
| @@ -1140,7 +1177,7 @@ static void rt_del(unsigned hash, struct rtable *rt) | |||
| 1140 | spin_lock_bh(rt_hash_lock_addr(hash)); | 1177 | spin_lock_bh(rt_hash_lock_addr(hash)); |
| 1141 | ip_rt_put(rt); | 1178 | ip_rt_put(rt); |
| 1142 | while ((aux = *rthp) != NULL) { | 1179 | while ((aux = *rthp) != NULL) { |
| 1143 | if (aux == rt || (aux->rt_genid != atomic_read(&rt_genid))) { | 1180 | if (aux == rt || rt_is_expired(aux)) { |
| 1144 | *rthp = aux->u.dst.rt_next; | 1181 | *rthp = aux->u.dst.rt_next; |
| 1145 | rt_free(aux); | 1182 | rt_free(aux); |
| 1146 | continue; | 1183 | continue; |
| @@ -1182,7 +1219,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
| 1182 | 1219 | ||
| 1183 | for (i = 0; i < 2; i++) { | 1220 | for (i = 0; i < 2; i++) { |
| 1184 | for (k = 0; k < 2; k++) { | 1221 | for (k = 0; k < 2; k++) { |
| 1185 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]); | 1222 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k], |
| 1223 | rt_genid(net)); | ||
| 1186 | 1224 | ||
| 1187 | rthp=&rt_hash_table[hash].chain; | 1225 | rthp=&rt_hash_table[hash].chain; |
| 1188 | 1226 | ||
| @@ -1194,7 +1232,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
| 1194 | rth->fl.fl4_src != skeys[i] || | 1232 | rth->fl.fl4_src != skeys[i] || |
| 1195 | rth->fl.oif != ikeys[k] || | 1233 | rth->fl.oif != ikeys[k] || |
| 1196 | rth->fl.iif != 0 || | 1234 | rth->fl.iif != 0 || |
| 1197 | rth->rt_genid != atomic_read(&rt_genid) || | 1235 | rt_is_expired(rth) || |
| 1198 | !net_eq(dev_net(rth->u.dst.dev), net)) { | 1236 | !net_eq(dev_net(rth->u.dst.dev), net)) { |
| 1199 | rthp = &rth->u.dst.rt_next; | 1237 | rthp = &rth->u.dst.rt_next; |
| 1200 | continue; | 1238 | continue; |
| @@ -1233,7 +1271,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
| 1233 | rt->u.dst.neighbour = NULL; | 1271 | rt->u.dst.neighbour = NULL; |
| 1234 | rt->u.dst.hh = NULL; | 1272 | rt->u.dst.hh = NULL; |
| 1235 | rt->u.dst.xfrm = NULL; | 1273 | rt->u.dst.xfrm = NULL; |
| 1236 | rt->rt_genid = atomic_read(&rt_genid); | 1274 | rt->rt_genid = rt_genid(net); |
| 1237 | rt->rt_flags |= RTCF_REDIRECTED; | 1275 | rt->rt_flags |= RTCF_REDIRECTED; |
| 1238 | 1276 | ||
| 1239 | /* Gateway is different ... */ | 1277 | /* Gateway is different ... */ |
| @@ -1297,7 +1335,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
| 1297 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || | 1335 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || |
| 1298 | rt->u.dst.expires) { | 1336 | rt->u.dst.expires) { |
| 1299 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, | 1337 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, |
| 1300 | rt->fl.oif); | 1338 | rt->fl.oif, |
| 1339 | rt_genid(dev_net(dst->dev))); | ||
| 1301 | #if RT_CACHE_DEBUG >= 1 | 1340 | #if RT_CACHE_DEBUG >= 1 |
| 1302 | printk(KERN_DEBUG "ipv4_negative_advice: redirect to " | 1341 | printk(KERN_DEBUG "ipv4_negative_advice: redirect to " |
| 1303 | NIPQUAD_FMT "/%02x dropped\n", | 1342 | NIPQUAD_FMT "/%02x dropped\n", |
| @@ -1390,7 +1429,8 @@ static int ip_error(struct sk_buff *skb) | |||
| 1390 | break; | 1429 | break; |
| 1391 | case ENETUNREACH: | 1430 | case ENETUNREACH: |
| 1392 | code = ICMP_NET_UNREACH; | 1431 | code = ICMP_NET_UNREACH; |
| 1393 | IP_INC_STATS_BH(IPSTATS_MIB_INNOROUTES); | 1432 | IP_INC_STATS_BH(dev_net(rt->u.dst.dev), |
| 1433 | IPSTATS_MIB_INNOROUTES); | ||
| 1394 | break; | 1434 | break; |
| 1395 | case EACCES: | 1435 | case EACCES: |
| 1396 | code = ICMP_PKT_FILTERED; | 1436 | code = ICMP_PKT_FILTERED; |
| @@ -1446,7 +1486,8 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | |||
| 1446 | 1486 | ||
| 1447 | for (k = 0; k < 2; k++) { | 1487 | for (k = 0; k < 2; k++) { |
| 1448 | for (i = 0; i < 2; i++) { | 1488 | for (i = 0; i < 2; i++) { |
| 1449 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]); | 1489 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k], |
| 1490 | rt_genid(net)); | ||
| 1450 | 1491 | ||
| 1451 | rcu_read_lock(); | 1492 | rcu_read_lock(); |
| 1452 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 1493 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; |
| @@ -1461,7 +1502,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | |||
| 1461 | rth->fl.iif != 0 || | 1502 | rth->fl.iif != 0 || |
| 1462 | dst_metric_locked(&rth->u.dst, RTAX_MTU) || | 1503 | dst_metric_locked(&rth->u.dst, RTAX_MTU) || |
| 1463 | !net_eq(dev_net(rth->u.dst.dev), net) || | 1504 | !net_eq(dev_net(rth->u.dst.dev), net) || |
| 1464 | rth->rt_genid != atomic_read(&rt_genid)) | 1505 | !rt_is_expired(rth)) |
| 1465 | continue; | 1506 | continue; |
| 1466 | 1507 | ||
| 1467 | if (new_mtu < 68 || new_mtu >= old_mtu) { | 1508 | if (new_mtu < 68 || new_mtu >= old_mtu) { |
| @@ -1696,7 +1737,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1696 | rth->fl.oif = 0; | 1737 | rth->fl.oif = 0; |
| 1697 | rth->rt_gateway = daddr; | 1738 | rth->rt_gateway = daddr; |
| 1698 | rth->rt_spec_dst= spec_dst; | 1739 | rth->rt_spec_dst= spec_dst; |
| 1699 | rth->rt_genid = atomic_read(&rt_genid); | 1740 | rth->rt_genid = rt_genid(dev_net(dev)); |
| 1700 | rth->rt_flags = RTCF_MULTICAST; | 1741 | rth->rt_flags = RTCF_MULTICAST; |
| 1701 | rth->rt_type = RTN_MULTICAST; | 1742 | rth->rt_type = RTN_MULTICAST; |
| 1702 | if (our) { | 1743 | if (our) { |
| @@ -1711,7 +1752,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1711 | RT_CACHE_STAT_INC(in_slow_mc); | 1752 | RT_CACHE_STAT_INC(in_slow_mc); |
| 1712 | 1753 | ||
| 1713 | in_dev_put(in_dev); | 1754 | in_dev_put(in_dev); |
| 1714 | hash = rt_hash(daddr, saddr, dev->ifindex); | 1755 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
| 1715 | return rt_intern_hash(hash, rth, &skb->rtable); | 1756 | return rt_intern_hash(hash, rth, &skb->rtable); |
| 1716 | 1757 | ||
| 1717 | e_nobufs: | 1758 | e_nobufs: |
| @@ -1837,7 +1878,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 1837 | 1878 | ||
| 1838 | rth->u.dst.input = ip_forward; | 1879 | rth->u.dst.input = ip_forward; |
| 1839 | rth->u.dst.output = ip_output; | 1880 | rth->u.dst.output = ip_output; |
| 1840 | rth->rt_genid = atomic_read(&rt_genid); | 1881 | rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); |
| 1841 | 1882 | ||
| 1842 | rt_set_nexthop(rth, res, itag); | 1883 | rt_set_nexthop(rth, res, itag); |
| 1843 | 1884 | ||
| @@ -1872,7 +1913,8 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
| 1872 | return err; | 1913 | return err; |
| 1873 | 1914 | ||
| 1874 | /* put it into the cache */ | 1915 | /* put it into the cache */ |
| 1875 | hash = rt_hash(daddr, saddr, fl->iif); | 1916 | hash = rt_hash(daddr, saddr, fl->iif, |
| 1917 | rt_genid(dev_net(rth->u.dst.dev))); | ||
| 1876 | return rt_intern_hash(hash, rth, &skb->rtable); | 1918 | return rt_intern_hash(hash, rth, &skb->rtable); |
| 1877 | } | 1919 | } |
| 1878 | 1920 | ||
| @@ -1998,7 +2040,7 @@ local_input: | |||
| 1998 | goto e_nobufs; | 2040 | goto e_nobufs; |
| 1999 | 2041 | ||
| 2000 | rth->u.dst.output= ip_rt_bug; | 2042 | rth->u.dst.output= ip_rt_bug; |
| 2001 | rth->rt_genid = atomic_read(&rt_genid); | 2043 | rth->rt_genid = rt_genid(net); |
| 2002 | 2044 | ||
| 2003 | atomic_set(&rth->u.dst.__refcnt, 1); | 2045 | atomic_set(&rth->u.dst.__refcnt, 1); |
| 2004 | rth->u.dst.flags= DST_HOST; | 2046 | rth->u.dst.flags= DST_HOST; |
| @@ -2028,7 +2070,7 @@ local_input: | |||
| 2028 | rth->rt_flags &= ~RTCF_LOCAL; | 2070 | rth->rt_flags &= ~RTCF_LOCAL; |
| 2029 | } | 2071 | } |
| 2030 | rth->rt_type = res.type; | 2072 | rth->rt_type = res.type; |
| 2031 | hash = rt_hash(daddr, saddr, fl.iif); | 2073 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
| 2032 | err = rt_intern_hash(hash, rth, &skb->rtable); | 2074 | err = rt_intern_hash(hash, rth, &skb->rtable); |
| 2033 | goto done; | 2075 | goto done; |
| 2034 | 2076 | ||
| @@ -2079,7 +2121,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2079 | 2121 | ||
| 2080 | net = dev_net(dev); | 2122 | net = dev_net(dev); |
| 2081 | tos &= IPTOS_RT_MASK; | 2123 | tos &= IPTOS_RT_MASK; |
| 2082 | hash = rt_hash(daddr, saddr, iif); | 2124 | hash = rt_hash(daddr, saddr, iif, rt_genid(net)); |
| 2083 | 2125 | ||
| 2084 | rcu_read_lock(); | 2126 | rcu_read_lock(); |
| 2085 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 2127 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; |
| @@ -2091,7 +2133,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2091 | (rth->fl.fl4_tos ^ tos)) == 0 && | 2133 | (rth->fl.fl4_tos ^ tos)) == 0 && |
| 2092 | rth->fl.mark == skb->mark && | 2134 | rth->fl.mark == skb->mark && |
| 2093 | net_eq(dev_net(rth->u.dst.dev), net) && | 2135 | net_eq(dev_net(rth->u.dst.dev), net) && |
| 2094 | rth->rt_genid == atomic_read(&rt_genid)) { | 2136 | !rt_is_expired(rth)) { |
| 2095 | dst_use(&rth->u.dst, jiffies); | 2137 | dst_use(&rth->u.dst, jiffies); |
| 2096 | RT_CACHE_STAT_INC(in_hit); | 2138 | RT_CACHE_STAT_INC(in_hit); |
| 2097 | rcu_read_unlock(); | 2139 | rcu_read_unlock(); |
| @@ -2219,7 +2261,7 @@ static int __mkroute_output(struct rtable **result, | |||
| 2219 | rth->rt_spec_dst= fl->fl4_src; | 2261 | rth->rt_spec_dst= fl->fl4_src; |
| 2220 | 2262 | ||
| 2221 | rth->u.dst.output=ip_output; | 2263 | rth->u.dst.output=ip_output; |
| 2222 | rth->rt_genid = atomic_read(&rt_genid); | 2264 | rth->rt_genid = rt_genid(dev_net(dev_out)); |
| 2223 | 2265 | ||
| 2224 | RT_CACHE_STAT_INC(out_slow_tot); | 2266 | RT_CACHE_STAT_INC(out_slow_tot); |
| 2225 | 2267 | ||
| @@ -2268,7 +2310,8 @@ static int ip_mkroute_output(struct rtable **rp, | |||
| 2268 | int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); | 2310 | int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); |
| 2269 | unsigned hash; | 2311 | unsigned hash; |
| 2270 | if (err == 0) { | 2312 | if (err == 0) { |
| 2271 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif); | 2313 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
| 2314 | rt_genid(dev_net(dev_out))); | ||
| 2272 | err = rt_intern_hash(hash, rth, rp); | 2315 | err = rt_intern_hash(hash, rth, rp); |
| 2273 | } | 2316 | } |
| 2274 | 2317 | ||
| @@ -2480,7 +2523,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, | |||
| 2480 | unsigned hash; | 2523 | unsigned hash; |
| 2481 | struct rtable *rth; | 2524 | struct rtable *rth; |
| 2482 | 2525 | ||
| 2483 | hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif); | 2526 | hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif, rt_genid(net)); |
| 2484 | 2527 | ||
| 2485 | rcu_read_lock_bh(); | 2528 | rcu_read_lock_bh(); |
| 2486 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 2529 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; |
| @@ -2493,7 +2536,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, | |||
| 2493 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & | 2536 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & |
| 2494 | (IPTOS_RT_MASK | RTO_ONLINK)) && | 2537 | (IPTOS_RT_MASK | RTO_ONLINK)) && |
| 2495 | net_eq(dev_net(rth->u.dst.dev), net) && | 2538 | net_eq(dev_net(rth->u.dst.dev), net) && |
| 2496 | rth->rt_genid == atomic_read(&rt_genid)) { | 2539 | !rt_is_expired(rth)) { |
| 2497 | dst_use(&rth->u.dst, jiffies); | 2540 | dst_use(&rth->u.dst, jiffies); |
| 2498 | RT_CACHE_STAT_INC(out_hit); | 2541 | RT_CACHE_STAT_INC(out_hit); |
| 2499 | rcu_read_unlock_bh(); | 2542 | rcu_read_unlock_bh(); |
| @@ -2524,7 +2567,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
| 2524 | }; | 2567 | }; |
| 2525 | 2568 | ||
| 2526 | 2569 | ||
| 2527 | static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp) | 2570 | static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi *flp) |
| 2528 | { | 2571 | { |
| 2529 | struct rtable *ort = *rp; | 2572 | struct rtable *ort = *rp; |
| 2530 | struct rtable *rt = (struct rtable *) | 2573 | struct rtable *rt = (struct rtable *) |
| @@ -2548,7 +2591,7 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp) | |||
| 2548 | rt->idev = ort->idev; | 2591 | rt->idev = ort->idev; |
| 2549 | if (rt->idev) | 2592 | if (rt->idev) |
| 2550 | in_dev_hold(rt->idev); | 2593 | in_dev_hold(rt->idev); |
| 2551 | rt->rt_genid = atomic_read(&rt_genid); | 2594 | rt->rt_genid = rt_genid(net); |
| 2552 | rt->rt_flags = ort->rt_flags; | 2595 | rt->rt_flags = ort->rt_flags; |
| 2553 | rt->rt_type = ort->rt_type; | 2596 | rt->rt_type = ort->rt_type; |
| 2554 | rt->rt_dst = ort->rt_dst; | 2597 | rt->rt_dst = ort->rt_dst; |
| @@ -2584,7 +2627,7 @@ int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, | |||
| 2584 | err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, | 2627 | err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, |
| 2585 | flags ? XFRM_LOOKUP_WAIT : 0); | 2628 | flags ? XFRM_LOOKUP_WAIT : 0); |
| 2586 | if (err == -EREMOTE) | 2629 | if (err == -EREMOTE) |
| 2587 | err = ipv4_dst_blackhole(rp, flp); | 2630 | err = ipv4_dst_blackhole(net, rp, flp); |
| 2588 | 2631 | ||
| 2589 | return err; | 2632 | return err; |
| 2590 | } | 2633 | } |
| @@ -2803,7 +2846,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2803 | rt = rcu_dereference(rt->u.dst.rt_next), idx++) { | 2846 | rt = rcu_dereference(rt->u.dst.rt_next), idx++) { |
| 2804 | if (!net_eq(dev_net(rt->u.dst.dev), net) || idx < s_idx) | 2847 | if (!net_eq(dev_net(rt->u.dst.dev), net) || idx < s_idx) |
| 2805 | continue; | 2848 | continue; |
| 2806 | if (rt->rt_genid != atomic_read(&rt_genid)) | 2849 | if (rt_is_expired(rt)) |
| 2807 | continue; | 2850 | continue; |
| 2808 | skb->dst = dst_clone(&rt->u.dst); | 2851 | skb->dst = dst_clone(&rt->u.dst); |
| 2809 | if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid, | 2852 | if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid, |
| @@ -2827,19 +2870,25 @@ done: | |||
| 2827 | 2870 | ||
| 2828 | void ip_rt_multicast_event(struct in_device *in_dev) | 2871 | void ip_rt_multicast_event(struct in_device *in_dev) |
| 2829 | { | 2872 | { |
| 2830 | rt_cache_flush(0); | 2873 | rt_cache_flush(dev_net(in_dev->dev), 0); |
| 2831 | } | 2874 | } |
| 2832 | 2875 | ||
| 2833 | #ifdef CONFIG_SYSCTL | 2876 | #ifdef CONFIG_SYSCTL |
| 2834 | static int flush_delay; | 2877 | static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write, |
| 2835 | |||
| 2836 | static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write, | ||
| 2837 | struct file *filp, void __user *buffer, | 2878 | struct file *filp, void __user *buffer, |
| 2838 | size_t *lenp, loff_t *ppos) | 2879 | size_t *lenp, loff_t *ppos) |
| 2839 | { | 2880 | { |
| 2840 | if (write) { | 2881 | if (write) { |
| 2841 | proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 2882 | int flush_delay; |
| 2842 | rt_cache_flush(flush_delay); | 2883 | ctl_table ctl; |
| 2884 | struct net *net; | ||
| 2885 | |||
| 2886 | memcpy(&ctl, __ctl, sizeof(ctl)); | ||
| 2887 | ctl.data = &flush_delay; | ||
| 2888 | proc_dointvec(&ctl, write, filp, buffer, lenp, ppos); | ||
| 2889 | |||
| 2890 | net = (struct net *)__ctl->extra1; | ||
| 2891 | rt_cache_flush(net, flush_delay); | ||
| 2843 | return 0; | 2892 | return 0; |
| 2844 | } | 2893 | } |
| 2845 | 2894 | ||
| @@ -2855,25 +2904,18 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, | |||
| 2855 | size_t newlen) | 2904 | size_t newlen) |
| 2856 | { | 2905 | { |
| 2857 | int delay; | 2906 | int delay; |
| 2907 | struct net *net; | ||
| 2858 | if (newlen != sizeof(int)) | 2908 | if (newlen != sizeof(int)) |
| 2859 | return -EINVAL; | 2909 | return -EINVAL; |
| 2860 | if (get_user(delay, (int __user *)newval)) | 2910 | if (get_user(delay, (int __user *)newval)) |
| 2861 | return -EFAULT; | 2911 | return -EFAULT; |
| 2862 | rt_cache_flush(delay); | 2912 | net = (struct net *)table->extra1; |
| 2913 | rt_cache_flush(net, delay); | ||
| 2863 | return 0; | 2914 | return 0; |
| 2864 | } | 2915 | } |
| 2865 | 2916 | ||
| 2866 | ctl_table ipv4_route_table[] = { | 2917 | ctl_table ipv4_route_table[] = { |
| 2867 | { | 2918 | { |
| 2868 | .ctl_name = NET_IPV4_ROUTE_FLUSH, | ||
| 2869 | .procname = "flush", | ||
| 2870 | .data = &flush_delay, | ||
| 2871 | .maxlen = sizeof(int), | ||
| 2872 | .mode = 0200, | ||
| 2873 | .proc_handler = &ipv4_sysctl_rtcache_flush, | ||
| 2874 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, | ||
| 2875 | }, | ||
| 2876 | { | ||
| 2877 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, | 2919 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, |
| 2878 | .procname = "gc_thresh", | 2920 | .procname = "gc_thresh", |
| 2879 | .data = &ipv4_dst_ops.gc_thresh, | 2921 | .data = &ipv4_dst_ops.gc_thresh, |
| @@ -3011,8 +3053,97 @@ ctl_table ipv4_route_table[] = { | |||
| 3011 | }, | 3053 | }, |
| 3012 | { .ctl_name = 0 } | 3054 | { .ctl_name = 0 } |
| 3013 | }; | 3055 | }; |
| 3056 | |||
| 3057 | static __net_initdata struct ctl_path ipv4_route_path[] = { | ||
| 3058 | { .procname = "net", .ctl_name = CTL_NET, }, | ||
| 3059 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, | ||
| 3060 | { .procname = "route", .ctl_name = NET_IPV4_ROUTE, }, | ||
| 3061 | { }, | ||
| 3062 | }; | ||
| 3063 | |||
| 3064 | |||
| 3065 | static struct ctl_table ipv4_route_flush_table[] = { | ||
| 3066 | { | ||
| 3067 | .ctl_name = NET_IPV4_ROUTE_FLUSH, | ||
| 3068 | .procname = "flush", | ||
| 3069 | .maxlen = sizeof(int), | ||
| 3070 | .mode = 0200, | ||
| 3071 | .proc_handler = &ipv4_sysctl_rtcache_flush, | ||
| 3072 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, | ||
| 3073 | }, | ||
| 3074 | { .ctl_name = 0 }, | ||
| 3075 | }; | ||
| 3076 | |||
| 3077 | static __net_init int sysctl_route_net_init(struct net *net) | ||
| 3078 | { | ||
| 3079 | struct ctl_table *tbl; | ||
| 3080 | |||
| 3081 | tbl = ipv4_route_flush_table; | ||
| 3082 | if (net != &init_net) { | ||
| 3083 | tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); | ||
| 3084 | if (tbl == NULL) | ||
| 3085 | goto err_dup; | ||
| 3086 | } | ||
| 3087 | tbl[0].extra1 = net; | ||
| 3088 | |||
| 3089 | net->ipv4.route_hdr = | ||
| 3090 | register_net_sysctl_table(net, ipv4_route_path, tbl); | ||
| 3091 | if (net->ipv4.route_hdr == NULL) | ||
| 3092 | goto err_reg; | ||
| 3093 | return 0; | ||
| 3094 | |||
| 3095 | err_reg: | ||
| 3096 | if (tbl != ipv4_route_flush_table) | ||
| 3097 | kfree(tbl); | ||
| 3098 | err_dup: | ||
| 3099 | return -ENOMEM; | ||
| 3100 | } | ||
| 3101 | |||
| 3102 | static __net_exit void sysctl_route_net_exit(struct net *net) | ||
| 3103 | { | ||
| 3104 | struct ctl_table *tbl; | ||
| 3105 | |||
| 3106 | tbl = net->ipv4.route_hdr->ctl_table_arg; | ||
| 3107 | unregister_net_sysctl_table(net->ipv4.route_hdr); | ||
| 3108 | BUG_ON(tbl == ipv4_route_flush_table); | ||
| 3109 | kfree(tbl); | ||
| 3110 | } | ||
| 3111 | |||
| 3112 | static __net_initdata struct pernet_operations sysctl_route_ops = { | ||
| 3113 | .init = sysctl_route_net_init, | ||
| 3114 | .exit = sysctl_route_net_exit, | ||
| 3115 | }; | ||
| 3014 | #endif | 3116 | #endif |
| 3015 | 3117 | ||
| 3118 | |||
| 3119 | static __net_init int rt_secret_timer_init(struct net *net) | ||
| 3120 | { | ||
| 3121 | atomic_set(&net->ipv4.rt_genid, | ||
| 3122 | (int) ((num_physpages ^ (num_physpages>>8)) ^ | ||
| 3123 | (jiffies ^ (jiffies >> 7)))); | ||
| 3124 | |||
| 3125 | net->ipv4.rt_secret_timer.function = rt_secret_rebuild; | ||
| 3126 | net->ipv4.rt_secret_timer.data = (unsigned long)net; | ||
| 3127 | init_timer_deferrable(&net->ipv4.rt_secret_timer); | ||
| 3128 | |||
| 3129 | net->ipv4.rt_secret_timer.expires = | ||
| 3130 | jiffies + net_random() % ip_rt_secret_interval + | ||
| 3131 | ip_rt_secret_interval; | ||
| 3132 | add_timer(&net->ipv4.rt_secret_timer); | ||
| 3133 | return 0; | ||
| 3134 | } | ||
| 3135 | |||
| 3136 | static __net_exit void rt_secret_timer_exit(struct net *net) | ||
| 3137 | { | ||
| 3138 | del_timer_sync(&net->ipv4.rt_secret_timer); | ||
| 3139 | } | ||
| 3140 | |||
| 3141 | static __net_initdata struct pernet_operations rt_secret_timer_ops = { | ||
| 3142 | .init = rt_secret_timer_init, | ||
| 3143 | .exit = rt_secret_timer_exit, | ||
| 3144 | }; | ||
| 3145 | |||
| 3146 | |||
| 3016 | #ifdef CONFIG_NET_CLS_ROUTE | 3147 | #ifdef CONFIG_NET_CLS_ROUTE |
| 3017 | struct ip_rt_acct *ip_rt_acct __read_mostly; | 3148 | struct ip_rt_acct *ip_rt_acct __read_mostly; |
| 3018 | #endif /* CONFIG_NET_CLS_ROUTE */ | 3149 | #endif /* CONFIG_NET_CLS_ROUTE */ |
| @@ -3031,9 +3162,6 @@ int __init ip_rt_init(void) | |||
| 3031 | { | 3162 | { |
| 3032 | int rc = 0; | 3163 | int rc = 0; |
| 3033 | 3164 | ||
| 3034 | atomic_set(&rt_genid, (int) ((num_physpages ^ (num_physpages>>8)) ^ | ||
| 3035 | (jiffies ^ (jiffies >> 7)))); | ||
| 3036 | |||
| 3037 | #ifdef CONFIG_NET_CLS_ROUTE | 3165 | #ifdef CONFIG_NET_CLS_ROUTE |
| 3038 | ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct)); | 3166 | ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct)); |
| 3039 | if (!ip_rt_acct) | 3167 | if (!ip_rt_acct) |
| @@ -3065,19 +3193,14 @@ int __init ip_rt_init(void) | |||
| 3065 | devinet_init(); | 3193 | devinet_init(); |
| 3066 | ip_fib_init(); | 3194 | ip_fib_init(); |
| 3067 | 3195 | ||
| 3068 | rt_secret_timer.function = rt_secret_rebuild; | ||
| 3069 | rt_secret_timer.data = 0; | ||
| 3070 | init_timer_deferrable(&rt_secret_timer); | ||
| 3071 | |||
| 3072 | /* All the timers, started at system startup tend | 3196 | /* All the timers, started at system startup tend |
| 3073 | to synchronize. Perturb it a bit. | 3197 | to synchronize. Perturb it a bit. |
| 3074 | */ | 3198 | */ |
| 3075 | schedule_delayed_work(&expires_work, | 3199 | schedule_delayed_work(&expires_work, |
| 3076 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); | 3200 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); |
| 3077 | 3201 | ||
| 3078 | rt_secret_timer.expires = jiffies + net_random() % ip_rt_secret_interval + | 3202 | if (register_pernet_subsys(&rt_secret_timer_ops)) |
| 3079 | ip_rt_secret_interval; | 3203 | printk(KERN_ERR "Unable to setup rt_secret_timer\n"); |
| 3080 | add_timer(&rt_secret_timer); | ||
| 3081 | 3204 | ||
| 3082 | if (ip_rt_proc_init()) | 3205 | if (ip_rt_proc_init()) |
| 3083 | printk(KERN_ERR "Unable to create route proc files\n"); | 3206 | printk(KERN_ERR "Unable to create route proc files\n"); |
| @@ -3087,6 +3210,9 @@ int __init ip_rt_init(void) | |||
| 3087 | #endif | 3210 | #endif |
| 3088 | rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL); | 3211 | rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL); |
| 3089 | 3212 | ||
| 3213 | #ifdef CONFIG_SYSCTL | ||
| 3214 | register_pernet_subsys(&sysctl_route_ops); | ||
| 3215 | #endif | ||
| 3090 | return rc; | 3216 | return rc; |
| 3091 | } | 3217 | } |
| 3092 | 3218 | ||
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index d182a2a26291..51bc24d3b8a7 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
| @@ -8,8 +8,6 @@ | |||
| 8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
| 9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | * | ||
| 12 | * $Id: syncookies.c,v 1.18 2002/02/01 22:01:04 davem Exp $ | ||
| 13 | */ | 11 | */ |
| 14 | 12 | ||
| 15 | #include <linux/tcp.h> | 13 | #include <linux/tcp.h> |
| @@ -175,7 +173,7 @@ __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) | |||
| 175 | ; | 173 | ; |
| 176 | *mssp = msstab[mssind] + 1; | 174 | *mssp = msstab[mssind] + 1; |
| 177 | 175 | ||
| 178 | NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESSENT); | 176 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); |
| 179 | 177 | ||
| 180 | return secure_tcp_syn_cookie(iph->saddr, iph->daddr, | 178 | return secure_tcp_syn_cookie(iph->saddr, iph->daddr, |
| 181 | th->source, th->dest, ntohl(th->seq), | 179 | th->source, th->dest, ntohl(th->seq), |
| @@ -271,11 +269,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
| 271 | 269 | ||
| 272 | if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || | 270 | if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || |
| 273 | (mss = cookie_check(skb, cookie)) == 0) { | 271 | (mss = cookie_check(skb, cookie)) == 0) { |
| 274 | NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESFAILED); | 272 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); |
| 275 | goto out; | 273 | goto out; |
| 276 | } | 274 | } |
| 277 | 275 | ||
| 278 | NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV); | 276 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); |
| 279 | 277 | ||
| 280 | /* check for timestamp cookie support */ | 278 | /* check for timestamp cookie support */ |
| 281 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | 279 | memset(&tcp_opt, 0, sizeof(tcp_opt)); |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index c437f804ee38..14ef202a2254 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem. | 2 | * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem. |
| 3 | * | 3 | * |
| 4 | * $Id: sysctl_net_ipv4.c,v 1.50 2001/10/20 00:00:11 davem Exp $ | ||
| 5 | * | ||
| 6 | * Begun April 1, 1996, Mike Shaver. | 4 | * Begun April 1, 1996, Mike Shaver. |
| 7 | * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS] | 5 | * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS] |
| 8 | */ | 6 | */ |
| @@ -795,7 +793,8 @@ static struct ctl_table ipv4_net_table[] = { | |||
| 795 | .data = &init_net.ipv4.sysctl_icmp_ratelimit, | 793 | .data = &init_net.ipv4.sysctl_icmp_ratelimit, |
| 796 | .maxlen = sizeof(int), | 794 | .maxlen = sizeof(int), |
| 797 | .mode = 0644, | 795 | .mode = 0644, |
| 798 | .proc_handler = &proc_dointvec | 796 | .proc_handler = &proc_dointvec_ms_jiffies, |
| 797 | .strategy = &sysctl_ms_jiffies | ||
| 799 | }, | 798 | }, |
| 800 | { | 799 | { |
| 801 | .ctl_name = NET_IPV4_ICMP_RATEMASK, | 800 | .ctl_name = NET_IPV4_ICMP_RATEMASK, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1d723de18686..0b491bf03db4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 10 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
| @@ -279,8 +277,6 @@ | |||
| 279 | 277 | ||
| 280 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; | 278 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; |
| 281 | 279 | ||
| 282 | DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly; | ||
| 283 | |||
| 284 | atomic_t tcp_orphan_count = ATOMIC_INIT(0); | 280 | atomic_t tcp_orphan_count = ATOMIC_INIT(0); |
| 285 | 281 | ||
| 286 | EXPORT_SYMBOL_GPL(tcp_orphan_count); | 282 | EXPORT_SYMBOL_GPL(tcp_orphan_count); |
| @@ -318,10 +314,10 @@ int tcp_memory_pressure __read_mostly; | |||
| 318 | 314 | ||
| 319 | EXPORT_SYMBOL(tcp_memory_pressure); | 315 | EXPORT_SYMBOL(tcp_memory_pressure); |
| 320 | 316 | ||
| 321 | void tcp_enter_memory_pressure(void) | 317 | void tcp_enter_memory_pressure(struct sock *sk) |
| 322 | { | 318 | { |
| 323 | if (!tcp_memory_pressure) { | 319 | if (!tcp_memory_pressure) { |
| 324 | NET_INC_STATS(LINUX_MIB_TCPMEMORYPRESSURES); | 320 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMEMORYPRESSURES); |
| 325 | tcp_memory_pressure = 1; | 321 | tcp_memory_pressure = 1; |
| 326 | } | 322 | } |
| 327 | } | 323 | } |
| @@ -346,8 +342,8 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 346 | return inet_csk_listen_poll(sk); | 342 | return inet_csk_listen_poll(sk); |
| 347 | 343 | ||
| 348 | /* Socket is not locked. We are protected from async events | 344 | /* Socket is not locked. We are protected from async events |
| 349 | by poll logic and correct handling of state changes | 345 | * by poll logic and correct handling of state changes |
| 350 | made by another threads is impossible in any case. | 346 | * made by other threads is impossible in any case. |
| 351 | */ | 347 | */ |
| 352 | 348 | ||
| 353 | mask = 0; | 349 | mask = 0; |
| @@ -373,10 +369,10 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 373 | * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP | 369 | * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP |
| 374 | * if and only if shutdown has been made in both directions. | 370 | * if and only if shutdown has been made in both directions. |
| 375 | * Actually, it is interesting to look how Solaris and DUX | 371 | * Actually, it is interesting to look how Solaris and DUX |
| 376 | * solve this dilemma. I would prefer, if PULLHUP were maskable, | 372 | * solve this dilemma. I would prefer, if POLLHUP were maskable, |
| 377 | * then we could set it on SND_SHUTDOWN. BTW examples given | 373 | * then we could set it on SND_SHUTDOWN. BTW examples given |
| 378 | * in Stevens' books assume exactly this behaviour, it explains | 374 | * in Stevens' books assume exactly this behaviour, it explains |
| 379 | * why PULLHUP is incompatible with POLLOUT. --ANK | 375 | * why POLLHUP is incompatible with POLLOUT. --ANK |
| 380 | * | 376 | * |
| 381 | * NOTE. Check for TCP_CLOSE is added. The goal is to prevent | 377 | * NOTE. Check for TCP_CLOSE is added. The goal is to prevent |
| 382 | * blocking on fresh not-connected or disconnected socket. --ANK | 378 | * blocking on fresh not-connected or disconnected socket. --ANK |
| @@ -651,7 +647,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp) | |||
| 651 | } | 647 | } |
| 652 | __kfree_skb(skb); | 648 | __kfree_skb(skb); |
| 653 | } else { | 649 | } else { |
| 654 | sk->sk_prot->enter_memory_pressure(); | 650 | sk->sk_prot->enter_memory_pressure(sk); |
| 655 | sk_stream_moderate_sndbuf(sk); | 651 | sk_stream_moderate_sndbuf(sk); |
| 656 | } | 652 | } |
| 657 | return NULL; | 653 | return NULL; |
| @@ -1155,7 +1151,7 @@ static void tcp_prequeue_process(struct sock *sk) | |||
| 1155 | struct sk_buff *skb; | 1151 | struct sk_buff *skb; |
| 1156 | struct tcp_sock *tp = tcp_sk(sk); | 1152 | struct tcp_sock *tp = tcp_sk(sk); |
| 1157 | 1153 | ||
| 1158 | NET_INC_STATS_USER(LINUX_MIB_TCPPREQUEUED); | 1154 | NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPPREQUEUED); |
| 1159 | 1155 | ||
| 1160 | /* RX process wants to run with disabled BHs, though it is not | 1156 | /* RX process wants to run with disabled BHs, though it is not |
| 1161 | * necessary */ | 1157 | * necessary */ |
| @@ -1477,7 +1473,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1477 | /* __ Restore normal policy in scheduler __ */ | 1473 | /* __ Restore normal policy in scheduler __ */ |
| 1478 | 1474 | ||
| 1479 | if ((chunk = len - tp->ucopy.len) != 0) { | 1475 | if ((chunk = len - tp->ucopy.len) != 0) { |
| 1480 | NET_ADD_STATS_USER(LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG, chunk); | 1476 | NET_ADD_STATS_USER(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG, chunk); |
| 1481 | len -= chunk; | 1477 | len -= chunk; |
| 1482 | copied += chunk; | 1478 | copied += chunk; |
| 1483 | } | 1479 | } |
| @@ -1488,7 +1484,7 @@ do_prequeue: | |||
| 1488 | tcp_prequeue_process(sk); | 1484 | tcp_prequeue_process(sk); |
| 1489 | 1485 | ||
| 1490 | if ((chunk = len - tp->ucopy.len) != 0) { | 1486 | if ((chunk = len - tp->ucopy.len) != 0) { |
| 1491 | NET_ADD_STATS_USER(LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); | 1487 | NET_ADD_STATS_USER(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); |
| 1492 | len -= chunk; | 1488 | len -= chunk; |
| 1493 | copied += chunk; | 1489 | copied += chunk; |
| 1494 | } | 1490 | } |
| @@ -1603,7 +1599,7 @@ skip_copy: | |||
| 1603 | tcp_prequeue_process(sk); | 1599 | tcp_prequeue_process(sk); |
| 1604 | 1600 | ||
| 1605 | if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) { | 1601 | if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) { |
| 1606 | NET_ADD_STATS_USER(LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); | 1602 | NET_ADD_STATS_USER(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); |
| 1607 | len -= chunk; | 1603 | len -= chunk; |
| 1608 | copied += chunk; | 1604 | copied += chunk; |
| 1609 | } | 1605 | } |
| @@ -1670,12 +1666,12 @@ void tcp_set_state(struct sock *sk, int state) | |||
| 1670 | switch (state) { | 1666 | switch (state) { |
| 1671 | case TCP_ESTABLISHED: | 1667 | case TCP_ESTABLISHED: |
| 1672 | if (oldstate != TCP_ESTABLISHED) | 1668 | if (oldstate != TCP_ESTABLISHED) |
| 1673 | TCP_INC_STATS(TCP_MIB_CURRESTAB); | 1669 | TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); |
| 1674 | break; | 1670 | break; |
| 1675 | 1671 | ||
| 1676 | case TCP_CLOSE: | 1672 | case TCP_CLOSE: |
| 1677 | if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) | 1673 | if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) |
| 1678 | TCP_INC_STATS(TCP_MIB_ESTABRESETS); | 1674 | TCP_INC_STATS(sock_net(sk), TCP_MIB_ESTABRESETS); |
| 1679 | 1675 | ||
| 1680 | sk->sk_prot->unhash(sk); | 1676 | sk->sk_prot->unhash(sk); |
| 1681 | if (inet_csk(sk)->icsk_bind_hash && | 1677 | if (inet_csk(sk)->icsk_bind_hash && |
| @@ -1684,7 +1680,7 @@ void tcp_set_state(struct sock *sk, int state) | |||
| 1684 | /* fall through */ | 1680 | /* fall through */ |
| 1685 | default: | 1681 | default: |
| 1686 | if (oldstate==TCP_ESTABLISHED) | 1682 | if (oldstate==TCP_ESTABLISHED) |
| 1687 | TCP_DEC_STATS(TCP_MIB_CURRESTAB); | 1683 | TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); |
| 1688 | } | 1684 | } |
| 1689 | 1685 | ||
| 1690 | /* Change state AFTER socket is unhashed to avoid closed | 1686 | /* Change state AFTER socket is unhashed to avoid closed |
| @@ -1795,13 +1791,13 @@ void tcp_close(struct sock *sk, long timeout) | |||
| 1795 | */ | 1791 | */ |
| 1796 | if (data_was_unread) { | 1792 | if (data_was_unread) { |
| 1797 | /* Unread data was tossed, zap the connection. */ | 1793 | /* Unread data was tossed, zap the connection. */ |
| 1798 | NET_INC_STATS_USER(LINUX_MIB_TCPABORTONCLOSE); | 1794 | NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); |
| 1799 | tcp_set_state(sk, TCP_CLOSE); | 1795 | tcp_set_state(sk, TCP_CLOSE); |
| 1800 | tcp_send_active_reset(sk, GFP_KERNEL); | 1796 | tcp_send_active_reset(sk, GFP_KERNEL); |
| 1801 | } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { | 1797 | } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { |
| 1802 | /* Check zero linger _after_ checking for unread data. */ | 1798 | /* Check zero linger _after_ checking for unread data. */ |
| 1803 | sk->sk_prot->disconnect(sk, 0); | 1799 | sk->sk_prot->disconnect(sk, 0); |
| 1804 | NET_INC_STATS_USER(LINUX_MIB_TCPABORTONDATA); | 1800 | NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONDATA); |
| 1805 | } else if (tcp_close_state(sk)) { | 1801 | } else if (tcp_close_state(sk)) { |
| 1806 | /* We FIN if the application ate all the data before | 1802 | /* We FIN if the application ate all the data before |
| 1807 | * zapping the connection. | 1803 | * zapping the connection. |
| @@ -1873,7 +1869,8 @@ adjudge_to_death: | |||
| 1873 | if (tp->linger2 < 0) { | 1869 | if (tp->linger2 < 0) { |
| 1874 | tcp_set_state(sk, TCP_CLOSE); | 1870 | tcp_set_state(sk, TCP_CLOSE); |
| 1875 | tcp_send_active_reset(sk, GFP_ATOMIC); | 1871 | tcp_send_active_reset(sk, GFP_ATOMIC); |
| 1876 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONLINGER); | 1872 | NET_INC_STATS_BH(sock_net(sk), |
| 1873 | LINUX_MIB_TCPABORTONLINGER); | ||
| 1877 | } else { | 1874 | } else { |
| 1878 | const int tmo = tcp_fin_time(sk); | 1875 | const int tmo = tcp_fin_time(sk); |
| 1879 | 1876 | ||
| @@ -1895,7 +1892,8 @@ adjudge_to_death: | |||
| 1895 | "sockets\n"); | 1892 | "sockets\n"); |
| 1896 | tcp_set_state(sk, TCP_CLOSE); | 1893 | tcp_set_state(sk, TCP_CLOSE); |
| 1897 | tcp_send_active_reset(sk, GFP_ATOMIC); | 1894 | tcp_send_active_reset(sk, GFP_ATOMIC); |
| 1898 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); | 1895 | NET_INC_STATS_BH(sock_net(sk), |
| 1896 | LINUX_MIB_TCPABORTONMEMORY); | ||
| 1899 | } | 1897 | } |
| 1900 | } | 1898 | } |
| 1901 | 1899 | ||
| @@ -2590,12 +2588,69 @@ void __tcp_put_md5sig_pool(void) | |||
| 2590 | } | 2588 | } |
| 2591 | 2589 | ||
| 2592 | EXPORT_SYMBOL(__tcp_put_md5sig_pool); | 2590 | EXPORT_SYMBOL(__tcp_put_md5sig_pool); |
| 2591 | |||
| 2592 | int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, | ||
| 2593 | struct tcphdr *th) | ||
| 2594 | { | ||
| 2595 | struct scatterlist sg; | ||
| 2596 | int err; | ||
| 2597 | |||
| 2598 | __sum16 old_checksum = th->check; | ||
| 2599 | th->check = 0; | ||
| 2600 | /* options aren't included in the hash */ | ||
| 2601 | sg_init_one(&sg, th, sizeof(struct tcphdr)); | ||
| 2602 | err = crypto_hash_update(&hp->md5_desc, &sg, sizeof(struct tcphdr)); | ||
| 2603 | th->check = old_checksum; | ||
| 2604 | return err; | ||
| 2605 | } | ||
| 2606 | |||
| 2607 | EXPORT_SYMBOL(tcp_md5_hash_header); | ||
| 2608 | |||
| 2609 | int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, | ||
| 2610 | struct sk_buff *skb, unsigned header_len) | ||
| 2611 | { | ||
| 2612 | struct scatterlist sg; | ||
| 2613 | const struct tcphdr *tp = tcp_hdr(skb); | ||
| 2614 | struct hash_desc *desc = &hp->md5_desc; | ||
| 2615 | unsigned i; | ||
| 2616 | const unsigned head_data_len = skb_headlen(skb) > header_len ? | ||
| 2617 | skb_headlen(skb) - header_len : 0; | ||
| 2618 | const struct skb_shared_info *shi = skb_shinfo(skb); | ||
| 2619 | |||
| 2620 | sg_init_table(&sg, 1); | ||
| 2621 | |||
| 2622 | sg_set_buf(&sg, ((u8 *) tp) + header_len, head_data_len); | ||
| 2623 | if (crypto_hash_update(desc, &sg, head_data_len)) | ||
| 2624 | return 1; | ||
| 2625 | |||
| 2626 | for (i = 0; i < shi->nr_frags; ++i) { | ||
| 2627 | const struct skb_frag_struct *f = &shi->frags[i]; | ||
| 2628 | sg_set_page(&sg, f->page, f->size, f->page_offset); | ||
| 2629 | if (crypto_hash_update(desc, &sg, f->size)) | ||
| 2630 | return 1; | ||
| 2631 | } | ||
| 2632 | |||
| 2633 | return 0; | ||
| 2634 | } | ||
| 2635 | |||
| 2636 | EXPORT_SYMBOL(tcp_md5_hash_skb_data); | ||
| 2637 | |||
| 2638 | int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, struct tcp_md5sig_key *key) | ||
| 2639 | { | ||
| 2640 | struct scatterlist sg; | ||
| 2641 | |||
| 2642 | sg_init_one(&sg, key->key, key->keylen); | ||
| 2643 | return crypto_hash_update(&hp->md5_desc, &sg, key->keylen); | ||
| 2644 | } | ||
| 2645 | |||
| 2646 | EXPORT_SYMBOL(tcp_md5_hash_key); | ||
| 2647 | |||
| 2593 | #endif | 2648 | #endif |
| 2594 | 2649 | ||
| 2595 | void tcp_done(struct sock *sk) | 2650 | void tcp_done(struct sock *sk) |
| 2596 | { | 2651 | { |
| 2597 | if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) | 2652 | if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) |
| 2598 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | 2653 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS); |
| 2599 | 2654 | ||
| 2600 | tcp_set_state(sk, TCP_CLOSE); | 2655 | tcp_set_state(sk, TCP_CLOSE); |
| 2601 | tcp_clear_xmit_timers(sk); | 2656 | tcp_clear_xmit_timers(sk); |
| @@ -2732,4 +2787,3 @@ EXPORT_SYMBOL(tcp_splice_read); | |||
| 2732 | EXPORT_SYMBOL(tcp_sendpage); | 2787 | EXPORT_SYMBOL(tcp_sendpage); |
| 2733 | EXPORT_SYMBOL(tcp_setsockopt); | 2788 | EXPORT_SYMBOL(tcp_setsockopt); |
| 2734 | EXPORT_SYMBOL(tcp_shutdown); | 2789 | EXPORT_SYMBOL(tcp_shutdown); |
| 2735 | EXPORT_SYMBOL(tcp_statistics); | ||
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 2fbcc7d1b1a0..838d491dfda7 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tcp_diag.c Module for monitoring TCP transport protocols sockets. | 2 | * tcp_diag.c Module for monitoring TCP transport protocols sockets. |
| 3 | * | 3 | * |
| 4 | * Version: $Id: tcp_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | 4 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 7 | * | 5 | * |
| 8 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index cad73b7dfef0..1f5e6049883e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 10 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
| @@ -604,7 +602,7 @@ static u32 tcp_rto_min(struct sock *sk) | |||
| 604 | u32 rto_min = TCP_RTO_MIN; | 602 | u32 rto_min = TCP_RTO_MIN; |
| 605 | 603 | ||
| 606 | if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) | 604 | if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) |
| 607 | rto_min = dst_metric(dst, RTAX_RTO_MIN); | 605 | rto_min = dst_metric_rtt(dst, RTAX_RTO_MIN); |
| 608 | return rto_min; | 606 | return rto_min; |
| 609 | } | 607 | } |
| 610 | 608 | ||
| @@ -731,6 +729,7 @@ void tcp_update_metrics(struct sock *sk) | |||
| 731 | if (dst && (dst->flags & DST_HOST)) { | 729 | if (dst && (dst->flags & DST_HOST)) { |
| 732 | const struct inet_connection_sock *icsk = inet_csk(sk); | 730 | const struct inet_connection_sock *icsk = inet_csk(sk); |
| 733 | int m; | 731 | int m; |
| 732 | unsigned long rtt; | ||
| 734 | 733 | ||
| 735 | if (icsk->icsk_backoff || !tp->srtt) { | 734 | if (icsk->icsk_backoff || !tp->srtt) { |
| 736 | /* This session failed to estimate rtt. Why? | 735 | /* This session failed to estimate rtt. Why? |
| @@ -742,7 +741,8 @@ void tcp_update_metrics(struct sock *sk) | |||
| 742 | return; | 741 | return; |
| 743 | } | 742 | } |
| 744 | 743 | ||
| 745 | m = dst_metric(dst, RTAX_RTT) - tp->srtt; | 744 | rtt = dst_metric_rtt(dst, RTAX_RTT); |
| 745 | m = rtt - tp->srtt; | ||
| 746 | 746 | ||
| 747 | /* If newly calculated rtt larger than stored one, | 747 | /* If newly calculated rtt larger than stored one, |
| 748 | * store new one. Otherwise, use EWMA. Remember, | 748 | * store new one. Otherwise, use EWMA. Remember, |
| @@ -750,12 +750,13 @@ void tcp_update_metrics(struct sock *sk) | |||
| 750 | */ | 750 | */ |
| 751 | if (!(dst_metric_locked(dst, RTAX_RTT))) { | 751 | if (!(dst_metric_locked(dst, RTAX_RTT))) { |
| 752 | if (m <= 0) | 752 | if (m <= 0) |
| 753 | dst->metrics[RTAX_RTT - 1] = tp->srtt; | 753 | set_dst_metric_rtt(dst, RTAX_RTT, tp->srtt); |
| 754 | else | 754 | else |
| 755 | dst->metrics[RTAX_RTT - 1] -= (m >> 3); | 755 | set_dst_metric_rtt(dst, RTAX_RTT, rtt - (m >> 3)); |
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | if (!(dst_metric_locked(dst, RTAX_RTTVAR))) { | 758 | if (!(dst_metric_locked(dst, RTAX_RTTVAR))) { |
| 759 | unsigned long var; | ||
| 759 | if (m < 0) | 760 | if (m < 0) |
| 760 | m = -m; | 761 | m = -m; |
| 761 | 762 | ||
| @@ -764,11 +765,13 @@ void tcp_update_metrics(struct sock *sk) | |||
| 764 | if (m < tp->mdev) | 765 | if (m < tp->mdev) |
| 765 | m = tp->mdev; | 766 | m = tp->mdev; |
| 766 | 767 | ||
| 767 | if (m >= dst_metric(dst, RTAX_RTTVAR)) | 768 | var = dst_metric_rtt(dst, RTAX_RTTVAR); |
| 768 | dst->metrics[RTAX_RTTVAR - 1] = m; | 769 | if (m >= var) |
| 770 | var = m; | ||
| 769 | else | 771 | else |
| 770 | dst->metrics[RTAX_RTTVAR-1] -= | 772 | var -= (var - m) >> 2; |
| 771 | (dst_metric(dst, RTAX_RTTVAR) - m)>>2; | 773 | |
| 774 | set_dst_metric_rtt(dst, RTAX_RTTVAR, var); | ||
| 772 | } | 775 | } |
| 773 | 776 | ||
| 774 | if (tp->snd_ssthresh >= 0xFFFF) { | 777 | if (tp->snd_ssthresh >= 0xFFFF) { |
| @@ -899,7 +902,7 @@ static void tcp_init_metrics(struct sock *sk) | |||
| 899 | if (dst_metric(dst, RTAX_RTT) == 0) | 902 | if (dst_metric(dst, RTAX_RTT) == 0) |
| 900 | goto reset; | 903 | goto reset; |
| 901 | 904 | ||
| 902 | if (!tp->srtt && dst_metric(dst, RTAX_RTT) < (TCP_TIMEOUT_INIT << 3)) | 905 | if (!tp->srtt && dst_metric_rtt(dst, RTAX_RTT) < (TCP_TIMEOUT_INIT << 3)) |
| 903 | goto reset; | 906 | goto reset; |
| 904 | 907 | ||
| 905 | /* Initial rtt is determined from SYN,SYN-ACK. | 908 | /* Initial rtt is determined from SYN,SYN-ACK. |
| @@ -916,12 +919,12 @@ static void tcp_init_metrics(struct sock *sk) | |||
| 916 | * to low value, and then abruptly stops to do it and starts to delay | 919 | * to low value, and then abruptly stops to do it and starts to delay |
| 917 | * ACKs, wait for troubles. | 920 | * ACKs, wait for troubles. |
| 918 | */ | 921 | */ |
| 919 | if (dst_metric(dst, RTAX_RTT) > tp->srtt) { | 922 | if (dst_metric_rtt(dst, RTAX_RTT) > tp->srtt) { |
| 920 | tp->srtt = dst_metric(dst, RTAX_RTT); | 923 | tp->srtt = dst_metric_rtt(dst, RTAX_RTT); |
| 921 | tp->rtt_seq = tp->snd_nxt; | 924 | tp->rtt_seq = tp->snd_nxt; |
| 922 | } | 925 | } |
| 923 | if (dst_metric(dst, RTAX_RTTVAR) > tp->mdev) { | 926 | if (dst_metric_rtt(dst, RTAX_RTTVAR) > tp->mdev) { |
| 924 | tp->mdev = dst_metric(dst, RTAX_RTTVAR); | 927 | tp->mdev = dst_metric_rtt(dst, RTAX_RTTVAR); |
| 925 | tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); | 928 | tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); |
| 926 | } | 929 | } |
| 927 | tcp_set_rto(sk); | 930 | tcp_set_rto(sk); |
| @@ -949,17 +952,21 @@ static void tcp_update_reordering(struct sock *sk, const int metric, | |||
| 949 | { | 952 | { |
| 950 | struct tcp_sock *tp = tcp_sk(sk); | 953 | struct tcp_sock *tp = tcp_sk(sk); |
| 951 | if (metric > tp->reordering) { | 954 | if (metric > tp->reordering) { |
| 955 | int mib_idx; | ||
| 956 | |||
| 952 | tp->reordering = min(TCP_MAX_REORDERING, metric); | 957 | tp->reordering = min(TCP_MAX_REORDERING, metric); |
| 953 | 958 | ||
| 954 | /* This exciting event is worth to be remembered. 8) */ | 959 | /* This exciting event is worth to be remembered. 8) */ |
| 955 | if (ts) | 960 | if (ts) |
| 956 | NET_INC_STATS_BH(LINUX_MIB_TCPTSREORDER); | 961 | mib_idx = LINUX_MIB_TCPTSREORDER; |
| 957 | else if (tcp_is_reno(tp)) | 962 | else if (tcp_is_reno(tp)) |
| 958 | NET_INC_STATS_BH(LINUX_MIB_TCPRENOREORDER); | 963 | mib_idx = LINUX_MIB_TCPRENOREORDER; |
| 959 | else if (tcp_is_fack(tp)) | 964 | else if (tcp_is_fack(tp)) |
| 960 | NET_INC_STATS_BH(LINUX_MIB_TCPFACKREORDER); | 965 | mib_idx = LINUX_MIB_TCPFACKREORDER; |
| 961 | else | 966 | else |
| 962 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKREORDER); | 967 | mib_idx = LINUX_MIB_TCPSACKREORDER; |
| 968 | |||
| 969 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 963 | #if FASTRETRANS_DEBUG > 1 | 970 | #if FASTRETRANS_DEBUG > 1 |
| 964 | printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n", | 971 | printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n", |
| 965 | tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, | 972 | tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, |
| @@ -1155,7 +1162,7 @@ static void tcp_mark_lost_retrans(struct sock *sk) | |||
| 1155 | tp->lost_out += tcp_skb_pcount(skb); | 1162 | tp->lost_out += tcp_skb_pcount(skb); |
| 1156 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; | 1163 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; |
| 1157 | } | 1164 | } |
| 1158 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); | 1165 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSTRETRANSMIT); |
| 1159 | } else { | 1166 | } else { |
| 1160 | if (before(ack_seq, new_low_seq)) | 1167 | if (before(ack_seq, new_low_seq)) |
| 1161 | new_low_seq = ack_seq; | 1168 | new_low_seq = ack_seq; |
| @@ -1167,10 +1174,11 @@ static void tcp_mark_lost_retrans(struct sock *sk) | |||
| 1167 | tp->lost_retrans_low = new_low_seq; | 1174 | tp->lost_retrans_low = new_low_seq; |
| 1168 | } | 1175 | } |
| 1169 | 1176 | ||
| 1170 | static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, | 1177 | static int tcp_check_dsack(struct sock *sk, struct sk_buff *ack_skb, |
| 1171 | struct tcp_sack_block_wire *sp, int num_sacks, | 1178 | struct tcp_sack_block_wire *sp, int num_sacks, |
| 1172 | u32 prior_snd_una) | 1179 | u32 prior_snd_una) |
| 1173 | { | 1180 | { |
| 1181 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 1174 | u32 start_seq_0 = get_unaligned_be32(&sp[0].start_seq); | 1182 | u32 start_seq_0 = get_unaligned_be32(&sp[0].start_seq); |
| 1175 | u32 end_seq_0 = get_unaligned_be32(&sp[0].end_seq); | 1183 | u32 end_seq_0 = get_unaligned_be32(&sp[0].end_seq); |
| 1176 | int dup_sack = 0; | 1184 | int dup_sack = 0; |
| @@ -1178,7 +1186,7 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, | |||
| 1178 | if (before(start_seq_0, TCP_SKB_CB(ack_skb)->ack_seq)) { | 1186 | if (before(start_seq_0, TCP_SKB_CB(ack_skb)->ack_seq)) { |
| 1179 | dup_sack = 1; | 1187 | dup_sack = 1; |
| 1180 | tcp_dsack_seen(tp); | 1188 | tcp_dsack_seen(tp); |
| 1181 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); | 1189 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKRECV); |
| 1182 | } else if (num_sacks > 1) { | 1190 | } else if (num_sacks > 1) { |
| 1183 | u32 end_seq_1 = get_unaligned_be32(&sp[1].end_seq); | 1191 | u32 end_seq_1 = get_unaligned_be32(&sp[1].end_seq); |
| 1184 | u32 start_seq_1 = get_unaligned_be32(&sp[1].start_seq); | 1192 | u32 start_seq_1 = get_unaligned_be32(&sp[1].start_seq); |
| @@ -1187,7 +1195,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, | |||
| 1187 | !before(start_seq_0, start_seq_1)) { | 1195 | !before(start_seq_0, start_seq_1)) { |
| 1188 | dup_sack = 1; | 1196 | dup_sack = 1; |
| 1189 | tcp_dsack_seen(tp); | 1197 | tcp_dsack_seen(tp); |
| 1190 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); | 1198 | NET_INC_STATS_BH(sock_net(sk), |
| 1199 | LINUX_MIB_TCPDSACKOFORECV); | ||
| 1191 | } | 1200 | } |
| 1192 | } | 1201 | } |
| 1193 | 1202 | ||
| @@ -1414,10 +1423,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, | |||
| 1414 | unsigned char *ptr = (skb_transport_header(ack_skb) + | 1423 | unsigned char *ptr = (skb_transport_header(ack_skb) + |
| 1415 | TCP_SKB_CB(ack_skb)->sacked); | 1424 | TCP_SKB_CB(ack_skb)->sacked); |
| 1416 | struct tcp_sack_block_wire *sp_wire = (struct tcp_sack_block_wire *)(ptr+2); | 1425 | struct tcp_sack_block_wire *sp_wire = (struct tcp_sack_block_wire *)(ptr+2); |
| 1417 | struct tcp_sack_block sp[4]; | 1426 | struct tcp_sack_block sp[TCP_NUM_SACKS]; |
| 1418 | struct tcp_sack_block *cache; | 1427 | struct tcp_sack_block *cache; |
| 1419 | struct sk_buff *skb; | 1428 | struct sk_buff *skb; |
| 1420 | int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE) >> 3; | 1429 | int num_sacks = min(TCP_NUM_SACKS, (ptr[1] - TCPOLEN_SACK_BASE) >> 3); |
| 1421 | int used_sacks; | 1430 | int used_sacks; |
| 1422 | int reord = tp->packets_out; | 1431 | int reord = tp->packets_out; |
| 1423 | int flag = 0; | 1432 | int flag = 0; |
| @@ -1432,7 +1441,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, | |||
| 1432 | tcp_highest_sack_reset(sk); | 1441 | tcp_highest_sack_reset(sk); |
| 1433 | } | 1442 | } |
| 1434 | 1443 | ||
| 1435 | found_dup_sack = tcp_check_dsack(tp, ack_skb, sp_wire, | 1444 | found_dup_sack = tcp_check_dsack(sk, ack_skb, sp_wire, |
| 1436 | num_sacks, prior_snd_una); | 1445 | num_sacks, prior_snd_una); |
| 1437 | if (found_dup_sack) | 1446 | if (found_dup_sack) |
| 1438 | flag |= FLAG_DSACKING_ACK; | 1447 | flag |= FLAG_DSACKING_ACK; |
| @@ -1458,18 +1467,22 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, | |||
| 1458 | if (!tcp_is_sackblock_valid(tp, dup_sack, | 1467 | if (!tcp_is_sackblock_valid(tp, dup_sack, |
| 1459 | sp[used_sacks].start_seq, | 1468 | sp[used_sacks].start_seq, |
| 1460 | sp[used_sacks].end_seq)) { | 1469 | sp[used_sacks].end_seq)) { |
| 1470 | int mib_idx; | ||
| 1471 | |||
| 1461 | if (dup_sack) { | 1472 | if (dup_sack) { |
| 1462 | if (!tp->undo_marker) | 1473 | if (!tp->undo_marker) |
| 1463 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKIGNOREDNOUNDO); | 1474 | mib_idx = LINUX_MIB_TCPDSACKIGNOREDNOUNDO; |
| 1464 | else | 1475 | else |
| 1465 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKIGNOREDOLD); | 1476 | mib_idx = LINUX_MIB_TCPDSACKIGNOREDOLD; |
| 1466 | } else { | 1477 | } else { |
| 1467 | /* Don't count olds caused by ACK reordering */ | 1478 | /* Don't count olds caused by ACK reordering */ |
| 1468 | if ((TCP_SKB_CB(ack_skb)->ack_seq != tp->snd_una) && | 1479 | if ((TCP_SKB_CB(ack_skb)->ack_seq != tp->snd_una) && |
| 1469 | !after(sp[used_sacks].end_seq, tp->snd_una)) | 1480 | !after(sp[used_sacks].end_seq, tp->snd_una)) |
| 1470 | continue; | 1481 | continue; |
| 1471 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKDISCARD); | 1482 | mib_idx = LINUX_MIB_TCPSACKDISCARD; |
| 1472 | } | 1483 | } |
| 1484 | |||
| 1485 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 1473 | if (i == 0) | 1486 | if (i == 0) |
| 1474 | first_sack_index = -1; | 1487 | first_sack_index = -1; |
| 1475 | continue; | 1488 | continue; |
| @@ -1962,7 +1975,7 @@ static int tcp_check_sack_reneging(struct sock *sk, int flag) | |||
| 1962 | { | 1975 | { |
| 1963 | if (flag & FLAG_SACK_RENEGING) { | 1976 | if (flag & FLAG_SACK_RENEGING) { |
| 1964 | struct inet_connection_sock *icsk = inet_csk(sk); | 1977 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 1965 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKRENEGING); | 1978 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSACKRENEGING); |
| 1966 | 1979 | ||
| 1967 | tcp_enter_loss(sk, 1); | 1980 | tcp_enter_loss(sk, 1); |
| 1968 | icsk->icsk_retransmits++; | 1981 | icsk->icsk_retransmits++; |
| @@ -2382,15 +2395,19 @@ static int tcp_try_undo_recovery(struct sock *sk) | |||
| 2382 | struct tcp_sock *tp = tcp_sk(sk); | 2395 | struct tcp_sock *tp = tcp_sk(sk); |
| 2383 | 2396 | ||
| 2384 | if (tcp_may_undo(tp)) { | 2397 | if (tcp_may_undo(tp)) { |
| 2398 | int mib_idx; | ||
| 2399 | |||
| 2385 | /* Happy end! We did not retransmit anything | 2400 | /* Happy end! We did not retransmit anything |
| 2386 | * or our original transmission succeeded. | 2401 | * or our original transmission succeeded. |
| 2387 | */ | 2402 | */ |
| 2388 | DBGUNDO(sk, inet_csk(sk)->icsk_ca_state == TCP_CA_Loss ? "loss" : "retrans"); | 2403 | DBGUNDO(sk, inet_csk(sk)->icsk_ca_state == TCP_CA_Loss ? "loss" : "retrans"); |
| 2389 | tcp_undo_cwr(sk, 1); | 2404 | tcp_undo_cwr(sk, 1); |
| 2390 | if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) | 2405 | if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) |
| 2391 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSSUNDO); | 2406 | mib_idx = LINUX_MIB_TCPLOSSUNDO; |
| 2392 | else | 2407 | else |
| 2393 | NET_INC_STATS_BH(LINUX_MIB_TCPFULLUNDO); | 2408 | mib_idx = LINUX_MIB_TCPFULLUNDO; |
| 2409 | |||
| 2410 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 2394 | tp->undo_marker = 0; | 2411 | tp->undo_marker = 0; |
| 2395 | } | 2412 | } |
| 2396 | if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { | 2413 | if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { |
| @@ -2413,7 +2430,7 @@ static void tcp_try_undo_dsack(struct sock *sk) | |||
| 2413 | DBGUNDO(sk, "D-SACK"); | 2430 | DBGUNDO(sk, "D-SACK"); |
| 2414 | tcp_undo_cwr(sk, 1); | 2431 | tcp_undo_cwr(sk, 1); |
| 2415 | tp->undo_marker = 0; | 2432 | tp->undo_marker = 0; |
| 2416 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKUNDO); | 2433 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKUNDO); |
| 2417 | } | 2434 | } |
| 2418 | } | 2435 | } |
| 2419 | 2436 | ||
| @@ -2436,7 +2453,7 @@ static int tcp_try_undo_partial(struct sock *sk, int acked) | |||
| 2436 | 2453 | ||
| 2437 | DBGUNDO(sk, "Hoe"); | 2454 | DBGUNDO(sk, "Hoe"); |
| 2438 | tcp_undo_cwr(sk, 0); | 2455 | tcp_undo_cwr(sk, 0); |
| 2439 | NET_INC_STATS_BH(LINUX_MIB_TCPPARTIALUNDO); | 2456 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPARTIALUNDO); |
| 2440 | 2457 | ||
| 2441 | /* So... Do not make Hoe's retransmit yet. | 2458 | /* So... Do not make Hoe's retransmit yet. |
| 2442 | * If the first packet was delayed, the rest | 2459 | * If the first packet was delayed, the rest |
| @@ -2465,7 +2482,7 @@ static int tcp_try_undo_loss(struct sock *sk) | |||
| 2465 | DBGUNDO(sk, "partial loss"); | 2482 | DBGUNDO(sk, "partial loss"); |
| 2466 | tp->lost_out = 0; | 2483 | tp->lost_out = 0; |
| 2467 | tcp_undo_cwr(sk, 1); | 2484 | tcp_undo_cwr(sk, 1); |
| 2468 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSSUNDO); | 2485 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSSUNDO); |
| 2469 | inet_csk(sk)->icsk_retransmits = 0; | 2486 | inet_csk(sk)->icsk_retransmits = 0; |
| 2470 | tp->undo_marker = 0; | 2487 | tp->undo_marker = 0; |
| 2471 | if (tcp_is_sack(tp)) | 2488 | if (tcp_is_sack(tp)) |
| @@ -2562,7 +2579,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) | |||
| 2562 | int is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); | 2579 | int is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); |
| 2563 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && | 2580 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && |
| 2564 | (tcp_fackets_out(tp) > tp->reordering)); | 2581 | (tcp_fackets_out(tp) > tp->reordering)); |
| 2565 | int fast_rexmit = 0; | 2582 | int fast_rexmit = 0, mib_idx; |
| 2566 | 2583 | ||
| 2567 | if (WARN_ON(!tp->packets_out && tp->sacked_out)) | 2584 | if (WARN_ON(!tp->packets_out && tp->sacked_out)) |
| 2568 | tp->sacked_out = 0; | 2585 | tp->sacked_out = 0; |
| @@ -2584,7 +2601,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) | |||
| 2584 | icsk->icsk_ca_state != TCP_CA_Open && | 2601 | icsk->icsk_ca_state != TCP_CA_Open && |
| 2585 | tp->fackets_out > tp->reordering) { | 2602 | tp->fackets_out > tp->reordering) { |
| 2586 | tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); | 2603 | tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); |
| 2587 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSS); | 2604 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); |
| 2588 | } | 2605 | } |
| 2589 | 2606 | ||
| 2590 | /* D. Check consistency of the current state. */ | 2607 | /* D. Check consistency of the current state. */ |
| @@ -2685,9 +2702,11 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) | |||
| 2685 | /* Otherwise enter Recovery state */ | 2702 | /* Otherwise enter Recovery state */ |
| 2686 | 2703 | ||
| 2687 | if (tcp_is_reno(tp)) | 2704 | if (tcp_is_reno(tp)) |
| 2688 | NET_INC_STATS_BH(LINUX_MIB_TCPRENORECOVERY); | 2705 | mib_idx = LINUX_MIB_TCPRENORECOVERY; |
| 2689 | else | 2706 | else |
| 2690 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKRECOVERY); | 2707 | mib_idx = LINUX_MIB_TCPSACKRECOVERY; |
| 2708 | |||
| 2709 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 2691 | 2710 | ||
| 2692 | tp->high_seq = tp->snd_nxt; | 2711 | tp->high_seq = tp->snd_nxt; |
| 2693 | tp->prior_ssthresh = 0; | 2712 | tp->prior_ssthresh = 0; |
| @@ -3198,7 +3217,7 @@ static int tcp_process_frto(struct sock *sk, int flag) | |||
| 3198 | } | 3217 | } |
| 3199 | tp->frto_counter = 0; | 3218 | tp->frto_counter = 0; |
| 3200 | tp->undo_marker = 0; | 3219 | tp->undo_marker = 0; |
| 3201 | NET_INC_STATS_BH(LINUX_MIB_TCPSPURIOUSRTOS); | 3220 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSPURIOUSRTOS); |
| 3202 | } | 3221 | } |
| 3203 | return 0; | 3222 | return 0; |
| 3204 | } | 3223 | } |
| @@ -3251,12 +3270,12 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
| 3251 | 3270 | ||
| 3252 | tcp_ca_event(sk, CA_EVENT_FAST_ACK); | 3271 | tcp_ca_event(sk, CA_EVENT_FAST_ACK); |
| 3253 | 3272 | ||
| 3254 | NET_INC_STATS_BH(LINUX_MIB_TCPHPACKS); | 3273 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPACKS); |
| 3255 | } else { | 3274 | } else { |
| 3256 | if (ack_seq != TCP_SKB_CB(skb)->end_seq) | 3275 | if (ack_seq != TCP_SKB_CB(skb)->end_seq) |
| 3257 | flag |= FLAG_DATA; | 3276 | flag |= FLAG_DATA; |
| 3258 | else | 3277 | else |
| 3259 | NET_INC_STATS_BH(LINUX_MIB_TCPPUREACKS); | 3278 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPUREACKS); |
| 3260 | 3279 | ||
| 3261 | flag |= tcp_ack_update_window(sk, skb, ack, ack_seq); | 3280 | flag |= tcp_ack_update_window(sk, skb, ack, ack_seq); |
| 3262 | 3281 | ||
| @@ -3450,6 +3469,43 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, | |||
| 3450 | return 1; | 3469 | return 1; |
| 3451 | } | 3470 | } |
| 3452 | 3471 | ||
| 3472 | #ifdef CONFIG_TCP_MD5SIG | ||
| 3473 | /* | ||
| 3474 | * Parse MD5 Signature option | ||
| 3475 | */ | ||
| 3476 | u8 *tcp_parse_md5sig_option(struct tcphdr *th) | ||
| 3477 | { | ||
| 3478 | int length = (th->doff << 2) - sizeof (*th); | ||
| 3479 | u8 *ptr = (u8*)(th + 1); | ||
| 3480 | |||
| 3481 | /* If the TCP option is too short, we can short cut */ | ||
| 3482 | if (length < TCPOLEN_MD5SIG) | ||
| 3483 | return NULL; | ||
| 3484 | |||
| 3485 | while (length > 0) { | ||
| 3486 | int opcode = *ptr++; | ||
| 3487 | int opsize; | ||
| 3488 | |||
| 3489 | switch(opcode) { | ||
| 3490 | case TCPOPT_EOL: | ||
| 3491 | return NULL; | ||
| 3492 | case TCPOPT_NOP: | ||
| 3493 | length--; | ||
| 3494 | continue; | ||
| 3495 | default: | ||
| 3496 | opsize = *ptr++; | ||
| 3497 | if (opsize < 2 || opsize > length) | ||
| 3498 | return NULL; | ||
| 3499 | if (opcode == TCPOPT_MD5SIG) | ||
| 3500 | return ptr; | ||
| 3501 | } | ||
| 3502 | ptr += opsize - 2; | ||
| 3503 | length -= opsize; | ||
| 3504 | } | ||
| 3505 | return NULL; | ||
| 3506 | } | ||
| 3507 | #endif | ||
| 3508 | |||
| 3453 | static inline void tcp_store_ts_recent(struct tcp_sock *tp) | 3509 | static inline void tcp_store_ts_recent(struct tcp_sock *tp) |
| 3454 | { | 3510 | { |
| 3455 | tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; | 3511 | tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; |
| @@ -3662,26 +3718,33 @@ static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, | |||
| 3662 | return 0; | 3718 | return 0; |
| 3663 | } | 3719 | } |
| 3664 | 3720 | ||
| 3665 | static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq) | 3721 | static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) |
| 3666 | { | 3722 | { |
| 3723 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 3724 | |||
| 3667 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { | 3725 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { |
| 3726 | int mib_idx; | ||
| 3727 | |||
| 3668 | if (before(seq, tp->rcv_nxt)) | 3728 | if (before(seq, tp->rcv_nxt)) |
| 3669 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOLDSENT); | 3729 | mib_idx = LINUX_MIB_TCPDSACKOLDSENT; |
| 3670 | else | 3730 | else |
| 3671 | NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFOSENT); | 3731 | mib_idx = LINUX_MIB_TCPDSACKOFOSENT; |
| 3732 | |||
| 3733 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 3672 | 3734 | ||
| 3673 | tp->rx_opt.dsack = 1; | 3735 | tp->rx_opt.dsack = 1; |
| 3674 | tp->duplicate_sack[0].start_seq = seq; | 3736 | tp->duplicate_sack[0].start_seq = seq; |
| 3675 | tp->duplicate_sack[0].end_seq = end_seq; | 3737 | tp->duplicate_sack[0].end_seq = end_seq; |
| 3676 | tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + 1, | 3738 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + 1; |
| 3677 | 4 - tp->rx_opt.tstamp_ok); | ||
| 3678 | } | 3739 | } |
| 3679 | } | 3740 | } |
| 3680 | 3741 | ||
| 3681 | static void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq) | 3742 | static void tcp_dsack_extend(struct sock *sk, u32 seq, u32 end_seq) |
| 3682 | { | 3743 | { |
| 3744 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 3745 | |||
| 3683 | if (!tp->rx_opt.dsack) | 3746 | if (!tp->rx_opt.dsack) |
| 3684 | tcp_dsack_set(tp, seq, end_seq); | 3747 | tcp_dsack_set(sk, seq, end_seq); |
| 3685 | else | 3748 | else |
| 3686 | tcp_sack_extend(tp->duplicate_sack, seq, end_seq); | 3749 | tcp_sack_extend(tp->duplicate_sack, seq, end_seq); |
| 3687 | } | 3750 | } |
| @@ -3692,7 +3755,7 @@ static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb) | |||
| 3692 | 3755 | ||
| 3693 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && | 3756 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && |
| 3694 | before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { | 3757 | before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { |
| 3695 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOST); | 3758 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); |
| 3696 | tcp_enter_quickack_mode(sk); | 3759 | tcp_enter_quickack_mode(sk); |
| 3697 | 3760 | ||
| 3698 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { | 3761 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { |
| @@ -3700,7 +3763,7 @@ static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb) | |||
| 3700 | 3763 | ||
| 3701 | if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) | 3764 | if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) |
| 3702 | end_seq = tp->rcv_nxt; | 3765 | end_seq = tp->rcv_nxt; |
| 3703 | tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, end_seq); | 3766 | tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, end_seq); |
| 3704 | } | 3767 | } |
| 3705 | } | 3768 | } |
| 3706 | 3769 | ||
| @@ -3727,9 +3790,8 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp) | |||
| 3727 | * Decrease num_sacks. | 3790 | * Decrease num_sacks. |
| 3728 | */ | 3791 | */ |
| 3729 | tp->rx_opt.num_sacks--; | 3792 | tp->rx_opt.num_sacks--; |
| 3730 | tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + | 3793 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + |
| 3731 | tp->rx_opt.dsack, | 3794 | tp->rx_opt.dsack; |
| 3732 | 4 - tp->rx_opt.tstamp_ok); | ||
| 3733 | for (i = this_sack; i < tp->rx_opt.num_sacks; i++) | 3795 | for (i = this_sack; i < tp->rx_opt.num_sacks; i++) |
| 3734 | sp[i] = sp[i + 1]; | 3796 | sp[i] = sp[i + 1]; |
| 3735 | continue; | 3797 | continue; |
| @@ -3779,7 +3841,7 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq) | |||
| 3779 | * | 3841 | * |
| 3780 | * If the sack array is full, forget about the last one. | 3842 | * If the sack array is full, forget about the last one. |
| 3781 | */ | 3843 | */ |
| 3782 | if (this_sack >= 4) { | 3844 | if (this_sack >= TCP_NUM_SACKS) { |
| 3783 | this_sack--; | 3845 | this_sack--; |
| 3784 | tp->rx_opt.num_sacks--; | 3846 | tp->rx_opt.num_sacks--; |
| 3785 | sp--; | 3847 | sp--; |
| @@ -3792,8 +3854,7 @@ new_sack: | |||
| 3792 | sp->start_seq = seq; | 3854 | sp->start_seq = seq; |
| 3793 | sp->end_seq = end_seq; | 3855 | sp->end_seq = end_seq; |
| 3794 | tp->rx_opt.num_sacks++; | 3856 | tp->rx_opt.num_sacks++; |
| 3795 | tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, | 3857 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; |
| 3796 | 4 - tp->rx_opt.tstamp_ok); | ||
| 3797 | } | 3858 | } |
| 3798 | 3859 | ||
| 3799 | /* RCV.NXT advances, some SACKs should be eaten. */ | 3860 | /* RCV.NXT advances, some SACKs should be eaten. */ |
| @@ -3830,9 +3891,8 @@ static void tcp_sack_remove(struct tcp_sock *tp) | |||
| 3830 | } | 3891 | } |
| 3831 | if (num_sacks != tp->rx_opt.num_sacks) { | 3892 | if (num_sacks != tp->rx_opt.num_sacks) { |
| 3832 | tp->rx_opt.num_sacks = num_sacks; | 3893 | tp->rx_opt.num_sacks = num_sacks; |
| 3833 | tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + | 3894 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + |
| 3834 | tp->rx_opt.dsack, | 3895 | tp->rx_opt.dsack; |
| 3835 | 4 - tp->rx_opt.tstamp_ok); | ||
| 3836 | } | 3896 | } |
| 3837 | } | 3897 | } |
| 3838 | 3898 | ||
| @@ -3853,7 +3913,7 @@ static void tcp_ofo_queue(struct sock *sk) | |||
| 3853 | __u32 dsack = dsack_high; | 3913 | __u32 dsack = dsack_high; |
| 3854 | if (before(TCP_SKB_CB(skb)->end_seq, dsack_high)) | 3914 | if (before(TCP_SKB_CB(skb)->end_seq, dsack_high)) |
| 3855 | dsack_high = TCP_SKB_CB(skb)->end_seq; | 3915 | dsack_high = TCP_SKB_CB(skb)->end_seq; |
| 3856 | tcp_dsack_extend(tp, TCP_SKB_CB(skb)->seq, dsack); | 3916 | tcp_dsack_extend(sk, TCP_SKB_CB(skb)->seq, dsack); |
| 3857 | } | 3917 | } |
| 3858 | 3918 | ||
| 3859 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { | 3919 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { |
| @@ -3911,8 +3971,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
| 3911 | 3971 | ||
| 3912 | if (tp->rx_opt.dsack) { | 3972 | if (tp->rx_opt.dsack) { |
| 3913 | tp->rx_opt.dsack = 0; | 3973 | tp->rx_opt.dsack = 0; |
| 3914 | tp->rx_opt.eff_sacks = min_t(unsigned int, tp->rx_opt.num_sacks, | 3974 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks; |
| 3915 | 4 - tp->rx_opt.tstamp_ok); | ||
| 3916 | } | 3975 | } |
| 3917 | 3976 | ||
| 3918 | /* Queue data for delivery to the user. | 3977 | /* Queue data for delivery to the user. |
| @@ -3981,8 +4040,8 @@ queue_and_out: | |||
| 3981 | 4040 | ||
| 3982 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { | 4041 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { |
| 3983 | /* A retransmit, 2nd most common case. Force an immediate ack. */ | 4042 | /* A retransmit, 2nd most common case. Force an immediate ack. */ |
| 3984 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOST); | 4043 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); |
| 3985 | tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); | 4044 | tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); |
| 3986 | 4045 | ||
| 3987 | out_of_window: | 4046 | out_of_window: |
| 3988 | tcp_enter_quickack_mode(sk); | 4047 | tcp_enter_quickack_mode(sk); |
| @@ -4004,7 +4063,7 @@ drop: | |||
| 4004 | tp->rcv_nxt, TCP_SKB_CB(skb)->seq, | 4063 | tp->rcv_nxt, TCP_SKB_CB(skb)->seq, |
| 4005 | TCP_SKB_CB(skb)->end_seq); | 4064 | TCP_SKB_CB(skb)->end_seq); |
| 4006 | 4065 | ||
| 4007 | tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, tp->rcv_nxt); | 4066 | tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, tp->rcv_nxt); |
| 4008 | 4067 | ||
| 4009 | /* If window is closed, drop tail of packet. But after | 4068 | /* If window is closed, drop tail of packet. But after |
| 4010 | * remembering D-SACK for its head made in previous line. | 4069 | * remembering D-SACK for its head made in previous line. |
| @@ -4069,12 +4128,12 @@ drop: | |||
| 4069 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4128 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
| 4070 | /* All the bits are present. Drop. */ | 4129 | /* All the bits are present. Drop. */ |
| 4071 | __kfree_skb(skb); | 4130 | __kfree_skb(skb); |
| 4072 | tcp_dsack_set(tp, seq, end_seq); | 4131 | tcp_dsack_set(sk, seq, end_seq); |
| 4073 | goto add_sack; | 4132 | goto add_sack; |
| 4074 | } | 4133 | } |
| 4075 | if (after(seq, TCP_SKB_CB(skb1)->seq)) { | 4134 | if (after(seq, TCP_SKB_CB(skb1)->seq)) { |
| 4076 | /* Partial overlap. */ | 4135 | /* Partial overlap. */ |
| 4077 | tcp_dsack_set(tp, seq, | 4136 | tcp_dsack_set(sk, seq, |
| 4078 | TCP_SKB_CB(skb1)->end_seq); | 4137 | TCP_SKB_CB(skb1)->end_seq); |
| 4079 | } else { | 4138 | } else { |
| 4080 | skb1 = skb1->prev; | 4139 | skb1 = skb1->prev; |
| @@ -4087,12 +4146,12 @@ drop: | |||
| 4087 | (struct sk_buff *)&tp->out_of_order_queue && | 4146 | (struct sk_buff *)&tp->out_of_order_queue && |
| 4088 | after(end_seq, TCP_SKB_CB(skb1)->seq)) { | 4147 | after(end_seq, TCP_SKB_CB(skb1)->seq)) { |
| 4089 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4148 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
| 4090 | tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, | 4149 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, |
| 4091 | end_seq); | 4150 | end_seq); |
| 4092 | break; | 4151 | break; |
| 4093 | } | 4152 | } |
| 4094 | __skb_unlink(skb1, &tp->out_of_order_queue); | 4153 | __skb_unlink(skb1, &tp->out_of_order_queue); |
| 4095 | tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, | 4154 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, |
| 4096 | TCP_SKB_CB(skb1)->end_seq); | 4155 | TCP_SKB_CB(skb1)->end_seq); |
| 4097 | __kfree_skb(skb1); | 4156 | __kfree_skb(skb1); |
| 4098 | } | 4157 | } |
| @@ -4123,7 +4182,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
| 4123 | struct sk_buff *next = skb->next; | 4182 | struct sk_buff *next = skb->next; |
| 4124 | __skb_unlink(skb, list); | 4183 | __skb_unlink(skb, list); |
| 4125 | __kfree_skb(skb); | 4184 | __kfree_skb(skb); |
| 4126 | NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED); | 4185 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED); |
| 4127 | skb = next; | 4186 | skb = next; |
| 4128 | continue; | 4187 | continue; |
| 4129 | } | 4188 | } |
| @@ -4191,7 +4250,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
| 4191 | struct sk_buff *next = skb->next; | 4250 | struct sk_buff *next = skb->next; |
| 4192 | __skb_unlink(skb, list); | 4251 | __skb_unlink(skb, list); |
| 4193 | __kfree_skb(skb); | 4252 | __kfree_skb(skb); |
| 4194 | NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED); | 4253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED); |
| 4195 | skb = next; | 4254 | skb = next; |
| 4196 | if (skb == tail || | 4255 | if (skb == tail || |
| 4197 | tcp_hdr(skb)->syn || | 4256 | tcp_hdr(skb)->syn || |
| @@ -4254,7 +4313,7 @@ static int tcp_prune_ofo_queue(struct sock *sk) | |||
| 4254 | int res = 0; | 4313 | int res = 0; |
| 4255 | 4314 | ||
| 4256 | if (!skb_queue_empty(&tp->out_of_order_queue)) { | 4315 | if (!skb_queue_empty(&tp->out_of_order_queue)) { |
| 4257 | NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED); | 4316 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_OFOPRUNED); |
| 4258 | __skb_queue_purge(&tp->out_of_order_queue); | 4317 | __skb_queue_purge(&tp->out_of_order_queue); |
| 4259 | 4318 | ||
| 4260 | /* Reset SACK state. A conforming SACK implementation will | 4319 | /* Reset SACK state. A conforming SACK implementation will |
| @@ -4283,7 +4342,7 @@ static int tcp_prune_queue(struct sock *sk) | |||
| 4283 | 4342 | ||
| 4284 | SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq); | 4343 | SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq); |
| 4285 | 4344 | ||
| 4286 | NET_INC_STATS_BH(LINUX_MIB_PRUNECALLED); | 4345 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PRUNECALLED); |
| 4287 | 4346 | ||
| 4288 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) | 4347 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) |
| 4289 | tcp_clamp_window(sk); | 4348 | tcp_clamp_window(sk); |
| @@ -4312,7 +4371,7 @@ static int tcp_prune_queue(struct sock *sk) | |||
| 4312 | * drop receive data on the floor. It will get retransmitted | 4371 | * drop receive data on the floor. It will get retransmitted |
| 4313 | * and hopefully then we'll have sufficient space. | 4372 | * and hopefully then we'll have sufficient space. |
| 4314 | */ | 4373 | */ |
| 4315 | NET_INC_STATS_BH(LINUX_MIB_RCVPRUNED); | 4374 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_RCVPRUNED); |
| 4316 | 4375 | ||
| 4317 | /* Massive buffer overcommit. */ | 4376 | /* Massive buffer overcommit. */ |
| 4318 | tp->pred_flags = 0; | 4377 | tp->pred_flags = 0; |
| @@ -4742,7 +4801,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 4742 | tcp_data_snd_check(sk); | 4801 | tcp_data_snd_check(sk); |
| 4743 | return 0; | 4802 | return 0; |
| 4744 | } else { /* Header too small */ | 4803 | } else { /* Header too small */ |
| 4745 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 4804 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
| 4746 | goto discard; | 4805 | goto discard; |
| 4747 | } | 4806 | } |
| 4748 | } else { | 4807 | } else { |
| @@ -4779,7 +4838,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 4779 | 4838 | ||
| 4780 | __skb_pull(skb, tcp_header_len); | 4839 | __skb_pull(skb, tcp_header_len); |
| 4781 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; | 4840 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; |
| 4782 | NET_INC_STATS_BH(LINUX_MIB_TCPHPHITSTOUSER); | 4841 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITSTOUSER); |
| 4783 | } | 4842 | } |
| 4784 | if (copied_early) | 4843 | if (copied_early) |
| 4785 | tcp_cleanup_rbuf(sk, skb->len); | 4844 | tcp_cleanup_rbuf(sk, skb->len); |
| @@ -4802,7 +4861,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 4802 | if ((int)skb->truesize > sk->sk_forward_alloc) | 4861 | if ((int)skb->truesize > sk->sk_forward_alloc) |
| 4803 | goto step5; | 4862 | goto step5; |
| 4804 | 4863 | ||
| 4805 | NET_INC_STATS_BH(LINUX_MIB_TCPHPHITS); | 4864 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS); |
| 4806 | 4865 | ||
| 4807 | /* Bulk data transfer: receiver */ | 4866 | /* Bulk data transfer: receiver */ |
| 4808 | __skb_pull(skb, tcp_header_len); | 4867 | __skb_pull(skb, tcp_header_len); |
| @@ -4846,7 +4905,7 @@ slow_path: | |||
| 4846 | if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && | 4905 | if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && |
| 4847 | tcp_paws_discard(sk, skb)) { | 4906 | tcp_paws_discard(sk, skb)) { |
| 4848 | if (!th->rst) { | 4907 | if (!th->rst) { |
| 4849 | NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED); | 4908 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
| 4850 | tcp_send_dupack(sk, skb); | 4909 | tcp_send_dupack(sk, skb); |
| 4851 | goto discard; | 4910 | goto discard; |
| 4852 | } | 4911 | } |
| @@ -4881,8 +4940,8 @@ slow_path: | |||
| 4881 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | 4940 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); |
| 4882 | 4941 | ||
| 4883 | if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { | 4942 | if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { |
| 4884 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 4943 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
| 4885 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONSYN); | 4944 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN); |
| 4886 | tcp_reset(sk); | 4945 | tcp_reset(sk); |
| 4887 | return 1; | 4946 | return 1; |
| 4888 | } | 4947 | } |
| @@ -4904,7 +4963,7 @@ step5: | |||
| 4904 | return 0; | 4963 | return 0; |
| 4905 | 4964 | ||
| 4906 | csum_error: | 4965 | csum_error: |
| 4907 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 4966 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
| 4908 | 4967 | ||
| 4909 | discard: | 4968 | discard: |
| 4910 | __kfree_skb(skb); | 4969 | __kfree_skb(skb); |
| @@ -4938,7 +4997,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 4938 | if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && | 4997 | if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && |
| 4939 | !between(tp->rx_opt.rcv_tsecr, tp->retrans_stamp, | 4998 | !between(tp->rx_opt.rcv_tsecr, tp->retrans_stamp, |
| 4940 | tcp_time_stamp)) { | 4999 | tcp_time_stamp)) { |
| 4941 | NET_INC_STATS_BH(LINUX_MIB_PAWSACTIVEREJECTED); | 5000 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSACTIVEREJECTED); |
| 4942 | goto reset_and_undo; | 5001 | goto reset_and_undo; |
| 4943 | } | 5002 | } |
| 4944 | 5003 | ||
| @@ -5222,7 +5281,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5222 | if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && | 5281 | if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && |
| 5223 | tcp_paws_discard(sk, skb)) { | 5282 | tcp_paws_discard(sk, skb)) { |
| 5224 | if (!th->rst) { | 5283 | if (!th->rst) { |
| 5225 | NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED); | 5284 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
| 5226 | tcp_send_dupack(sk, skb); | 5285 | tcp_send_dupack(sk, skb); |
| 5227 | goto discard; | 5286 | goto discard; |
| 5228 | } | 5287 | } |
| @@ -5251,7 +5310,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5251 | * Check for a SYN in window. | 5310 | * Check for a SYN in window. |
| 5252 | */ | 5311 | */ |
| 5253 | if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { | 5312 | if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { |
| 5254 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONSYN); | 5313 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN); |
| 5255 | tcp_reset(sk); | 5314 | tcp_reset(sk); |
| 5256 | return 1; | 5315 | return 1; |
| 5257 | } | 5316 | } |
| @@ -5333,7 +5392,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5333 | (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && | 5392 | (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && |
| 5334 | after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt))) { | 5393 | after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt))) { |
| 5335 | tcp_done(sk); | 5394 | tcp_done(sk); |
| 5336 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONDATA); | 5395 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONDATA); |
| 5337 | return 1; | 5396 | return 1; |
| 5338 | } | 5397 | } |
| 5339 | 5398 | ||
| @@ -5393,7 +5452,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5393 | if (sk->sk_shutdown & RCV_SHUTDOWN) { | 5452 | if (sk->sk_shutdown & RCV_SHUTDOWN) { |
| 5394 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && | 5453 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && |
| 5395 | after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { | 5454 | after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { |
| 5396 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONDATA); | 5455 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONDATA); |
| 5397 | tcp_reset(sk); | 5456 | tcp_reset(sk); |
| 5398 | return 1; | 5457 | return 1; |
| 5399 | } | 5458 | } |
| @@ -5422,6 +5481,9 @@ EXPORT_SYMBOL(sysctl_tcp_ecn); | |||
| 5422 | EXPORT_SYMBOL(sysctl_tcp_reordering); | 5481 | EXPORT_SYMBOL(sysctl_tcp_reordering); |
| 5423 | EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); | 5482 | EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); |
| 5424 | EXPORT_SYMBOL(tcp_parse_options); | 5483 | EXPORT_SYMBOL(tcp_parse_options); |
| 5484 | #ifdef CONFIG_TCP_MD5SIG | ||
| 5485 | EXPORT_SYMBOL(tcp_parse_md5sig_option); | ||
| 5486 | #endif | ||
| 5425 | EXPORT_SYMBOL(tcp_rcv_established); | 5487 | EXPORT_SYMBOL(tcp_rcv_established); |
| 5426 | EXPORT_SYMBOL(tcp_rcv_state_process); | 5488 | EXPORT_SYMBOL(tcp_rcv_state_process); |
| 5427 | EXPORT_SYMBOL(tcp_initialize_rcv_mss); | 5489 | EXPORT_SYMBOL(tcp_initialize_rcv_mss); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ffe869ac1bcf..a82df6307567 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp_ipv4.c,v 1.240 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * IPv4 specific functions | 8 | * IPv4 specific functions |
| 11 | * | 9 | * |
| 12 | * | 10 | * |
| @@ -89,10 +87,14 @@ int sysctl_tcp_low_latency __read_mostly; | |||
| 89 | #ifdef CONFIG_TCP_MD5SIG | 87 | #ifdef CONFIG_TCP_MD5SIG |
| 90 | static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, | 88 | static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, |
| 91 | __be32 addr); | 89 | __be32 addr); |
| 92 | static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, | 90 | static int tcp_v4_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key, |
| 93 | __be32 saddr, __be32 daddr, | 91 | __be32 daddr, __be32 saddr, struct tcphdr *th); |
| 94 | struct tcphdr *th, int protocol, | 92 | #else |
| 95 | unsigned int tcplen); | 93 | static inline |
| 94 | struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr) | ||
| 95 | { | ||
| 96 | return NULL; | ||
| 97 | } | ||
| 96 | #endif | 98 | #endif |
| 97 | 99 | ||
| 98 | struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { | 100 | struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { |
| @@ -172,7 +174,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 172 | inet->sport, usin->sin_port, sk, 1); | 174 | inet->sport, usin->sin_port, sk, 1); |
| 173 | if (tmp < 0) { | 175 | if (tmp < 0) { |
| 174 | if (tmp == -ENETUNREACH) | 176 | if (tmp == -ENETUNREACH) |
| 175 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 177 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
| 176 | return tmp; | 178 | return tmp; |
| 177 | } | 179 | } |
| 178 | 180 | ||
| @@ -340,16 +342,17 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
| 340 | struct sock *sk; | 342 | struct sock *sk; |
| 341 | __u32 seq; | 343 | __u32 seq; |
| 342 | int err; | 344 | int err; |
| 345 | struct net *net = dev_net(skb->dev); | ||
| 343 | 346 | ||
| 344 | if (skb->len < (iph->ihl << 2) + 8) { | 347 | if (skb->len < (iph->ihl << 2) + 8) { |
| 345 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 348 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
| 346 | return; | 349 | return; |
| 347 | } | 350 | } |
| 348 | 351 | ||
| 349 | sk = inet_lookup(dev_net(skb->dev), &tcp_hashinfo, iph->daddr, th->dest, | 352 | sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest, |
| 350 | iph->saddr, th->source, inet_iif(skb)); | 353 | iph->saddr, th->source, inet_iif(skb)); |
| 351 | if (!sk) { | 354 | if (!sk) { |
| 352 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 355 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
| 353 | return; | 356 | return; |
| 354 | } | 357 | } |
| 355 | if (sk->sk_state == TCP_TIME_WAIT) { | 358 | if (sk->sk_state == TCP_TIME_WAIT) { |
| @@ -362,7 +365,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
| 362 | * servers this needs to be solved differently. | 365 | * servers this needs to be solved differently. |
| 363 | */ | 366 | */ |
| 364 | if (sock_owned_by_user(sk)) | 367 | if (sock_owned_by_user(sk)) |
| 365 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); | 368 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); |
| 366 | 369 | ||
| 367 | if (sk->sk_state == TCP_CLOSE) | 370 | if (sk->sk_state == TCP_CLOSE) |
| 368 | goto out; | 371 | goto out; |
| @@ -371,7 +374,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
| 371 | seq = ntohl(th->seq); | 374 | seq = ntohl(th->seq); |
| 372 | if (sk->sk_state != TCP_LISTEN && | 375 | if (sk->sk_state != TCP_LISTEN && |
| 373 | !between(seq, tp->snd_una, tp->snd_nxt)) { | 376 | !between(seq, tp->snd_una, tp->snd_nxt)) { |
| 374 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); | 377 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); |
| 375 | goto out; | 378 | goto out; |
| 376 | } | 379 | } |
| 377 | 380 | ||
| @@ -418,7 +421,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
| 418 | BUG_TRAP(!req->sk); | 421 | BUG_TRAP(!req->sk); |
| 419 | 422 | ||
| 420 | if (seq != tcp_rsk(req)->snt_isn) { | 423 | if (seq != tcp_rsk(req)->snt_isn) { |
| 421 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); | 424 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); |
| 422 | goto out; | 425 | goto out; |
| 423 | } | 426 | } |
| 424 | 427 | ||
| @@ -540,6 +543,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
| 540 | #ifdef CONFIG_TCP_MD5SIG | 543 | #ifdef CONFIG_TCP_MD5SIG |
| 541 | struct tcp_md5sig_key *key; | 544 | struct tcp_md5sig_key *key; |
| 542 | #endif | 545 | #endif |
| 546 | struct net *net; | ||
| 543 | 547 | ||
| 544 | /* Never send a reset in response to a reset. */ | 548 | /* Never send a reset in response to a reset. */ |
| 545 | if (th->rst) | 549 | if (th->rst) |
| @@ -578,12 +582,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
| 578 | arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED; | 582 | arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED; |
| 579 | rep.th.doff = arg.iov[0].iov_len / 4; | 583 | rep.th.doff = arg.iov[0].iov_len / 4; |
| 580 | 584 | ||
| 581 | tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[1], | 585 | tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[1], |
| 582 | key, | 586 | key, ip_hdr(skb)->daddr, |
| 583 | ip_hdr(skb)->daddr, | 587 | ip_hdr(skb)->saddr, &rep.th); |
| 584 | ip_hdr(skb)->saddr, | ||
| 585 | &rep.th, IPPROTO_TCP, | ||
| 586 | arg.iov[0].iov_len); | ||
| 587 | } | 588 | } |
| 588 | #endif | 589 | #endif |
| 589 | arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, | 590 | arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, |
| @@ -591,20 +592,21 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
| 591 | sizeof(struct tcphdr), IPPROTO_TCP, 0); | 592 | sizeof(struct tcphdr), IPPROTO_TCP, 0); |
| 592 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 593 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
| 593 | 594 | ||
| 594 | ip_send_reply(dev_net(skb->dst->dev)->ipv4.tcp_sock, skb, | 595 | net = dev_net(skb->dst->dev); |
| 596 | ip_send_reply(net->ipv4.tcp_sock, skb, | ||
| 595 | &arg, arg.iov[0].iov_len); | 597 | &arg, arg.iov[0].iov_len); |
| 596 | 598 | ||
| 597 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 599 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
| 598 | TCP_INC_STATS_BH(TCP_MIB_OUTRSTS); | 600 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); |
| 599 | } | 601 | } |
| 600 | 602 | ||
| 601 | /* The code following below sending ACKs in SYN-RECV and TIME-WAIT states | 603 | /* The code following below sending ACKs in SYN-RECV and TIME-WAIT states |
| 602 | outside socket context is ugly, certainly. What can I do? | 604 | outside socket context is ugly, certainly. What can I do? |
| 603 | */ | 605 | */ |
| 604 | 606 | ||
| 605 | static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | 607 | static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, |
| 606 | struct sk_buff *skb, u32 seq, u32 ack, | 608 | u32 win, u32 ts, int oif, |
| 607 | u32 win, u32 ts) | 609 | struct tcp_md5sig_key *key) |
| 608 | { | 610 | { |
| 609 | struct tcphdr *th = tcp_hdr(skb); | 611 | struct tcphdr *th = tcp_hdr(skb); |
| 610 | struct { | 612 | struct { |
| @@ -616,10 +618,7 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
| 616 | ]; | 618 | ]; |
| 617 | } rep; | 619 | } rep; |
| 618 | struct ip_reply_arg arg; | 620 | struct ip_reply_arg arg; |
| 619 | #ifdef CONFIG_TCP_MD5SIG | 621 | struct net *net = dev_net(skb->dev); |
| 620 | struct tcp_md5sig_key *key; | ||
| 621 | struct tcp_md5sig_key tw_key; | ||
| 622 | #endif | ||
| 623 | 622 | ||
| 624 | memset(&rep.th, 0, sizeof(struct tcphdr)); | 623 | memset(&rep.th, 0, sizeof(struct tcphdr)); |
| 625 | memset(&arg, 0, sizeof(arg)); | 624 | memset(&arg, 0, sizeof(arg)); |
| @@ -645,23 +644,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
| 645 | rep.th.window = htons(win); | 644 | rep.th.window = htons(win); |
| 646 | 645 | ||
| 647 | #ifdef CONFIG_TCP_MD5SIG | 646 | #ifdef CONFIG_TCP_MD5SIG |
| 648 | /* | ||
| 649 | * The SKB holds an imcoming packet, but may not have a valid ->sk | ||
| 650 | * pointer. This is especially the case when we're dealing with a | ||
| 651 | * TIME_WAIT ack, because the sk structure is long gone, and only | ||
| 652 | * the tcp_timewait_sock remains. So the md5 key is stashed in that | ||
| 653 | * structure, and we use it in preference. I believe that (twsk || | ||
| 654 | * skb->sk) holds true, but we program defensively. | ||
| 655 | */ | ||
| 656 | if (!twsk && skb->sk) { | ||
| 657 | key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr); | ||
| 658 | } else if (twsk && twsk->tw_md5_keylen) { | ||
| 659 | tw_key.key = twsk->tw_md5_key; | ||
| 660 | tw_key.keylen = twsk->tw_md5_keylen; | ||
| 661 | key = &tw_key; | ||
| 662 | } else | ||
| 663 | key = NULL; | ||
| 664 | |||
| 665 | if (key) { | 647 | if (key) { |
| 666 | int offset = (ts) ? 3 : 0; | 648 | int offset = (ts) ? 3 : 0; |
| 667 | 649 | ||
| @@ -672,25 +654,22 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
| 672 | arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED; | 654 | arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED; |
| 673 | rep.th.doff = arg.iov[0].iov_len/4; | 655 | rep.th.doff = arg.iov[0].iov_len/4; |
| 674 | 656 | ||
| 675 | tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[offset], | 657 | tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[offset], |
| 676 | key, | 658 | key, ip_hdr(skb)->daddr, |
| 677 | ip_hdr(skb)->daddr, | 659 | ip_hdr(skb)->saddr, &rep.th); |
| 678 | ip_hdr(skb)->saddr, | ||
| 679 | &rep.th, IPPROTO_TCP, | ||
| 680 | arg.iov[0].iov_len); | ||
| 681 | } | 660 | } |
| 682 | #endif | 661 | #endif |
| 683 | arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, | 662 | arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, |
| 684 | ip_hdr(skb)->saddr, /* XXX */ | 663 | ip_hdr(skb)->saddr, /* XXX */ |
| 685 | arg.iov[0].iov_len, IPPROTO_TCP, 0); | 664 | arg.iov[0].iov_len, IPPROTO_TCP, 0); |
| 686 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 665 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
| 687 | if (twsk) | 666 | if (oif) |
| 688 | arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; | 667 | arg.bound_dev_if = oif; |
| 689 | 668 | ||
| 690 | ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb, | 669 | ip_send_reply(net->ipv4.tcp_sock, skb, |
| 691 | &arg, arg.iov[0].iov_len); | 670 | &arg, arg.iov[0].iov_len); |
| 692 | 671 | ||
| 693 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 672 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
| 694 | } | 673 | } |
| 695 | 674 | ||
| 696 | static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) | 675 | static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) |
| @@ -698,9 +677,12 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
| 698 | struct inet_timewait_sock *tw = inet_twsk(sk); | 677 | struct inet_timewait_sock *tw = inet_twsk(sk); |
| 699 | struct tcp_timewait_sock *tcptw = tcp_twsk(sk); | 678 | struct tcp_timewait_sock *tcptw = tcp_twsk(sk); |
| 700 | 679 | ||
| 701 | tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, | 680 | tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, |
| 702 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, | 681 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
| 703 | tcptw->tw_ts_recent); | 682 | tcptw->tw_ts_recent, |
| 683 | tw->tw_bound_dev_if, | ||
| 684 | tcp_twsk_md5_key(tcptw) | ||
| 685 | ); | ||
| 704 | 686 | ||
| 705 | inet_twsk_put(tw); | 687 | inet_twsk_put(tw); |
| 706 | } | 688 | } |
| @@ -708,9 +690,11 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
| 708 | static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, | 690 | static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, |
| 709 | struct request_sock *req) | 691 | struct request_sock *req) |
| 710 | { | 692 | { |
| 711 | tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, | 693 | tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, |
| 712 | tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, | 694 | tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, |
| 713 | req->ts_recent); | 695 | req->ts_recent, |
| 696 | 0, | ||
| 697 | tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr)); | ||
| 714 | } | 698 | } |
| 715 | 699 | ||
| 716 | /* | 700 | /* |
| @@ -1000,32 +984,13 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval, | |||
| 1000 | newkey, cmd.tcpm_keylen); | 984 | newkey, cmd.tcpm_keylen); |
| 1001 | } | 985 | } |
| 1002 | 986 | ||
| 1003 | static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, | 987 | static int tcp_v4_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, |
| 1004 | __be32 saddr, __be32 daddr, | 988 | __be32 daddr, __be32 saddr, int nbytes) |
| 1005 | struct tcphdr *th, int protocol, | ||
| 1006 | unsigned int tcplen) | ||
| 1007 | { | 989 | { |
| 1008 | struct scatterlist sg[4]; | ||
| 1009 | __u16 data_len; | ||
| 1010 | int block = 0; | ||
| 1011 | __sum16 old_checksum; | ||
| 1012 | struct tcp_md5sig_pool *hp; | ||
| 1013 | struct tcp4_pseudohdr *bp; | 990 | struct tcp4_pseudohdr *bp; |
| 1014 | struct hash_desc *desc; | 991 | struct scatterlist sg; |
| 1015 | int err; | ||
| 1016 | unsigned int nbytes = 0; | ||
| 1017 | |||
| 1018 | /* | ||
| 1019 | * Okay, so RFC2385 is turned on for this connection, | ||
| 1020 | * so we need to generate the MD5 hash for the packet now. | ||
| 1021 | */ | ||
| 1022 | |||
| 1023 | hp = tcp_get_md5sig_pool(); | ||
| 1024 | if (!hp) | ||
| 1025 | goto clear_hash_noput; | ||
| 1026 | 992 | ||
| 1027 | bp = &hp->md5_blk.ip4; | 993 | bp = &hp->md5_blk.ip4; |
| 1028 | desc = &hp->md5_desc; | ||
| 1029 | 994 | ||
| 1030 | /* | 995 | /* |
| 1031 | * 1. the TCP pseudo-header (in the order: source IP address, | 996 | * 1. the TCP pseudo-header (in the order: source IP address, |
| @@ -1035,86 +1000,96 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, | |||
| 1035 | bp->saddr = saddr; | 1000 | bp->saddr = saddr; |
| 1036 | bp->daddr = daddr; | 1001 | bp->daddr = daddr; |
| 1037 | bp->pad = 0; | 1002 | bp->pad = 0; |
| 1038 | bp->protocol = protocol; | 1003 | bp->protocol = IPPROTO_TCP; |
| 1039 | bp->len = htons(tcplen); | 1004 | bp->len = cpu_to_be16(nbytes); |
| 1040 | |||
| 1041 | sg_init_table(sg, 4); | ||
| 1042 | |||
| 1043 | sg_set_buf(&sg[block++], bp, sizeof(*bp)); | ||
| 1044 | nbytes += sizeof(*bp); | ||
| 1045 | |||
| 1046 | /* 2. the TCP header, excluding options, and assuming a | ||
| 1047 | * checksum of zero/ | ||
| 1048 | */ | ||
| 1049 | old_checksum = th->check; | ||
| 1050 | th->check = 0; | ||
| 1051 | sg_set_buf(&sg[block++], th, sizeof(struct tcphdr)); | ||
| 1052 | nbytes += sizeof(struct tcphdr); | ||
| 1053 | 1005 | ||
| 1054 | /* 3. the TCP segment data (if any) */ | 1006 | sg_init_one(&sg, bp, sizeof(*bp)); |
| 1055 | data_len = tcplen - (th->doff << 2); | 1007 | return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); |
| 1056 | if (data_len > 0) { | 1008 | } |
| 1057 | unsigned char *data = (unsigned char *)th + (th->doff << 2); | ||
| 1058 | sg_set_buf(&sg[block++], data, data_len); | ||
| 1059 | nbytes += data_len; | ||
| 1060 | } | ||
| 1061 | 1009 | ||
| 1062 | /* 4. an independently-specified key or password, known to both | 1010 | static int tcp_v4_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key, |
| 1063 | * TCPs and presumably connection-specific | 1011 | __be32 daddr, __be32 saddr, struct tcphdr *th) |
| 1064 | */ | 1012 | { |
| 1065 | sg_set_buf(&sg[block++], key->key, key->keylen); | 1013 | struct tcp_md5sig_pool *hp; |
| 1066 | nbytes += key->keylen; | 1014 | struct hash_desc *desc; |
| 1067 | 1015 | ||
| 1068 | sg_mark_end(&sg[block - 1]); | 1016 | hp = tcp_get_md5sig_pool(); |
| 1017 | if (!hp) | ||
| 1018 | goto clear_hash_noput; | ||
| 1019 | desc = &hp->md5_desc; | ||
| 1069 | 1020 | ||
| 1070 | /* Now store the Hash into the packet */ | 1021 | if (crypto_hash_init(desc)) |
| 1071 | err = crypto_hash_init(desc); | ||
| 1072 | if (err) | ||
| 1073 | goto clear_hash; | 1022 | goto clear_hash; |
| 1074 | err = crypto_hash_update(desc, sg, nbytes); | 1023 | if (tcp_v4_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2)) |
| 1075 | if (err) | ||
| 1076 | goto clear_hash; | 1024 | goto clear_hash; |
| 1077 | err = crypto_hash_final(desc, md5_hash); | 1025 | if (tcp_md5_hash_header(hp, th)) |
| 1078 | if (err) | 1026 | goto clear_hash; |
| 1027 | if (tcp_md5_hash_key(hp, key)) | ||
| 1028 | goto clear_hash; | ||
| 1029 | if (crypto_hash_final(desc, md5_hash)) | ||
| 1079 | goto clear_hash; | 1030 | goto clear_hash; |
| 1080 | 1031 | ||
| 1081 | /* Reset header, and free up the crypto */ | ||
| 1082 | tcp_put_md5sig_pool(); | 1032 | tcp_put_md5sig_pool(); |
| 1083 | th->check = old_checksum; | ||
| 1084 | |||
| 1085 | out: | ||
| 1086 | return 0; | 1033 | return 0; |
| 1034 | |||
| 1087 | clear_hash: | 1035 | clear_hash: |
| 1088 | tcp_put_md5sig_pool(); | 1036 | tcp_put_md5sig_pool(); |
| 1089 | clear_hash_noput: | 1037 | clear_hash_noput: |
| 1090 | memset(md5_hash, 0, 16); | 1038 | memset(md5_hash, 0, 16); |
| 1091 | goto out; | 1039 | return 1; |
| 1092 | } | 1040 | } |
| 1093 | 1041 | ||
| 1094 | int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, | 1042 | int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, |
| 1095 | struct sock *sk, | 1043 | struct sock *sk, struct request_sock *req, |
| 1096 | struct dst_entry *dst, | 1044 | struct sk_buff *skb) |
| 1097 | struct request_sock *req, | ||
| 1098 | struct tcphdr *th, int protocol, | ||
| 1099 | unsigned int tcplen) | ||
| 1100 | { | 1045 | { |
| 1046 | struct tcp_md5sig_pool *hp; | ||
| 1047 | struct hash_desc *desc; | ||
| 1048 | struct tcphdr *th = tcp_hdr(skb); | ||
| 1101 | __be32 saddr, daddr; | 1049 | __be32 saddr, daddr; |
| 1102 | 1050 | ||
| 1103 | if (sk) { | 1051 | if (sk) { |
| 1104 | saddr = inet_sk(sk)->saddr; | 1052 | saddr = inet_sk(sk)->saddr; |
| 1105 | daddr = inet_sk(sk)->daddr; | 1053 | daddr = inet_sk(sk)->daddr; |
| 1054 | } else if (req) { | ||
| 1055 | saddr = inet_rsk(req)->loc_addr; | ||
| 1056 | daddr = inet_rsk(req)->rmt_addr; | ||
| 1106 | } else { | 1057 | } else { |
| 1107 | struct rtable *rt = (struct rtable *)dst; | 1058 | const struct iphdr *iph = ip_hdr(skb); |
| 1108 | BUG_ON(!rt); | 1059 | saddr = iph->saddr; |
| 1109 | saddr = rt->rt_src; | 1060 | daddr = iph->daddr; |
| 1110 | daddr = rt->rt_dst; | ||
| 1111 | } | 1061 | } |
| 1112 | return tcp_v4_do_calc_md5_hash(md5_hash, key, | 1062 | |
| 1113 | saddr, daddr, | 1063 | hp = tcp_get_md5sig_pool(); |
| 1114 | th, protocol, tcplen); | 1064 | if (!hp) |
| 1065 | goto clear_hash_noput; | ||
| 1066 | desc = &hp->md5_desc; | ||
| 1067 | |||
| 1068 | if (crypto_hash_init(desc)) | ||
| 1069 | goto clear_hash; | ||
| 1070 | |||
| 1071 | if (tcp_v4_md5_hash_pseudoheader(hp, daddr, saddr, skb->len)) | ||
| 1072 | goto clear_hash; | ||
| 1073 | if (tcp_md5_hash_header(hp, th)) | ||
| 1074 | goto clear_hash; | ||
| 1075 | if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2)) | ||
| 1076 | goto clear_hash; | ||
| 1077 | if (tcp_md5_hash_key(hp, key)) | ||
| 1078 | goto clear_hash; | ||
| 1079 | if (crypto_hash_final(desc, md5_hash)) | ||
| 1080 | goto clear_hash; | ||
| 1081 | |||
| 1082 | tcp_put_md5sig_pool(); | ||
| 1083 | return 0; | ||
| 1084 | |||
| 1085 | clear_hash: | ||
| 1086 | tcp_put_md5sig_pool(); | ||
| 1087 | clear_hash_noput: | ||
| 1088 | memset(md5_hash, 0, 16); | ||
| 1089 | return 1; | ||
| 1115 | } | 1090 | } |
| 1116 | 1091 | ||
| 1117 | EXPORT_SYMBOL(tcp_v4_calc_md5_hash); | 1092 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); |
| 1118 | 1093 | ||
| 1119 | static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) | 1094 | static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) |
| 1120 | { | 1095 | { |
| @@ -1130,52 +1105,12 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) | |||
| 1130 | struct tcp_md5sig_key *hash_expected; | 1105 | struct tcp_md5sig_key *hash_expected; |
| 1131 | const struct iphdr *iph = ip_hdr(skb); | 1106 | const struct iphdr *iph = ip_hdr(skb); |
| 1132 | struct tcphdr *th = tcp_hdr(skb); | 1107 | struct tcphdr *th = tcp_hdr(skb); |
| 1133 | int length = (th->doff << 2) - sizeof(struct tcphdr); | ||
| 1134 | int genhash; | 1108 | int genhash; |
| 1135 | unsigned char *ptr; | ||
| 1136 | unsigned char newhash[16]; | 1109 | unsigned char newhash[16]; |
| 1137 | 1110 | ||
| 1138 | hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); | 1111 | hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); |
| 1112 | hash_location = tcp_parse_md5sig_option(th); | ||
| 1139 | 1113 | ||
| 1140 | /* | ||
| 1141 | * If the TCP option length is less than the TCP_MD5SIG | ||
| 1142 | * option length, then we can shortcut | ||
| 1143 | */ | ||
| 1144 | if (length < TCPOLEN_MD5SIG) { | ||
| 1145 | if (hash_expected) | ||
| 1146 | return 1; | ||
| 1147 | else | ||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /* Okay, we can't shortcut - we have to grub through the options */ | ||
| 1152 | ptr = (unsigned char *)(th + 1); | ||
| 1153 | while (length > 0) { | ||
| 1154 | int opcode = *ptr++; | ||
| 1155 | int opsize; | ||
| 1156 | |||
| 1157 | switch (opcode) { | ||
| 1158 | case TCPOPT_EOL: | ||
| 1159 | goto done_opts; | ||
| 1160 | case TCPOPT_NOP: | ||
| 1161 | length--; | ||
| 1162 | continue; | ||
| 1163 | default: | ||
| 1164 | opsize = *ptr++; | ||
| 1165 | if (opsize < 2) | ||
| 1166 | goto done_opts; | ||
| 1167 | if (opsize > length) | ||
| 1168 | goto done_opts; | ||
| 1169 | |||
| 1170 | if (opcode == TCPOPT_MD5SIG) { | ||
| 1171 | hash_location = ptr; | ||
| 1172 | goto done_opts; | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | ptr += opsize-2; | ||
| 1176 | length -= opsize; | ||
| 1177 | } | ||
| 1178 | done_opts: | ||
| 1179 | /* We've parsed the options - do we have a hash? */ | 1114 | /* We've parsed the options - do we have a hash? */ |
| 1180 | if (!hash_expected && !hash_location) | 1115 | if (!hash_expected && !hash_location) |
| 1181 | return 0; | 1116 | return 0; |
| @@ -1199,11 +1134,9 @@ done_opts: | |||
| 1199 | /* Okay, so this is hash_expected and hash_location - | 1134 | /* Okay, so this is hash_expected and hash_location - |
| 1200 | * so we need to calculate the checksum. | 1135 | * so we need to calculate the checksum. |
| 1201 | */ | 1136 | */ |
| 1202 | genhash = tcp_v4_do_calc_md5_hash(newhash, | 1137 | genhash = tcp_v4_md5_hash_skb(newhash, |
| 1203 | hash_expected, | 1138 | hash_expected, |
| 1204 | iph->saddr, iph->daddr, | 1139 | NULL, NULL, skb); |
| 1205 | th, sk->sk_protocol, | ||
| 1206 | skb->len); | ||
| 1207 | 1140 | ||
| 1208 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { | 1141 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { |
| 1209 | if (net_ratelimit()) { | 1142 | if (net_ratelimit()) { |
| @@ -1347,7 +1280,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1347 | if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL && | 1280 | if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL && |
| 1348 | (s32)(peer->tcp_ts - req->ts_recent) > | 1281 | (s32)(peer->tcp_ts - req->ts_recent) > |
| 1349 | TCP_PAWS_WINDOW) { | 1282 | TCP_PAWS_WINDOW) { |
| 1350 | NET_INC_STATS_BH(LINUX_MIB_PAWSPASSIVEREJECTED); | 1283 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); |
| 1351 | goto drop_and_release; | 1284 | goto drop_and_release; |
| 1352 | } | 1285 | } |
| 1353 | } | 1286 | } |
| @@ -1452,6 +1385,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
| 1452 | if (newkey != NULL) | 1385 | if (newkey != NULL) |
| 1453 | tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr, | 1386 | tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr, |
| 1454 | newkey, key->keylen); | 1387 | newkey, key->keylen); |
| 1388 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; | ||
| 1455 | } | 1389 | } |
| 1456 | #endif | 1390 | #endif |
| 1457 | 1391 | ||
| @@ -1461,9 +1395,9 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
| 1461 | return newsk; | 1395 | return newsk; |
| 1462 | 1396 | ||
| 1463 | exit_overflow: | 1397 | exit_overflow: |
| 1464 | NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS); | 1398 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); |
| 1465 | exit: | 1399 | exit: |
| 1466 | NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS); | 1400 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); |
| 1467 | dst_release(dst); | 1401 | dst_release(dst); |
| 1468 | return NULL; | 1402 | return NULL; |
| 1469 | } | 1403 | } |
| @@ -1590,7 +1524,7 @@ discard: | |||
| 1590 | return 0; | 1524 | return 0; |
| 1591 | 1525 | ||
| 1592 | csum_err: | 1526 | csum_err: |
| 1593 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1527 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
| 1594 | goto discard; | 1528 | goto discard; |
| 1595 | } | 1529 | } |
| 1596 | 1530 | ||
| @@ -1604,12 +1538,13 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
| 1604 | struct tcphdr *th; | 1538 | struct tcphdr *th; |
| 1605 | struct sock *sk; | 1539 | struct sock *sk; |
| 1606 | int ret; | 1540 | int ret; |
| 1541 | struct net *net = dev_net(skb->dev); | ||
| 1607 | 1542 | ||
| 1608 | if (skb->pkt_type != PACKET_HOST) | 1543 | if (skb->pkt_type != PACKET_HOST) |
| 1609 | goto discard_it; | 1544 | goto discard_it; |
| 1610 | 1545 | ||
| 1611 | /* Count it even if it's bad */ | 1546 | /* Count it even if it's bad */ |
| 1612 | TCP_INC_STATS_BH(TCP_MIB_INSEGS); | 1547 | TCP_INC_STATS_BH(net, TCP_MIB_INSEGS); |
| 1613 | 1548 | ||
| 1614 | if (!pskb_may_pull(skb, sizeof(struct tcphdr))) | 1549 | if (!pskb_may_pull(skb, sizeof(struct tcphdr))) |
| 1615 | goto discard_it; | 1550 | goto discard_it; |
| @@ -1638,7 +1573,7 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
| 1638 | TCP_SKB_CB(skb)->flags = iph->tos; | 1573 | TCP_SKB_CB(skb)->flags = iph->tos; |
| 1639 | TCP_SKB_CB(skb)->sacked = 0; | 1574 | TCP_SKB_CB(skb)->sacked = 0; |
| 1640 | 1575 | ||
| 1641 | sk = __inet_lookup(dev_net(skb->dev), &tcp_hashinfo, iph->saddr, | 1576 | sk = __inet_lookup(net, &tcp_hashinfo, iph->saddr, |
| 1642 | th->source, iph->daddr, th->dest, inet_iif(skb)); | 1577 | th->source, iph->daddr, th->dest, inet_iif(skb)); |
| 1643 | if (!sk) | 1578 | if (!sk) |
| 1644 | goto no_tcp_socket; | 1579 | goto no_tcp_socket; |
| @@ -1685,7 +1620,7 @@ no_tcp_socket: | |||
| 1685 | 1620 | ||
| 1686 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { | 1621 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { |
| 1687 | bad_packet: | 1622 | bad_packet: |
| 1688 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1623 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
| 1689 | } else { | 1624 | } else { |
| 1690 | tcp_v4_send_reset(NULL, skb); | 1625 | tcp_v4_send_reset(NULL, skb); |
| 1691 | } | 1626 | } |
| @@ -1706,7 +1641,7 @@ do_time_wait: | |||
| 1706 | } | 1641 | } |
| 1707 | 1642 | ||
| 1708 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { | 1643 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { |
| 1709 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1644 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
| 1710 | inet_twsk_put(inet_twsk(sk)); | 1645 | inet_twsk_put(inet_twsk(sk)); |
| 1711 | goto discard_it; | 1646 | goto discard_it; |
| 1712 | } | 1647 | } |
| @@ -1814,7 +1749,7 @@ struct inet_connection_sock_af_ops ipv4_specific = { | |||
| 1814 | #ifdef CONFIG_TCP_MD5SIG | 1749 | #ifdef CONFIG_TCP_MD5SIG |
| 1815 | static struct tcp_sock_af_ops tcp_sock_ipv4_specific = { | 1750 | static struct tcp_sock_af_ops tcp_sock_ipv4_specific = { |
| 1816 | .md5_lookup = tcp_v4_md5_lookup, | 1751 | .md5_lookup = tcp_v4_md5_lookup, |
| 1817 | .calc_md5_hash = tcp_v4_calc_md5_hash, | 1752 | .calc_md5_hash = tcp_v4_md5_hash_skb, |
| 1818 | .md5_add = tcp_v4_md5_add_func, | 1753 | .md5_add = tcp_v4_md5_add_func, |
| 1819 | .md5_parse = tcp_v4_parse_md5_keys, | 1754 | .md5_parse = tcp_v4_parse_md5_keys, |
| 1820 | }; | 1755 | }; |
| @@ -1871,7 +1806,7 @@ static int tcp_v4_init_sock(struct sock *sk) | |||
| 1871 | return 0; | 1806 | return 0; |
| 1872 | } | 1807 | } |
| 1873 | 1808 | ||
| 1874 | int tcp_v4_destroy_sock(struct sock *sk) | 1809 | void tcp_v4_destroy_sock(struct sock *sk) |
| 1875 | { | 1810 | { |
| 1876 | struct tcp_sock *tp = tcp_sk(sk); | 1811 | struct tcp_sock *tp = tcp_sk(sk); |
| 1877 | 1812 | ||
| @@ -1915,8 +1850,6 @@ int tcp_v4_destroy_sock(struct sock *sk) | |||
| 1915 | } | 1850 | } |
| 1916 | 1851 | ||
| 1917 | atomic_dec(&tcp_sockets_allocated); | 1852 | atomic_dec(&tcp_sockets_allocated); |
| 1918 | |||
| 1919 | return 0; | ||
| 1920 | } | 1853 | } |
| 1921 | 1854 | ||
| 1922 | EXPORT_SYMBOL(tcp_v4_destroy_sock); | 1855 | EXPORT_SYMBOL(tcp_v4_destroy_sock); |
| @@ -1959,8 +1892,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
| 1959 | req = req->dl_next; | 1892 | req = req->dl_next; |
| 1960 | while (1) { | 1893 | while (1) { |
| 1961 | while (req) { | 1894 | while (req) { |
| 1962 | if (req->rsk_ops->family == st->family && | 1895 | if (req->rsk_ops->family == st->family) { |
| 1963 | net_eq(sock_net(req->sk), net)) { | ||
| 1964 | cur = req; | 1896 | cur = req; |
| 1965 | goto out; | 1897 | goto out; |
| 1966 | } | 1898 | } |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 8245247a6ceb..204c42162660 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 10 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
| @@ -246,7 +244,7 @@ kill: | |||
| 246 | } | 244 | } |
| 247 | 245 | ||
| 248 | if (paws_reject) | 246 | if (paws_reject) |
| 249 | NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED); | 247 | NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_PAWSESTABREJECTED); |
| 250 | 248 | ||
| 251 | if (!th->rst) { | 249 | if (!th->rst) { |
| 252 | /* In this case we must reset the TIMEWAIT timer. | 250 | /* In this case we must reset the TIMEWAIT timer. |
| @@ -482,7 +480,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 482 | newtp->rx_opt.mss_clamp = req->mss; | 480 | newtp->rx_opt.mss_clamp = req->mss; |
| 483 | TCP_ECN_openreq_child(newtp, req); | 481 | TCP_ECN_openreq_child(newtp, req); |
| 484 | 482 | ||
| 485 | TCP_INC_STATS_BH(TCP_MIB_PASSIVEOPENS); | 483 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); |
| 486 | } | 484 | } |
| 487 | return newsk; | 485 | return newsk; |
| 488 | } | 486 | } |
| @@ -613,7 +611,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
| 613 | if (!(flg & TCP_FLAG_RST)) | 611 | if (!(flg & TCP_FLAG_RST)) |
| 614 | req->rsk_ops->send_ack(skb, req); | 612 | req->rsk_ops->send_ack(skb, req); |
| 615 | if (paws_reject) | 613 | if (paws_reject) |
| 616 | NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED); | 614 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
| 617 | return NULL; | 615 | return NULL; |
| 618 | } | 616 | } |
| 619 | 617 | ||
| @@ -632,7 +630,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
| 632 | * "fourth, check the SYN bit" | 630 | * "fourth, check the SYN bit" |
| 633 | */ | 631 | */ |
| 634 | if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { | 632 | if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { |
| 635 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | 633 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS); |
| 636 | goto embryonic_reset; | 634 | goto embryonic_reset; |
| 637 | } | 635 | } |
| 638 | 636 | ||
| @@ -697,7 +695,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
| 697 | } | 695 | } |
| 698 | 696 | ||
| 699 | embryonic_reset: | 697 | embryonic_reset: |
| 700 | NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS); | 698 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); |
| 701 | if (!(flg & TCP_FLAG_RST)) | 699 | if (!(flg & TCP_FLAG_RST)) |
| 702 | req->rsk_ops->send_reset(sk, skb); | 700 | req->rsk_ops->send_reset(sk, skb); |
| 703 | 701 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ad993ecb4810..a00532de2a8c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 10 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
| @@ -347,28 +345,82 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) | |||
| 347 | TCP_SKB_CB(skb)->end_seq = seq; | 345 | TCP_SKB_CB(skb)->end_seq = seq; |
| 348 | } | 346 | } |
| 349 | 347 | ||
| 350 | static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, | 348 | #define OPTION_SACK_ADVERTISE (1 << 0) |
| 351 | __u32 tstamp, __u8 **md5_hash) | 349 | #define OPTION_TS (1 << 1) |
| 352 | { | 350 | #define OPTION_MD5 (1 << 2) |
| 353 | if (tp->rx_opt.tstamp_ok) { | 351 | |
| 352 | struct tcp_out_options { | ||
| 353 | u8 options; /* bit field of OPTION_* */ | ||
| 354 | u8 ws; /* window scale, 0 to disable */ | ||
| 355 | u8 num_sack_blocks; /* number of SACK blocks to include */ | ||
| 356 | u16 mss; /* 0 to disable */ | ||
| 357 | __u32 tsval, tsecr; /* need to include OPTION_TS */ | ||
| 358 | }; | ||
| 359 | |||
| 360 | static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | ||
| 361 | const struct tcp_out_options *opts, | ||
| 362 | __u8 **md5_hash) { | ||
| 363 | if (unlikely(OPTION_MD5 & opts->options)) { | ||
| 364 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 365 | (TCPOPT_NOP << 16) | | ||
| 366 | (TCPOPT_MD5SIG << 8) | | ||
| 367 | TCPOLEN_MD5SIG); | ||
| 368 | *md5_hash = (__u8 *)ptr; | ||
| 369 | ptr += 4; | ||
| 370 | } else { | ||
| 371 | *md5_hash = NULL; | ||
| 372 | } | ||
| 373 | |||
| 374 | if (likely(OPTION_TS & opts->options)) { | ||
| 375 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) { | ||
| 376 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | | ||
| 377 | (TCPOLEN_SACK_PERM << 16) | | ||
| 378 | (TCPOPT_TIMESTAMP << 8) | | ||
| 379 | TCPOLEN_TIMESTAMP); | ||
| 380 | } else { | ||
| 381 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 382 | (TCPOPT_NOP << 16) | | ||
| 383 | (TCPOPT_TIMESTAMP << 8) | | ||
| 384 | TCPOLEN_TIMESTAMP); | ||
| 385 | } | ||
| 386 | *ptr++ = htonl(opts->tsval); | ||
| 387 | *ptr++ = htonl(opts->tsecr); | ||
| 388 | } | ||
| 389 | |||
| 390 | if (unlikely(opts->mss)) { | ||
| 391 | *ptr++ = htonl((TCPOPT_MSS << 24) | | ||
| 392 | (TCPOLEN_MSS << 16) | | ||
| 393 | opts->mss); | ||
| 394 | } | ||
| 395 | |||
| 396 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options && | ||
| 397 | !(OPTION_TS & opts->options))) { | ||
| 354 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 398 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
| 355 | (TCPOPT_NOP << 16) | | 399 | (TCPOPT_NOP << 16) | |
| 356 | (TCPOPT_TIMESTAMP << 8) | | 400 | (TCPOPT_SACK_PERM << 8) | |
| 357 | TCPOLEN_TIMESTAMP); | 401 | TCPOLEN_SACK_PERM); |
| 358 | *ptr++ = htonl(tstamp); | 402 | } |
| 359 | *ptr++ = htonl(tp->rx_opt.ts_recent); | 403 | |
| 404 | if (unlikely(opts->ws)) { | ||
| 405 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 406 | (TCPOPT_WINDOW << 16) | | ||
| 407 | (TCPOLEN_WINDOW << 8) | | ||
| 408 | opts->ws); | ||
| 360 | } | 409 | } |
| 361 | if (tp->rx_opt.eff_sacks) { | 410 | |
| 362 | struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks; | 411 | if (unlikely(opts->num_sack_blocks)) { |
| 412 | struct tcp_sack_block *sp = tp->rx_opt.dsack ? | ||
| 413 | tp->duplicate_sack : tp->selective_acks; | ||
| 363 | int this_sack; | 414 | int this_sack; |
| 364 | 415 | ||
| 365 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 416 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
| 366 | (TCPOPT_NOP << 16) | | 417 | (TCPOPT_NOP << 16) | |
| 367 | (TCPOPT_SACK << 8) | | 418 | (TCPOPT_SACK << 8) | |
| 368 | (TCPOLEN_SACK_BASE + (tp->rx_opt.eff_sacks * | 419 | (TCPOLEN_SACK_BASE + (opts->num_sack_blocks * |
| 369 | TCPOLEN_SACK_PERBLOCK))); | 420 | TCPOLEN_SACK_PERBLOCK))); |
| 370 | 421 | ||
| 371 | for (this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) { | 422 | for (this_sack = 0; this_sack < opts->num_sack_blocks; |
| 423 | ++this_sack) { | ||
| 372 | *ptr++ = htonl(sp[this_sack].start_seq); | 424 | *ptr++ = htonl(sp[this_sack].start_seq); |
| 373 | *ptr++ = htonl(sp[this_sack].end_seq); | 425 | *ptr++ = htonl(sp[this_sack].end_seq); |
| 374 | } | 426 | } |
| @@ -378,81 +430,137 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, | |||
| 378 | tp->rx_opt.eff_sacks--; | 430 | tp->rx_opt.eff_sacks--; |
| 379 | } | 431 | } |
| 380 | } | 432 | } |
| 433 | } | ||
| 434 | |||
| 435 | static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb, | ||
| 436 | struct tcp_out_options *opts, | ||
| 437 | struct tcp_md5sig_key **md5) { | ||
| 438 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 439 | unsigned size = 0; | ||
| 440 | |||
| 381 | #ifdef CONFIG_TCP_MD5SIG | 441 | #ifdef CONFIG_TCP_MD5SIG |
| 382 | if (md5_hash) { | 442 | *md5 = tp->af_specific->md5_lookup(sk, sk); |
| 383 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 443 | if (*md5) { |
| 384 | (TCPOPT_NOP << 16) | | 444 | opts->options |= OPTION_MD5; |
| 385 | (TCPOPT_MD5SIG << 8) | | 445 | size += TCPOLEN_MD5SIG_ALIGNED; |
| 386 | TCPOLEN_MD5SIG); | ||
| 387 | *md5_hash = (__u8 *)ptr; | ||
| 388 | } | 446 | } |
| 447 | #else | ||
| 448 | *md5 = NULL; | ||
| 389 | #endif | 449 | #endif |
| 450 | |||
| 451 | /* We always get an MSS option. The option bytes which will be seen in | ||
| 452 | * normal data packets should timestamps be used, must be in the MSS | ||
| 453 | * advertised. But we subtract them from tp->mss_cache so that | ||
| 454 | * calculations in tcp_sendmsg are simpler etc. So account for this | ||
| 455 | * fact here if necessary. If we don't do this correctly, as a | ||
| 456 | * receiver we won't recognize data packets as being full sized when we | ||
| 457 | * should, and thus we won't abide by the delayed ACK rules correctly. | ||
| 458 | * SACKs don't matter, we never delay an ACK when we have any of those | ||
| 459 | * going out. */ | ||
| 460 | opts->mss = tcp_advertise_mss(sk); | ||
| 461 | size += TCPOLEN_MSS_ALIGNED; | ||
| 462 | |||
| 463 | if (likely(sysctl_tcp_timestamps && *md5 == NULL)) { | ||
| 464 | opts->options |= OPTION_TS; | ||
| 465 | opts->tsval = TCP_SKB_CB(skb)->when; | ||
| 466 | opts->tsecr = tp->rx_opt.ts_recent; | ||
| 467 | size += TCPOLEN_TSTAMP_ALIGNED; | ||
| 468 | } | ||
| 469 | if (likely(sysctl_tcp_window_scaling)) { | ||
| 470 | opts->ws = tp->rx_opt.rcv_wscale; | ||
| 471 | size += TCPOLEN_WSCALE_ALIGNED; | ||
| 472 | } | ||
| 473 | if (likely(sysctl_tcp_sack)) { | ||
| 474 | opts->options |= OPTION_SACK_ADVERTISE; | ||
| 475 | if (unlikely(!(OPTION_TS & opts->options))) | ||
| 476 | size += TCPOLEN_SACKPERM_ALIGNED; | ||
| 477 | } | ||
| 478 | |||
| 479 | return size; | ||
| 390 | } | 480 | } |
| 391 | 481 | ||
| 392 | /* Construct a tcp options header for a SYN or SYN_ACK packet. | 482 | static unsigned tcp_synack_options(struct sock *sk, |
| 393 | * If this is every changed make sure to change the definition of | 483 | struct request_sock *req, |
| 394 | * MAX_SYN_SIZE to match the new maximum number of options that you | 484 | unsigned mss, struct sk_buff *skb, |
| 395 | * can generate. | 485 | struct tcp_out_options *opts, |
| 396 | * | 486 | struct tcp_md5sig_key **md5) { |
| 397 | * Note - that with the RFC2385 TCP option, we make room for the | 487 | unsigned size = 0; |
| 398 | * 16 byte MD5 hash. This will be filled in later, so the pointer for the | 488 | struct inet_request_sock *ireq = inet_rsk(req); |
| 399 | * location to be filled is passed back up. | 489 | char doing_ts; |
| 400 | */ | 490 | |
| 401 | static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack, | ||
| 402 | int offer_wscale, int wscale, __u32 tstamp, | ||
| 403 | __u32 ts_recent, __u8 **md5_hash) | ||
| 404 | { | ||
| 405 | /* We always get an MSS option. | ||
| 406 | * The option bytes which will be seen in normal data | ||
| 407 | * packets should timestamps be used, must be in the MSS | ||
| 408 | * advertised. But we subtract them from tp->mss_cache so | ||
| 409 | * that calculations in tcp_sendmsg are simpler etc. | ||
| 410 | * So account for this fact here if necessary. If we | ||
| 411 | * don't do this correctly, as a receiver we won't | ||
| 412 | * recognize data packets as being full sized when we | ||
| 413 | * should, and thus we won't abide by the delayed ACK | ||
| 414 | * rules correctly. | ||
| 415 | * SACKs don't matter, we never delay an ACK when we | ||
| 416 | * have any of those going out. | ||
| 417 | */ | ||
| 418 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | ||
| 419 | if (ts) { | ||
| 420 | if (sack) | ||
| 421 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | | ||
| 422 | (TCPOLEN_SACK_PERM << 16) | | ||
| 423 | (TCPOPT_TIMESTAMP << 8) | | ||
| 424 | TCPOLEN_TIMESTAMP); | ||
| 425 | else | ||
| 426 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 427 | (TCPOPT_NOP << 16) | | ||
| 428 | (TCPOPT_TIMESTAMP << 8) | | ||
| 429 | TCPOLEN_TIMESTAMP); | ||
| 430 | *ptr++ = htonl(tstamp); /* TSVAL */ | ||
| 431 | *ptr++ = htonl(ts_recent); /* TSECR */ | ||
| 432 | } else if (sack) | ||
| 433 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 434 | (TCPOPT_NOP << 16) | | ||
| 435 | (TCPOPT_SACK_PERM << 8) | | ||
| 436 | TCPOLEN_SACK_PERM); | ||
| 437 | if (offer_wscale) | ||
| 438 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 439 | (TCPOPT_WINDOW << 16) | | ||
| 440 | (TCPOLEN_WINDOW << 8) | | ||
| 441 | (wscale)); | ||
| 442 | #ifdef CONFIG_TCP_MD5SIG | 491 | #ifdef CONFIG_TCP_MD5SIG |
| 443 | /* | 492 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); |
| 444 | * If MD5 is enabled, then we set the option, and include the size | 493 | if (*md5) { |
| 445 | * (always 18). The actual MD5 hash is added just before the | 494 | opts->options |= OPTION_MD5; |
| 446 | * packet is sent. | 495 | size += TCPOLEN_MD5SIG_ALIGNED; |
| 447 | */ | ||
| 448 | if (md5_hash) { | ||
| 449 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
| 450 | (TCPOPT_NOP << 16) | | ||
| 451 | (TCPOPT_MD5SIG << 8) | | ||
| 452 | TCPOLEN_MD5SIG); | ||
| 453 | *md5_hash = (__u8 *)ptr; | ||
| 454 | } | 496 | } |
| 497 | #else | ||
| 498 | *md5 = NULL; | ||
| 455 | #endif | 499 | #endif |
| 500 | |||
| 501 | /* we can't fit any SACK blocks in a packet with MD5 + TS | ||
| 502 | options. There was discussion about disabling SACK rather than TS in | ||
| 503 | order to fit in better with old, buggy kernels, but that was deemed | ||
| 504 | to be unnecessary. */ | ||
| 505 | doing_ts = ireq->tstamp_ok && !(*md5 && ireq->sack_ok); | ||
| 506 | |||
| 507 | opts->mss = mss; | ||
| 508 | size += TCPOLEN_MSS_ALIGNED; | ||
| 509 | |||
| 510 | if (likely(ireq->wscale_ok)) { | ||
| 511 | opts->ws = ireq->rcv_wscale; | ||
| 512 | size += TCPOLEN_WSCALE_ALIGNED; | ||
| 513 | } | ||
| 514 | if (likely(doing_ts)) { | ||
| 515 | opts->options |= OPTION_TS; | ||
| 516 | opts->tsval = TCP_SKB_CB(skb)->when; | ||
| 517 | opts->tsecr = req->ts_recent; | ||
| 518 | size += TCPOLEN_TSTAMP_ALIGNED; | ||
| 519 | } | ||
| 520 | if (likely(ireq->sack_ok)) { | ||
| 521 | opts->options |= OPTION_SACK_ADVERTISE; | ||
| 522 | if (unlikely(!doing_ts)) | ||
| 523 | size += TCPOLEN_SACKPERM_ALIGNED; | ||
| 524 | } | ||
| 525 | |||
| 526 | return size; | ||
| 527 | } | ||
| 528 | |||
| 529 | static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb, | ||
| 530 | struct tcp_out_options *opts, | ||
| 531 | struct tcp_md5sig_key **md5) { | ||
| 532 | struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; | ||
| 533 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 534 | unsigned size = 0; | ||
| 535 | |||
| 536 | #ifdef CONFIG_TCP_MD5SIG | ||
| 537 | *md5 = tp->af_specific->md5_lookup(sk, sk); | ||
| 538 | if (unlikely(*md5)) { | ||
| 539 | opts->options |= OPTION_MD5; | ||
| 540 | size += TCPOLEN_MD5SIG_ALIGNED; | ||
| 541 | } | ||
| 542 | #else | ||
| 543 | *md5 = NULL; | ||
| 544 | #endif | ||
| 545 | |||
| 546 | if (likely(tp->rx_opt.tstamp_ok)) { | ||
| 547 | opts->options |= OPTION_TS; | ||
| 548 | opts->tsval = tcb ? tcb->when : 0; | ||
| 549 | opts->tsecr = tp->rx_opt.ts_recent; | ||
| 550 | size += TCPOLEN_TSTAMP_ALIGNED; | ||
| 551 | } | ||
| 552 | |||
| 553 | if (unlikely(tp->rx_opt.eff_sacks)) { | ||
| 554 | const unsigned remaining = MAX_TCP_OPTION_SPACE - size; | ||
| 555 | opts->num_sack_blocks = | ||
| 556 | min_t(unsigned, tp->rx_opt.eff_sacks, | ||
| 557 | (remaining - TCPOLEN_SACK_BASE_ALIGNED) / | ||
| 558 | TCPOLEN_SACK_PERBLOCK); | ||
| 559 | size += TCPOLEN_SACK_BASE_ALIGNED + | ||
| 560 | opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; | ||
| 561 | } | ||
| 562 | |||
| 563 | return size; | ||
| 456 | } | 564 | } |
| 457 | 565 | ||
| 458 | /* This routine actually transmits TCP packets queued in by | 566 | /* This routine actually transmits TCP packets queued in by |
| @@ -473,13 +581,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 473 | struct inet_sock *inet; | 581 | struct inet_sock *inet; |
| 474 | struct tcp_sock *tp; | 582 | struct tcp_sock *tp; |
| 475 | struct tcp_skb_cb *tcb; | 583 | struct tcp_skb_cb *tcb; |
| 476 | int tcp_header_size; | 584 | struct tcp_out_options opts; |
| 477 | #ifdef CONFIG_TCP_MD5SIG | 585 | unsigned tcp_options_size, tcp_header_size; |
| 478 | struct tcp_md5sig_key *md5; | 586 | struct tcp_md5sig_key *md5; |
| 479 | __u8 *md5_hash_location; | 587 | __u8 *md5_hash_location; |
| 480 | #endif | ||
| 481 | struct tcphdr *th; | 588 | struct tcphdr *th; |
| 482 | int sysctl_flags; | ||
| 483 | int err; | 589 | int err; |
| 484 | 590 | ||
| 485 | BUG_ON(!skb || !tcp_skb_pcount(skb)); | 591 | BUG_ON(!skb || !tcp_skb_pcount(skb)); |
| @@ -502,50 +608,18 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 502 | inet = inet_sk(sk); | 608 | inet = inet_sk(sk); |
| 503 | tp = tcp_sk(sk); | 609 | tp = tcp_sk(sk); |
| 504 | tcb = TCP_SKB_CB(skb); | 610 | tcb = TCP_SKB_CB(skb); |
| 505 | tcp_header_size = tp->tcp_header_len; | 611 | memset(&opts, 0, sizeof(opts)); |
| 506 | |||
| 507 | #define SYSCTL_FLAG_TSTAMPS 0x1 | ||
| 508 | #define SYSCTL_FLAG_WSCALE 0x2 | ||
| 509 | #define SYSCTL_FLAG_SACK 0x4 | ||
| 510 | 612 | ||
| 511 | sysctl_flags = 0; | 613 | if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) |
| 512 | if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) { | 614 | tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5); |
| 513 | tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS; | 615 | else |
| 514 | if (sysctl_tcp_timestamps) { | 616 | tcp_options_size = tcp_established_options(sk, skb, &opts, |
| 515 | tcp_header_size += TCPOLEN_TSTAMP_ALIGNED; | 617 | &md5); |
| 516 | sysctl_flags |= SYSCTL_FLAG_TSTAMPS; | 618 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
| 517 | } | ||
| 518 | if (sysctl_tcp_window_scaling) { | ||
| 519 | tcp_header_size += TCPOLEN_WSCALE_ALIGNED; | ||
| 520 | sysctl_flags |= SYSCTL_FLAG_WSCALE; | ||
| 521 | } | ||
| 522 | if (sysctl_tcp_sack) { | ||
| 523 | sysctl_flags |= SYSCTL_FLAG_SACK; | ||
| 524 | if (!(sysctl_flags & SYSCTL_FLAG_TSTAMPS)) | ||
| 525 | tcp_header_size += TCPOLEN_SACKPERM_ALIGNED; | ||
| 526 | } | ||
| 527 | } else if (unlikely(tp->rx_opt.eff_sacks)) { | ||
| 528 | /* A SACK is 2 pad bytes, a 2 byte header, plus | ||
| 529 | * 2 32-bit sequence numbers for each SACK block. | ||
| 530 | */ | ||
| 531 | tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED + | ||
| 532 | (tp->rx_opt.eff_sacks * | ||
| 533 | TCPOLEN_SACK_PERBLOCK)); | ||
| 534 | } | ||
| 535 | 619 | ||
| 536 | if (tcp_packets_in_flight(tp) == 0) | 620 | if (tcp_packets_in_flight(tp) == 0) |
| 537 | tcp_ca_event(sk, CA_EVENT_TX_START); | 621 | tcp_ca_event(sk, CA_EVENT_TX_START); |
| 538 | 622 | ||
| 539 | #ifdef CONFIG_TCP_MD5SIG | ||
| 540 | /* | ||
| 541 | * Are we doing MD5 on this segment? If so - make | ||
| 542 | * room for it. | ||
| 543 | */ | ||
| 544 | md5 = tp->af_specific->md5_lookup(sk, sk); | ||
| 545 | if (md5) | ||
| 546 | tcp_header_size += TCPOLEN_MD5SIG_ALIGNED; | ||
| 547 | #endif | ||
| 548 | |||
| 549 | skb_push(skb, tcp_header_size); | 623 | skb_push(skb, tcp_header_size); |
| 550 | skb_reset_transport_header(skb); | 624 | skb_reset_transport_header(skb); |
| 551 | skb_set_owner_w(skb, sk); | 625 | skb_set_owner_w(skb, sk); |
| @@ -576,39 +650,16 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 576 | th->urg = 1; | 650 | th->urg = 1; |
| 577 | } | 651 | } |
| 578 | 652 | ||
| 579 | if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) { | 653 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); |
| 580 | tcp_syn_build_options((__be32 *)(th + 1), | 654 | if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0)) |
| 581 | tcp_advertise_mss(sk), | ||
| 582 | (sysctl_flags & SYSCTL_FLAG_TSTAMPS), | ||
| 583 | (sysctl_flags & SYSCTL_FLAG_SACK), | ||
| 584 | (sysctl_flags & SYSCTL_FLAG_WSCALE), | ||
| 585 | tp->rx_opt.rcv_wscale, | ||
| 586 | tcb->when, | ||
| 587 | tp->rx_opt.ts_recent, | ||
| 588 | |||
| 589 | #ifdef CONFIG_TCP_MD5SIG | ||
| 590 | md5 ? &md5_hash_location : | ||
| 591 | #endif | ||
| 592 | NULL); | ||
| 593 | } else { | ||
| 594 | tcp_build_and_update_options((__be32 *)(th + 1), | ||
| 595 | tp, tcb->when, | ||
| 596 | #ifdef CONFIG_TCP_MD5SIG | ||
| 597 | md5 ? &md5_hash_location : | ||
| 598 | #endif | ||
| 599 | NULL); | ||
| 600 | TCP_ECN_send(sk, skb, tcp_header_size); | 655 | TCP_ECN_send(sk, skb, tcp_header_size); |
| 601 | } | ||
| 602 | 656 | ||
| 603 | #ifdef CONFIG_TCP_MD5SIG | 657 | #ifdef CONFIG_TCP_MD5SIG |
| 604 | /* Calculate the MD5 hash, as we have all we need now */ | 658 | /* Calculate the MD5 hash, as we have all we need now */ |
| 605 | if (md5) { | 659 | if (md5) { |
| 660 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | ||
| 606 | tp->af_specific->calc_md5_hash(md5_hash_location, | 661 | tp->af_specific->calc_md5_hash(md5_hash_location, |
| 607 | md5, | 662 | md5, sk, NULL, skb); |
| 608 | sk, NULL, NULL, | ||
| 609 | tcp_hdr(skb), | ||
| 610 | sk->sk_protocol, | ||
| 611 | skb->len); | ||
| 612 | } | 663 | } |
| 613 | #endif | 664 | #endif |
| 614 | 665 | ||
| @@ -621,7 +672,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 621 | tcp_event_data_sent(tp, skb, sk); | 672 | tcp_event_data_sent(tp, skb, sk); |
| 622 | 673 | ||
| 623 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) | 674 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) |
| 624 | TCP_INC_STATS(TCP_MIB_OUTSEGS); | 675 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); |
| 625 | 676 | ||
| 626 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 677 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
| 627 | if (likely(err <= 0)) | 678 | if (likely(err <= 0)) |
| @@ -630,10 +681,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 630 | tcp_enter_cwr(sk, 1); | 681 | tcp_enter_cwr(sk, 1); |
| 631 | 682 | ||
| 632 | return net_xmit_eval(err); | 683 | return net_xmit_eval(err); |
| 633 | |||
| 634 | #undef SYSCTL_FLAG_TSTAMPS | ||
| 635 | #undef SYSCTL_FLAG_WSCALE | ||
| 636 | #undef SYSCTL_FLAG_SACK | ||
| 637 | } | 684 | } |
| 638 | 685 | ||
| 639 | /* This routine just queue's the buffer | 686 | /* This routine just queue's the buffer |
| @@ -974,6 +1021,9 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
| 974 | u32 mss_now; | 1021 | u32 mss_now; |
| 975 | u16 xmit_size_goal; | 1022 | u16 xmit_size_goal; |
| 976 | int doing_tso = 0; | 1023 | int doing_tso = 0; |
| 1024 | unsigned header_len; | ||
| 1025 | struct tcp_out_options opts; | ||
| 1026 | struct tcp_md5sig_key *md5; | ||
| 977 | 1027 | ||
| 978 | mss_now = tp->mss_cache; | 1028 | mss_now = tp->mss_cache; |
| 979 | 1029 | ||
| @@ -986,14 +1036,16 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
| 986 | mss_now = tcp_sync_mss(sk, mtu); | 1036 | mss_now = tcp_sync_mss(sk, mtu); |
| 987 | } | 1037 | } |
| 988 | 1038 | ||
| 989 | if (tp->rx_opt.eff_sacks) | 1039 | header_len = tcp_established_options(sk, NULL, &opts, &md5) + |
| 990 | mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + | 1040 | sizeof(struct tcphdr); |
| 991 | (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); | 1041 | /* The mss_cache is sized based on tp->tcp_header_len, which assumes |
| 992 | 1042 | * some common options. If this is an odd packet (because we have SACK | |
| 993 | #ifdef CONFIG_TCP_MD5SIG | 1043 | * blocks etc) then our calculated header_len will be different, and |
| 994 | if (tp->af_specific->md5_lookup(sk, sk)) | 1044 | * we have to adjust mss_now correspondingly */ |
| 995 | mss_now -= TCPOLEN_MD5SIG_ALIGNED; | 1045 | if (header_len != tp->tcp_header_len) { |
| 996 | #endif | 1046 | int delta = (int) header_len - tp->tcp_header_len; |
| 1047 | mss_now -= delta; | ||
| 1048 | } | ||
| 997 | 1049 | ||
| 998 | xmit_size_goal = mss_now; | 1050 | xmit_size_goal = mss_now; |
| 999 | 1051 | ||
| @@ -1913,7 +1965,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 1913 | 1965 | ||
| 1914 | if (err == 0) { | 1966 | if (err == 0) { |
| 1915 | /* Update global TCP statistics. */ | 1967 | /* Update global TCP statistics. */ |
| 1916 | TCP_INC_STATS(TCP_MIB_RETRANSSEGS); | 1968 | TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); |
| 1917 | 1969 | ||
| 1918 | tp->total_retrans++; | 1970 | tp->total_retrans++; |
| 1919 | 1971 | ||
| @@ -1988,14 +2040,17 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
| 1988 | 2040 | ||
| 1989 | if (sacked & TCPCB_LOST) { | 2041 | if (sacked & TCPCB_LOST) { |
| 1990 | if (!(sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) { | 2042 | if (!(sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) { |
| 2043 | int mib_idx; | ||
| 2044 | |||
| 1991 | if (tcp_retransmit_skb(sk, skb)) { | 2045 | if (tcp_retransmit_skb(sk, skb)) { |
| 1992 | tp->retransmit_skb_hint = NULL; | 2046 | tp->retransmit_skb_hint = NULL; |
| 1993 | return; | 2047 | return; |
| 1994 | } | 2048 | } |
| 1995 | if (icsk->icsk_ca_state != TCP_CA_Loss) | 2049 | if (icsk->icsk_ca_state != TCP_CA_Loss) |
| 1996 | NET_INC_STATS_BH(LINUX_MIB_TCPFASTRETRANS); | 2050 | mib_idx = LINUX_MIB_TCPFASTRETRANS; |
| 1997 | else | 2051 | else |
| 1998 | NET_INC_STATS_BH(LINUX_MIB_TCPSLOWSTARTRETRANS); | 2052 | mib_idx = LINUX_MIB_TCPSLOWSTARTRETRANS; |
| 2053 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 1999 | 2054 | ||
| 2000 | if (skb == tcp_write_queue_head(sk)) | 2055 | if (skb == tcp_write_queue_head(sk)) |
| 2001 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 2056 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
| @@ -2065,7 +2120,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
| 2065 | inet_csk(sk)->icsk_rto, | 2120 | inet_csk(sk)->icsk_rto, |
| 2066 | TCP_RTO_MAX); | 2121 | TCP_RTO_MAX); |
| 2067 | 2122 | ||
| 2068 | NET_INC_STATS_BH(LINUX_MIB_TCPFORWARDRETRANS); | 2123 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFORWARDRETRANS); |
| 2069 | } | 2124 | } |
| 2070 | } | 2125 | } |
| 2071 | 2126 | ||
| @@ -2119,7 +2174,7 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority) | |||
| 2119 | /* NOTE: No TCP options attached and we never retransmit this. */ | 2174 | /* NOTE: No TCP options attached and we never retransmit this. */ |
| 2120 | skb = alloc_skb(MAX_TCP_HEADER, priority); | 2175 | skb = alloc_skb(MAX_TCP_HEADER, priority); |
| 2121 | if (!skb) { | 2176 | if (!skb) { |
| 2122 | NET_INC_STATS(LINUX_MIB_TCPABORTFAILED); | 2177 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTFAILED); |
| 2123 | return; | 2178 | return; |
| 2124 | } | 2179 | } |
| 2125 | 2180 | ||
| @@ -2130,9 +2185,9 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority) | |||
| 2130 | /* Send it off. */ | 2185 | /* Send it off. */ |
| 2131 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2186 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
| 2132 | if (tcp_transmit_skb(sk, skb, 0, priority)) | 2187 | if (tcp_transmit_skb(sk, skb, 0, priority)) |
| 2133 | NET_INC_STATS(LINUX_MIB_TCPABORTFAILED); | 2188 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTFAILED); |
| 2134 | 2189 | ||
| 2135 | TCP_INC_STATS(TCP_MIB_OUTRSTS); | 2190 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTRSTS); |
| 2136 | } | 2191 | } |
| 2137 | 2192 | ||
| 2138 | /* WARNING: This routine must only be called when we have already sent | 2193 | /* WARNING: This routine must only be called when we have already sent |
| @@ -2180,11 +2235,10 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2180 | struct tcp_sock *tp = tcp_sk(sk); | 2235 | struct tcp_sock *tp = tcp_sk(sk); |
| 2181 | struct tcphdr *th; | 2236 | struct tcphdr *th; |
| 2182 | int tcp_header_size; | 2237 | int tcp_header_size; |
| 2238 | struct tcp_out_options opts; | ||
| 2183 | struct sk_buff *skb; | 2239 | struct sk_buff *skb; |
| 2184 | #ifdef CONFIG_TCP_MD5SIG | ||
| 2185 | struct tcp_md5sig_key *md5; | 2240 | struct tcp_md5sig_key *md5; |
| 2186 | __u8 *md5_hash_location; | 2241 | __u8 *md5_hash_location; |
| 2187 | #endif | ||
| 2188 | 2242 | ||
| 2189 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); | 2243 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); |
| 2190 | if (skb == NULL) | 2244 | if (skb == NULL) |
| @@ -2195,18 +2249,27 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2195 | 2249 | ||
| 2196 | skb->dst = dst_clone(dst); | 2250 | skb->dst = dst_clone(dst); |
| 2197 | 2251 | ||
| 2198 | tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + | 2252 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ |
| 2199 | (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + | 2253 | __u8 rcv_wscale; |
| 2200 | (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + | 2254 | /* Set this up on the first call only */ |
| 2201 | /* SACK_PERM is in the place of NOP NOP of TS */ | 2255 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); |
| 2202 | ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); | 2256 | /* tcp_full_space because it is guaranteed to be the first packet */ |
| 2257 | tcp_select_initial_window(tcp_full_space(sk), | ||
| 2258 | dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | ||
| 2259 | &req->rcv_wnd, | ||
| 2260 | &req->window_clamp, | ||
| 2261 | ireq->wscale_ok, | ||
| 2262 | &rcv_wscale); | ||
| 2263 | ireq->rcv_wscale = rcv_wscale; | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | memset(&opts, 0, sizeof(opts)); | ||
| 2267 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | ||
| 2268 | tcp_header_size = tcp_synack_options(sk, req, | ||
| 2269 | dst_metric(dst, RTAX_ADVMSS), | ||
| 2270 | skb, &opts, &md5) + | ||
| 2271 | sizeof(struct tcphdr); | ||
| 2203 | 2272 | ||
| 2204 | #ifdef CONFIG_TCP_MD5SIG | ||
| 2205 | /* Are we doing MD5 on this segment? If so - make room for it */ | ||
| 2206 | md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); | ||
| 2207 | if (md5) | ||
| 2208 | tcp_header_size += TCPOLEN_MD5SIG_ALIGNED; | ||
| 2209 | #endif | ||
| 2210 | skb_push(skb, tcp_header_size); | 2273 | skb_push(skb, tcp_header_size); |
| 2211 | skb_reset_transport_header(skb); | 2274 | skb_reset_transport_header(skb); |
| 2212 | 2275 | ||
| @@ -2224,19 +2287,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2224 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); | 2287 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); |
| 2225 | th->seq = htonl(TCP_SKB_CB(skb)->seq); | 2288 | th->seq = htonl(TCP_SKB_CB(skb)->seq); |
| 2226 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); | 2289 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); |
| 2227 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ | ||
| 2228 | __u8 rcv_wscale; | ||
| 2229 | /* Set this up on the first call only */ | ||
| 2230 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); | ||
| 2231 | /* tcp_full_space because it is guaranteed to be the first packet */ | ||
| 2232 | tcp_select_initial_window(tcp_full_space(sk), | ||
| 2233 | dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | ||
| 2234 | &req->rcv_wnd, | ||
| 2235 | &req->window_clamp, | ||
| 2236 | ireq->wscale_ok, | ||
| 2237 | &rcv_wscale); | ||
| 2238 | ireq->rcv_wscale = rcv_wscale; | ||
| 2239 | } | ||
| 2240 | 2290 | ||
| 2241 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ | 2291 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ |
| 2242 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2292 | th->window = htons(min(req->rcv_wnd, 65535U)); |
| @@ -2245,29 +2295,15 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2245 | TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); | 2295 | TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); |
| 2246 | else | 2296 | else |
| 2247 | #endif | 2297 | #endif |
| 2248 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2298 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); |
| 2249 | tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok, | ||
| 2250 | ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale, | ||
| 2251 | TCP_SKB_CB(skb)->when, | ||
| 2252 | req->ts_recent, | ||
| 2253 | ( | ||
| 2254 | #ifdef CONFIG_TCP_MD5SIG | ||
| 2255 | md5 ? &md5_hash_location : | ||
| 2256 | #endif | ||
| 2257 | NULL) | ||
| 2258 | ); | ||
| 2259 | |||
| 2260 | th->doff = (tcp_header_size >> 2); | 2299 | th->doff = (tcp_header_size >> 2); |
| 2261 | TCP_INC_STATS(TCP_MIB_OUTSEGS); | 2300 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); |
| 2262 | 2301 | ||
| 2263 | #ifdef CONFIG_TCP_MD5SIG | 2302 | #ifdef CONFIG_TCP_MD5SIG |
| 2264 | /* Okay, we have all we need - do the md5 hash if needed */ | 2303 | /* Okay, we have all we need - do the md5 hash if needed */ |
| 2265 | if (md5) { | 2304 | if (md5) { |
| 2266 | tp->af_specific->calc_md5_hash(md5_hash_location, | 2305 | tp->af_specific->calc_md5_hash(md5_hash_location, |
| 2267 | md5, | 2306 | md5, NULL, req, skb); |
| 2268 | NULL, dst, req, | ||
| 2269 | tcp_hdr(skb), sk->sk_protocol, | ||
| 2270 | skb->len); | ||
| 2271 | } | 2307 | } |
| 2272 | #endif | 2308 | #endif |
| 2273 | 2309 | ||
| @@ -2367,7 +2403,7 @@ int tcp_connect(struct sock *sk) | |||
| 2367 | */ | 2403 | */ |
| 2368 | tp->snd_nxt = tp->write_seq; | 2404 | tp->snd_nxt = tp->write_seq; |
| 2369 | tp->pushed_seq = tp->write_seq; | 2405 | tp->pushed_seq = tp->write_seq; |
| 2370 | TCP_INC_STATS(TCP_MIB_ACTIVEOPENS); | 2406 | TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS); |
| 2371 | 2407 | ||
| 2372 | /* Timer for repeating the SYN until an answer. */ | 2408 | /* Timer for repeating the SYN until an answer. */ |
| 2373 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 2409 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 63ed9d6830e7..328e0cf42b3c 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Implementation of the Transmission Control Protocol(TCP). | 6 | * Implementation of the Transmission Control Protocol(TCP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 10 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
| @@ -50,7 +48,7 @@ static void tcp_write_err(struct sock *sk) | |||
| 50 | sk->sk_error_report(sk); | 48 | sk->sk_error_report(sk); |
| 51 | 49 | ||
| 52 | tcp_done(sk); | 50 | tcp_done(sk); |
| 53 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONTIMEOUT); | 51 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT); |
| 54 | } | 52 | } |
| 55 | 53 | ||
| 56 | /* Do not allow orphaned sockets to eat all our resources. | 54 | /* Do not allow orphaned sockets to eat all our resources. |
| @@ -91,7 +89,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) | |||
| 91 | if (do_reset) | 89 | if (do_reset) |
| 92 | tcp_send_active_reset(sk, GFP_ATOMIC); | 90 | tcp_send_active_reset(sk, GFP_ATOMIC); |
| 93 | tcp_done(sk); | 91 | tcp_done(sk); |
| 94 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); | 92 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); |
| 95 | return 1; | 93 | return 1; |
| 96 | } | 94 | } |
| 97 | return 0; | 95 | return 0; |
| @@ -181,7 +179,7 @@ static void tcp_delack_timer(unsigned long data) | |||
| 181 | if (sock_owned_by_user(sk)) { | 179 | if (sock_owned_by_user(sk)) { |
| 182 | /* Try again later. */ | 180 | /* Try again later. */ |
| 183 | icsk->icsk_ack.blocked = 1; | 181 | icsk->icsk_ack.blocked = 1; |
| 184 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED); | 182 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); |
| 185 | sk_reset_timer(sk, &icsk->icsk_delack_timer, jiffies + TCP_DELACK_MIN); | 183 | sk_reset_timer(sk, &icsk->icsk_delack_timer, jiffies + TCP_DELACK_MIN); |
| 186 | goto out_unlock; | 184 | goto out_unlock; |
| 187 | } | 185 | } |
| @@ -200,7 +198,7 @@ static void tcp_delack_timer(unsigned long data) | |||
| 200 | if (!skb_queue_empty(&tp->ucopy.prequeue)) { | 198 | if (!skb_queue_empty(&tp->ucopy.prequeue)) { |
| 201 | struct sk_buff *skb; | 199 | struct sk_buff *skb; |
| 202 | 200 | ||
| 203 | NET_INC_STATS_BH(LINUX_MIB_TCPSCHEDULERFAILED); | 201 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSCHEDULERFAILED); |
| 204 | 202 | ||
| 205 | while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) | 203 | while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) |
| 206 | sk->sk_backlog_rcv(sk, skb); | 204 | sk->sk_backlog_rcv(sk, skb); |
| @@ -220,7 +218,7 @@ static void tcp_delack_timer(unsigned long data) | |||
| 220 | icsk->icsk_ack.ato = TCP_ATO_MIN; | 218 | icsk->icsk_ack.ato = TCP_ATO_MIN; |
| 221 | } | 219 | } |
| 222 | tcp_send_ack(sk); | 220 | tcp_send_ack(sk); |
| 223 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS); | 221 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKS); |
| 224 | } | 222 | } |
| 225 | TCP_CHECK_TIMER(sk); | 223 | TCP_CHECK_TIMER(sk); |
| 226 | 224 | ||
| @@ -328,24 +326,27 @@ static void tcp_retransmit_timer(struct sock *sk) | |||
| 328 | goto out; | 326 | goto out; |
| 329 | 327 | ||
| 330 | if (icsk->icsk_retransmits == 0) { | 328 | if (icsk->icsk_retransmits == 0) { |
| 329 | int mib_idx; | ||
| 330 | |||
| 331 | if (icsk->icsk_ca_state == TCP_CA_Disorder || | 331 | if (icsk->icsk_ca_state == TCP_CA_Disorder || |
| 332 | icsk->icsk_ca_state == TCP_CA_Recovery) { | 332 | icsk->icsk_ca_state == TCP_CA_Recovery) { |
| 333 | if (tcp_is_sack(tp)) { | 333 | if (tcp_is_sack(tp)) { |
| 334 | if (icsk->icsk_ca_state == TCP_CA_Recovery) | 334 | if (icsk->icsk_ca_state == TCP_CA_Recovery) |
| 335 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKRECOVERYFAIL); | 335 | mib_idx = LINUX_MIB_TCPSACKRECOVERYFAIL; |
| 336 | else | 336 | else |
| 337 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKFAILURES); | 337 | mib_idx = LINUX_MIB_TCPSACKFAILURES; |
| 338 | } else { | 338 | } else { |
| 339 | if (icsk->icsk_ca_state == TCP_CA_Recovery) | 339 | if (icsk->icsk_ca_state == TCP_CA_Recovery) |
| 340 | NET_INC_STATS_BH(LINUX_MIB_TCPRENORECOVERYFAIL); | 340 | mib_idx = LINUX_MIB_TCPRENORECOVERYFAIL; |
| 341 | else | 341 | else |
| 342 | NET_INC_STATS_BH(LINUX_MIB_TCPRENOFAILURES); | 342 | mib_idx = LINUX_MIB_TCPRENOFAILURES; |
| 343 | } | 343 | } |
| 344 | } else if (icsk->icsk_ca_state == TCP_CA_Loss) { | 344 | } else if (icsk->icsk_ca_state == TCP_CA_Loss) { |
| 345 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSSFAILURES); | 345 | mib_idx = LINUX_MIB_TCPLOSSFAILURES; |
| 346 | } else { | 346 | } else { |
| 347 | NET_INC_STATS_BH(LINUX_MIB_TCPTIMEOUTS); | 347 | mib_idx = LINUX_MIB_TCPTIMEOUTS; |
| 348 | } | 348 | } |
| 349 | NET_INC_STATS_BH(sock_net(sk), mib_idx); | ||
| 349 | } | 350 | } |
| 350 | 351 | ||
| 351 | if (tcp_use_frto(sk)) { | 352 | if (tcp_use_frto(sk)) { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 56fcda3694ba..383d17359d01 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * The User Datagram Protocol (UDP). | 6 | * The User Datagram Protocol (UDP). |
| 7 | * | 7 | * |
| 8 | * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $ | ||
| 9 | * | ||
| 10 | * Authors: Ross Biro | 8 | * Authors: Ross Biro |
| 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 9 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
| 12 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | 10 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> |
| @@ -110,9 +108,6 @@ | |||
| 110 | * Snmp MIB for the UDP layer | 108 | * Snmp MIB for the UDP layer |
| 111 | */ | 109 | */ |
| 112 | 110 | ||
| 113 | DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly; | ||
| 114 | EXPORT_SYMBOL(udp_statistics); | ||
| 115 | |||
| 116 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; | 111 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
| 117 | EXPORT_SYMBOL(udp_stats_in6); | 112 | EXPORT_SYMBOL(udp_stats_in6); |
| 118 | 113 | ||
| @@ -136,7 +131,7 @@ static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, | |||
| 136 | struct sock *sk; | 131 | struct sock *sk; |
| 137 | struct hlist_node *node; | 132 | struct hlist_node *node; |
| 138 | 133 | ||
| 139 | sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) | 134 | sk_for_each(sk, node, &udptable[udp_hashfn(net, num)]) |
| 140 | if (net_eq(sock_net(sk), net) && sk->sk_hash == num) | 135 | if (net_eq(sock_net(sk), net) && sk->sk_hash == num) |
| 141 | return 1; | 136 | return 1; |
| 142 | return 0; | 137 | return 0; |
| @@ -176,7 +171,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 176 | for (i = 0; i < UDP_HTABLE_SIZE; i++) { | 171 | for (i = 0; i < UDP_HTABLE_SIZE; i++) { |
| 177 | int size = 0; | 172 | int size = 0; |
| 178 | 173 | ||
| 179 | head = &udptable[rover & (UDP_HTABLE_SIZE - 1)]; | 174 | head = &udptable[udp_hashfn(net, rover)]; |
| 180 | if (hlist_empty(head)) | 175 | if (hlist_empty(head)) |
| 181 | goto gotit; | 176 | goto gotit; |
| 182 | 177 | ||
| @@ -213,7 +208,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
| 213 | gotit: | 208 | gotit: |
| 214 | snum = rover; | 209 | snum = rover; |
| 215 | } else { | 210 | } else { |
| 216 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; | 211 | head = &udptable[udp_hashfn(net, snum)]; |
| 217 | 212 | ||
| 218 | sk_for_each(sk2, node, head) | 213 | sk_for_each(sk2, node, head) |
| 219 | if (sk2->sk_hash == snum && | 214 | if (sk2->sk_hash == snum && |
| @@ -229,7 +224,7 @@ gotit: | |||
| 229 | inet_sk(sk)->num = snum; | 224 | inet_sk(sk)->num = snum; |
| 230 | sk->sk_hash = snum; | 225 | sk->sk_hash = snum; |
| 231 | if (sk_unhashed(sk)) { | 226 | if (sk_unhashed(sk)) { |
| 232 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; | 227 | head = &udptable[udp_hashfn(net, snum)]; |
| 233 | sk_add_node(sk, head); | 228 | sk_add_node(sk, head); |
| 234 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 229 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
| 235 | } | 230 | } |
| @@ -266,7 +261,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
| 266 | int badness = -1; | 261 | int badness = -1; |
| 267 | 262 | ||
| 268 | read_lock(&udp_hash_lock); | 263 | read_lock(&udp_hash_lock); |
| 269 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | 264 | sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { |
| 270 | struct inet_sock *inet = inet_sk(sk); | 265 | struct inet_sock *inet = inet_sk(sk); |
| 271 | 266 | ||
| 272 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && | 267 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && |
| @@ -356,11 +351,12 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[]) | |||
| 356 | struct sock *sk; | 351 | struct sock *sk; |
| 357 | int harderr; | 352 | int harderr; |
| 358 | int err; | 353 | int err; |
| 354 | struct net *net = dev_net(skb->dev); | ||
| 359 | 355 | ||
| 360 | sk = __udp4_lib_lookup(dev_net(skb->dev), iph->daddr, uh->dest, | 356 | sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, |
| 361 | iph->saddr, uh->source, skb->dev->ifindex, udptable); | 357 | iph->saddr, uh->source, skb->dev->ifindex, udptable); |
| 362 | if (sk == NULL) { | 358 | if (sk == NULL) { |
| 363 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 359 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
| 364 | return; /* No socket for error */ | 360 | return; /* No socket for error */ |
| 365 | } | 361 | } |
| 366 | 362 | ||
| @@ -528,7 +524,8 @@ out: | |||
| 528 | up->len = 0; | 524 | up->len = 0; |
| 529 | up->pending = 0; | 525 | up->pending = 0; |
| 530 | if (!err) | 526 | if (!err) |
| 531 | UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite); | 527 | UDP_INC_STATS_USER(sock_net(sk), |
| 528 | UDP_MIB_OUTDATAGRAMS, is_udplite); | ||
| 532 | return err; | 529 | return err; |
| 533 | } | 530 | } |
| 534 | 531 | ||
| @@ -656,11 +653,13 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 656 | .uli_u = { .ports = | 653 | .uli_u = { .ports = |
| 657 | { .sport = inet->sport, | 654 | { .sport = inet->sport, |
| 658 | .dport = dport } } }; | 655 | .dport = dport } } }; |
| 656 | struct net *net = sock_net(sk); | ||
| 657 | |||
| 659 | security_sk_classify_flow(sk, &fl); | 658 | security_sk_classify_flow(sk, &fl); |
| 660 | err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1); | 659 | err = ip_route_output_flow(net, &rt, &fl, sk, 1); |
| 661 | if (err) { | 660 | if (err) { |
| 662 | if (err == -ENETUNREACH) | 661 | if (err == -ENETUNREACH) |
| 663 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 662 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
| 664 | goto out; | 663 | goto out; |
| 665 | } | 664 | } |
| 666 | 665 | ||
| @@ -727,7 +726,8 @@ out: | |||
| 727 | * seems like overkill. | 726 | * seems like overkill. |
| 728 | */ | 727 | */ |
| 729 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { | 728 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { |
| 730 | UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite); | 729 | UDP_INC_STATS_USER(sock_net(sk), |
| 730 | UDP_MIB_SNDBUFERRORS, is_udplite); | ||
| 731 | } | 731 | } |
| 732 | return err; | 732 | return err; |
| 733 | 733 | ||
| @@ -890,7 +890,8 @@ try_again: | |||
| 890 | goto out_free; | 890 | goto out_free; |
| 891 | 891 | ||
| 892 | if (!peeked) | 892 | if (!peeked) |
| 893 | UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite); | 893 | UDP_INC_STATS_USER(sock_net(sk), |
| 894 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
| 894 | 895 | ||
| 895 | sock_recv_timestamp(msg, sk, skb); | 896 | sock_recv_timestamp(msg, sk, skb); |
| 896 | 897 | ||
| @@ -919,7 +920,7 @@ out: | |||
| 919 | csum_copy_err: | 920 | csum_copy_err: |
| 920 | lock_sock(sk); | 921 | lock_sock(sk); |
| 921 | if (!skb_kill_datagram(sk, skb, flags)) | 922 | if (!skb_kill_datagram(sk, skb, flags)) |
| 922 | UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); | 923 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
| 923 | release_sock(sk); | 924 | release_sock(sk); |
| 924 | 925 | ||
| 925 | if (noblock) | 926 | if (noblock) |
| @@ -990,7 +991,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
| 990 | 991 | ||
| 991 | ret = (*up->encap_rcv)(sk, skb); | 992 | ret = (*up->encap_rcv)(sk, skb); |
| 992 | if (ret <= 0) { | 993 | if (ret <= 0) { |
| 993 | UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, | 994 | UDP_INC_STATS_BH(sock_net(sk), |
| 995 | UDP_MIB_INDATAGRAMS, | ||
| 994 | is_udplite); | 996 | is_udplite); |
| 995 | return -ret; | 997 | return -ret; |
| 996 | } | 998 | } |
| @@ -1042,15 +1044,18 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
| 1042 | 1044 | ||
| 1043 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { | 1045 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { |
| 1044 | /* Note that an ENOMEM error is charged twice */ | 1046 | /* Note that an ENOMEM error is charged twice */ |
| 1045 | if (rc == -ENOMEM) | 1047 | if (rc == -ENOMEM) { |
| 1046 | UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); | 1048 | UDP_INC_STATS_BH(sock_net(sk), |
| 1049 | UDP_MIB_RCVBUFERRORS, is_udplite); | ||
| 1050 | atomic_inc(&sk->sk_drops); | ||
| 1051 | } | ||
| 1047 | goto drop; | 1052 | goto drop; |
| 1048 | } | 1053 | } |
| 1049 | 1054 | ||
| 1050 | return 0; | 1055 | return 0; |
| 1051 | 1056 | ||
| 1052 | drop: | 1057 | drop: |
| 1053 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); | 1058 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
| 1054 | kfree_skb(skb); | 1059 | kfree_skb(skb); |
| 1055 | return -1; | 1060 | return -1; |
| 1056 | } | 1061 | } |
| @@ -1061,7 +1066,7 @@ drop: | |||
| 1061 | * Note: called only from the BH handler context, | 1066 | * Note: called only from the BH handler context, |
| 1062 | * so we don't need to lock the hashes. | 1067 | * so we don't need to lock the hashes. |
| 1063 | */ | 1068 | */ |
| 1064 | static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | 1069 | static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, |
| 1065 | struct udphdr *uh, | 1070 | struct udphdr *uh, |
| 1066 | __be32 saddr, __be32 daddr, | 1071 | __be32 saddr, __be32 daddr, |
| 1067 | struct hlist_head udptable[]) | 1072 | struct hlist_head udptable[]) |
| @@ -1070,7 +1075,7 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
| 1070 | int dif; | 1075 | int dif; |
| 1071 | 1076 | ||
| 1072 | read_lock(&udp_hash_lock); | 1077 | read_lock(&udp_hash_lock); |
| 1073 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | 1078 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); |
| 1074 | dif = skb->dev->ifindex; | 1079 | dif = skb->dev->ifindex; |
| 1075 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 1080 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
| 1076 | if (sk) { | 1081 | if (sk) { |
| @@ -1158,6 +1163,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
| 1158 | struct rtable *rt = (struct rtable*)skb->dst; | 1163 | struct rtable *rt = (struct rtable*)skb->dst; |
| 1159 | __be32 saddr = ip_hdr(skb)->saddr; | 1164 | __be32 saddr = ip_hdr(skb)->saddr; |
| 1160 | __be32 daddr = ip_hdr(skb)->daddr; | 1165 | __be32 daddr = ip_hdr(skb)->daddr; |
| 1166 | struct net *net = dev_net(skb->dev); | ||
| 1161 | 1167 | ||
| 1162 | /* | 1168 | /* |
| 1163 | * Validate the packet. | 1169 | * Validate the packet. |
| @@ -1180,9 +1186,10 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
| 1180 | goto csum_error; | 1186 | goto csum_error; |
| 1181 | 1187 | ||
| 1182 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) | 1188 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) |
| 1183 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); | 1189 | return __udp4_lib_mcast_deliver(net, skb, uh, |
| 1190 | saddr, daddr, udptable); | ||
| 1184 | 1191 | ||
| 1185 | sk = __udp4_lib_lookup(dev_net(skb->dev), saddr, uh->source, daddr, | 1192 | sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, |
| 1186 | uh->dest, inet_iif(skb), udptable); | 1193 | uh->dest, inet_iif(skb), udptable); |
| 1187 | 1194 | ||
| 1188 | if (sk != NULL) { | 1195 | if (sk != NULL) { |
| @@ -1211,7 +1218,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
| 1211 | if (udp_lib_checksum_complete(skb)) | 1218 | if (udp_lib_checksum_complete(skb)) |
| 1212 | goto csum_error; | 1219 | goto csum_error; |
| 1213 | 1220 | ||
| 1214 | UDP_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); | 1221 | UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); |
| 1215 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 1222 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
| 1216 | 1223 | ||
| 1217 | /* | 1224 | /* |
| @@ -1245,7 +1252,7 @@ csum_error: | |||
| 1245 | ntohs(uh->dest), | 1252 | ntohs(uh->dest), |
| 1246 | ulen); | 1253 | ulen); |
| 1247 | drop: | 1254 | drop: |
| 1248 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); | 1255 | UDP_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); |
| 1249 | kfree_skb(skb); | 1256 | kfree_skb(skb); |
| 1250 | return 0; | 1257 | return 0; |
| 1251 | } | 1258 | } |
| @@ -1255,12 +1262,11 @@ int udp_rcv(struct sk_buff *skb) | |||
| 1255 | return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP); | 1262 | return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP); |
| 1256 | } | 1263 | } |
| 1257 | 1264 | ||
| 1258 | int udp_destroy_sock(struct sock *sk) | 1265 | void udp_destroy_sock(struct sock *sk) |
| 1259 | { | 1266 | { |
| 1260 | lock_sock(sk); | 1267 | lock_sock(sk); |
| 1261 | udp_flush_pending_frames(sk); | 1268 | udp_flush_pending_frames(sk); |
| 1262 | release_sock(sk); | 1269 | release_sock(sk); |
| 1263 | return 0; | ||
| 1264 | } | 1270 | } |
| 1265 | 1271 | ||
| 1266 | /* | 1272 | /* |
| @@ -1319,6 +1325,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
| 1319 | return -ENOPROTOOPT; | 1325 | return -ENOPROTOOPT; |
| 1320 | if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ | 1326 | if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ |
| 1321 | val = 8; | 1327 | val = 8; |
| 1328 | else if (val > USHORT_MAX) | ||
| 1329 | val = USHORT_MAX; | ||
| 1322 | up->pcslen = val; | 1330 | up->pcslen = val; |
| 1323 | up->pcflag |= UDPLITE_SEND_CC; | 1331 | up->pcflag |= UDPLITE_SEND_CC; |
| 1324 | break; | 1332 | break; |
| @@ -1331,6 +1339,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
| 1331 | return -ENOPROTOOPT; | 1339 | return -ENOPROTOOPT; |
| 1332 | if (val != 0 && val < 8) /* Avoid silly minimal values. */ | 1340 | if (val != 0 && val < 8) /* Avoid silly minimal values. */ |
| 1333 | val = 8; | 1341 | val = 8; |
| 1342 | else if (val > USHORT_MAX) | ||
| 1343 | val = USHORT_MAX; | ||
| 1334 | up->pcrlen = val; | 1344 | up->pcrlen = val; |
| 1335 | up->pcflag |= UDPLITE_RECV_CC; | 1345 | up->pcflag |= UDPLITE_RECV_CC; |
| 1336 | break; | 1346 | break; |
| @@ -1453,7 +1463,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 1453 | spin_lock_bh(&rcvq->lock); | 1463 | spin_lock_bh(&rcvq->lock); |
| 1454 | while ((skb = skb_peek(rcvq)) != NULL && | 1464 | while ((skb = skb_peek(rcvq)) != NULL && |
| 1455 | udp_lib_checksum_complete(skb)) { | 1465 | udp_lib_checksum_complete(skb)) { |
| 1456 | UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_lite); | 1466 | UDP_INC_STATS_BH(sock_net(sk), |
| 1467 | UDP_MIB_INERRORS, is_lite); | ||
| 1457 | __skb_unlink(skb, rcvq); | 1468 | __skb_unlink(skb, rcvq); |
| 1458 | kfree_skb(skb); | 1469 | kfree_skb(skb); |
| 1459 | } | 1470 | } |
| @@ -1629,12 +1640,13 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, | |||
| 1629 | __u16 srcp = ntohs(inet->sport); | 1640 | __u16 srcp = ntohs(inet->sport); |
| 1630 | 1641 | ||
| 1631 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" | 1642 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
| 1632 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n", | 1643 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", |
| 1633 | bucket, src, srcp, dest, destp, sp->sk_state, | 1644 | bucket, src, srcp, dest, destp, sp->sk_state, |
| 1634 | atomic_read(&sp->sk_wmem_alloc), | 1645 | atomic_read(&sp->sk_wmem_alloc), |
| 1635 | atomic_read(&sp->sk_rmem_alloc), | 1646 | atomic_read(&sp->sk_rmem_alloc), |
| 1636 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 1647 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
| 1637 | atomic_read(&sp->sk_refcnt), sp, len); | 1648 | atomic_read(&sp->sk_refcnt), sp, |
| 1649 | atomic_read(&sp->sk_drops), len); | ||
| 1638 | } | 1650 | } |
| 1639 | 1651 | ||
| 1640 | int udp4_seq_show(struct seq_file *seq, void *v) | 1652 | int udp4_seq_show(struct seq_file *seq, void *v) |
| @@ -1643,7 +1655,7 @@ int udp4_seq_show(struct seq_file *seq, void *v) | |||
| 1643 | seq_printf(seq, "%-127s\n", | 1655 | seq_printf(seq, "%-127s\n", |
| 1644 | " sl local_address rem_address st tx_queue " | 1656 | " sl local_address rem_address st tx_queue " |
| 1645 | "rx_queue tr tm->when retrnsmt uid timeout " | 1657 | "rx_queue tr tm->when retrnsmt uid timeout " |
| 1646 | "inode"); | 1658 | "inode ref pointer drops"); |
| 1647 | else { | 1659 | else { |
| 1648 | struct udp_iter_state *state = seq->private; | 1660 | struct udp_iter_state *state = seq->private; |
| 1649 | int len; | 1661 | int len; |
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 7288bf7977fb..2e9bad2fa1bc 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h | |||
| @@ -26,7 +26,7 @@ extern int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 26 | extern int udp_sendpage(struct sock *sk, struct page *page, int offset, | 26 | extern int udp_sendpage(struct sock *sk, struct page *page, int offset, |
| 27 | size_t size, int flags); | 27 | size_t size, int flags); |
| 28 | extern int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); | 28 | extern int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); |
| 29 | extern int udp_destroy_sock(struct sock *sk); | 29 | extern void udp_destroy_sock(struct sock *sk); |
| 30 | 30 | ||
| 31 | #ifdef CONFIG_PROC_FS | 31 | #ifdef CONFIG_PROC_FS |
| 32 | extern int udp4_seq_show(struct seq_file *seq, void *v); | 32 | extern int udp4_seq_show(struct seq_file *seq, void *v); |
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index 72ce26b6c4d3..3c807964da96 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828). | 2 | * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828). |
| 3 | * | 3 | * |
| 4 | * Version: $Id: udplite.c,v 1.25 2006/10/19 07:22:36 gerrit Exp $ | ||
| 5 | * | ||
| 6 | * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> | 4 | * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> |
| 7 | * | 5 | * |
| 8 | * Changes: | 6 | * Changes: |
| @@ -13,7 +11,6 @@ | |||
| 13 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
| 14 | */ | 12 | */ |
| 15 | #include "udp_impl.h" | 13 | #include "udp_impl.h" |
| 16 | DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics) __read_mostly; | ||
| 17 | 14 | ||
| 18 | struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; | 15 | struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; |
| 19 | 16 | ||
