aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip6_fib.h3
-rw-r--r--include/net/ip6_route.h4
-rw-r--r--net/ipv6/fib6_rules.c2
-rw-r--r--net/ipv6/route.c32
4 files changed, 17 insertions, 24 deletions
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 6a3f26a04509..e4438de3bd6b 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -173,9 +173,6 @@ struct fib6_table {
173#define RT6_TABLE_LOCAL RT6_TABLE_MAIN 173#define RT6_TABLE_LOCAL RT6_TABLE_MAIN
174#endif 174#endif
175 175
176#define RT6_F_STRICT 1
177#define RT6_F_HAS_SADDR 2
178
179typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *, 176typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *,
180 struct flowi *, int); 177 struct flowi *, int);
181 178
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 0d40f84df21b..297909570041 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -32,6 +32,10 @@ struct route_info {
32#include <linux/ip.h> 32#include <linux/ip.h>
33#include <linux/ipv6.h> 33#include <linux/ipv6.h>
34 34
35#define RT6_LOOKUP_F_IFACE 0x1
36#define RT6_LOOKUP_F_REACHABLE 0x2
37#define RT6_LOOKUP_F_HAS_SADDR 0x4
38
35struct pol_chain { 39struct pol_chain {
36 int type; 40 int type;
37 int priority; 41 int priority;
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 2c4fbc855e6c..7b4908cc52b3 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -117,7 +117,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
117 if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) 117 if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
118 return 0; 118 return 0;
119 119
120 if ((flags & RT6_F_HAS_SADDR) && 120 if ((flags & RT6_LOOKUP_F_HAS_SADDR) &&
121 !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) 121 !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
122 return 0; 122 return 0;
123 123
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index fd6f2ec4fa09..20691285aee5 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -76,9 +76,6 @@
76 76
77#define CLONE_OFFLINK_ROUTE 0 77#define CLONE_OFFLINK_ROUTE 0
78 78
79#define RT6_SELECT_F_IFACE 0x1
80#define RT6_SELECT_F_REACHABLE 0x2
81
82static int ip6_rt_max_size = 4096; 79static int ip6_rt_max_size = 4096;
83static int ip6_rt_gc_min_interval = HZ / 2; 80static int ip6_rt_gc_min_interval = HZ / 2;
84static int ip6_rt_gc_timeout = 60*HZ; 81static int ip6_rt_gc_timeout = 60*HZ;
@@ -340,7 +337,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
340 int m, n; 337 int m, n;
341 338
342 m = rt6_check_dev(rt, oif); 339 m = rt6_check_dev(rt, oif);
343 if (!m && (strict & RT6_SELECT_F_IFACE)) 340 if (!m && (strict & RT6_LOOKUP_F_IFACE))
344 return -1; 341 return -1;
345#ifdef CONFIG_IPV6_ROUTER_PREF 342#ifdef CONFIG_IPV6_ROUTER_PREF
346 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; 343 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
@@ -348,7 +345,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
348 n = rt6_check_neigh(rt); 345 n = rt6_check_neigh(rt);
349 if (n > 1) 346 if (n > 1)
350 m |= 16; 347 m |= 16;
351 else if (!n && strict & RT6_SELECT_F_REACHABLE) 348 else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
352 return -1; 349 return -1;
353 return m; 350 return m;
354} 351}
@@ -388,7 +385,7 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
388 } 385 }
389 386
390 if (!match && 387 if (!match &&
391 (strict & RT6_SELECT_F_REACHABLE) && 388 (strict & RT6_LOOKUP_F_REACHABLE) &&
392 last && last != rt0) { 389 last && last != rt0) {
393 /* no entries matched; do round-robin */ 390 /* no entries matched; do round-robin */
394 static DEFINE_SPINLOCK(lock); 391 static DEFINE_SPINLOCK(lock);
@@ -511,7 +508,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table,
511 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 508 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
512restart: 509restart:
513 rt = fn->leaf; 510 rt = fn->leaf;
514 rt = rt6_device_match(rt, fl->oif, flags & RT6_F_STRICT); 511 rt = rt6_device_match(rt, fl->oif, flags);
515 BACKTRACK(&fl->fl6_src); 512 BACKTRACK(&fl->fl6_src);
516 dst_hold(&rt->u.dst); 513 dst_hold(&rt->u.dst);
517out: 514out:
@@ -537,7 +534,7 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
537 }, 534 },
538 }; 535 };
539 struct dst_entry *dst; 536 struct dst_entry *dst;
540 int flags = strict ? RT6_F_STRICT : 0; 537 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
541 538
542 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); 539 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
543 if (dst->error == 0) 540 if (dst->error == 0)
@@ -633,10 +630,9 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
633 int strict = 0; 630 int strict = 0;
634 int attempts = 3; 631 int attempts = 3;
635 int err; 632 int err;
636 int reachable = RT6_SELECT_F_REACHABLE; 633 int reachable = RT6_LOOKUP_F_REACHABLE;
637 634
638 if (flags & RT6_F_STRICT) 635 strict |= flags & RT6_LOOKUP_F_IFACE;
639 strict = RT6_SELECT_F_IFACE;
640 636
641relookup: 637relookup:
642 read_lock_bh(&table->tb6_lock); 638 read_lock_bh(&table->tb6_lock);
@@ -712,10 +708,7 @@ void ip6_route_input(struct sk_buff *skb)
712 }, 708 },
713 .proto = iph->nexthdr, 709 .proto = iph->nexthdr,
714 }; 710 };
715 int flags = 0; 711 int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0;
716
717 if (rt6_need_strict(&iph->daddr))
718 flags |= RT6_F_STRICT;
719 712
720 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); 713 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
721} 714}
@@ -728,10 +721,9 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
728 int strict = 0; 721 int strict = 0;
729 int attempts = 3; 722 int attempts = 3;
730 int err; 723 int err;
731 int reachable = RT6_SELECT_F_REACHABLE; 724 int reachable = RT6_LOOKUP_F_REACHABLE;
732 725
733 if (flags & RT6_F_STRICT) 726 strict |= flags & RT6_LOOKUP_F_IFACE;
734 strict = RT6_SELECT_F_IFACE;
735 727
736relookup: 728relookup:
737 read_lock_bh(&table->tb6_lock); 729 read_lock_bh(&table->tb6_lock);
@@ -797,7 +789,7 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
797 int flags = 0; 789 int flags = 0;
798 790
799 if (rt6_need_strict(&fl->fl6_dst)) 791 if (rt6_need_strict(&fl->fl6_dst))
800 flags |= RT6_F_STRICT; 792 flags |= RT6_LOOKUP_F_IFACE;
801 793
802 return fib6_rule_lookup(fl, flags, ip6_pol_route_output); 794 return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
803} 795}
@@ -1362,7 +1354,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1362 }, 1354 },
1363 .gateway = *gateway, 1355 .gateway = *gateway,
1364 }; 1356 };
1365 int flags = rt6_need_strict(dest) ? RT6_F_STRICT : 0; 1357 int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0;
1366 1358
1367 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); 1359 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
1368} 1360}