diff mbox

net 04/05: fib_rules: allow to delete local rule

Message ID 20091130175534.7555.48216.sendpatchset@x2.localnet
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Patrick McHardy Nov. 30, 2009, 5:55 p.m. UTC
commit ca1ba96aaa05cc0a2a7f172990e7787354c8b7b9
Author: Patrick McHardy <kaber@trash.net>
Date:   Mon Nov 30 16:05:51 2009 +0100

    net: fib_rules: allow to delete local rule
    
    Allow to delete the local rule and recreate it with a lower priority. This
    can be used to force packets with a local destination out on the wire instead
    of routing them to loopback. Additionally this patch allows to recreate rules
    with a priority of 0.
    
    Combined with the previous patch to allow oif classification, a socket can
    be bound to the desired interface and packets routed to the wire like this:
    
    # move local rule to lower priority
    ip rule add pref 1000 lookup local
    ip rule del pref 0
    
    # route packets of sockets bound to eth0 to the wire independant
    # of the destination address
    ip rule add pref 100 oif eth0 lookup 100
    ip route add default dev eth0 lookup 100
    
    Signed-off-by: Patrick McHardy <kaber@trash.net>

--
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

Comments

jamal Dec. 1, 2009, 1:23 p.m. UTC | #1
Nice. I recall there was a lot of sentiment against this back
when - in particular from Alexey. I cant remember the details
neither can i think off top of my head why this would be bad
other than allowing people to shoot their big toe without
knowing it.
CCing Robert and Alexey. Mass quoting to provide context for 
both Alexey and Robert.

cheers,
jamal


On Mon, 2009-11-30 at 18:55 +0100, Patrick McHardy wrote:
> commit ca1ba96aaa05cc0a2a7f172990e7787354c8b7b9
> Author: Patrick McHardy <kaber@trash.net>
> Date:   Mon Nov 30 16:05:51 2009 +0100
> 
>     net: fib_rules: allow to delete local rule
>     
>     Allow to delete the local rule and recreate it with a lower priority. This
>     can be used to force packets with a local destination out on the wire instead
>     of routing them to loopback. Additionally this patch allows to recreate rules
>     with a priority of 0.
>     
>     Combined with the previous patch to allow oif classification, a socket can
>     be bound to the desired interface and packets routed to the wire like this:
>     
>     # move local rule to lower priority
>     ip rule add pref 1000 lookup local
>     ip rule del pref 0
>     
>     # route packets of sockets bound to eth0 to the wire independant
>     # of the destination address
>     ip rule add pref 100 oif eth0 lookup 100
>     ip route add default dev eth0 lookup 100
>     
>     Signed-off-by: Patrick McHardy <kaber@trash.net>
> 
> diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> index d1a70ad..ef0e7d9 100644
> --- a/net/core/fib_rules.c
> +++ b/net/core/fib_rules.c
> @@ -287,7 +287,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
>  	rule->flags = frh->flags;
>  	rule->table = frh_get_table(frh, tb);
>  
> -	if (!rule->pref && ops->default_pref)
> +	if (!tb[FRA_PRIORITY] && ops->default_pref)
>  		rule->pref = ops->default_pref(ops);
>  
>  	err = -EINVAL;
> diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
> index 835262c..1239ed2 100644
> --- a/net/ipv4/fib_rules.c
> +++ b/net/ipv4/fib_rules.c
> @@ -284,7 +284,7 @@ static int fib_default_rules_init(struct fib_rules_ops *ops)
>  {
>  	int err;
>  
> -	err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
> +	err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0);
>  	if (err < 0)
>  		return err;
>  	err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
> diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
> index 00a7a5e..3b38f49 100644
> --- a/net/ipv6/fib6_rules.c
> +++ b/net/ipv6/fib6_rules.c
> @@ -276,7 +276,7 @@ static int fib6_rules_net_init(struct net *net)
>  	INIT_LIST_HEAD(&net->ipv6.fib6_rules_ops->rules_list);
>  
>  	err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0,
> -				   RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
> +				   RT6_TABLE_LOCAL, 0);
>  	if (err)
>  		goto out_fib6_rules_ops;
>  
> --
> 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

--
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
Alexey Kuznetsov Dec. 1, 2009, 5:12 p.m. UTC | #2
Hello!

> Nice. I recall there was a lot of sentiment against this back
> when - in particular from Alexey. I cant remember the details

Indeed, I refused to do this.

Sometimes, we have to determine that an address is local in a context
where we do not have information to form a proper request to rule database.
In this case we do direct lookup in fixed table, which is designated
to contain local routes. So that rule 0 was hardwired to lookup in the
same table.

Frankly, it will work provided we do not require too much of self-consistency.
Those days I could not stand this, but it is not illegal.

Alexey
--
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
Patrick McHardy Dec. 1, 2009, 5:38 p.m. UTC | #3
Alexey Kuznetsov wrote:
> Hello!
> 
>> Nice. I recall there was a lot of sentiment against this back
>> when - in particular from Alexey. I cant remember the details
> 
> Indeed, I refused to do this.
> 
> Sometimes, we have to determine that an address is local in a context
> where we do not have information to form a proper request to rule database.
> In this case we do direct lookup in fixed table, which is designated
> to contain local routes. So that rule 0 was hardwired to lookup in the
> same table.

Yes, you have to carefully set up your rules preceeding the local
rule when using this. Using marks or oif should work fine without
affecting the cases where we just need some information like the
device or addresses.

> Frankly, it will work provided we do not require too much of self-consistency.
> Those days I could not stand this, but it is not illegal.

In fact, you should already be able to do this by moving the
contents of the local table to a different one :)
--
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 mbox

Patch

diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index d1a70ad..ef0e7d9 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -287,7 +287,7 @@  static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 	rule->flags = frh->flags;
 	rule->table = frh_get_table(frh, tb);
 
-	if (!rule->pref && ops->default_pref)
+	if (!tb[FRA_PRIORITY] && ops->default_pref)
 		rule->pref = ops->default_pref(ops);
 
 	err = -EINVAL;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 835262c..1239ed2 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -284,7 +284,7 @@  static int fib_default_rules_init(struct fib_rules_ops *ops)
 {
 	int err;
 
-	err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
+	err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0);
 	if (err < 0)
 		return err;
 	err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 00a7a5e..3b38f49 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -276,7 +276,7 @@  static int fib6_rules_net_init(struct net *net)
 	INIT_LIST_HEAD(&net->ipv6.fib6_rules_ops->rules_list);
 
 	err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0,
-				   RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
+				   RT6_TABLE_LOCAL, 0);
 	if (err)
 		goto out_fib6_rules_ops;