Skip to content

Commit

Permalink
[IPV6] FIB6RULE: Find source address during looking up route.
Browse files Browse the repository at this point in the history
When looking up route for destination with rules with
source address restrictions, we may need to find a source
address for the traffic if not given.

Based on patch from Noriaki TAKAMIYA <[email protected]>.

Signed-off-by: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
yoshfuji authored and David S. Miller committed Apr 26, 2007
1 parent ea2f10a commit 29f6af7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
11 changes: 7 additions & 4 deletions include/linux/fib_rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
#include <linux/rtnetlink.h>

/* rule is permanent, and cannot be deleted */
#define FIB_RULE_PERMANENT 1
#define FIB_RULE_INVERT 2
#define FIB_RULE_UNRESOLVED 4
#define FIB_RULE_DEV_DETACHED 8
#define FIB_RULE_PERMANENT 0x00000001
#define FIB_RULE_INVERT 0x00000002
#define FIB_RULE_UNRESOLVED 0x00000004
#define FIB_RULE_DEV_DETACHED 0x00000008

/* try to find source address in routing lookups */
#define FIB_RULE_FIND_SADDR 0x00010000

struct fib_rule_hdr
{
Expand Down
34 changes: 31 additions & 3 deletions net/ipv6/fib6_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <net/fib_rules.h>
#include <net/ipv6.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <net/netlink.h>

Expand Down Expand Up @@ -95,8 +96,27 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if (table)
rt = lookup(table, flp, flags);

if (rt != &ip6_null_entry)
if (rt != &ip6_null_entry) {
struct fib6_rule *r = (struct fib6_rule *)rule;

/*
* If we need to find a source address for this traffic,
* we check the result if it meets requirement of the rule.
*/
if ((rule->flags & FIB_RULE_FIND_SADDR) &&
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
struct in6_addr saddr;
if (ipv6_get_saddr(&rt->u.dst, &flp->fl6_dst,
&saddr))
goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
r->src.plen))
goto again;
ipv6_addr_copy(&flp->fl6_src, &saddr);
}
goto out;
}
again:
dst_release(&rt->u.dst);
rt = NULL;
goto out;
Expand All @@ -117,9 +137,17 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
return 0;

/*
* If FIB_RULE_FIND_SADDR is set and we do not have a
* source address for the traffic, we defer check for
* source address.
*/
if (r->src.plen) {
if (!(flags & RT6_LOOKUP_F_HAS_SADDR) ||
!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
if (flags & RT6_LOOKUP_F_HAS_SADDR) {
if (!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr,
r->src.plen))
return 0;
} else if (!(r->common.flags & FIB_RULE_FIND_SADDR))
return 0;
}

Expand Down

0 comments on commit 29f6af7

Please sign in to comment.