aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/af_inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r--net/ipv4/af_inet.c179
1 files changed, 143 insertions, 36 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 163ae4068b5f..bf147f8db399 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -99,6 +99,7 @@
99#include <net/arp.h> 99#include <net/arp.h>
100#include <net/route.h> 100#include <net/route.h>
101#include <net/ip_fib.h> 101#include <net/ip_fib.h>
102#include <net/inet_connection_sock.h>
102#include <net/tcp.h> 103#include <net/tcp.h>
103#include <net/udp.h> 104#include <net/udp.h>
104#include <linux/skbuff.h> 105#include <linux/skbuff.h>
@@ -112,11 +113,7 @@
112#include <linux/mroute.h> 113#include <linux/mroute.h>
113#endif 114#endif
114 115
115DEFINE_SNMP_STAT(struct linux_mib, net_statistics); 116DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
116
117#ifdef INET_REFCNT_DEBUG
118atomic_t inet_sock_nr;
119#endif
120 117
121extern void ip_mc_drop_socket(struct sock *sk); 118extern void ip_mc_drop_socket(struct sock *sk);
122 119
@@ -153,11 +150,7 @@ void inet_sock_destruct(struct sock *sk)
153 if (inet->opt) 150 if (inet->opt)
154 kfree(inet->opt); 151 kfree(inet->opt);
155 dst_release(sk->sk_dst_cache); 152 dst_release(sk->sk_dst_cache);
156#ifdef INET_REFCNT_DEBUG 153 sk_refcnt_debug_dec(sk);
157 atomic_dec(&inet_sock_nr);
158 printk(KERN_DEBUG "INET socket %p released, %d are still alive\n",
159 sk, atomic_read(&inet_sock_nr));
160#endif
161} 154}
162 155
163/* 156/*
@@ -210,7 +203,7 @@ int inet_listen(struct socket *sock, int backlog)
210 * we can only allow the backlog to be adjusted. 203 * we can only allow the backlog to be adjusted.
211 */ 204 */
212 if (old_state != TCP_LISTEN) { 205 if (old_state != TCP_LISTEN) {
213 err = tcp_listen_start(sk); 206 err = inet_csk_listen_start(sk, TCP_SYNQ_HSIZE);
214 if (err) 207 if (err)
215 goto out; 208 goto out;
216 } 209 }
@@ -235,12 +228,14 @@ static int inet_create(struct socket *sock, int protocol)
235 struct proto *answer_prot; 228 struct proto *answer_prot;
236 unsigned char answer_flags; 229 unsigned char answer_flags;
237 char answer_no_check; 230 char answer_no_check;
238 int err; 231 int try_loading_module = 0;
232 int err = -ESOCKTNOSUPPORT;
239 233
240 sock->state = SS_UNCONNECTED; 234 sock->state = SS_UNCONNECTED;
241 235
242 /* Look for the requested type/protocol pair. */ 236 /* Look for the requested type/protocol pair. */
243 answer = NULL; 237 answer = NULL;
238lookup_protocol:
244 rcu_read_lock(); 239 rcu_read_lock();
245 list_for_each_rcu(p, &inetsw[sock->type]) { 240 list_for_each_rcu(p, &inetsw[sock->type]) {
246 answer = list_entry(p, struct inet_protosw, list); 241 answer = list_entry(p, struct inet_protosw, list);
@@ -261,9 +256,28 @@ static int inet_create(struct socket *sock, int protocol)
261 answer = NULL; 256 answer = NULL;
262 } 257 }
263 258
264 err = -ESOCKTNOSUPPORT; 259 if (unlikely(answer == NULL)) {
265 if (!answer) 260 if (try_loading_module < 2) {
266 goto out_rcu_unlock; 261 rcu_read_unlock();
262 /*
263 * Be more specific, e.g. net-pf-2-proto-132-type-1
264 * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM)
265 */
266 if (++try_loading_module == 1)
267 request_module("net-pf-%d-proto-%d-type-%d",
268 PF_INET, protocol, sock->type);
269 /*
270 * Fall back to generic, e.g. net-pf-2-proto-132
271 * (net-pf-PF_INET-proto-IPPROTO_SCTP)
272 */
273 else
274 request_module("net-pf-%d-proto-%d",
275 PF_INET, protocol);
276 goto lookup_protocol;
277 } else
278 goto out_rcu_unlock;
279 }
280
267 err = -EPERM; 281 err = -EPERM;
268 if (answer->capability > 0 && !capable(answer->capability)) 282 if (answer->capability > 0 && !capable(answer->capability))
269 goto out_rcu_unlock; 283 goto out_rcu_unlock;
@@ -317,9 +331,7 @@ static int inet_create(struct socket *sock, int protocol)
317 inet->mc_index = 0; 331 inet->mc_index = 0;
318 inet->mc_list = NULL; 332 inet->mc_list = NULL;
319 333
320#ifdef INET_REFCNT_DEBUG 334 sk_refcnt_debug_inc(sk);
321 atomic_inc(&inet_sock_nr);
322#endif
323 335
324 if (inet->num) { 336 if (inet->num) {
325 /* It assumes that any protocol which allows 337 /* It assumes that any protocol which allows
@@ -847,10 +859,6 @@ static struct net_proto_family inet_family_ops = {
847 .owner = THIS_MODULE, 859 .owner = THIS_MODULE,
848}; 860};
849 861
850
851extern void tcp_init(void);
852extern void tcp_v4_init(struct net_proto_family *);
853
854/* Upon startup we insert all the elements in inetsw_array[] into 862/* Upon startup we insert all the elements in inetsw_array[] into
855 * the linked list inetsw. 863 * the linked list inetsw.
856 */ 864 */
@@ -961,6 +969,119 @@ void inet_unregister_protosw(struct inet_protosw *p)
961 } 969 }
962} 970}
963 971
972/*
973 * Shall we try to damage output packets if routing dev changes?
974 */
975
976int sysctl_ip_dynaddr;
977
978static int inet_sk_reselect_saddr(struct sock *sk)
979{
980 struct inet_sock *inet = inet_sk(sk);
981 int err;
982 struct rtable *rt;
983 __u32 old_saddr = inet->saddr;
984 __u32 new_saddr;
985 __u32 daddr = inet->daddr;
986
987 if (inet->opt && inet->opt->srr)
988 daddr = inet->opt->faddr;
989
990 /* Query new route. */
991 err = ip_route_connect(&rt, daddr, 0,
992 RT_CONN_FLAGS(sk),
993 sk->sk_bound_dev_if,
994 sk->sk_protocol,
995 inet->sport, inet->dport, sk);
996 if (err)
997 return err;
998
999 sk_setup_caps(sk, &rt->u.dst);
1000
1001 new_saddr = rt->rt_src;
1002
1003 if (new_saddr == old_saddr)
1004 return 0;
1005
1006 if (sysctl_ip_dynaddr > 1) {
1007 printk(KERN_INFO "%s(): shifting inet->"
1008 "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",
1009 __FUNCTION__,
1010 NIPQUAD(old_saddr),
1011 NIPQUAD(new_saddr));
1012 }
1013
1014 inet->saddr = inet->rcv_saddr = new_saddr;
1015
1016 /*
1017 * XXX The only one ugly spot where we need to
1018 * XXX really change the sockets identity after
1019 * XXX it has entered the hashes. -DaveM
1020 *
1021 * Besides that, it does not check for connection
1022 * uniqueness. Wait for troubles.
1023 */
1024 __sk_prot_rehash(sk);
1025 return 0;
1026}
1027
1028int inet_sk_rebuild_header(struct sock *sk)
1029{
1030 struct inet_sock *inet = inet_sk(sk);
1031 struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
1032 u32 daddr;
1033 int err;
1034
1035 /* Route is OK, nothing to do. */
1036 if (rt)
1037 return 0;
1038
1039 /* Reroute. */
1040 daddr = inet->daddr;
1041 if (inet->opt && inet->opt->srr)
1042 daddr = inet->opt->faddr;
1043{
1044 struct flowi fl = {
1045 .oif = sk->sk_bound_dev_if,
1046 .nl_u = {
1047 .ip4_u = {
1048 .daddr = daddr,
1049 .saddr = inet->saddr,
1050 .tos = RT_CONN_FLAGS(sk),
1051 },
1052 },
1053 .proto = sk->sk_protocol,
1054 .uli_u = {
1055 .ports = {
1056 .sport = inet->sport,
1057 .dport = inet->dport,
1058 },
1059 },
1060 };
1061
1062 err = ip_route_output_flow(&rt, &fl, sk, 0);
1063}
1064 if (!err)
1065 sk_setup_caps(sk, &rt->u.dst);
1066 else {
1067 /* Routing failed... */
1068 sk->sk_route_caps = 0;
1069 /*
1070 * Other protocols have to map its equivalent state to TCP_SYN_SENT.
1071 * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme
1072 */
1073 if (!sysctl_ip_dynaddr ||
1074 sk->sk_state != TCP_SYN_SENT ||
1075 (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
1076 (err = inet_sk_reselect_saddr(sk)) != 0)
1077 sk->sk_err_soft = -err;
1078 }
1079
1080 return err;
1081}
1082
1083EXPORT_SYMBOL(inet_sk_rebuild_header);
1084
964#ifdef CONFIG_IP_MULTICAST 1085#ifdef CONFIG_IP_MULTICAST
965static struct net_protocol igmp_protocol = { 1086static struct net_protocol igmp_protocol = {
966 .handler = igmp_rcv, 1087 .handler = igmp_rcv,
@@ -1007,7 +1128,6 @@ static int __init init_ipv4_mibs(void)
1007} 1128}
1008 1129
1009static int ipv4_proc_init(void); 1130static int ipv4_proc_init(void);
1010extern void ipfrag_init(void);
1011 1131
1012/* 1132/*
1013 * IP protocol layer initialiser 1133 * IP protocol layer initialiser
@@ -1128,19 +1248,10 @@ module_init(inet_init);
1128/* ------------------------------------------------------------------------ */ 1248/* ------------------------------------------------------------------------ */
1129 1249
1130#ifdef CONFIG_PROC_FS 1250#ifdef CONFIG_PROC_FS
1131extern int fib_proc_init(void);
1132extern void fib_proc_exit(void);
1133#ifdef CONFIG_IP_FIB_TRIE 1251#ifdef CONFIG_IP_FIB_TRIE
1134extern int fib_stat_proc_init(void); 1252extern int fib_stat_proc_init(void);
1135extern void fib_stat_proc_exit(void); 1253extern void fib_stat_proc_exit(void);
1136#endif 1254#endif
1137extern int ip_misc_proc_init(void);
1138extern int raw_proc_init(void);
1139extern void raw_proc_exit(void);
1140extern int tcp4_proc_init(void);
1141extern void tcp4_proc_exit(void);
1142extern int udp4_proc_init(void);
1143extern void udp4_proc_exit(void);
1144 1255
1145static int __init ipv4_proc_init(void) 1256static int __init ipv4_proc_init(void)
1146{ 1257{
@@ -1205,7 +1316,3 @@ EXPORT_SYMBOL(inet_stream_ops);
1205EXPORT_SYMBOL(inet_unregister_protosw); 1316EXPORT_SYMBOL(inet_unregister_protosw);
1206EXPORT_SYMBOL(net_statistics); 1317EXPORT_SYMBOL(net_statistics);
1207EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); 1318EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
1208
1209#ifdef INET_REFCNT_DEBUG
1210EXPORT_SYMBOL(inet_sock_nr);
1211#endif