diff options
author | Martin KaFai Lau <kafai@fb.com> | 2014-10-20 16:42:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-24 00:14:39 -0400 |
commit | a3c00e46efdb4009369971c97203ea67f7630fe4 (patch) | |
tree | 98789f21ff6f3fd596ec49933fc69d5d0979be44 /net/ipv6 | |
parent | 105970f6087ae240b00deaff85773ed9bf381145 (diff) |
ipv6: Remove BACKTRACK macro
It is the prep work to reduce the number of calls to fib6_lookup().
The BACKTRACK macro could be hard-to-read and error-prone due to
its side effects (mainly goto).
This patch is to:
1. Replace BACKTRACK macro with a function (fib6_backtrack) with the following
return values:
* If it is backtrack-able, returns next fn for retry.
* If it reaches the root, returns NULL.
2. The caller needs to decide if a backtrack is needed (by testing
rt == net->ipv6.ip6_null_entry).
3. Rename the goto labels in ip6_pol_route() to make the next few
patches easier to read.
Cc: David Miller <davem@davemloft.net>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/route.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a318dd89b6d9..f1ab2f4f4529 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -772,23 +772,22 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
772 | } | 772 | } |
773 | #endif | 773 | #endif |
774 | 774 | ||
775 | #define BACKTRACK(__net, saddr) \ | 775 | static struct fib6_node* fib6_backtrack(struct fib6_node *fn, |
776 | do { \ | 776 | struct in6_addr *saddr) |
777 | if (rt == __net->ipv6.ip6_null_entry) { \ | 777 | { |
778 | struct fib6_node *pn; \ | 778 | struct fib6_node *pn; |
779 | while (1) { \ | 779 | while (1) { |
780 | if (fn->fn_flags & RTN_TL_ROOT) \ | 780 | if (fn->fn_flags & RTN_TL_ROOT) |
781 | goto out; \ | 781 | return NULL; |
782 | pn = fn->parent; \ | 782 | pn = fn->parent; |
783 | if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \ | 783 | if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) |
784 | fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \ | 784 | fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); |
785 | else \ | 785 | else |
786 | fn = pn; \ | 786 | fn = pn; |
787 | if (fn->fn_flags & RTN_RTINFO) \ | 787 | if (fn->fn_flags & RTN_RTINFO) |
788 | goto restart; \ | 788 | return fn; |
789 | } \ | 789 | } |
790 | } \ | 790 | } |
791 | } while (0) | ||
792 | 791 | ||
793 | static struct rt6_info *ip6_pol_route_lookup(struct net *net, | 792 | static struct rt6_info *ip6_pol_route_lookup(struct net *net, |
794 | struct fib6_table *table, | 793 | struct fib6_table *table, |
@@ -804,8 +803,11 @@ restart: | |||
804 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); | 803 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); |
805 | if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) | 804 | if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) |
806 | rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, flags); | 805 | rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, flags); |
807 | BACKTRACK(net, &fl6->saddr); | 806 | if (rt == net->ipv6.ip6_null_entry) { |
808 | out: | 807 | fn = fib6_backtrack(fn, &fl6->saddr); |
808 | if (fn) | ||
809 | goto restart; | ||
810 | } | ||
809 | dst_use(&rt->dst, jiffies); | 811 | dst_use(&rt->dst, jiffies); |
810 | read_unlock_bh(&table->tb6_lock); | 812 | read_unlock_bh(&table->tb6_lock); |
811 | return rt; | 813 | return rt; |
@@ -924,19 +926,25 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, | |||
924 | 926 | ||
925 | strict |= flags & RT6_LOOKUP_F_IFACE; | 927 | strict |= flags & RT6_LOOKUP_F_IFACE; |
926 | 928 | ||
927 | relookup: | 929 | redo_fib6_lookup_lock: |
928 | read_lock_bh(&table->tb6_lock); | 930 | read_lock_bh(&table->tb6_lock); |
929 | 931 | ||
930 | restart_2: | 932 | redo_fib6_lookup: |
931 | fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); | 933 | fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); |
932 | 934 | ||
933 | restart: | 935 | redo_rt6_select: |
934 | rt = rt6_select(fn, oif, strict | reachable); | 936 | rt = rt6_select(fn, oif, strict | reachable); |
935 | if (rt->rt6i_nsiblings) | 937 | if (rt->rt6i_nsiblings) |
936 | rt = rt6_multipath_select(rt, fl6, oif, strict | reachable); | 938 | rt = rt6_multipath_select(rt, fl6, oif, strict | reachable); |
937 | BACKTRACK(net, &fl6->saddr); | 939 | if (rt == net->ipv6.ip6_null_entry) { |
938 | if (rt == net->ipv6.ip6_null_entry || | 940 | fn = fib6_backtrack(fn, &fl6->saddr); |
939 | rt->rt6i_flags & RTF_CACHE) | 941 | if (fn) |
942 | goto redo_rt6_select; | ||
943 | else | ||
944 | goto out; | ||
945 | } | ||
946 | |||
947 | if (rt->rt6i_flags & RTF_CACHE) | ||
940 | goto out; | 948 | goto out; |
941 | 949 | ||
942 | dst_hold(&rt->dst); | 950 | dst_hold(&rt->dst); |
@@ -967,12 +975,12 @@ restart: | |||
967 | * released someone could insert this route. Relookup. | 975 | * released someone could insert this route. Relookup. |
968 | */ | 976 | */ |
969 | ip6_rt_put(rt); | 977 | ip6_rt_put(rt); |
970 | goto relookup; | 978 | goto redo_fib6_lookup_lock; |
971 | 979 | ||
972 | out: | 980 | out: |
973 | if (reachable) { | 981 | if (reachable) { |
974 | reachable = 0; | 982 | reachable = 0; |
975 | goto restart_2; | 983 | goto redo_fib6_lookup; |
976 | } | 984 | } |
977 | dst_hold(&rt->dst); | 985 | dst_hold(&rt->dst); |
978 | read_unlock_bh(&table->tb6_lock); | 986 | read_unlock_bh(&table->tb6_lock); |
@@ -1235,10 +1243,12 @@ restart: | |||
1235 | rt = net->ipv6.ip6_null_entry; | 1243 | rt = net->ipv6.ip6_null_entry; |
1236 | else if (rt->dst.error) { | 1244 | else if (rt->dst.error) { |
1237 | rt = net->ipv6.ip6_null_entry; | 1245 | rt = net->ipv6.ip6_null_entry; |
1238 | goto out; | 1246 | } else if (rt == net->ipv6.ip6_null_entry) { |
1247 | fn = fib6_backtrack(fn, &fl6->saddr); | ||
1248 | if (fn) | ||
1249 | goto restart; | ||
1239 | } | 1250 | } |
1240 | BACKTRACK(net, &fl6->saddr); | 1251 | |
1241 | out: | ||
1242 | dst_hold(&rt->dst); | 1252 | dst_hold(&rt->dst); |
1243 | 1253 | ||
1244 | read_unlock_bh(&table->tb6_lock); | 1254 | read_unlock_bh(&table->tb6_lock); |