diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:43:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:43:21 -0400 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/ipv4/route.c | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
macvlan: fix panic if lowerdev in a bond
tg3: Add braces around 5906 workaround.
tg3: Fix NETIF_F_LOOPBACK error
macvlan: remove one synchronize_rcu() call
networking: NET_CLS_ROUTE4 depends on INET
irda: Fix error propagation in ircomm_lmp_connect_response()
irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
be2net: Kill set but unused variable 'req' in lancer_fw_download()
irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
isdn: capi: Use pr_debug() instead of ifdefs.
tg3: Update version to 3.119
tg3: Apply rx_discards fix to 5719/5720
...
Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 385 |
1 files changed, 189 insertions, 196 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 99e6e4bb1c72..b24d58e6bbcd 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -156,7 +156,7 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old) | |||
156 | u32 *p = NULL; | 156 | u32 *p = NULL; |
157 | 157 | ||
158 | if (!rt->peer) | 158 | if (!rt->peer) |
159 | rt_bind_peer(rt, 1); | 159 | rt_bind_peer(rt, rt->rt_dst, 1); |
160 | 160 | ||
161 | peer = rt->peer; | 161 | peer = rt->peer; |
162 | if (peer) { | 162 | if (peer) { |
@@ -424,7 +424,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
424 | dst_metric(&r->dst, RTAX_WINDOW), | 424 | dst_metric(&r->dst, RTAX_WINDOW), |
425 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + | 425 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + |
426 | dst_metric(&r->dst, RTAX_RTTVAR)), | 426 | dst_metric(&r->dst, RTAX_RTTVAR)), |
427 | r->rt_tos, | 427 | r->rt_key_tos, |
428 | r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1, | 428 | r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1, |
429 | r->dst.hh ? (r->dst.hh->hh_output == | 429 | r->dst.hh ? (r->dst.hh->hh_output == |
430 | dev_queue_xmit) : 0, | 430 | dev_queue_xmit) : 0, |
@@ -724,7 +724,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | |||
724 | return (((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | | 724 | return (((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | |
725 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 725 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
726 | (rt1->rt_mark ^ rt2->rt_mark) | | 726 | (rt1->rt_mark ^ rt2->rt_mark) | |
727 | (rt1->rt_tos ^ rt2->rt_tos) | | 727 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
728 | (rt1->rt_oif ^ rt2->rt_oif) | | 728 | (rt1->rt_oif ^ rt2->rt_oif) | |
729 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; | 729 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; |
730 | } | 730 | } |
@@ -968,10 +968,6 @@ static int rt_garbage_collect(struct dst_ops *ops) | |||
968 | break; | 968 | break; |
969 | 969 | ||
970 | expire >>= 1; | 970 | expire >>= 1; |
971 | #if RT_CACHE_DEBUG >= 2 | ||
972 | printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire, | ||
973 | dst_entries_get_fast(&ipv4_dst_ops), goal, i); | ||
974 | #endif | ||
975 | 971 | ||
976 | if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) | 972 | if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) |
977 | goto out; | 973 | goto out; |
@@ -992,10 +988,6 @@ work_done: | |||
992 | dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh || | 988 | dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh || |
993 | dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh) | 989 | dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh) |
994 | expire = ip_rt_gc_timeout; | 990 | expire = ip_rt_gc_timeout; |
995 | #if RT_CACHE_DEBUG >= 2 | ||
996 | printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire, | ||
997 | dst_entries_get_fast(&ipv4_dst_ops), goal, rover); | ||
998 | #endif | ||
999 | out: return 0; | 991 | out: return 0; |
1000 | } | 992 | } |
1001 | 993 | ||
@@ -1179,16 +1171,6 @@ restart: | |||
1179 | 1171 | ||
1180 | rt->dst.rt_next = rt_hash_table[hash].chain; | 1172 | rt->dst.rt_next = rt_hash_table[hash].chain; |
1181 | 1173 | ||
1182 | #if RT_CACHE_DEBUG >= 2 | ||
1183 | if (rt->dst.rt_next) { | ||
1184 | struct rtable *trt; | ||
1185 | printk(KERN_DEBUG "rt_cache @%02x: %pI4", | ||
1186 | hash, &rt->rt_dst); | ||
1187 | for (trt = rt->dst.rt_next; trt; trt = trt->dst.rt_next) | ||
1188 | printk(" . %pI4", &trt->rt_dst); | ||
1189 | printk("\n"); | ||
1190 | } | ||
1191 | #endif | ||
1192 | /* | 1174 | /* |
1193 | * Since lookup is lockfree, we must make sure | 1175 | * Since lookup is lockfree, we must make sure |
1194 | * previous writes to rt are committed to memory | 1176 | * previous writes to rt are committed to memory |
@@ -1211,11 +1193,11 @@ static u32 rt_peer_genid(void) | |||
1211 | return atomic_read(&__rt_peer_genid); | 1193 | return atomic_read(&__rt_peer_genid); |
1212 | } | 1194 | } |
1213 | 1195 | ||
1214 | void rt_bind_peer(struct rtable *rt, int create) | 1196 | void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) |
1215 | { | 1197 | { |
1216 | struct inet_peer *peer; | 1198 | struct inet_peer *peer; |
1217 | 1199 | ||
1218 | peer = inet_getpeer_v4(rt->rt_dst, create); | 1200 | peer = inet_getpeer_v4(daddr, create); |
1219 | 1201 | ||
1220 | if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) | 1202 | if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) |
1221 | inet_putpeer(peer); | 1203 | inet_putpeer(peer); |
@@ -1249,7 +1231,7 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) | |||
1249 | 1231 | ||
1250 | if (rt) { | 1232 | if (rt) { |
1251 | if (rt->peer == NULL) | 1233 | if (rt->peer == NULL) |
1252 | rt_bind_peer(rt, 1); | 1234 | rt_bind_peer(rt, rt->rt_dst, 1); |
1253 | 1235 | ||
1254 | /* If peer is attached to destination, it is never detached, | 1236 | /* If peer is attached to destination, it is never detached, |
1255 | so that we need not to grab a lock to dereference it. | 1237 | so that we need not to grab a lock to dereference it. |
@@ -1347,10 +1329,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1347 | unsigned hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, | 1329 | unsigned hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, |
1348 | rt->rt_oif, | 1330 | rt->rt_oif, |
1349 | rt_genid(dev_net(dst->dev))); | 1331 | rt_genid(dev_net(dst->dev))); |
1350 | #if RT_CACHE_DEBUG >= 1 | ||
1351 | printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n", | ||
1352 | &rt->rt_dst, rt->rt_tos); | ||
1353 | #endif | ||
1354 | rt_del(hash, rt); | 1332 | rt_del(hash, rt); |
1355 | ret = NULL; | 1333 | ret = NULL; |
1356 | } else if (rt->peer && | 1334 | } else if (rt->peer && |
@@ -1399,7 +1377,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
1399 | rcu_read_unlock(); | 1377 | rcu_read_unlock(); |
1400 | 1378 | ||
1401 | if (!rt->peer) | 1379 | if (!rt->peer) |
1402 | rt_bind_peer(rt, 1); | 1380 | rt_bind_peer(rt, rt->rt_dst, 1); |
1403 | peer = rt->peer; | 1381 | peer = rt->peer; |
1404 | if (!peer) { | 1382 | if (!peer) { |
1405 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); | 1383 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); |
@@ -1435,7 +1413,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
1435 | peer->rate_tokens == ip_rt_redirect_number && | 1413 | peer->rate_tokens == ip_rt_redirect_number && |
1436 | net_ratelimit()) | 1414 | net_ratelimit()) |
1437 | printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n", | 1415 | printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n", |
1438 | &rt->rt_src, rt->rt_iif, | 1416 | &ip_hdr(skb)->saddr, rt->rt_iif, |
1439 | &rt->rt_dst, &rt->rt_gateway); | 1417 | &rt->rt_dst, &rt->rt_gateway); |
1440 | #endif | 1418 | #endif |
1441 | } | 1419 | } |
@@ -1467,7 +1445,7 @@ static int ip_error(struct sk_buff *skb) | |||
1467 | } | 1445 | } |
1468 | 1446 | ||
1469 | if (!rt->peer) | 1447 | if (!rt->peer) |
1470 | rt_bind_peer(rt, 1); | 1448 | rt_bind_peer(rt, rt->rt_dst, 1); |
1471 | peer = rt->peer; | 1449 | peer = rt->peer; |
1472 | 1450 | ||
1473 | send = true; | 1451 | send = true; |
@@ -1507,7 +1485,7 @@ static inline unsigned short guess_mtu(unsigned short old_mtu) | |||
1507 | return 68; | 1485 | return 68; |
1508 | } | 1486 | } |
1509 | 1487 | ||
1510 | unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | 1488 | unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, |
1511 | unsigned short new_mtu, | 1489 | unsigned short new_mtu, |
1512 | struct net_device *dev) | 1490 | struct net_device *dev) |
1513 | { | 1491 | { |
@@ -1574,7 +1552,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1574 | dst_confirm(dst); | 1552 | dst_confirm(dst); |
1575 | 1553 | ||
1576 | if (!rt->peer) | 1554 | if (!rt->peer) |
1577 | rt_bind_peer(rt, 1); | 1555 | rt_bind_peer(rt, rt->rt_dst, 1); |
1578 | peer = rt->peer; | 1556 | peer = rt->peer; |
1579 | if (peer) { | 1557 | if (peer) { |
1580 | if (mtu < ip_rt_min_pmtu) | 1558 | if (mtu < ip_rt_min_pmtu) |
@@ -1631,7 +1609,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | |||
1631 | struct inet_peer *peer; | 1609 | struct inet_peer *peer; |
1632 | 1610 | ||
1633 | if (!rt->peer) | 1611 | if (!rt->peer) |
1634 | rt_bind_peer(rt, 0); | 1612 | rt_bind_peer(rt, rt->rt_dst, 0); |
1635 | 1613 | ||
1636 | peer = rt->peer; | 1614 | peer = rt->peer; |
1637 | if (peer && peer->pmtu_expires) | 1615 | if (peer && peer->pmtu_expires) |
@@ -1699,22 +1677,26 @@ static int ip_rt_bug(struct sk_buff *skb) | |||
1699 | in IP options! | 1677 | in IP options! |
1700 | */ | 1678 | */ |
1701 | 1679 | ||
1702 | void ip_rt_get_source(u8 *addr, struct rtable *rt) | 1680 | void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) |
1703 | { | 1681 | { |
1704 | __be32 src; | 1682 | __be32 src; |
1705 | struct fib_result res; | ||
1706 | 1683 | ||
1707 | if (rt_is_output_route(rt)) | 1684 | if (rt_is_output_route(rt)) |
1708 | src = rt->rt_src; | 1685 | src = ip_hdr(skb)->saddr; |
1709 | else { | 1686 | else { |
1710 | struct flowi4 fl4 = { | 1687 | struct fib_result res; |
1711 | .daddr = rt->rt_key_dst, | 1688 | struct flowi4 fl4; |
1712 | .saddr = rt->rt_key_src, | 1689 | struct iphdr *iph; |
1713 | .flowi4_tos = rt->rt_tos, | 1690 | |
1714 | .flowi4_oif = rt->rt_oif, | 1691 | iph = ip_hdr(skb); |
1715 | .flowi4_iif = rt->rt_iif, | 1692 | |
1716 | .flowi4_mark = rt->rt_mark, | 1693 | memset(&fl4, 0, sizeof(fl4)); |
1717 | }; | 1694 | fl4.daddr = iph->daddr; |
1695 | fl4.saddr = iph->saddr; | ||
1696 | fl4.flowi4_tos = iph->tos; | ||
1697 | fl4.flowi4_oif = rt->dst.dev->ifindex; | ||
1698 | fl4.flowi4_iif = skb->dev->ifindex; | ||
1699 | fl4.flowi4_mark = skb->mark; | ||
1718 | 1700 | ||
1719 | rcu_read_lock(); | 1701 | rcu_read_lock(); |
1720 | if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) | 1702 | if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) |
@@ -1767,7 +1749,7 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst) | |||
1767 | return mtu; | 1749 | return mtu; |
1768 | } | 1750 | } |
1769 | 1751 | ||
1770 | static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4, | 1752 | static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, |
1771 | struct fib_info *fi) | 1753 | struct fib_info *fi) |
1772 | { | 1754 | { |
1773 | struct inet_peer *peer; | 1755 | struct inet_peer *peer; |
@@ -1776,7 +1758,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4, | |||
1776 | /* If a peer entry exists for this destination, we must hook | 1758 | /* If a peer entry exists for this destination, we must hook |
1777 | * it up in order to get at cached metrics. | 1759 | * it up in order to get at cached metrics. |
1778 | */ | 1760 | */ |
1779 | if (oldflp4 && (oldflp4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS)) | 1761 | if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS)) |
1780 | create = 1; | 1762 | create = 1; |
1781 | 1763 | ||
1782 | rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create); | 1764 | rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create); |
@@ -1803,7 +1785,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4, | |||
1803 | } | 1785 | } |
1804 | } | 1786 | } |
1805 | 1787 | ||
1806 | static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4, | 1788 | static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4, |
1807 | const struct fib_result *res, | 1789 | const struct fib_result *res, |
1808 | struct fib_info *fi, u16 type, u32 itag) | 1790 | struct fib_info *fi, u16 type, u32 itag) |
1809 | { | 1791 | { |
@@ -1813,7 +1795,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4, | |||
1813 | if (FIB_RES_GW(*res) && | 1795 | if (FIB_RES_GW(*res) && |
1814 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) | 1796 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) |
1815 | rt->rt_gateway = FIB_RES_GW(*res); | 1797 | rt->rt_gateway = FIB_RES_GW(*res); |
1816 | rt_init_metrics(rt, oldflp4, fi); | 1798 | rt_init_metrics(rt, fl4, fi); |
1817 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1799 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1818 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; | 1800 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; |
1819 | #endif | 1801 | #endif |
@@ -1830,20 +1812,15 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4, | |||
1830 | #endif | 1812 | #endif |
1831 | set_class_tag(rt, itag); | 1813 | set_class_tag(rt, itag); |
1832 | #endif | 1814 | #endif |
1833 | rt->rt_type = type; | ||
1834 | } | 1815 | } |
1835 | 1816 | ||
1836 | static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm) | 1817 | static struct rtable *rt_dst_alloc(struct net_device *dev, |
1818 | bool nopolicy, bool noxfrm) | ||
1837 | { | 1819 | { |
1838 | struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1); | 1820 | return dst_alloc(&ipv4_dst_ops, dev, 1, -1, |
1839 | if (rt) { | 1821 | DST_HOST | |
1840 | rt->dst.obsolete = -1; | 1822 | (nopolicy ? DST_NOPOLICY : 0) | |
1841 | 1823 | (noxfrm ? DST_NOXFRM : 0)); | |
1842 | rt->dst.flags = DST_HOST | | ||
1843 | (nopolicy ? DST_NOPOLICY : 0) | | ||
1844 | (noxfrm ? DST_NOXFRM : 0); | ||
1845 | } | ||
1846 | return rt; | ||
1847 | } | 1824 | } |
1848 | 1825 | ||
1849 | /* called in rcu_read_lock() section */ | 1826 | /* called in rcu_read_lock() section */ |
@@ -1871,36 +1848,38 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1871 | goto e_inval; | 1848 | goto e_inval; |
1872 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 1849 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
1873 | } else { | 1850 | } else { |
1874 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, | 1851 | err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, |
1875 | &itag, 0); | 1852 | &itag); |
1876 | if (err < 0) | 1853 | if (err < 0) |
1877 | goto e_err; | 1854 | goto e_err; |
1878 | } | 1855 | } |
1879 | rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false); | 1856 | rth = rt_dst_alloc(init_net.loopback_dev, |
1857 | IN_DEV_CONF_GET(in_dev, NOPOLICY), false); | ||
1880 | if (!rth) | 1858 | if (!rth) |
1881 | goto e_nobufs; | 1859 | goto e_nobufs; |
1882 | 1860 | ||
1861 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
1862 | rth->dst.tclassid = itag; | ||
1863 | #endif | ||
1883 | rth->dst.output = ip_rt_bug; | 1864 | rth->dst.output = ip_rt_bug; |
1884 | 1865 | ||
1885 | rth->rt_key_dst = daddr; | 1866 | rth->rt_key_dst = daddr; |
1886 | rth->rt_dst = daddr; | ||
1887 | rth->rt_tos = tos; | ||
1888 | rth->rt_mark = skb->mark; | ||
1889 | rth->rt_key_src = saddr; | 1867 | rth->rt_key_src = saddr; |
1868 | rth->rt_genid = rt_genid(dev_net(dev)); | ||
1869 | rth->rt_flags = RTCF_MULTICAST; | ||
1870 | rth->rt_type = RTN_MULTICAST; | ||
1871 | rth->rt_key_tos = tos; | ||
1872 | rth->rt_dst = daddr; | ||
1890 | rth->rt_src = saddr; | 1873 | rth->rt_src = saddr; |
1891 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
1892 | rth->dst.tclassid = itag; | ||
1893 | #endif | ||
1894 | rth->rt_route_iif = dev->ifindex; | 1874 | rth->rt_route_iif = dev->ifindex; |
1895 | rth->rt_iif = dev->ifindex; | 1875 | rth->rt_iif = dev->ifindex; |
1896 | rth->dst.dev = init_net.loopback_dev; | ||
1897 | dev_hold(rth->dst.dev); | ||
1898 | rth->rt_oif = 0; | 1876 | rth->rt_oif = 0; |
1877 | rth->rt_mark = skb->mark; | ||
1899 | rth->rt_gateway = daddr; | 1878 | rth->rt_gateway = daddr; |
1900 | rth->rt_spec_dst= spec_dst; | 1879 | rth->rt_spec_dst= spec_dst; |
1901 | rth->rt_genid = rt_genid(dev_net(dev)); | 1880 | rth->rt_peer_genid = 0; |
1902 | rth->rt_flags = RTCF_MULTICAST; | 1881 | rth->peer = NULL; |
1903 | rth->rt_type = RTN_MULTICAST; | 1882 | rth->fi = NULL; |
1904 | if (our) { | 1883 | if (our) { |
1905 | rth->dst.input= ip_local_deliver; | 1884 | rth->dst.input= ip_local_deliver; |
1906 | rth->rt_flags |= RTCF_LOCAL; | 1885 | rth->rt_flags |= RTCF_LOCAL; |
@@ -1981,8 +1960,8 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1981 | } | 1960 | } |
1982 | 1961 | ||
1983 | 1962 | ||
1984 | err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), | 1963 | err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), |
1985 | in_dev->dev, &spec_dst, &itag, skb->mark); | 1964 | in_dev->dev, &spec_dst, &itag); |
1986 | if (err < 0) { | 1965 | if (err < 0) { |
1987 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, | 1966 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, |
1988 | saddr); | 1967 | saddr); |
@@ -2013,7 +1992,8 @@ static int __mkroute_input(struct sk_buff *skb, | |||
2013 | } | 1992 | } |
2014 | } | 1993 | } |
2015 | 1994 | ||
2016 | rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), | 1995 | rth = rt_dst_alloc(out_dev->dev, |
1996 | IN_DEV_CONF_GET(in_dev, NOPOLICY), | ||
2017 | IN_DEV_CONF_GET(out_dev, NOXFRM)); | 1997 | IN_DEV_CONF_GET(out_dev, NOXFRM)); |
2018 | if (!rth) { | 1998 | if (!rth) { |
2019 | err = -ENOBUFS; | 1999 | err = -ENOBUFS; |
@@ -2021,27 +2001,28 @@ static int __mkroute_input(struct sk_buff *skb, | |||
2021 | } | 2001 | } |
2022 | 2002 | ||
2023 | rth->rt_key_dst = daddr; | 2003 | rth->rt_key_dst = daddr; |
2024 | rth->rt_dst = daddr; | ||
2025 | rth->rt_tos = tos; | ||
2026 | rth->rt_mark = skb->mark; | ||
2027 | rth->rt_key_src = saddr; | 2004 | rth->rt_key_src = saddr; |
2005 | rth->rt_genid = rt_genid(dev_net(rth->dst.dev)); | ||
2006 | rth->rt_flags = flags; | ||
2007 | rth->rt_type = res->type; | ||
2008 | rth->rt_key_tos = tos; | ||
2009 | rth->rt_dst = daddr; | ||
2028 | rth->rt_src = saddr; | 2010 | rth->rt_src = saddr; |
2029 | rth->rt_gateway = daddr; | ||
2030 | rth->rt_route_iif = in_dev->dev->ifindex; | 2011 | rth->rt_route_iif = in_dev->dev->ifindex; |
2031 | rth->rt_iif = in_dev->dev->ifindex; | 2012 | rth->rt_iif = in_dev->dev->ifindex; |
2032 | rth->dst.dev = (out_dev)->dev; | ||
2033 | dev_hold(rth->dst.dev); | ||
2034 | rth->rt_oif = 0; | 2013 | rth->rt_oif = 0; |
2014 | rth->rt_mark = skb->mark; | ||
2015 | rth->rt_gateway = daddr; | ||
2035 | rth->rt_spec_dst= spec_dst; | 2016 | rth->rt_spec_dst= spec_dst; |
2017 | rth->rt_peer_genid = 0; | ||
2018 | rth->peer = NULL; | ||
2019 | rth->fi = NULL; | ||
2036 | 2020 | ||
2037 | rth->dst.input = ip_forward; | 2021 | rth->dst.input = ip_forward; |
2038 | rth->dst.output = ip_output; | 2022 | rth->dst.output = ip_output; |
2039 | rth->rt_genid = rt_genid(dev_net(rth->dst.dev)); | ||
2040 | 2023 | ||
2041 | rt_set_nexthop(rth, NULL, res, res->fi, res->type, itag); | 2024 | rt_set_nexthop(rth, NULL, res, res->fi, res->type, itag); |
2042 | 2025 | ||
2043 | rth->rt_flags = flags; | ||
2044 | |||
2045 | *result = rth; | 2026 | *result = rth; |
2046 | err = 0; | 2027 | err = 0; |
2047 | cleanup: | 2028 | cleanup: |
@@ -2150,9 +2131,9 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2150 | goto brd_input; | 2131 | goto brd_input; |
2151 | 2132 | ||
2152 | if (res.type == RTN_LOCAL) { | 2133 | if (res.type == RTN_LOCAL) { |
2153 | err = fib_validate_source(saddr, daddr, tos, | 2134 | err = fib_validate_source(skb, saddr, daddr, tos, |
2154 | net->loopback_dev->ifindex, | 2135 | net->loopback_dev->ifindex, |
2155 | dev, &spec_dst, &itag, skb->mark); | 2136 | dev, &spec_dst, &itag); |
2156 | if (err < 0) | 2137 | if (err < 0) |
2157 | goto martian_source_keep_err; | 2138 | goto martian_source_keep_err; |
2158 | if (err) | 2139 | if (err) |
@@ -2176,8 +2157,8 @@ brd_input: | |||
2176 | if (ipv4_is_zeronet(saddr)) | 2157 | if (ipv4_is_zeronet(saddr)) |
2177 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 2158 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
2178 | else { | 2159 | else { |
2179 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, | 2160 | err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, |
2180 | &itag, skb->mark); | 2161 | &itag); |
2181 | if (err < 0) | 2162 | if (err < 0) |
2182 | goto martian_source_keep_err; | 2163 | goto martian_source_keep_err; |
2183 | if (err) | 2164 | if (err) |
@@ -2188,36 +2169,42 @@ brd_input: | |||
2188 | RT_CACHE_STAT_INC(in_brd); | 2169 | RT_CACHE_STAT_INC(in_brd); |
2189 | 2170 | ||
2190 | local_input: | 2171 | local_input: |
2191 | rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false); | 2172 | rth = rt_dst_alloc(net->loopback_dev, |
2173 | IN_DEV_CONF_GET(in_dev, NOPOLICY), false); | ||
2192 | if (!rth) | 2174 | if (!rth) |
2193 | goto e_nobufs; | 2175 | goto e_nobufs; |
2194 | 2176 | ||
2177 | rth->dst.input= ip_local_deliver; | ||
2195 | rth->dst.output= ip_rt_bug; | 2178 | rth->dst.output= ip_rt_bug; |
2196 | rth->rt_genid = rt_genid(net); | 2179 | #ifdef CONFIG_IP_ROUTE_CLASSID |
2180 | rth->dst.tclassid = itag; | ||
2181 | #endif | ||
2197 | 2182 | ||
2198 | rth->rt_key_dst = daddr; | 2183 | rth->rt_key_dst = daddr; |
2199 | rth->rt_dst = daddr; | ||
2200 | rth->rt_tos = tos; | ||
2201 | rth->rt_mark = skb->mark; | ||
2202 | rth->rt_key_src = saddr; | 2184 | rth->rt_key_src = saddr; |
2185 | rth->rt_genid = rt_genid(net); | ||
2186 | rth->rt_flags = flags|RTCF_LOCAL; | ||
2187 | rth->rt_type = res.type; | ||
2188 | rth->rt_key_tos = tos; | ||
2189 | rth->rt_dst = daddr; | ||
2203 | rth->rt_src = saddr; | 2190 | rth->rt_src = saddr; |
2204 | #ifdef CONFIG_IP_ROUTE_CLASSID | 2191 | #ifdef CONFIG_IP_ROUTE_CLASSID |
2205 | rth->dst.tclassid = itag; | 2192 | rth->dst.tclassid = itag; |
2206 | #endif | 2193 | #endif |
2207 | rth->rt_route_iif = dev->ifindex; | 2194 | rth->rt_route_iif = dev->ifindex; |
2208 | rth->rt_iif = dev->ifindex; | 2195 | rth->rt_iif = dev->ifindex; |
2209 | rth->dst.dev = net->loopback_dev; | 2196 | rth->rt_oif = 0; |
2210 | dev_hold(rth->dst.dev); | 2197 | rth->rt_mark = skb->mark; |
2211 | rth->rt_gateway = daddr; | 2198 | rth->rt_gateway = daddr; |
2212 | rth->rt_spec_dst= spec_dst; | 2199 | rth->rt_spec_dst= spec_dst; |
2213 | rth->dst.input= ip_local_deliver; | 2200 | rth->rt_peer_genid = 0; |
2214 | rth->rt_flags = flags|RTCF_LOCAL; | 2201 | rth->peer = NULL; |
2202 | rth->fi = NULL; | ||
2215 | if (res.type == RTN_UNREACHABLE) { | 2203 | if (res.type == RTN_UNREACHABLE) { |
2216 | rth->dst.input= ip_error; | 2204 | rth->dst.input= ip_error; |
2217 | rth->dst.error= -err; | 2205 | rth->dst.error= -err; |
2218 | rth->rt_flags &= ~RTCF_LOCAL; | 2206 | rth->rt_flags &= ~RTCF_LOCAL; |
2219 | } | 2207 | } |
2220 | rth->rt_type = res.type; | ||
2221 | hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net)); | 2208 | hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net)); |
2222 | rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif); | 2209 | rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif); |
2223 | err = 0; | 2210 | err = 0; |
@@ -2288,7 +2275,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2288 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | | 2275 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
2289 | (rth->rt_iif ^ iif) | | 2276 | (rth->rt_iif ^ iif) | |
2290 | rth->rt_oif | | 2277 | rth->rt_oif | |
2291 | (rth->rt_tos ^ tos)) == 0 && | 2278 | (rth->rt_key_tos ^ tos)) == 0 && |
2292 | rth->rt_mark == skb->mark && | 2279 | rth->rt_mark == skb->mark && |
2293 | net_eq(dev_net(rth->dst.dev), net) && | 2280 | net_eq(dev_net(rth->dst.dev), net) && |
2294 | !rt_is_expired(rth)) { | 2281 | !rt_is_expired(rth)) { |
@@ -2349,12 +2336,12 @@ EXPORT_SYMBOL(ip_route_input_common); | |||
2349 | /* called with rcu_read_lock() */ | 2336 | /* called with rcu_read_lock() */ |
2350 | static struct rtable *__mkroute_output(const struct fib_result *res, | 2337 | static struct rtable *__mkroute_output(const struct fib_result *res, |
2351 | const struct flowi4 *fl4, | 2338 | const struct flowi4 *fl4, |
2352 | const struct flowi4 *oldflp4, | 2339 | __be32 orig_daddr, __be32 orig_saddr, |
2353 | struct net_device *dev_out, | 2340 | int orig_oif, struct net_device *dev_out, |
2354 | unsigned int flags) | 2341 | unsigned int flags) |
2355 | { | 2342 | { |
2356 | struct fib_info *fi = res->fi; | 2343 | struct fib_info *fi = res->fi; |
2357 | u32 tos = RT_FL_TOS(oldflp4); | 2344 | u32 tos = RT_FL_TOS(fl4); |
2358 | struct in_device *in_dev; | 2345 | struct in_device *in_dev; |
2359 | u16 type = res->type; | 2346 | u16 type = res->type; |
2360 | struct rtable *rth; | 2347 | struct rtable *rth; |
@@ -2381,8 +2368,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2381 | fi = NULL; | 2368 | fi = NULL; |
2382 | } else if (type == RTN_MULTICAST) { | 2369 | } else if (type == RTN_MULTICAST) { |
2383 | flags |= RTCF_MULTICAST | RTCF_LOCAL; | 2370 | flags |= RTCF_MULTICAST | RTCF_LOCAL; |
2384 | if (!ip_check_mc_rcu(in_dev, oldflp4->daddr, oldflp4->saddr, | 2371 | if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, |
2385 | oldflp4->flowi4_proto)) | 2372 | fl4->flowi4_proto)) |
2386 | flags &= ~RTCF_LOCAL; | 2373 | flags &= ~RTCF_LOCAL; |
2387 | /* If multicast route do not exist use | 2374 | /* If multicast route do not exist use |
2388 | * default one, but do not gateway in this case. | 2375 | * default one, but do not gateway in this case. |
@@ -2392,29 +2379,31 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2392 | fi = NULL; | 2379 | fi = NULL; |
2393 | } | 2380 | } |
2394 | 2381 | ||
2395 | rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), | 2382 | rth = rt_dst_alloc(dev_out, |
2383 | IN_DEV_CONF_GET(in_dev, NOPOLICY), | ||
2396 | IN_DEV_CONF_GET(in_dev, NOXFRM)); | 2384 | IN_DEV_CONF_GET(in_dev, NOXFRM)); |
2397 | if (!rth) | 2385 | if (!rth) |
2398 | return ERR_PTR(-ENOBUFS); | 2386 | return ERR_PTR(-ENOBUFS); |
2399 | 2387 | ||
2400 | rth->rt_key_dst = oldflp4->daddr; | 2388 | rth->dst.output = ip_output; |
2401 | rth->rt_tos = tos; | 2389 | |
2402 | rth->rt_key_src = oldflp4->saddr; | 2390 | rth->rt_key_dst = orig_daddr; |
2403 | rth->rt_oif = oldflp4->flowi4_oif; | 2391 | rth->rt_key_src = orig_saddr; |
2404 | rth->rt_mark = oldflp4->flowi4_mark; | 2392 | rth->rt_genid = rt_genid(dev_net(dev_out)); |
2393 | rth->rt_flags = flags; | ||
2394 | rth->rt_type = type; | ||
2395 | rth->rt_key_tos = tos; | ||
2405 | rth->rt_dst = fl4->daddr; | 2396 | rth->rt_dst = fl4->daddr; |
2406 | rth->rt_src = fl4->saddr; | 2397 | rth->rt_src = fl4->saddr; |
2407 | rth->rt_route_iif = 0; | 2398 | rth->rt_route_iif = 0; |
2408 | rth->rt_iif = oldflp4->flowi4_oif ? : dev_out->ifindex; | 2399 | rth->rt_iif = orig_oif ? : dev_out->ifindex; |
2409 | /* get references to the devices that are to be hold by the routing | 2400 | rth->rt_oif = orig_oif; |
2410 | cache entry */ | 2401 | rth->rt_mark = fl4->flowi4_mark; |
2411 | rth->dst.dev = dev_out; | ||
2412 | dev_hold(dev_out); | ||
2413 | rth->rt_gateway = fl4->daddr; | 2402 | rth->rt_gateway = fl4->daddr; |
2414 | rth->rt_spec_dst= fl4->saddr; | 2403 | rth->rt_spec_dst= fl4->saddr; |
2415 | 2404 | rth->rt_peer_genid = 0; | |
2416 | rth->dst.output=ip_output; | 2405 | rth->peer = NULL; |
2417 | rth->rt_genid = rt_genid(dev_net(dev_out)); | 2406 | rth->fi = NULL; |
2418 | 2407 | ||
2419 | RT_CACHE_STAT_INC(out_slow_tot); | 2408 | RT_CACHE_STAT_INC(out_slow_tot); |
2420 | 2409 | ||
@@ -2432,7 +2421,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2432 | #ifdef CONFIG_IP_MROUTE | 2421 | #ifdef CONFIG_IP_MROUTE |
2433 | if (type == RTN_MULTICAST) { | 2422 | if (type == RTN_MULTICAST) { |
2434 | if (IN_DEV_MFORWARD(in_dev) && | 2423 | if (IN_DEV_MFORWARD(in_dev) && |
2435 | !ipv4_is_local_multicast(oldflp4->daddr)) { | 2424 | !ipv4_is_local_multicast(fl4->daddr)) { |
2436 | rth->dst.input = ip_mr_input; | 2425 | rth->dst.input = ip_mr_input; |
2437 | rth->dst.output = ip_mc_output; | 2426 | rth->dst.output = ip_mc_output; |
2438 | } | 2427 | } |
@@ -2440,9 +2429,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2440 | #endif | 2429 | #endif |
2441 | } | 2430 | } |
2442 | 2431 | ||
2443 | rt_set_nexthop(rth, oldflp4, res, fi, type, 0); | 2432 | rt_set_nexthop(rth, fl4, res, fi, type, 0); |
2444 | 2433 | ||
2445 | rth->rt_flags = flags; | ||
2446 | return rth; | 2434 | return rth; |
2447 | } | 2435 | } |
2448 | 2436 | ||
@@ -2451,36 +2439,37 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2451 | * called with rcu_read_lock(); | 2439 | * called with rcu_read_lock(); |
2452 | */ | 2440 | */ |
2453 | 2441 | ||
2454 | static struct rtable *ip_route_output_slow(struct net *net, | 2442 | static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) |
2455 | const struct flowi4 *oldflp4) | ||
2456 | { | 2443 | { |
2457 | u32 tos = RT_FL_TOS(oldflp4); | ||
2458 | struct flowi4 fl4; | ||
2459 | struct fib_result res; | ||
2460 | unsigned int flags = 0; | ||
2461 | struct net_device *dev_out = NULL; | 2444 | struct net_device *dev_out = NULL; |
2445 | u32 tos = RT_FL_TOS(fl4); | ||
2446 | unsigned int flags = 0; | ||
2447 | struct fib_result res; | ||
2462 | struct rtable *rth; | 2448 | struct rtable *rth; |
2449 | __be32 orig_daddr; | ||
2450 | __be32 orig_saddr; | ||
2451 | int orig_oif; | ||
2463 | 2452 | ||
2464 | res.fi = NULL; | 2453 | res.fi = NULL; |
2465 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 2454 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
2466 | res.r = NULL; | 2455 | res.r = NULL; |
2467 | #endif | 2456 | #endif |
2468 | 2457 | ||
2469 | fl4.flowi4_oif = oldflp4->flowi4_oif; | 2458 | orig_daddr = fl4->daddr; |
2470 | fl4.flowi4_iif = net->loopback_dev->ifindex; | 2459 | orig_saddr = fl4->saddr; |
2471 | fl4.flowi4_mark = oldflp4->flowi4_mark; | 2460 | orig_oif = fl4->flowi4_oif; |
2472 | fl4.daddr = oldflp4->daddr; | 2461 | |
2473 | fl4.saddr = oldflp4->saddr; | 2462 | fl4->flowi4_iif = net->loopback_dev->ifindex; |
2474 | fl4.flowi4_tos = tos & IPTOS_RT_MASK; | 2463 | fl4->flowi4_tos = tos & IPTOS_RT_MASK; |
2475 | fl4.flowi4_scope = ((tos & RTO_ONLINK) ? | 2464 | fl4->flowi4_scope = ((tos & RTO_ONLINK) ? |
2476 | RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); | 2465 | RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); |
2477 | 2466 | ||
2478 | rcu_read_lock(); | 2467 | rcu_read_lock(); |
2479 | if (oldflp4->saddr) { | 2468 | if (fl4->saddr) { |
2480 | rth = ERR_PTR(-EINVAL); | 2469 | rth = ERR_PTR(-EINVAL); |
2481 | if (ipv4_is_multicast(oldflp4->saddr) || | 2470 | if (ipv4_is_multicast(fl4->saddr) || |
2482 | ipv4_is_lbcast(oldflp4->saddr) || | 2471 | ipv4_is_lbcast(fl4->saddr) || |
2483 | ipv4_is_zeronet(oldflp4->saddr)) | 2472 | ipv4_is_zeronet(fl4->saddr)) |
2484 | goto out; | 2473 | goto out; |
2485 | 2474 | ||
2486 | /* I removed check for oif == dev_out->oif here. | 2475 | /* I removed check for oif == dev_out->oif here. |
@@ -2491,11 +2480,11 @@ static struct rtable *ip_route_output_slow(struct net *net, | |||
2491 | of another iface. --ANK | 2480 | of another iface. --ANK |
2492 | */ | 2481 | */ |
2493 | 2482 | ||
2494 | if (oldflp4->flowi4_oif == 0 && | 2483 | if (fl4->flowi4_oif == 0 && |
2495 | (ipv4_is_multicast(oldflp4->daddr) || | 2484 | (ipv4_is_multicast(fl4->daddr) || |
2496 | ipv4_is_lbcast(oldflp4->daddr))) { | 2485 | ipv4_is_lbcast(fl4->daddr))) { |
2497 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ | 2486 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ |
2498 | dev_out = __ip_dev_find(net, oldflp4->saddr, false); | 2487 | dev_out = __ip_dev_find(net, fl4->saddr, false); |
2499 | if (dev_out == NULL) | 2488 | if (dev_out == NULL) |
2500 | goto out; | 2489 | goto out; |
2501 | 2490 | ||
@@ -2514,20 +2503,20 @@ static struct rtable *ip_route_output_slow(struct net *net, | |||
2514 | Luckily, this hack is good workaround. | 2503 | Luckily, this hack is good workaround. |
2515 | */ | 2504 | */ |
2516 | 2505 | ||
2517 | fl4.flowi4_oif = dev_out->ifindex; | 2506 | fl4->flowi4_oif = dev_out->ifindex; |
2518 | goto make_route; | 2507 | goto make_route; |
2519 | } | 2508 | } |
2520 | 2509 | ||
2521 | if (!(oldflp4->flowi4_flags & FLOWI_FLAG_ANYSRC)) { | 2510 | if (!(fl4->flowi4_flags & FLOWI_FLAG_ANYSRC)) { |
2522 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ | 2511 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ |
2523 | if (!__ip_dev_find(net, oldflp4->saddr, false)) | 2512 | if (!__ip_dev_find(net, fl4->saddr, false)) |
2524 | goto out; | 2513 | goto out; |
2525 | } | 2514 | } |
2526 | } | 2515 | } |
2527 | 2516 | ||
2528 | 2517 | ||
2529 | if (oldflp4->flowi4_oif) { | 2518 | if (fl4->flowi4_oif) { |
2530 | dev_out = dev_get_by_index_rcu(net, oldflp4->flowi4_oif); | 2519 | dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif); |
2531 | rth = ERR_PTR(-ENODEV); | 2520 | rth = ERR_PTR(-ENODEV); |
2532 | if (dev_out == NULL) | 2521 | if (dev_out == NULL) |
2533 | goto out; | 2522 | goto out; |
@@ -2537,37 +2526,37 @@ static struct rtable *ip_route_output_slow(struct net *net, | |||
2537 | rth = ERR_PTR(-ENETUNREACH); | 2526 | rth = ERR_PTR(-ENETUNREACH); |
2538 | goto out; | 2527 | goto out; |
2539 | } | 2528 | } |
2540 | if (ipv4_is_local_multicast(oldflp4->daddr) || | 2529 | if (ipv4_is_local_multicast(fl4->daddr) || |
2541 | ipv4_is_lbcast(oldflp4->daddr)) { | 2530 | ipv4_is_lbcast(fl4->daddr)) { |
2542 | if (!fl4.saddr) | 2531 | if (!fl4->saddr) |
2543 | fl4.saddr = inet_select_addr(dev_out, 0, | 2532 | fl4->saddr = inet_select_addr(dev_out, 0, |
2544 | RT_SCOPE_LINK); | 2533 | RT_SCOPE_LINK); |
2545 | goto make_route; | 2534 | goto make_route; |
2546 | } | 2535 | } |
2547 | if (!fl4.saddr) { | 2536 | if (fl4->saddr) { |
2548 | if (ipv4_is_multicast(oldflp4->daddr)) | 2537 | if (ipv4_is_multicast(fl4->daddr)) |
2549 | fl4.saddr = inet_select_addr(dev_out, 0, | 2538 | fl4->saddr = inet_select_addr(dev_out, 0, |
2550 | fl4.flowi4_scope); | 2539 | fl4->flowi4_scope); |
2551 | else if (!oldflp4->daddr) | 2540 | else if (!fl4->daddr) |
2552 | fl4.saddr = inet_select_addr(dev_out, 0, | 2541 | fl4->saddr = inet_select_addr(dev_out, 0, |
2553 | RT_SCOPE_HOST); | 2542 | RT_SCOPE_HOST); |
2554 | } | 2543 | } |
2555 | } | 2544 | } |
2556 | 2545 | ||
2557 | if (!fl4.daddr) { | 2546 | if (!fl4->daddr) { |
2558 | fl4.daddr = fl4.saddr; | 2547 | fl4->daddr = fl4->saddr; |
2559 | if (!fl4.daddr) | 2548 | if (!fl4->daddr) |
2560 | fl4.daddr = fl4.saddr = htonl(INADDR_LOOPBACK); | 2549 | fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK); |
2561 | dev_out = net->loopback_dev; | 2550 | dev_out = net->loopback_dev; |
2562 | fl4.flowi4_oif = net->loopback_dev->ifindex; | 2551 | fl4->flowi4_oif = net->loopback_dev->ifindex; |
2563 | res.type = RTN_LOCAL; | 2552 | res.type = RTN_LOCAL; |
2564 | flags |= RTCF_LOCAL; | 2553 | flags |= RTCF_LOCAL; |
2565 | goto make_route; | 2554 | goto make_route; |
2566 | } | 2555 | } |
2567 | 2556 | ||
2568 | if (fib_lookup(net, &fl4, &res)) { | 2557 | if (fib_lookup(net, fl4, &res)) { |
2569 | res.fi = NULL; | 2558 | res.fi = NULL; |
2570 | if (oldflp4->flowi4_oif) { | 2559 | if (fl4->flowi4_oif) { |
2571 | /* Apparently, routing tables are wrong. Assume, | 2560 | /* Apparently, routing tables are wrong. Assume, |
2572 | that the destination is on link. | 2561 | that the destination is on link. |
2573 | 2562 | ||
@@ -2586,9 +2575,9 @@ static struct rtable *ip_route_output_slow(struct net *net, | |||
2586 | likely IPv6, but we do not. | 2575 | likely IPv6, but we do not. |
2587 | */ | 2576 | */ |
2588 | 2577 | ||
2589 | if (fl4.saddr == 0) | 2578 | if (fl4->saddr == 0) |
2590 | fl4.saddr = inet_select_addr(dev_out, 0, | 2579 | fl4->saddr = inet_select_addr(dev_out, 0, |
2591 | RT_SCOPE_LINK); | 2580 | RT_SCOPE_LINK); |
2592 | res.type = RTN_UNICAST; | 2581 | res.type = RTN_UNICAST; |
2593 | goto make_route; | 2582 | goto make_route; |
2594 | } | 2583 | } |
@@ -2597,42 +2586,45 @@ static struct rtable *ip_route_output_slow(struct net *net, | |||
2597 | } | 2586 | } |
2598 | 2587 | ||
2599 | if (res.type == RTN_LOCAL) { | 2588 | if (res.type == RTN_LOCAL) { |
2600 | if (!fl4.saddr) { | 2589 | if (!fl4->saddr) { |
2601 | if (res.fi->fib_prefsrc) | 2590 | if (res.fi->fib_prefsrc) |
2602 | fl4.saddr = res.fi->fib_prefsrc; | 2591 | fl4->saddr = res.fi->fib_prefsrc; |
2603 | else | 2592 | else |
2604 | fl4.saddr = fl4.daddr; | 2593 | fl4->saddr = fl4->daddr; |
2605 | } | 2594 | } |
2606 | dev_out = net->loopback_dev; | 2595 | dev_out = net->loopback_dev; |
2607 | fl4.flowi4_oif = dev_out->ifindex; | 2596 | fl4->flowi4_oif = dev_out->ifindex; |
2608 | res.fi = NULL; | 2597 | res.fi = NULL; |
2609 | flags |= RTCF_LOCAL; | 2598 | flags |= RTCF_LOCAL; |
2610 | goto make_route; | 2599 | goto make_route; |
2611 | } | 2600 | } |
2612 | 2601 | ||
2613 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 2602 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
2614 | if (res.fi->fib_nhs > 1 && fl4.flowi4_oif == 0) | 2603 | if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0) |
2615 | fib_select_multipath(&res); | 2604 | fib_select_multipath(&res); |
2616 | else | 2605 | else |
2617 | #endif | 2606 | #endif |
2618 | if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif) | 2607 | if (!res.prefixlen && |
2608 | res.table->tb_num_default > 1 && | ||
2609 | res.type == RTN_UNICAST && !fl4->flowi4_oif) | ||
2619 | fib_select_default(&res); | 2610 | fib_select_default(&res); |
2620 | 2611 | ||
2621 | if (!fl4.saddr) | 2612 | if (!fl4->saddr) |
2622 | fl4.saddr = FIB_RES_PREFSRC(net, res); | 2613 | fl4->saddr = FIB_RES_PREFSRC(net, res); |
2623 | 2614 | ||
2624 | dev_out = FIB_RES_DEV(res); | 2615 | dev_out = FIB_RES_DEV(res); |
2625 | fl4.flowi4_oif = dev_out->ifindex; | 2616 | fl4->flowi4_oif = dev_out->ifindex; |
2626 | 2617 | ||
2627 | 2618 | ||
2628 | make_route: | 2619 | make_route: |
2629 | rth = __mkroute_output(&res, &fl4, oldflp4, dev_out, flags); | 2620 | rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, |
2621 | dev_out, flags); | ||
2630 | if (!IS_ERR(rth)) { | 2622 | if (!IS_ERR(rth)) { |
2631 | unsigned int hash; | 2623 | unsigned int hash; |
2632 | 2624 | ||
2633 | hash = rt_hash(oldflp4->daddr, oldflp4->saddr, oldflp4->flowi4_oif, | 2625 | hash = rt_hash(orig_daddr, orig_saddr, orig_oif, |
2634 | rt_genid(dev_net(dev_out))); | 2626 | rt_genid(dev_net(dev_out))); |
2635 | rth = rt_intern_hash(hash, rth, NULL, oldflp4->flowi4_oif); | 2627 | rth = rt_intern_hash(hash, rth, NULL, orig_oif); |
2636 | } | 2628 | } |
2637 | 2629 | ||
2638 | out: | 2630 | out: |
@@ -2640,7 +2632,7 @@ out: | |||
2640 | return rth; | 2632 | return rth; |
2641 | } | 2633 | } |
2642 | 2634 | ||
2643 | struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4) | 2635 | struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) |
2644 | { | 2636 | { |
2645 | struct rtable *rth; | 2637 | struct rtable *rth; |
2646 | unsigned int hash; | 2638 | unsigned int hash; |
@@ -2658,13 +2650,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4) | |||
2658 | rt_is_output_route(rth) && | 2650 | rt_is_output_route(rth) && |
2659 | rth->rt_oif == flp4->flowi4_oif && | 2651 | rth->rt_oif == flp4->flowi4_oif && |
2660 | rth->rt_mark == flp4->flowi4_mark && | 2652 | rth->rt_mark == flp4->flowi4_mark && |
2661 | !((rth->rt_tos ^ flp4->flowi4_tos) & | 2653 | !((rth->rt_key_tos ^ flp4->flowi4_tos) & |
2662 | (IPTOS_RT_MASK | RTO_ONLINK)) && | 2654 | (IPTOS_RT_MASK | RTO_ONLINK)) && |
2663 | net_eq(dev_net(rth->dst.dev), net) && | 2655 | net_eq(dev_net(rth->dst.dev), net) && |
2664 | !rt_is_expired(rth)) { | 2656 | !rt_is_expired(rth)) { |
2665 | dst_use(&rth->dst, jiffies); | 2657 | dst_use(&rth->dst, jiffies); |
2666 | RT_CACHE_STAT_INC(out_hit); | 2658 | RT_CACHE_STAT_INC(out_hit); |
2667 | rcu_read_unlock_bh(); | 2659 | rcu_read_unlock_bh(); |
2660 | if (!flp4->saddr) | ||
2661 | flp4->saddr = rth->rt_src; | ||
2662 | if (!flp4->daddr) | ||
2663 | flp4->daddr = rth->rt_dst; | ||
2668 | return rth; | 2664 | return rth; |
2669 | } | 2665 | } |
2670 | RT_CACHE_STAT_INC(out_hlist_search); | 2666 | RT_CACHE_STAT_INC(out_hlist_search); |
@@ -2709,7 +2705,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2709 | 2705 | ||
2710 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) | 2706 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) |
2711 | { | 2707 | { |
2712 | struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1); | 2708 | struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0); |
2713 | struct rtable *ort = (struct rtable *) dst_orig; | 2709 | struct rtable *ort = (struct rtable *) dst_orig; |
2714 | 2710 | ||
2715 | if (rt) { | 2711 | if (rt) { |
@@ -2726,7 +2722,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
2726 | 2722 | ||
2727 | rt->rt_key_dst = ort->rt_key_dst; | 2723 | rt->rt_key_dst = ort->rt_key_dst; |
2728 | rt->rt_key_src = ort->rt_key_src; | 2724 | rt->rt_key_src = ort->rt_key_src; |
2729 | rt->rt_tos = ort->rt_tos; | 2725 | rt->rt_key_tos = ort->rt_key_tos; |
2730 | rt->rt_route_iif = ort->rt_route_iif; | 2726 | rt->rt_route_iif = ort->rt_route_iif; |
2731 | rt->rt_iif = ort->rt_iif; | 2727 | rt->rt_iif = ort->rt_iif; |
2732 | rt->rt_oif = ort->rt_oif; | 2728 | rt->rt_oif = ort->rt_oif; |
@@ -2762,15 +2758,10 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4, | |||
2762 | if (IS_ERR(rt)) | 2758 | if (IS_ERR(rt)) |
2763 | return rt; | 2759 | return rt; |
2764 | 2760 | ||
2765 | if (flp4->flowi4_proto) { | 2761 | if (flp4->flowi4_proto) |
2766 | if (!flp4->saddr) | ||
2767 | flp4->saddr = rt->rt_src; | ||
2768 | if (!flp4->daddr) | ||
2769 | flp4->daddr = rt->rt_dst; | ||
2770 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, | 2762 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, |
2771 | flowi4_to_flowi(flp4), | 2763 | flowi4_to_flowi(flp4), |
2772 | sk, 0); | 2764 | sk, 0); |
2773 | } | ||
2774 | 2765 | ||
2775 | return rt; | 2766 | return rt; |
2776 | } | 2767 | } |
@@ -2794,7 +2785,7 @@ static int rt_fill_info(struct net *net, | |||
2794 | r->rtm_family = AF_INET; | 2785 | r->rtm_family = AF_INET; |
2795 | r->rtm_dst_len = 32; | 2786 | r->rtm_dst_len = 32; |
2796 | r->rtm_src_len = 0; | 2787 | r->rtm_src_len = 0; |
2797 | r->rtm_tos = rt->rt_tos; | 2788 | r->rtm_tos = rt->rt_key_tos; |
2798 | r->rtm_table = RT_TABLE_MAIN; | 2789 | r->rtm_table = RT_TABLE_MAIN; |
2799 | NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); | 2790 | NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); |
2800 | r->rtm_type = rt->rt_type; | 2791 | r->rtm_type = rt->rt_type; |
@@ -2848,7 +2839,9 @@ static int rt_fill_info(struct net *net, | |||
2848 | 2839 | ||
2849 | if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) && | 2840 | if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) && |
2850 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { | 2841 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { |
2851 | int err = ipmr_get_route(net, skb, r, nowait); | 2842 | int err = ipmr_get_route(net, skb, |
2843 | rt->rt_src, rt->rt_dst, | ||
2844 | r, nowait); | ||
2852 | if (err <= 0) { | 2845 | if (err <= 0) { |
2853 | if (!nowait) { | 2846 | if (!nowait) { |
2854 | if (err == 0) | 2847 | if (err == 0) |