lkml.org 
[lkml]   [2015]   [Jul]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.0 15/55] ip: report the original address of ICMP messages
    Date
    4.0-stable review patch.  If anyone has any objections, please let me know.

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

    From: Julian Anastasov <ja@ssi.bg>

    [ Upstream commit 34b99df4e6256ddafb663c6de0711dceceddfe0e ]

    ICMP messages can trigger ICMP and local errors. In this case
    serr->port is 0 and starting from Linux 4.0 we do not return
    the original target address to the error queue readers.
    Add function to define which errors provide addr_offset.
    With this fix my ping command is not silent anymore.

    Fixes: c247f0534cc5 ("ip: fix error queue empty skb handling")
    Signed-off-by: Julian Anastasov <ja@ssi.bg>
    Acked-by: Willem de Bruijn <willemb@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv4/ip_sockglue.c | 11 ++++++++++-
    net/ipv6/datagram.c | 12 +++++++++++-
    2 files changed, 21 insertions(+), 2 deletions(-)

    --- a/net/ipv4/ip_sockglue.c
    +++ b/net/ipv4/ip_sockglue.c
    @@ -432,6 +432,15 @@ void ip_local_error(struct sock *sk, int
    kfree_skb(skb);
    }

    +/* For some errors we have valid addr_offset even with zero payload and
    + * zero port. Also, addr_offset should be supported if port is set.
    + */
    +static inline bool ipv4_datagram_support_addr(struct sock_exterr_skb *serr)
    +{
    + return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
    + serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
    +}
    +
    /* IPv4 supports cmsg on all imcp errors and some timestamps
    *
    * Timestamp code paths do not initialize the fields expected by cmsg:
    @@ -498,7 +507,7 @@ int ip_recv_error(struct sock *sk, struc

    serr = SKB_EXT_ERR(skb);

    - if (sin && serr->port) {
    + if (sin && ipv4_datagram_support_addr(serr)) {
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
    serr->addr_offset);
    --- a/net/ipv6/datagram.c
    +++ b/net/ipv6/datagram.c
    @@ -325,6 +325,16 @@ void ipv6_local_rxpmtu(struct sock *sk,
    kfree_skb(skb);
    }

    +/* For some errors we have valid addr_offset even with zero payload and
    + * zero port. Also, addr_offset should be supported if port is set.
    + */
    +static inline bool ipv6_datagram_support_addr(struct sock_exterr_skb *serr)
    +{
    + return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6 ||
    + serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
    + serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
    +}
    +
    /* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL.
    *
    * At one point, excluding local errors was a quick test to identify icmp/icmp6
    @@ -389,7 +399,7 @@ int ipv6_recv_error(struct sock *sk, str

    serr = SKB_EXT_ERR(skb);

    - if (sin && serr->port) {
    + if (sin && ipv6_datagram_support_addr(serr)) {
    const unsigned char *nh = skb_network_header(skb);
    sin->sin6_family = AF_INET6;
    sin->sin6_flowinfo = 0;



    \
     
     \ /
      Last update: 2015-07-08 10:41    [W:9.372 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site