route.c (1d6ae775d7a948c9575658eb41184fd2e506c0df) | route.c (ce723d8e048ef98ea64d12379e3921c933f5b3e0) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * ROUTE - implementation of the IP router. 7 * 8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ --- 1746 unchanged lines hidden (view full) --- 1755 1756 1757 rth = dst_alloc(&ipv4_dst_ops); 1758 if (!rth) { 1759 err = -ENOBUFS; 1760 goto cleanup; 1761 } 1762 | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * ROUTE - implementation of the IP router. 7 * 8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ --- 1746 unchanged lines hidden (view full) --- 1755 1756 1757 rth = dst_alloc(&ipv4_dst_ops); 1758 if (!rth) { 1759 err = -ENOBUFS; 1760 goto cleanup; 1761 } 1762 |
1763 atomic_set(&rth->u.dst.__refcnt, 1); |
|
1763 rth->u.dst.flags= DST_HOST; 1764#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1765 if (res->fi->fib_nhs > 1) 1766 rth->u.dst.flags |= DST_BALANCED; 1767#endif 1768 if (in_dev->cnf.no_policy) 1769 rth->u.dst.flags |= DST_NOPOLICY; 1770 if (in_dev->cnf.no_xfrm) --- 44 unchanged lines hidden (view full) --- 1815 if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0) 1816 fib_select_multipath(fl, res); 1817#endif 1818 1819 /* create a routing cache entry */ 1820 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); 1821 if (err) 1822 return err; | 1764 rth->u.dst.flags= DST_HOST; 1765#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1766 if (res->fi->fib_nhs > 1) 1767 rth->u.dst.flags |= DST_BALANCED; 1768#endif 1769 if (in_dev->cnf.no_policy) 1770 rth->u.dst.flags |= DST_NOPOLICY; 1771 if (in_dev->cnf.no_xfrm) --- 44 unchanged lines hidden (view full) --- 1816 if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0) 1817 fib_select_multipath(fl, res); 1818#endif 1819 1820 /* create a routing cache entry */ 1821 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); 1822 if (err) 1823 return err; |
1823 atomic_set(&rth->u.dst.__refcnt, 1); | |
1824 1825 /* put it into the cache */ 1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1827 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1828} 1829 1830static inline int ip_mkroute_input(struct sk_buff *skb, 1831 struct fib_result* res, 1832 const struct flowi *fl, 1833 struct in_device *in_dev, 1834 u32 daddr, u32 saddr, u32 tos) 1835{ 1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | 1824 1825 /* put it into the cache */ 1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1827 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1828} 1829 1830static inline int ip_mkroute_input(struct sk_buff *skb, 1831 struct fib_result* res, 1832 const struct flowi *fl, 1833 struct in_device *in_dev, 1834 u32 daddr, u32 saddr, u32 tos) 1835{ 1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED |
1837 struct rtable* rth = NULL; 1838 unsigned char hop, hopcount, lasthop; | 1837 struct rtable* rth = NULL, *rtres; 1838 unsigned char hop, hopcount; |
1839 int err = -EINVAL; 1840 unsigned int hash; 1841 1842 if (res->fi) 1843 hopcount = res->fi->fib_nhs; 1844 else 1845 hopcount = 1; 1846 | 1839 int err = -EINVAL; 1840 unsigned int hash; 1841 1842 if (res->fi) 1843 hopcount = res->fi->fib_nhs; 1844 else 1845 hopcount = 1; 1846 |
1847 lasthop = hopcount - 1; 1848 | |
1849 /* distinguish between multipath and singlepath */ 1850 if (hopcount < 2) 1851 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, 1852 saddr, tos); 1853 1854 /* add all alternatives to the routing cache */ 1855 for (hop = 0; hop < hopcount; hop++) { 1856 res->nh_sel = hop; 1857 | 1847 /* distinguish between multipath and singlepath */ 1848 if (hopcount < 2) 1849 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, 1850 saddr, tos); 1851 1852 /* add all alternatives to the routing cache */ 1853 for (hop = 0; hop < hopcount; hop++) { 1854 res->nh_sel = hop; 1855 |
1856 /* put reference to previous result */ 1857 if (hop) 1858 ip_rt_put(rtres); 1859 |
|
1858 /* create a routing cache entry */ 1859 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, 1860 &rth); 1861 if (err) 1862 return err; 1863 1864 /* put it into the cache */ 1865 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); | 1860 /* create a routing cache entry */ 1861 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, 1862 &rth); 1863 if (err) 1864 return err; 1865 1866 /* put it into the cache */ 1867 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); |
1866 err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); | 1868 err = rt_intern_hash(hash, rth, &rtres); |
1867 if (err) 1868 return err; 1869 1870 /* forward hop information to multipath impl. */ 1871 multipath_set_nhinfo(rth, 1872 FIB_RES_NETWORK(*res), 1873 FIB_RES_NETMASK(*res), 1874 res->prefixlen, 1875 &FIB_RES_NH(*res)); | 1869 if (err) 1870 return err; 1871 1872 /* forward hop information to multipath impl. */ 1873 multipath_set_nhinfo(rth, 1874 FIB_RES_NETWORK(*res), 1875 FIB_RES_NETMASK(*res), 1876 res->prefixlen, 1877 &FIB_RES_NH(*res)); |
1876 1877 /* only for the last hop the reference count is handled 1878 * outside 1879 */ 1880 if (hop == lasthop) 1881 atomic_set(&(skb->dst->__refcnt), 1); | |
1882 } | 1878 } |
1879 skb->dst = &rtres->u.dst; |
|
1883 return err; 1884#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1885 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos); 1886#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1887} 1888 1889 1890/* --- 312 unchanged lines hidden (view full) --- 2203 2204 2205 rth = dst_alloc(&ipv4_dst_ops); 2206 if (!rth) { 2207 err = -ENOBUFS; 2208 goto cleanup; 2209 } 2210 | 1880 return err; 1881#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1882 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos); 1883#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1884} 1885 1886 1887/* --- 312 unchanged lines hidden (view full) --- 2200 2201 2202 rth = dst_alloc(&ipv4_dst_ops); 2203 if (!rth) { 2204 err = -ENOBUFS; 2205 goto cleanup; 2206 } 2207 |
2208 atomic_set(&rth->u.dst.__refcnt, 1); |
|
2211 rth->u.dst.flags= DST_HOST; 2212#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2213 if (res->fi) { 2214 rth->rt_multipath_alg = res->fi->fib_mp_alg; 2215 if (res->fi->fib_nhs > 1) 2216 rth->u.dst.flags |= DST_BALANCED; 2217 } 2218#endif --- 66 unchanged lines hidden (view full) --- 2285 unsigned flags) 2286{ 2287 struct rtable *rth = NULL; 2288 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); 2289 unsigned hash; 2290 if (err == 0) { 2291 u32 tos = RT_FL_TOS(oldflp); 2292 | 2209 rth->u.dst.flags= DST_HOST; 2210#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2211 if (res->fi) { 2212 rth->rt_multipath_alg = res->fi->fib_mp_alg; 2213 if (res->fi->fib_nhs > 1) 2214 rth->u.dst.flags |= DST_BALANCED; 2215 } 2216#endif --- 66 unchanged lines hidden (view full) --- 2283 unsigned flags) 2284{ 2285 struct rtable *rth = NULL; 2286 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); 2287 unsigned hash; 2288 if (err == 0) { 2289 u32 tos = RT_FL_TOS(oldflp); 2290 |
2293 atomic_set(&rth->u.dst.__refcnt, 1); 2294 | |
2295 hash = rt_hash_code(oldflp->fl4_dst, 2296 oldflp->fl4_src ^ (oldflp->oif << 5), tos); 2297 err = rt_intern_hash(hash, rth, rp); 2298 } 2299 2300 return err; 2301} 2302 --- 18 unchanged lines hidden (view full) --- 2321 struct net_device *dev2nexthop; 2322 2323 res->nh_sel = hop; 2324 2325 /* hold a work reference to the output device */ 2326 dev2nexthop = FIB_RES_DEV(*res); 2327 dev_hold(dev2nexthop); 2328 | 2291 hash = rt_hash_code(oldflp->fl4_dst, 2292 oldflp->fl4_src ^ (oldflp->oif << 5), tos); 2293 err = rt_intern_hash(hash, rth, rp); 2294 } 2295 2296 return err; 2297} 2298 --- 18 unchanged lines hidden (view full) --- 2317 struct net_device *dev2nexthop; 2318 2319 res->nh_sel = hop; 2320 2321 /* hold a work reference to the output device */ 2322 dev2nexthop = FIB_RES_DEV(*res); 2323 dev_hold(dev2nexthop); 2324 |
2325 /* put reference to previous result */ 2326 if (hop) 2327 ip_rt_put(*rp); 2328 |
|
2329 err = __mkroute_output(&rth, res, fl, oldflp, 2330 dev2nexthop, flags); 2331 2332 if (err != 0) 2333 goto cleanup; 2334 2335 hash = rt_hash_code(oldflp->fl4_dst, 2336 oldflp->fl4_src ^ --- 8 unchanged lines hidden (view full) --- 2345 &FIB_RES_NH(*res)); 2346 cleanup: 2347 /* release work reference to output device */ 2348 dev_put(dev2nexthop); 2349 2350 if (err != 0) 2351 return err; 2352 } | 2329 err = __mkroute_output(&rth, res, fl, oldflp, 2330 dev2nexthop, flags); 2331 2332 if (err != 0) 2333 goto cleanup; 2334 2335 hash = rt_hash_code(oldflp->fl4_dst, 2336 oldflp->fl4_src ^ --- 8 unchanged lines hidden (view full) --- 2345 &FIB_RES_NH(*res)); 2346 cleanup: 2347 /* release work reference to output device */ 2348 dev_put(dev2nexthop); 2349 2350 if (err != 0) 2351 return err; 2352 } |
2353 atomic_set(&(*rp)->u.dst.__refcnt, 1); | |
2354 return err; 2355 } else { 2356 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, 2357 flags); 2358 } 2359#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 2360 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, flags); 2361#endif --- 851 unchanged lines hidden --- | 2353 return err; 2354 } else { 2355 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, 2356 flags); 2357 } 2358#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 2359 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, flags); 2360#endif --- 851 unchanged lines hidden --- |