From patchwork Tue Nov 8 01:46:40 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Maciej_=C5=BBenczykowski?= X-Patchwork-Id: 124252 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 5B9DFB6F83 for ; Tue, 8 Nov 2011 12:46:59 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754156Ab1KHBqy (ORCPT ); Mon, 7 Nov 2011 20:46:54 -0500 Received: from mail-qy0-f174.google.com ([209.85.216.174]:59544 "EHLO mail-qy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752877Ab1KHBqx (ORCPT ); Mon, 7 Nov 2011 20:46:53 -0500 Received: by qyk27 with SMTP id 27so3115947qyk.19 for ; Mon, 07 Nov 2011 17:46:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=4w6dwHPPqfn1IhXLT3ONhMl9UojULA6xNmiJDdRmFG4=; b=HZ1z9FTvI+nJlYYzb+DjDyHJiW1a0EviRipojG2+LNyzhmvDhBfdlsmrtbc93LUxdB +PLt6xVEOJoyaQtTp0rfIApcb631NjXcZHimich+IV4iezpa6SquH7WYJu9ZwFZon6f4 Ro9eZUisCMFyYyHj6iKKVSg5ttOUf5jnvRlp8= Received: by 10.68.25.170 with SMTP id d10mr3661649pbg.7.1320716812268; Mon, 07 Nov 2011 17:46:52 -0800 (PST) Received: from localhost.localdomain (sugar.mtv.corp.google.com [172.22.97.53]) by mx.google.com with ESMTPS id jm5sm264726pbc.1.2011.11.07.17.46.51 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Nov 2011 17:46:51 -0800 (PST) From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= To: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Cc: netdev@vger.kernel.org, =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Subject: [PATCH] [RFC] net-netlink: fix tos/tclass for dual-stack ipv6 sockets Date: Mon, 7 Nov 2011 17:46:40 -0800 Message-Id: <1320716800-9151-1-git-send-email-zenczykowski@gmail.com> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1320711791-11005-1-git-send-email-zenczykowski@gmail.com> References: <1320711791-11005-1-git-send-email-zenczykowski@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Maciej Żenczykowski Something along the following lines would be needed. Signed-off-by: Maciej Żenczykowski --- include/net/ipv6.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ net/ipv4/inet_diag.c | 11 +++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 3b5ac1f..50c7a3b 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -465,6 +465,58 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); +/* Return true for: + * - an IPv4 socket (listening or connected) + * - an IPv4 connection on a dual-stack IPv6 socket + * - an IPv6 dual-stack listening socket -> can later accept IPv4 connection + */ +static inline bool sk_might_be_ipv4(struct sock *sk) { +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + const struct ipv6_pinfo *np; + + if (!sk) return false; + if (sk->sk_family == AF_INET) return true; + if (sk->sk_family != AF_INET6) return false; + np = inet6_sk(sk); + if (np->ipv6only) return false; + + if (ipv6_addr_v4mapped(&np->rcv_saddr)) return true; + if (!ipv6_addr_any(&np->rcv_saddr)) return false; + + if (sk->sk_state == TCP_LISTEN) return true; + + if (ipv6_addr_v4mapped(&np->saddr)) return true; + return false; +#else + return sk && (sk->sk_family == AF_INET); +#endif +} + +/* Return true for: + * - a native IPv6 connection + * - a listening IPv6 socket + */ +static inline bool sk_might_be_ipv6(struct sock *sk) { +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + const struct ipv6_pinfo *np; + + if (!sk) return false; + if (sk->sk_family != AF_INET6) return false; + np = inet6_sk(sk); + if (np->ipv6only) return true; + + if (ipv6_addr_v4mapped(&np->rcv_saddr)) return false; + if (!ipv6_addr_any(&np->rcv_saddr)) return true; + + if (sk->sk_state == TCP_LISTEN) return true; + + if (ipv6_addr_v4mapped(&np->saddr)) return false; + return true; +#else + return false; +#endif +} + /* * Prototypes exported by ipv6 */ diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 68e8ac5..39bc97c 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -108,9 +108,6 @@ static int inet_csk_diag_fill(struct sock *sk, icsk->icsk_ca_ops->name); } - if ((ext & (1 << (INET_DIAG_TOS - 1))) && (sk->sk_family != AF_INET6)) - RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos); - r->idiag_family = sk->sk_family; r->idiag_state = sk->sk_state; r->idiag_timer = 0; @@ -125,7 +122,13 @@ static int inet_csk_diag_fill(struct sock *sk, r->id.idiag_src[0] = inet->inet_rcv_saddr; r->id.idiag_dst[0] = inet->inet_daddr; + if ((ext & (1 << (INET_DIAG_TOS - 1))) && sk_might_be_ipv4(sk)) + RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos); + #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + if ((ext & (1 << (INET_DIAG_TCLASS - 1))) && sk_might_be_ipv6(sk)) + RTA_PUT_U8(skb, INET_DIAG_TCLASS, inet6_sk(sk)->tclass); + if (r->idiag_family == AF_INET6) { const struct ipv6_pinfo *np = inet6_sk(sk); @@ -133,8 +136,6 @@ static int inet_csk_diag_fill(struct sock *sk, &np->rcv_saddr); ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, &np->daddr); - if (ext & (1 << (INET_DIAG_TCLASS - 1))) - RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass); } #endif