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 ---