aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2014-10-20 16:42:43 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-24 00:14:39 -0400
commita3c00e46efdb4009369971c97203ea67f7630fe4 (patch)
tree98789f21ff6f3fd596ec49933fc69d5d0979be44 /net/ipv6
parent105970f6087ae240b00deaff85773ed9bf381145 (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.c70
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) \ 775static struct fib6_node* fib6_backtrack(struct fib6_node *fn,
776do { \ 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
793static struct rt6_info *ip6_pol_route_lookup(struct net *net, 792static 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) {
808out: 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
927relookup: 929redo_fib6_lookup_lock:
928 read_lock_bh(&table->tb6_lock); 930 read_lock_bh(&table->tb6_lock);
929 931
930restart_2: 932redo_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
933restart: 935redo_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
972out: 980out:
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
1241out:
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);