lkml.org 
[lkml]   [2013]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 47/61] ipv4: Add a socket release callback for datagram sockets
    Date
    3.7-stable review patch.  If anyone has any objections, please let me know.

    ------------------


    From: Steffen Klassert <steffen.klassert@secunet.com>

    [ Upstream commit 8141ed9fcedb278f4a3a78680591bef1e55f75fb ]

    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    include/net/ip.h | 2 ++
    net/ipv4/datagram.c | 25 +++++++++++++++++++++++++
    net/ipv4/ping.c | 1 +
    net/ipv4/raw.c | 1 +
    net/ipv4/udp.c | 1 +
    5 files changed, 30 insertions(+)

    --- a/include/net/ip.h
    +++ b/include/net/ip.h
    @@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_
    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;
    --- a/net/ipv4/datagram.c
    +++ b/net/ipv4/datagram.c
    @@ -85,3 +85,28 @@ out:
    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);
    --- a/net/ipv4/ping.c
    +++ b/net/ipv4/ping.c
    @@ -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,
    --- a/net/ipv4/raw.c
    +++ b/net/ipv4/raw.c
    @@ -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),
    --- a/net/ipv4/udp.c
    +++ b/net/ipv4/udp.c
    @@ -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,



    \
     
     \ /
      Last update: 2013-02-12 23:01    [W:4.144 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site