aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip.h2
-rw-r--r--net/ipv4/datagram.c25
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/udp.c1
5 files changed, 30 insertions, 0 deletions
diff --git a/include/net/ip.h b/include/net/ip.h
index 0707fb9551aa..a68f838a132c 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
143extern int ip4_datagram_connect(struct sock *sk, 143extern int ip4_datagram_connect(struct sock *sk,
144 struct sockaddr *uaddr, int addr_len); 144 struct sockaddr *uaddr, int addr_len);
145 145
146extern void ip4_datagram_release_cb(struct sock *sk);
147
146struct ip_reply_arg { 148struct ip_reply_arg {
147 struct kvec iov[1]; 149 struct kvec iov[1];
148 int flags; 150 int flags;
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index 424fafbc8cb0..b28e863fe0a7 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -85,3 +85,28 @@ out:
85 return err; 85 return err;
86} 86}
87EXPORT_SYMBOL(ip4_datagram_connect); 87EXPORT_SYMBOL(ip4_datagram_connect);
88
89void ip4_datagram_release_cb(struct sock *sk)
90{
91 const struct inet_sock *inet = inet_sk(sk);
92 const struct ip_options_rcu *inet_opt;
93 __be32 daddr = inet->inet_daddr;
94 struct flowi4 fl4;
95 struct rtable *rt;
96
97 if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
98 return;
99
100 rcu_read_lock();
101 inet_opt = rcu_dereference(inet->inet_opt);
102 if (inet_opt && inet_opt->opt.srr)
103 daddr = inet_opt->opt.faddr;
104 rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr,
105 inet->inet_saddr, inet->inet_dport,
106 inet->inet_sport, sk->sk_protocol,
107 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
108 if (!IS_ERR(rt))
109 __sk_dst_set(sk, &rt->dst);
110 rcu_read_unlock();
111}
112EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8f3d05424a3e..6f9c07268cf6 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -738,6 +738,7 @@ struct proto ping_prot = {
738 .recvmsg = ping_recvmsg, 738 .recvmsg = ping_recvmsg,
739 .bind = ping_bind, 739 .bind = ping_bind,
740 .backlog_rcv = ping_queue_rcv_skb, 740 .backlog_rcv = ping_queue_rcv_skb,
741 .release_cb = ip4_datagram_release_cb,
741 .hash = ping_v4_hash, 742 .hash = ping_v4_hash,
742 .unhash = ping_v4_unhash, 743 .unhash = ping_v4_unhash,
743 .get_port = ping_v4_get_port, 744 .get_port = ping_v4_get_port,
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 73d1e4df4bf6..6f08991409c3 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -894,6 +894,7 @@ struct proto raw_prot = {
894 .recvmsg = raw_recvmsg, 894 .recvmsg = raw_recvmsg,
895 .bind = raw_bind, 895 .bind = raw_bind,
896 .backlog_rcv = raw_rcv_skb, 896 .backlog_rcv = raw_rcv_skb,
897 .release_cb = ip4_datagram_release_cb,
897 .hash = raw_hash_sk, 898 .hash = raw_hash_sk,
898 .unhash = raw_unhash_sk, 899 .unhash = raw_unhash_sk,
899 .obj_size = sizeof(struct raw_sock), 900 .obj_size = sizeof(struct raw_sock),
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 79c8dbe59b54..1f4d405eafba 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1952,6 +1952,7 @@ struct proto udp_prot = {
1952 .recvmsg = udp_recvmsg, 1952 .recvmsg = udp_recvmsg,
1953 .sendpage = udp_sendpage, 1953 .sendpage = udp_sendpage,
1954 .backlog_rcv = __udp_queue_rcv_skb, 1954 .backlog_rcv = __udp_queue_rcv_skb,
1955 .release_cb = ip4_datagram_release_cb,
1955 .hash = udp_lib_hash, 1956 .hash = udp_lib_hash,
1956 .unhash = udp_lib_unhash, 1957 .unhash = udp_lib_unhash,
1957 .rehash = udp_v4_rehash, 1958 .rehash = udp_v4_rehash,