lkml.org 
[lkml]   [2020]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 74/77] rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket
    Date
    From: David Howells <dhowells@redhat.com>

    commit 37a675e768d7606fe8a53e0c459c9b53e121ac20 upstream.

    It seems that enabling IPV6_RECVERR on an IPv6 socket doesn't also turn on
    IP_RECVERR, so neither local errors nor ICMP-transported remote errors from
    IPv4 peer addresses are returned to the AF_RXRPC protocol.

    Make the sockopt setting code in rxrpc_open_socket() fall through from the
    AF_INET6 case to the AF_INET case to turn on all the AF_INET options too in
    the AF_INET6 case.

    Fixes: f2aeed3a591f ("rxrpc: Fix error reception on AF_INET6 sockets")
    Signed-off-by: David Howells <dhowells@redhat.com>
    Cc: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/rxrpc/local_object.c | 23 +++++++++++++----------
    1 file changed, 13 insertions(+), 10 deletions(-)

    --- a/net/rxrpc/local_object.c
    +++ b/net/rxrpc/local_object.c
    @@ -134,10 +134,10 @@ static int rxrpc_open_socket(struct rxrp
    }

    switch (local->srx.transport.family) {
    - case AF_INET:
    - /* we want to receive ICMP errors */
    + case AF_INET6:
    + /* we want to receive ICMPv6 errors */
    opt = 1;
    - ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
    + ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
    (char *) &opt, sizeof(opt));
    if (ret < 0) {
    _debug("setsockopt failed");
    @@ -145,19 +145,22 @@ static int rxrpc_open_socket(struct rxrp
    }

    /* we want to set the don't fragment bit */
    - opt = IP_PMTUDISC_DO;
    - ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
    + opt = IPV6_PMTUDISC_DO;
    + ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
    (char *) &opt, sizeof(opt));
    if (ret < 0) {
    _debug("setsockopt failed");
    goto error;
    }
    - break;

    - case AF_INET6:
    + /* Fall through and set IPv4 options too otherwise we don't get
    + * errors from IPv4 packets sent through the IPv6 socket.
    + */
    +
    + case AF_INET:
    /* we want to receive ICMP errors */
    opt = 1;
    - ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
    + ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
    (char *) &opt, sizeof(opt));
    if (ret < 0) {
    _debug("setsockopt failed");
    @@ -165,8 +168,8 @@ static int rxrpc_open_socket(struct rxrp
    }

    /* we want to set the don't fragment bit */
    - opt = IPV6_PMTUDISC_DO;
    - ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
    + opt = IP_PMTUDISC_DO;
    + ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
    (char *) &opt, sizeof(opt));
    if (ret < 0) {
    _debug("setsockopt failed");

    \
     
     \ /
      Last update: 2020-06-01 20:02    [W:4.513 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site