From patchwork Mon May 24 05:54:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 53381 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 3EB70B7D7D for ; Mon, 24 May 2010 15:54:29 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752162Ab0EXFyU (ORCPT ); Mon, 24 May 2010 01:54:20 -0400 Received: from smtp-out.google.com ([74.125.121.35]:35606 "EHLO smtp-out.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751174Ab0EXFyT (ORCPT ); Mon, 24 May 2010 01:54:19 -0400 Received: from wpaz1.hot.corp.google.com (wpaz1.hot.corp.google.com [172.24.198.65]) by smtp-out.google.com with ESMTP id o4O5sERO012029; Sun, 23 May 2010 22:54:15 -0700 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1274680455; bh=MvInD6dJQvEZgdXkDTvt30DeVkY=; h=Date:From:To:cc:Subject:Message-ID:MIME-Version:Content-Type; b=m8sbOgUAClY0FEYWCGhm05ZOO92v386bDKINr8m9HZ8eDK9wUyAPtvTXfxApWhd1X 6vhyxM/ZGs8h6i/jcHvuw== DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=date:from:to:cc:subject:message-id:user-agent: mime-version:content-type; b=gZFIahcDzq6xOT6tJ41XdCQr0otga/gTeNA0ltUko7aD52QeYr/9b45BOztYPDj60 eh553X7XtzcTIvb/TDLmw== Received: from pokey.mtv.corp.google.com (pokey.mtv.corp.google.com [172.22.64.87]) by wpaz1.hot.corp.google.com with ESMTP id o4O5sDW1003733; Sun, 23 May 2010 22:54:13 -0700 Received: by pokey.mtv.corp.google.com (Postfix, from userid 60832) id 3759A1C48F2; Sun, 23 May 2010 22:54:13 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by pokey.mtv.corp.google.com (Postfix) with ESMTP id 1C54F1C48F1; Sun, 23 May 2010 22:54:13 -0700 (PDT) Date: Sun, 23 May 2010 22:54:12 -0700 (PDT) From: Tom Herbert To: davem@davemloft.net cc: netdev@vger.kernel.org Subject: [PATCH] ipv4: Allow configuring subnets as local addresses Message-ID: User-Agent: Alpine 1.00 (DEB 882 2007-12-20) MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch allows a host to be configured to respond to any address in a specified range as if it were local, without actually needing to configure the address on an interface. This is done through routing table configuration. For instance, to configure a host to respond to any address in 10.1/16 received on eth0 as a local address we can do: ip rule add from all iif eth0 lookup 200 ip route add local 10.1/16 dev lo proto kernel scope host src 127.0.0.1 table 200 This host is now reachable by any 10.1/16 address (route lookup on input for packets received on eth0 can find the route). On output, the rule will not be matched so that this host can still send packets to 10.1/16 (not sent on loopback). Presumably, external routing can be configured to make sense out of this. To make this work, we needed to modify the logic in finding the interface which is assigned a given source address for output (dev_ip_find). We perform a normal fib_lookup instead of just a lookup on the local table, and in the lookup we ignore the input interface for matching. This patch is useful to implement IP-anycast for subnets of virtual addresses. Signed-off-by: Tom Herbert --- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/net/flow.h b/include/net/flow.h index bb08692..0ac3fb5 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -49,6 +49,7 @@ struct flowi { __u8 proto; __u8 flags; #define FLOWI_FLAG_ANYSRC 0x01 +#define FLOWI_FLAG_MATCH_ANY_IIF 0x02 union { struct { __be16 sport; diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 42e84e0..f6e18b2 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -182,7 +182,8 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, { int ret = 0; - if (rule->iifindex && (rule->iifindex != fl->iif)) + if (rule->iifindex && (rule->iifindex != fl->iif) && + !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) goto out; if (rule->oifindex && (rule->oifindex != fl->oif)) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 4f0ed45..64f953e 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -153,17 +153,16 @@ static void fib_flush(struct net *net) struct net_device * ip_dev_find(struct net *net, __be32 addr) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, + .flags = FLOWI_FLAG_MATCH_ANY_IIF }; struct fib_result res; struct net_device *dev = NULL; - struct fib_table *local_table; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif - local_table = fib_get_table(net, RT_TABLE_LOCAL); - if (!local_table || fib_table_lookup(local_table, &fl, &res)) + if (fib_lookup(net, &fl, &res)) return NULL; if (res.type != RTN_LOCAL) goto out;