route.c (9a2a537acc75dfd19c4358bc9cb6042bdc60698c) | route.c (b75cc8f90f07342467b3bd51dbc0054f185032c9) |
---|---|
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 --- 438 unchanged lines hidden (view full) --- 447 return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || 448 rt6_check_expired(rt->from); 449 } 450 return false; 451} 452 453static struct rt6_info *rt6_multipath_select(struct rt6_info *match, 454 struct flowi6 *fl6, int oif, | 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 --- 438 unchanged lines hidden (view full) --- 447 return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || 448 rt6_check_expired(rt->from); 449 } 450 return false; 451} 452 453static struct rt6_info *rt6_multipath_select(struct rt6_info *match, 454 struct flowi6 *fl6, int oif, |
455 const struct sk_buff *skb, |
|
455 int strict) 456{ 457 struct rt6_info *sibling, *next_sibling; 458 459 /* We might have already computed the hash for ICMPv6 errors. In such 460 * case it will always be non-zero. Otherwise now is the time to do it. 461 */ 462 if (!fl6->mp_hash) | 456 int strict) 457{ 458 struct rt6_info *sibling, *next_sibling; 459 460 /* We might have already computed the hash for ICMPv6 errors. In such 461 * case it will always be non-zero. Otherwise now is the time to do it. 462 */ 463 if (!fl6->mp_hash) |
463 fl6->mp_hash = rt6_multipath_hash(fl6, NULL, NULL); | 464 fl6->mp_hash = rt6_multipath_hash(fl6, skb, NULL); |
464 465 if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound)) 466 return match; 467 468 list_for_each_entry_safe(sibling, next_sibling, &match->rt6i_siblings, 469 rt6i_siblings) { 470 if (fl6->mp_hash > atomic_read(&sibling->rt6i_nh_upper_bound)) 471 continue; --- 437 unchanged lines hidden (view full) --- 909 rt = NULL; 910 } 911 *prt = rt; 912 return false; 913} 914 915static struct rt6_info *ip6_pol_route_lookup(struct net *net, 916 struct fib6_table *table, | 465 466 if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound)) 467 return match; 468 469 list_for_each_entry_safe(sibling, next_sibling, &match->rt6i_siblings, 470 rt6i_siblings) { 471 if (fl6->mp_hash > atomic_read(&sibling->rt6i_nh_upper_bound)) 472 continue; --- 437 unchanged lines hidden (view full) --- 910 rt = NULL; 911 } 912 *prt = rt; 913 return false; 914} 915 916static struct rt6_info *ip6_pol_route_lookup(struct net *net, 917 struct fib6_table *table, |
917 struct flowi6 *fl6, int flags) | 918 struct flowi6 *fl6, 919 const struct sk_buff *skb, 920 int flags) |
918{ 919 struct rt6_info *rt, *rt_cache; 920 struct fib6_node *fn; 921 922 rcu_read_lock(); 923 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); 924restart: 925 rt = rcu_dereference(fn->leaf); 926 if (!rt) { 927 rt = net->ipv6.ip6_null_entry; 928 } else { 929 rt = rt6_device_match(net, rt, &fl6->saddr, 930 fl6->flowi6_oif, flags); 931 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) | 921{ 922 struct rt6_info *rt, *rt_cache; 923 struct fib6_node *fn; 924 925 rcu_read_lock(); 926 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); 927restart: 928 rt = rcu_dereference(fn->leaf); 929 if (!rt) { 930 rt = net->ipv6.ip6_null_entry; 931 } else { 932 rt = rt6_device_match(net, rt, &fl6->saddr, 933 fl6->flowi6_oif, flags); 934 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) |
932 rt = rt6_multipath_select(rt, fl6, 933 fl6->flowi6_oif, flags); | 935 rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, 936 skb, flags); |
934 } 935 if (rt == net->ipv6.ip6_null_entry) { 936 fn = fib6_backtrack(fn, &fl6->saddr); 937 if (fn) 938 goto restart; 939 } 940 /* Search through exception table */ 941 rt_cache = rt6_find_cached_rt(rt, &fl6->daddr, &fl6->saddr); --- 7 unchanged lines hidden (view full) --- 949 950 trace_fib6_table_lookup(net, rt, table, fl6); 951 952 return rt; 953 954} 955 956struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, | 937 } 938 if (rt == net->ipv6.ip6_null_entry) { 939 fn = fib6_backtrack(fn, &fl6->saddr); 940 if (fn) 941 goto restart; 942 } 943 /* Search through exception table */ 944 rt_cache = rt6_find_cached_rt(rt, &fl6->daddr, &fl6->saddr); --- 7 unchanged lines hidden (view full) --- 952 953 trace_fib6_table_lookup(net, rt, table, fl6); 954 955 return rt; 956 957} 958 959struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, |
957 int flags) | 960 const struct sk_buff *skb, int flags) |
958{ | 961{ |
959 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup); | 962 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_lookup); |
960} 961EXPORT_SYMBOL_GPL(ip6_route_lookup); 962 963struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, | 963} 964EXPORT_SYMBOL_GPL(ip6_route_lookup); 965 966struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, |
964 const struct in6_addr *saddr, int oif, int strict) | 967 const struct in6_addr *saddr, int oif, 968 const struct sk_buff *skb, int strict) |
965{ 966 struct flowi6 fl6 = { 967 .flowi6_oif = oif, 968 .daddr = *daddr, 969 }; 970 struct dst_entry *dst; 971 int flags = strict ? RT6_LOOKUP_F_IFACE : 0; 972 973 if (saddr) { 974 memcpy(&fl6.saddr, saddr, sizeof(*saddr)); 975 flags |= RT6_LOOKUP_F_HAS_SADDR; 976 } 977 | 969{ 970 struct flowi6 fl6 = { 971 .flowi6_oif = oif, 972 .daddr = *daddr, 973 }; 974 struct dst_entry *dst; 975 int flags = strict ? RT6_LOOKUP_F_IFACE : 0; 976 977 if (saddr) { 978 memcpy(&fl6.saddr, saddr, sizeof(*saddr)); 979 flags |= RT6_LOOKUP_F_HAS_SADDR; 980 } 981 |
978 dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup); | 982 dst = fib6_rule_lookup(net, &fl6, skb, flags, ip6_pol_route_lookup); |
979 if (dst->error == 0) 980 return (struct rt6_info *) dst; 981 982 dst_release(dst); 983 984 return NULL; 985} 986EXPORT_SYMBOL(rt6_lookup); --- 655 unchanged lines hidden (view full) --- 1642 } 1643 bucket++; 1644 } 1645 } 1646 spin_unlock_bh(&rt6_exception_lock); 1647} 1648 1649struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, | 983 if (dst->error == 0) 984 return (struct rt6_info *) dst; 985 986 dst_release(dst); 987 988 return NULL; 989} 990EXPORT_SYMBOL(rt6_lookup); --- 655 unchanged lines hidden (view full) --- 1646 } 1647 bucket++; 1648 } 1649 } 1650 spin_unlock_bh(&rt6_exception_lock); 1651} 1652 1653struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, |
1650 int oif, struct flowi6 *fl6, int flags) | 1654 int oif, struct flowi6 *fl6, 1655 const struct sk_buff *skb, int flags) |
1651{ 1652 struct fib6_node *fn, *saved_fn; 1653 struct rt6_info *rt, *rt_cache; 1654 int strict = 0; 1655 1656 strict |= flags & RT6_LOOKUP_F_IFACE; 1657 strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE; 1658 if (net->ipv6.devconf_all->forwarding == 0) --- 5 unchanged lines hidden (view full) --- 1664 saved_fn = fn; 1665 1666 if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) 1667 oif = 0; 1668 1669redo_rt6_select: 1670 rt = rt6_select(net, fn, oif, strict); 1671 if (rt->rt6i_nsiblings) | 1656{ 1657 struct fib6_node *fn, *saved_fn; 1658 struct rt6_info *rt, *rt_cache; 1659 int strict = 0; 1660 1661 strict |= flags & RT6_LOOKUP_F_IFACE; 1662 strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE; 1663 if (net->ipv6.devconf_all->forwarding == 0) --- 5 unchanged lines hidden (view full) --- 1669 saved_fn = fn; 1670 1671 if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) 1672 oif = 0; 1673 1674redo_rt6_select: 1675 rt = rt6_select(net, fn, oif, strict); 1676 if (rt->rt6i_nsiblings) |
1672 rt = rt6_multipath_select(rt, fl6, oif, strict); | 1677 rt = rt6_multipath_select(rt, fl6, oif, skb, strict); |
1673 if (rt == net->ipv6.ip6_null_entry) { 1674 fn = fib6_backtrack(fn, &fl6->saddr); 1675 if (fn) 1676 goto redo_rt6_select; 1677 else if (strict & RT6_LOOKUP_F_REACHABLE) { 1678 /* also consider unreachable route */ 1679 strict &= ~RT6_LOOKUP_F_REACHABLE; 1680 fn = saved_fn; --- 82 unchanged lines hidden (view full) --- 1763 local_bh_enable(); 1764 rcu_read_unlock(); 1765 trace_fib6_table_lookup(net, pcpu_rt, table, fl6); 1766 return pcpu_rt; 1767 } 1768} 1769EXPORT_SYMBOL_GPL(ip6_pol_route); 1770 | 1678 if (rt == net->ipv6.ip6_null_entry) { 1679 fn = fib6_backtrack(fn, &fl6->saddr); 1680 if (fn) 1681 goto redo_rt6_select; 1682 else if (strict & RT6_LOOKUP_F_REACHABLE) { 1683 /* also consider unreachable route */ 1684 strict &= ~RT6_LOOKUP_F_REACHABLE; 1685 fn = saved_fn; --- 82 unchanged lines hidden (view full) --- 1768 local_bh_enable(); 1769 rcu_read_unlock(); 1770 trace_fib6_table_lookup(net, pcpu_rt, table, fl6); 1771 return pcpu_rt; 1772 } 1773} 1774EXPORT_SYMBOL_GPL(ip6_pol_route); 1775 |
1771static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, 1772 struct flowi6 *fl6, int flags) | 1776static struct rt6_info *ip6_pol_route_input(struct net *net, 1777 struct fib6_table *table, 1778 struct flowi6 *fl6, 1779 const struct sk_buff *skb, 1780 int flags) |
1773{ | 1781{ |
1774 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags); | 1782 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, skb, flags); |
1775} 1776 1777struct dst_entry *ip6_route_input_lookup(struct net *net, 1778 struct net_device *dev, | 1783} 1784 1785struct dst_entry *ip6_route_input_lookup(struct net *net, 1786 struct net_device *dev, |
1779 struct flowi6 *fl6, int flags) | 1787 struct flowi6 *fl6, 1788 const struct sk_buff *skb, 1789 int flags) |
1780{ 1781 if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG) 1782 flags |= RT6_LOOKUP_F_IFACE; 1783 | 1790{ 1791 if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG) 1792 flags |= RT6_LOOKUP_F_IFACE; 1793 |
1784 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input); | 1794 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_input); |
1785} 1786EXPORT_SYMBOL_GPL(ip6_route_input_lookup); 1787 1788static void ip6_multipath_l3_keys(const struct sk_buff *skb, 1789 struct flow_keys *keys, 1790 struct flow_keys *flkeys) 1791{ 1792 const struct ipv6hdr *outer_iph = ipv6_hdr(skb); --- 78 unchanged lines hidden (view full) --- 1871 fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; 1872 1873 if (fib6_rules_early_flow_dissect(net, skb, &fl6, &_flkeys)) 1874 flkeys = &_flkeys; 1875 1876 if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6)) 1877 fl6.mp_hash = rt6_multipath_hash(&fl6, skb, flkeys); 1878 skb_dst_drop(skb); | 1795} 1796EXPORT_SYMBOL_GPL(ip6_route_input_lookup); 1797 1798static void ip6_multipath_l3_keys(const struct sk_buff *skb, 1799 struct flow_keys *keys, 1800 struct flow_keys *flkeys) 1801{ 1802 const struct ipv6hdr *outer_iph = ipv6_hdr(skb); --- 78 unchanged lines hidden (view full) --- 1881 fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; 1882 1883 if (fib6_rules_early_flow_dissect(net, skb, &fl6, &_flkeys)) 1884 flkeys = &_flkeys; 1885 1886 if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6)) 1887 fl6.mp_hash = rt6_multipath_hash(&fl6, skb, flkeys); 1888 skb_dst_drop(skb); |
1879 skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); | 1889 skb_dst_set(skb, 1890 ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags)); |
1880} 1881 | 1891} 1892 |
1882static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 1883 struct flowi6 *fl6, int flags) | 1893static struct rt6_info *ip6_pol_route_output(struct net *net, 1894 struct fib6_table *table, 1895 struct flowi6 *fl6, 1896 const struct sk_buff *skb, 1897 int flags) |
1884{ | 1898{ |
1885 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); | 1899 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, skb, flags); |
1886} 1887 1888struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, 1889 struct flowi6 *fl6, int flags) 1890{ 1891 bool any_src; 1892 1893 if (rt6_need_strict(&fl6->daddr)) { --- 11 unchanged lines hidden (view full) --- 1905 (fl6->flowi6_oif && any_src)) 1906 flags |= RT6_LOOKUP_F_IFACE; 1907 1908 if (!any_src) 1909 flags |= RT6_LOOKUP_F_HAS_SADDR; 1910 else if (sk) 1911 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 1912 | 1900} 1901 1902struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, 1903 struct flowi6 *fl6, int flags) 1904{ 1905 bool any_src; 1906 1907 if (rt6_need_strict(&fl6->daddr)) { --- 11 unchanged lines hidden (view full) --- 1919 (fl6->flowi6_oif && any_src)) 1920 flags |= RT6_LOOKUP_F_IFACE; 1921 1922 if (!any_src) 1923 flags |= RT6_LOOKUP_F_HAS_SADDR; 1924 else if (sk) 1925 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 1926 |
1913 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); | 1927 return fib6_rule_lookup(net, fl6, NULL, flags, ip6_pol_route_output); |
1914} 1915EXPORT_SYMBOL_GPL(ip6_route_output_flags); 1916 1917struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 1918{ 1919 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; 1920 struct net_device *loopback_dev = net->loopback_dev; 1921 struct dst_entry *new = NULL; --- 232 unchanged lines hidden (view full) --- 2154struct ip6rd_flowi { 2155 struct flowi6 fl6; 2156 struct in6_addr gateway; 2157}; 2158 2159static struct rt6_info *__ip6_route_redirect(struct net *net, 2160 struct fib6_table *table, 2161 struct flowi6 *fl6, | 1928} 1929EXPORT_SYMBOL_GPL(ip6_route_output_flags); 1930 1931struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 1932{ 1933 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; 1934 struct net_device *loopback_dev = net->loopback_dev; 1935 struct dst_entry *new = NULL; --- 232 unchanged lines hidden (view full) --- 2168struct ip6rd_flowi { 2169 struct flowi6 fl6; 2170 struct in6_addr gateway; 2171}; 2172 2173static struct rt6_info *__ip6_route_redirect(struct net *net, 2174 struct fib6_table *table, 2175 struct flowi6 *fl6, |
2176 const struct sk_buff *skb, |
|
2162 int flags) 2163{ 2164 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; 2165 struct rt6_info *rt, *rt_cache; 2166 struct fib6_node *fn; 2167 2168 /* Get the "current" route for this destination and 2169 * check if the redirect has come from appropriate router. --- 57 unchanged lines hidden (view full) --- 2227 2228 rcu_read_unlock(); 2229 2230 trace_fib6_table_lookup(net, rt, table, fl6); 2231 return rt; 2232}; 2233 2234static struct dst_entry *ip6_route_redirect(struct net *net, | 2177 int flags) 2178{ 2179 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; 2180 struct rt6_info *rt, *rt_cache; 2181 struct fib6_node *fn; 2182 2183 /* Get the "current" route for this destination and 2184 * check if the redirect has come from appropriate router. --- 57 unchanged lines hidden (view full) --- 2242 2243 rcu_read_unlock(); 2244 2245 trace_fib6_table_lookup(net, rt, table, fl6); 2246 return rt; 2247}; 2248 2249static struct dst_entry *ip6_route_redirect(struct net *net, |
2235 const struct flowi6 *fl6, 2236 const struct in6_addr *gateway) | 2250 const struct flowi6 *fl6, 2251 const struct sk_buff *skb, 2252 const struct in6_addr *gateway) |
2237{ 2238 int flags = RT6_LOOKUP_F_HAS_SADDR; 2239 struct ip6rd_flowi rdfl; 2240 2241 rdfl.fl6 = *fl6; 2242 rdfl.gateway = *gateway; 2243 | 2253{ 2254 int flags = RT6_LOOKUP_F_HAS_SADDR; 2255 struct ip6rd_flowi rdfl; 2256 2257 rdfl.fl6 = *fl6; 2258 rdfl.gateway = *gateway; 2259 |
2244 return fib6_rule_lookup(net, &rdfl.fl6, | 2260 return fib6_rule_lookup(net, &rdfl.fl6, skb, |
2245 flags, __ip6_route_redirect); 2246} 2247 2248void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark, 2249 kuid_t uid) 2250{ 2251 const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; 2252 struct dst_entry *dst; 2253 struct flowi6 fl6; 2254 2255 memset(&fl6, 0, sizeof(fl6)); 2256 fl6.flowi6_iif = LOOPBACK_IFINDEX; 2257 fl6.flowi6_oif = oif; 2258 fl6.flowi6_mark = mark; 2259 fl6.daddr = iph->daddr; 2260 fl6.saddr = iph->saddr; 2261 fl6.flowlabel = ip6_flowinfo(iph); 2262 fl6.flowi6_uid = uid; 2263 | 2261 flags, __ip6_route_redirect); 2262} 2263 2264void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark, 2265 kuid_t uid) 2266{ 2267 const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; 2268 struct dst_entry *dst; 2269 struct flowi6 fl6; 2270 2271 memset(&fl6, 0, sizeof(fl6)); 2272 fl6.flowi6_iif = LOOPBACK_IFINDEX; 2273 fl6.flowi6_oif = oif; 2274 fl6.flowi6_mark = mark; 2275 fl6.daddr = iph->daddr; 2276 fl6.saddr = iph->saddr; 2277 fl6.flowlabel = ip6_flowinfo(iph); 2278 fl6.flowi6_uid = uid; 2279 |
2264 dst = ip6_route_redirect(net, &fl6, &ipv6_hdr(skb)->saddr); | 2280 dst = ip6_route_redirect(net, &fl6, skb, &ipv6_hdr(skb)->saddr); |
2265 rt6_do_redirect(dst, NULL, skb); 2266 dst_release(dst); 2267} 2268EXPORT_SYMBOL_GPL(ip6_redirect); 2269 2270void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif, 2271 u32 mark) 2272{ --- 5 unchanged lines hidden (view full) --- 2278 memset(&fl6, 0, sizeof(fl6)); 2279 fl6.flowi6_iif = LOOPBACK_IFINDEX; 2280 fl6.flowi6_oif = oif; 2281 fl6.flowi6_mark = mark; 2282 fl6.daddr = msg->dest; 2283 fl6.saddr = iph->daddr; 2284 fl6.flowi6_uid = sock_net_uid(net, NULL); 2285 | 2281 rt6_do_redirect(dst, NULL, skb); 2282 dst_release(dst); 2283} 2284EXPORT_SYMBOL_GPL(ip6_redirect); 2285 2286void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif, 2287 u32 mark) 2288{ --- 5 unchanged lines hidden (view full) --- 2294 memset(&fl6, 0, sizeof(fl6)); 2295 fl6.flowi6_iif = LOOPBACK_IFINDEX; 2296 fl6.flowi6_oif = oif; 2297 fl6.flowi6_mark = mark; 2298 fl6.daddr = msg->dest; 2299 fl6.saddr = iph->daddr; 2300 fl6.flowi6_uid = sock_net_uid(net, NULL); 2301 |
2286 dst = ip6_route_redirect(net, &fl6, &iph->saddr); | 2302 dst = ip6_route_redirect(net, &fl6, skb, &iph->saddr); |
2287 rt6_do_redirect(dst, NULL, skb); 2288 dst_release(dst); 2289} 2290 2291void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk) 2292{ 2293 ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark, 2294 sk->sk_uid); --- 185 unchanged lines hidden (view full) --- 2480 table = fib6_get_table(net, tbid); 2481 if (!table) 2482 return NULL; 2483 2484 if (!ipv6_addr_any(&cfg->fc_prefsrc)) 2485 flags |= RT6_LOOKUP_F_HAS_SADDR; 2486 2487 flags |= RT6_LOOKUP_F_IGNORE_LINKSTATE; | 2303 rt6_do_redirect(dst, NULL, skb); 2304 dst_release(dst); 2305} 2306 2307void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk) 2308{ 2309 ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark, 2310 sk->sk_uid); --- 185 unchanged lines hidden (view full) --- 2496 table = fib6_get_table(net, tbid); 2497 if (!table) 2498 return NULL; 2499 2500 if (!ipv6_addr_any(&cfg->fc_prefsrc)) 2501 flags |= RT6_LOOKUP_F_HAS_SADDR; 2502 2503 flags |= RT6_LOOKUP_F_IGNORE_LINKSTATE; |
2488 rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags); | 2504 rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, NULL, flags); |
2489 2490 /* if table lookup failed, fall back to full lookup */ 2491 if (rt == net->ipv6.ip6_null_entry) { 2492 ip6_rt_put(rt); 2493 rt = NULL; 2494 } 2495 2496 return rt; --- 46 unchanged lines hidden (view full) --- 2543 (dev && dev != grt->dst.dev)) { 2544 ip6_rt_put(grt); 2545 grt = NULL; 2546 } 2547 } 2548 } 2549 2550 if (!grt) | 2505 2506 /* if table lookup failed, fall back to full lookup */ 2507 if (rt == net->ipv6.ip6_null_entry) { 2508 ip6_rt_put(rt); 2509 rt = NULL; 2510 } 2511 2512 return rt; --- 46 unchanged lines hidden (view full) --- 2559 (dev && dev != grt->dst.dev)) { 2560 ip6_rt_put(grt); 2561 grt = NULL; 2562 } 2563 } 2564 } 2565 2566 if (!grt) |
2551 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); | 2567 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, NULL, 1); |
2552 2553 if (!grt) 2554 goto out; 2555 2556 if (dev) { 2557 if (dev != grt->dst.dev) { 2558 ip6_rt_put(grt); 2559 goto out; --- 2048 unchanged lines hidden (view full) --- 4608 goto errout; 4609 } 4610 4611 fl6.flowi6_iif = iif; 4612 4613 if (!ipv6_addr_any(&fl6.saddr)) 4614 flags |= RT6_LOOKUP_F_HAS_SADDR; 4615 | 2568 2569 if (!grt) 2570 goto out; 2571 2572 if (dev) { 2573 if (dev != grt->dst.dev) { 2574 ip6_rt_put(grt); 2575 goto out; --- 2048 unchanged lines hidden (view full) --- 4624 goto errout; 4625 } 4626 4627 fl6.flowi6_iif = iif; 4628 4629 if (!ipv6_addr_any(&fl6.saddr)) 4630 flags |= RT6_LOOKUP_F_HAS_SADDR; 4631 |
4616 dst = ip6_route_input_lookup(net, dev, &fl6, flags); | 4632 dst = ip6_route_input_lookup(net, dev, &fl6, NULL, flags); |
4617 4618 rcu_read_unlock(); 4619 } else { 4620 fl6.flowi6_oif = oif; 4621 4622 dst = ip6_route_output(net, NULL, &fl6); 4623 } 4624 --- 531 unchanged lines hidden --- | 4633 4634 rcu_read_unlock(); 4635 } else { 4636 fl6.flowi6_oif = oif; 4637 4638 dst = ip6_route_output(net, NULL, &fl6); 4639 } 4640 --- 531 unchanged lines hidden --- |