Skip to content

Commit

Permalink
ipv4: Add a socket release callback for datagram sockets
Browse files Browse the repository at this point in the history
This implements a socket release callback function to check
if the socket cached route got invalid during the time
we owned the socket. The function is used from udp, raw
and ping sockets.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
klassert authored and davem330 committed Jan 21, 2013
1 parent 9cb3a50 commit 8141ed9
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
extern int ip4_datagram_connect(struct sock *sk,
struct sockaddr *uaddr, int addr_len);

extern void ip4_datagram_release_cb(struct sock *sk);

struct ip_reply_arg {
struct kvec iov[1];
int flags;
Expand Down
25 changes: 25 additions & 0 deletions net/ipv4/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,28 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return err;
}
EXPORT_SYMBOL(ip4_datagram_connect);

void ip4_datagram_release_cb(struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct ip_options_rcu *inet_opt;
__be32 daddr = inet->inet_daddr;
struct flowi4 fl4;
struct rtable *rt;

if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
return;

rcu_read_lock();
inet_opt = rcu_dereference(inet->inet_opt);
if (inet_opt && inet_opt->opt.srr)
daddr = inet_opt->opt.faddr;
rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr,
inet->inet_saddr, inet->inet_dport,
inet->inet_sport, sk->sk_protocol,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
if (!IS_ERR(rt))
__sk_dst_set(sk, &rt->dst);
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
1 change: 1 addition & 0 deletions net/ipv4/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ struct proto ping_prot = {
.recvmsg = ping_recvmsg,
.bind = ping_bind,
.backlog_rcv = ping_queue_rcv_skb,
.release_cb = ip4_datagram_release_cb,
.hash = ping_v4_hash,
.unhash = ping_v4_unhash,
.get_port = ping_v4_get_port,
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@ struct proto raw_prot = {
.recvmsg = raw_recvmsg,
.bind = raw_bind,
.backlog_rcv = raw_rcv_skb,
.release_cb = ip4_datagram_release_cb,
.hash = raw_hash_sk,
.unhash = raw_unhash_sk,
.obj_size = sizeof(struct raw_sock),
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,7 @@ struct proto udp_prot = {
.recvmsg = udp_recvmsg,
.sendpage = udp_sendpage,
.backlog_rcv = __udp_queue_rcv_skb,
.release_cb = ip4_datagram_release_cb,
.hash = udp_lib_hash,
.unhash = udp_lib_unhash,
.rehash = udp_v4_rehash,
Expand Down

0 comments on commit 8141ed9

Please sign in to comment.