route.c (1d053da910947afccec96d90892c0f5488c7a9cf) | route.c (d4bea421f7322400d804c2284739e42e61f78349) |
---|---|
1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 1064 unchanged lines hidden (view full) --- 1073 flags); 1074 } 1075 if (f6i == net->ipv6.fib6_null_entry) { 1076 fn = fib6_backtrack(fn, &fl6->saddr); 1077 if (fn) 1078 goto restart; 1079 } 1080 | 1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 1064 unchanged lines hidden (view full) --- 1073 flags); 1074 } 1075 if (f6i == net->ipv6.fib6_null_entry) { 1076 fn = fib6_backtrack(fn, &fl6->saddr); 1077 if (fn) 1078 goto restart; 1079 } 1080 |
1081 trace_fib6_table_lookup(net, f6i, table, fl6); 1082 |
|
1081 /* Search through exception table */ 1082 rt = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr); 1083 if (rt) { 1084 if (ip6_hold_safe(net, &rt, true)) 1085 dst_use_noref(&rt->dst, jiffies); 1086 } else if (f6i == net->ipv6.fib6_null_entry) { 1087 rt = net->ipv6.ip6_null_entry; 1088 dst_hold(&rt->dst); 1089 } else { 1090 rt = ip6_create_rt_rcu(f6i); 1091 if (!rt) { 1092 rt = net->ipv6.ip6_null_entry; 1093 dst_hold(&rt->dst); 1094 } 1095 } 1096 1097 rcu_read_unlock(); 1098 | 1083 /* Search through exception table */ 1084 rt = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr); 1085 if (rt) { 1086 if (ip6_hold_safe(net, &rt, true)) 1087 dst_use_noref(&rt->dst, jiffies); 1088 } else if (f6i == net->ipv6.fib6_null_entry) { 1089 rt = net->ipv6.ip6_null_entry; 1090 dst_hold(&rt->dst); 1091 } else { 1092 rt = ip6_create_rt_rcu(f6i); 1093 if (!rt) { 1094 rt = net->ipv6.ip6_null_entry; 1095 dst_hold(&rt->dst); 1096 } 1097 } 1098 1099 rcu_read_unlock(); 1100 |
1099 trace_fib6_table_lookup(net, rt, table, fl6); 1100 | |
1101 return rt; 1102} 1103 1104struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, 1105 const struct sk_buff *skb, int flags) 1106{ 1107 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_lookup); 1108} --- 713 unchanged lines hidden (view full) --- 1822 else if (strict & RT6_LOOKUP_F_REACHABLE) { 1823 /* also consider unreachable route */ 1824 strict &= ~RT6_LOOKUP_F_REACHABLE; 1825 fn = saved_fn; 1826 goto redo_rt6_select; 1827 } 1828 } 1829 | 1101 return rt; 1102} 1103 1104struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, 1105 const struct sk_buff *skb, int flags) 1106{ 1107 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_lookup); 1108} --- 713 unchanged lines hidden (view full) --- 1822 else if (strict & RT6_LOOKUP_F_REACHABLE) { 1823 /* also consider unreachable route */ 1824 strict &= ~RT6_LOOKUP_F_REACHABLE; 1825 fn = saved_fn; 1826 goto redo_rt6_select; 1827 } 1828 } 1829 |
1830 trace_fib6_table_lookup(net, f6i, table, fl6); 1831 |
|
1830 return f6i; 1831} 1832 1833struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, 1834 int oif, struct flowi6 *fl6, 1835 const struct sk_buff *skb, int flags) 1836{ 1837 struct fib6_info *f6i; --- 10 unchanged lines hidden (view full) --- 1848 f6i = fib6_table_lookup(net, table, oif, fl6, strict); 1849 if (f6i->fib6_nsiblings) 1850 f6i = fib6_multipath_select(net, f6i, fl6, oif, skb, strict); 1851 1852 if (f6i == net->ipv6.fib6_null_entry) { 1853 rt = net->ipv6.ip6_null_entry; 1854 rcu_read_unlock(); 1855 dst_hold(&rt->dst); | 1832 return f6i; 1833} 1834 1835struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, 1836 int oif, struct flowi6 *fl6, 1837 const struct sk_buff *skb, int flags) 1838{ 1839 struct fib6_info *f6i; --- 10 unchanged lines hidden (view full) --- 1850 f6i = fib6_table_lookup(net, table, oif, fl6, strict); 1851 if (f6i->fib6_nsiblings) 1852 f6i = fib6_multipath_select(net, f6i, fl6, oif, skb, strict); 1853 1854 if (f6i == net->ipv6.fib6_null_entry) { 1855 rt = net->ipv6.ip6_null_entry; 1856 rcu_read_unlock(); 1857 dst_hold(&rt->dst); |
1856 trace_fib6_table_lookup(net, rt, table, fl6); | |
1857 return rt; 1858 } 1859 1860 /*Search through exception table */ 1861 rt = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr); 1862 if (rt) { 1863 if (ip6_hold_safe(net, &rt, true)) 1864 dst_use_noref(&rt->dst, jiffies); 1865 1866 rcu_read_unlock(); | 1858 return rt; 1859 } 1860 1861 /*Search through exception table */ 1862 rt = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr); 1863 if (rt) { 1864 if (ip6_hold_safe(net, &rt, true)) 1865 dst_use_noref(&rt->dst, jiffies); 1866 1867 rcu_read_unlock(); |
1867 trace_fib6_table_lookup(net, rt, table, fl6); | |
1868 return rt; 1869 } else if (unlikely((fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH) && 1870 !(f6i->fib6_flags & RTF_GATEWAY))) { 1871 /* Create a RTF_CACHE clone which will not be 1872 * owned by the fib6 tree. It is for the special case where 1873 * the daddr in the skb during the neighbor look-up is different 1874 * from the fl6->daddr used to look-up route here. 1875 */ --- 9 unchanged lines hidden (view full) --- 1885 */ 1886 rt6_uncached_list_add(uncached_rt); 1887 atomic_inc(&net->ipv6.rt6_stats->fib_rt_uncache); 1888 } else { 1889 uncached_rt = net->ipv6.ip6_null_entry; 1890 dst_hold(&uncached_rt->dst); 1891 } 1892 | 1868 return rt; 1869 } else if (unlikely((fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH) && 1870 !(f6i->fib6_flags & RTF_GATEWAY))) { 1871 /* Create a RTF_CACHE clone which will not be 1872 * owned by the fib6 tree. It is for the special case where 1873 * the daddr in the skb during the neighbor look-up is different 1874 * from the fl6->daddr used to look-up route here. 1875 */ --- 9 unchanged lines hidden (view full) --- 1885 */ 1886 rt6_uncached_list_add(uncached_rt); 1887 atomic_inc(&net->ipv6.rt6_stats->fib_rt_uncache); 1888 } else { 1889 uncached_rt = net->ipv6.ip6_null_entry; 1890 dst_hold(&uncached_rt->dst); 1891 } 1892 |
1893 trace_fib6_table_lookup(net, uncached_rt, table, fl6); | |
1894 return uncached_rt; | 1893 return uncached_rt; |
1895 | |
1896 } else { 1897 /* Get a percpu copy */ 1898 1899 struct rt6_info *pcpu_rt; 1900 1901 local_bh_disable(); 1902 pcpu_rt = rt6_get_pcpu_route(f6i); 1903 1904 if (!pcpu_rt) 1905 pcpu_rt = rt6_make_pcpu_route(net, f6i); 1906 1907 local_bh_enable(); 1908 rcu_read_unlock(); | 1894 } else { 1895 /* Get a percpu copy */ 1896 1897 struct rt6_info *pcpu_rt; 1898 1899 local_bh_disable(); 1900 pcpu_rt = rt6_get_pcpu_route(f6i); 1901 1902 if (!pcpu_rt) 1903 pcpu_rt = rt6_make_pcpu_route(net, f6i); 1904 1905 local_bh_enable(); 1906 rcu_read_unlock(); |
1909 trace_fib6_table_lookup(net, pcpu_rt, table, fl6); | 1907 |
1910 return pcpu_rt; 1911 } 1912} 1913EXPORT_SYMBOL_GPL(ip6_pol_route); 1914 1915static struct rt6_info *ip6_pol_route_input(struct net *net, 1916 struct fib6_table *table, 1917 struct flowi6 *fl6, --- 568 unchanged lines hidden (view full) --- 2486out: 2487 if (ret) 2488 dst_hold(&ret->dst); 2489 else 2490 ret = ip6_create_rt_rcu(rt); 2491 2492 rcu_read_unlock(); 2493 | 1908 return pcpu_rt; 1909 } 1910} 1911EXPORT_SYMBOL_GPL(ip6_pol_route); 1912 1913static struct rt6_info *ip6_pol_route_input(struct net *net, 1914 struct fib6_table *table, 1915 struct flowi6 *fl6, --- 568 unchanged lines hidden (view full) --- 2484out: 2485 if (ret) 2486 dst_hold(&ret->dst); 2487 else 2488 ret = ip6_create_rt_rcu(rt); 2489 2490 rcu_read_unlock(); 2491 |
2494 trace_fib6_table_lookup(net, ret, table, fl6); | 2492 trace_fib6_table_lookup(net, rt, table, fl6); |
2495 return ret; 2496}; 2497 2498static struct dst_entry *ip6_route_redirect(struct net *net, 2499 const struct flowi6 *fl6, 2500 const struct sk_buff *skb, 2501 const struct in6_addr *gateway) 2502{ --- 2859 unchanged lines hidden --- | 2493 return ret; 2494}; 2495 2496static struct dst_entry *ip6_route_redirect(struct net *net, 2497 const struct flowi6 *fl6, 2498 const struct sk_buff *skb, 2499 const struct in6_addr *gateway) 2500{ --- 2859 unchanged lines hidden --- |