From patchwork Thu Aug 27 21:16:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 511435 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 3C01814012C for ; Fri, 28 Aug 2015 07:18:30 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=YWxqhIGN; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751883AbbH0VSZ (ORCPT ); Thu, 27 Aug 2015 17:18:25 -0400 Received: from mail-pa0-f44.google.com ([209.85.220.44]:33353 "EHLO mail-pa0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751794AbbH0VSC (ORCPT ); Thu, 27 Aug 2015 17:18:02 -0400 Received: by pacti10 with SMTP id ti10so38515142pac.0 for ; Thu, 27 Aug 2015 14:18:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TX37FCYWiSIL8WB09k5l4zEAPTjCT4iVgTgwXdSQZTk=; b=YWxqhIGNvQ1qUThMPlGGNiRDRf213+v9rIL1Nk1j+PBIh7OTSqcPiqUgnKBXROMrc8 VXqIcnV8TdK0k7wiEIBkDXw4jlCLMC1WTCkJRH8erGZpU2JXfNNTUSl1+So5pcJe0vQL IPJ8kSY7mPHY4dsBJZQQta+eJLLd8cyGj0++E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TX37FCYWiSIL8WB09k5l4zEAPTjCT4iVgTgwXdSQZTk=; b=hJltuGzT00QsWBDdMjLrNYTLyVI0PltGtuT1K1PbW3lVr1j5bvdkySO05gELS+++mT Z8QZCdf+xqDWRhyto33uvSxv0t19ITjPPxwTlZgYEph9Lr1o+G4Lz6yMFlc0Yzvq25pR m/hVR1t19Y+9XfcEMFnozkSKpGbT2EciqnuhaQ5JpIhfSdZmWm/XF1tETnMV7Bcj0ORD /oa0uiZMbMGB70x6BXyltfmsXcILceYY8DTMlZ51CIzRUSTBtz2r5OArc4iOE72mXCAr yl4geggwiLXslBDwUFfpELr2wgRPf7wVi0mIB2gthMhriM0DSp283T1hitbU3r311Qix UT9Q== X-Gm-Message-State: ALoCoQkTswrtfJTAsL1WzVhnDcjxePwFkMHizsXE5qfFG7eI/aaIqFkqIP2f61cZZQUQP+2pg7jk X-Received: by 10.68.211.42 with SMTP id mz10mr9736635pbc.118.1440710281593; Thu, 27 Aug 2015 14:18:01 -0700 (PDT) Received: from monster-14.cumulusnetworks.com. ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id gx11sm3399742pbd.82.2015.08.27.14.18.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Aug 2015 14:18:00 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: David Ahern Subject: [PATCH net-next 5/5] net: Add support for VRFs to inetpeer cache Date: Thu, 27 Aug 2015 14:16:33 -0700 Message-Id: <1440710193-4824-6-git-send-email-dsa@cumulusnetworks.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1440710193-4824-1-git-send-email-dsa@cumulusnetworks.com> References: <1440710193-4824-1-git-send-email-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org inetpeer caches based on address only, so duplicate IP addresses within a namespace return the same cached entry. Enhance the ipv4 address key to contain both the IPv4 address and VRF device index. Signed-off-by: David Ahern --- include/net/inetpeer.h | 17 ++++++++++++----- net/ipv4/icmp.c | 3 ++- net/ipv4/ip_fragment.c | 3 ++- net/ipv4/route.c | 7 +++++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index e96bada9d19a..b372004dca3e 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -15,11 +15,17 @@ #include #include +/* IPv4 address key for cache lookups */ +struct ipv4_addr_key { + __be32 addr; + int vif; +}; + #define INETPEER_MAXKEYSZ (sizeof(struct in6_addr) / sizeof(u32)) struct inetpeer_addr { union { - __be32 a4; + struct ipv4_addr_key a4; struct in6_addr a6; u32 key[INETPEER_MAXKEYSZ]; }; @@ -71,13 +77,13 @@ void inet_initpeers(void) __init; static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip) { - iaddr->a4 = ip; + iaddr->a4.addr = ip; iaddr->family = AF_INET; } static inline __be32 inetpeer_get_addr_v4(struct inetpeer_addr *iaddr) { - return iaddr->a4; + return iaddr->a4.addr; } static inline void inetpeer_set_addr_v6(struct inetpeer_addr *iaddr, @@ -99,11 +105,12 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base, __be32 v4daddr, - int create) + int vif, int create) { struct inetpeer_addr daddr; - daddr.a4 = v4daddr; + daddr.a4.addr = v4daddr; + daddr.a4.vif = vif; daddr.family = AF_INET; return inet_getpeer(base, &daddr, create); } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index f16488efa1c8..79fe05befcae 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -309,9 +309,10 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, rc = false; if (icmp_global_allow()) { + int vif = vrf_master_ifindex(dst->dev); struct inet_peer *peer; - peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); + peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1); rc = inet_peer_xrlim_allow(peer, net->ipv4.sysctl_icmp_ratelimit); if (peer) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 15762e758861..fa7f15305f9a 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -151,7 +151,8 @@ static void ip4_frag_init(struct inet_frag_queue *q, const void *a) qp->vif = arg->vif; qp->user = arg->user; qp->peer = sysctl_ipfrag_max_dist ? - inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, 1) : NULL; + inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, arg->vif, 1) : + NULL; } static void ip4_frag_free(struct inet_frag_queue *q) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0b8a6531ef03..e1a60f6c1aad 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -838,6 +838,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) struct inet_peer *peer; struct net *net; int log_martians; + int vif; rcu_read_lock(); in_dev = __in_dev_get_rcu(rt->dst.dev); @@ -846,10 +847,11 @@ void ip_rt_send_redirect(struct sk_buff *skb) return; } log_martians = IN_DEV_LOG_MARTIANS(in_dev); + vif = vrf_master_ifindex_rcu(rt->dst.dev); rcu_read_unlock(); net = dev_net(rt->dst.dev); - peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); + peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif, 1); if (!peer) { icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt_nexthop(rt, ip_hdr(skb)->daddr)); @@ -938,7 +940,8 @@ static int ip_error(struct sk_buff *skb) break; } - peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); + peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, + vrf_master_ifindex(skb->dev), 1); send = true; if (peer) {