201-multiple_default_gateways.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. diff -urN linux-2.6.21.1.old/include/linux/netfilter_ipv4/ip_nat.h linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ip_nat.h
  2. --- linux-2.6.21.1.old/include/linux/netfilter_ipv4/ip_nat.h 2007-04-27 23:49:26.000000000 +0200
  3. +++ linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ip_nat.h 2007-05-26 20:46:11.801334024 +0200
  4. @@ -64,6 +64,13 @@
  5. struct ip_conntrack;
  6. +/* Call input routing for SNAT-ed traffic */
  7. +extern unsigned int ip_nat_route_input(unsigned int hooknum,
  8. + struct sk_buff **pskb,
  9. + const struct net_device *in,
  10. + const struct net_device *out,
  11. + int (*okfn)(struct sk_buff *));
  12. +
  13. /* Set up the info structure to map into this range. */
  14. extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack,
  15. const struct ip_nat_range *range,
  16. diff -urN linux-2.6.21.1.old/include/linux/rtnetlink.h linux-2.6.21.1.dev/include/linux/rtnetlink.h
  17. --- linux-2.6.21.1.old/include/linux/rtnetlink.h 2007-04-27 23:49:26.000000000 +0200
  18. +++ linux-2.6.21.1.dev/include/linux/rtnetlink.h 2007-05-26 20:46:11.883321560 +0200
  19. @@ -293,6 +293,8 @@
  20. #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
  21. #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
  22. #define RTNH_F_ONLINK 4 /* Gateway is forced on link */
  23. +#define RTNH_F_SUSPECT 8 /* We don't know the real state */
  24. +#define RTNH_F_BADSTATE (RTNH_F_DEAD | RTNH_F_SUSPECT)
  25. /* Macros to handle hexthops */
  26. diff -urN linux-2.6.21.1.old/include/net/flow.h linux-2.6.21.1.dev/include/net/flow.h
  27. --- linux-2.6.21.1.old/include/net/flow.h 2007-04-27 23:49:26.000000000 +0200
  28. +++ linux-2.6.21.1.dev/include/net/flow.h 2007-05-26 20:46:11.922315632 +0200
  29. @@ -19,6 +19,8 @@
  30. struct {
  31. __be32 daddr;
  32. __be32 saddr;
  33. + __u32 lsrc;
  34. + __u32 gw;
  35. __u8 tos;
  36. __u8 scope;
  37. } ip4_u;
  38. @@ -43,6 +45,8 @@
  39. #define fl6_flowlabel nl_u.ip6_u.flowlabel
  40. #define fl4_dst nl_u.ip4_u.daddr
  41. #define fl4_src nl_u.ip4_u.saddr
  42. +#define fl4_lsrc nl_u.ip4_u.lsrc
  43. +#define fl4_gw nl_u.ip4_u.gw
  44. #define fl4_tos nl_u.ip4_u.tos
  45. #define fl4_scope nl_u.ip4_u.scope
  46. diff -urN linux-2.6.21.1.old/net/ipv4/route.c linux-2.6.21.1.dev/net/ipv4/route.c
  47. --- linux-2.6.21.1.old/net/ipv4/route.c 2007-04-27 23:49:26.000000000 +0200
  48. +++ linux-2.6.21.1.dev/net/ipv4/route.c 2007-05-26 20:46:11.967308792 +0200
  49. @@ -1208,6 +1208,7 @@
  50. /* Gateway is different ... */
  51. rt->rt_gateway = new_gw;
  52. + if (rt->fl.fl4_gw) rt->fl.fl4_gw = new_gw;
  53. /* Redirect received -> path was valid */
  54. dst_confirm(&rth->u.dst);
  55. @@ -1643,6 +1644,7 @@
  56. rth->fl.fl4_tos = tos;
  57. rth->fl.mark = skb->mark;
  58. rth->fl.fl4_src = saddr;
  59. + rth->fl.fl4_lsrc = 0;
  60. rth->rt_src = saddr;
  61. #ifdef CONFIG_NET_CLS_ROUTE
  62. rth->u.dst.tclassid = itag;
  63. @@ -1653,6 +1655,7 @@
  64. dev_hold(rth->u.dst.dev);
  65. rth->idev = in_dev_get(rth->u.dst.dev);
  66. rth->fl.oif = 0;
  67. + rth->fl.fl4_gw = 0;
  68. rth->rt_gateway = daddr;
  69. rth->rt_spec_dst= spec_dst;
  70. rth->rt_type = RTN_MULTICAST;
  71. @@ -1716,7 +1719,7 @@
  72. static inline int __mkroute_input(struct sk_buff *skb,
  73. struct fib_result* res,
  74. struct in_device *in_dev,
  75. - __be32 daddr, __be32 saddr, u32 tos,
  76. + __be32 daddr, __be32 saddr, u32 tos, u32 lsrc,
  77. struct rtable **result)
  78. {
  79. @@ -1751,6 +1754,7 @@
  80. flags |= RTCF_DIRECTSRC;
  81. if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
  82. + !lsrc &&
  83. (IN_DEV_SHARED_MEDIA(out_dev) ||
  84. inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
  85. flags |= RTCF_DOREDIRECT;
  86. @@ -1788,6 +1792,7 @@
  87. rth->fl.mark = skb->mark;
  88. rth->fl.fl4_src = saddr;
  89. rth->rt_src = saddr;
  90. + rth->fl.fl4_lsrc = lsrc;
  91. rth->rt_gateway = daddr;
  92. rth->rt_iif =
  93. rth->fl.iif = in_dev->dev->ifindex;
  94. @@ -1795,6 +1800,7 @@
  95. dev_hold(rth->u.dst.dev);
  96. rth->idev = in_dev_get(rth->u.dst.dev);
  97. rth->fl.oif = 0;
  98. + rth->fl.fl4_gw = 0;
  99. rth->rt_spec_dst= spec_dst;
  100. rth->u.dst.input = ip_forward;
  101. @@ -1816,19 +1822,21 @@
  102. struct fib_result* res,
  103. const struct flowi *fl,
  104. struct in_device *in_dev,
  105. - __be32 daddr, __be32 saddr, u32 tos)
  106. + __be32 daddr, __be32 saddr, u32 tos,
  107. + u32 lsrc)
  108. {
  109. struct rtable* rth = NULL;
  110. int err;
  111. unsigned hash;
  112. + fib_select_default(fl, res);
  113. #ifdef CONFIG_IP_ROUTE_MULTIPATH
  114. - if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0)
  115. + if (res->fi && res->fi->fib_nhs > 1)
  116. fib_select_multipath(fl, res);
  117. #endif
  118. /* create a routing cache entry */
  119. - err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
  120. + err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, lsrc, &rth);
  121. if (err)
  122. return err;
  123. @@ -1841,7 +1849,8 @@
  124. struct fib_result* res,
  125. const struct flowi *fl,
  126. struct in_device *in_dev,
  127. - __be32 daddr, __be32 saddr, u32 tos)
  128. + __be32 daddr, __be32 saddr, u32 tos,
  129. + u32 lsrc)
  130. {
  131. #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
  132. struct rtable* rth = NULL, *rtres;
  133. @@ -1857,7 +1866,7 @@
  134. /* distinguish between multipath and singlepath */
  135. if (hopcount < 2)
  136. return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
  137. - saddr, tos);
  138. + saddr, tos, 0);
  139. /* add all alternatives to the routing cache */
  140. for (hop = 0; hop < hopcount; hop++) {
  141. @@ -1869,7 +1878,7 @@
  142. /* create a routing cache entry */
  143. err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
  144. - &rth);
  145. + 0, &rth);
  146. if (err)
  147. return err;
  148. @@ -1889,7 +1898,7 @@
  149. skb->dst = &rtres->u.dst;
  150. return err;
  151. #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
  152. - return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
  153. + return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos, lsrc);
  154. #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
  155. }
  156. @@ -1905,18 +1914,18 @@
  157. */
  158. static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
  159. - u8 tos, struct net_device *dev)
  160. + u8 tos, struct net_device *dev, u32 lsrc)
  161. {
  162. struct fib_result res;
  163. struct in_device *in_dev = in_dev_get(dev);
  164. struct flowi fl = { .nl_u = { .ip4_u =
  165. { .daddr = daddr,
  166. - .saddr = saddr,
  167. + .saddr = lsrc ? : saddr,
  168. .tos = tos,
  169. .scope = RT_SCOPE_UNIVERSE,
  170. } },
  171. .mark = skb->mark,
  172. - .iif = dev->ifindex };
  173. + .iif = lsrc? loopback_dev.ifindex : dev->ifindex };
  174. unsigned flags = 0;
  175. u32 itag = 0;
  176. struct rtable * rth;
  177. @@ -1949,6 +1958,12 @@
  178. if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
  179. goto martian_destination;
  180. + if (lsrc) {
  181. + if (MULTICAST(lsrc) || BADCLASS(lsrc) ||
  182. + ZERONET(lsrc) || LOOPBACK(lsrc))
  183. + goto e_inval;
  184. + }
  185. +
  186. /*
  187. * Now we are ready to route packet.
  188. */
  189. @@ -1958,6 +1973,10 @@
  190. goto no_route;
  191. }
  192. free_res = 1;
  193. + if (lsrc && res.type != RTN_UNICAST && res.type != RTN_NAT)
  194. + goto e_inval;
  195. + fl.iif = dev->ifindex;
  196. + fl.fl4_src = saddr;
  197. RT_CACHE_STAT_INC(in_slow_tot);
  198. @@ -1982,7 +2001,7 @@
  199. if (res.type != RTN_UNICAST)
  200. goto martian_destination;
  201. - err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
  202. + err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos, lsrc);
  203. if (err == -ENOBUFS)
  204. goto e_nobufs;
  205. if (err == -EINVAL)
  206. @@ -1997,6 +2016,8 @@
  207. brd_input:
  208. if (skb->protocol != htons(ETH_P_IP))
  209. goto e_inval;
  210. + if (lsrc)
  211. + goto e_inval;
  212. if (ZERONET(saddr))
  213. spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
  214. @@ -2037,6 +2058,7 @@
  215. rth->u.dst.dev = &loopback_dev;
  216. dev_hold(rth->u.dst.dev);
  217. rth->idev = in_dev_get(rth->u.dst.dev);
  218. + rth->fl.fl4_gw = 0;
  219. rth->rt_gateway = daddr;
  220. rth->rt_spec_dst= spec_dst;
  221. rth->u.dst.input= ip_local_deliver;
  222. @@ -2086,8 +2108,9 @@
  223. goto e_inval;
  224. }
  225. -int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
  226. - u8 tos, struct net_device *dev)
  227. +static inline int
  228. +ip_route_input_cached(struct sk_buff *skb, __be32 daddr, __be32 saddr,
  229. + u8 tos, struct net_device *dev, u32 lsrc)
  230. {
  231. struct rtable * rth;
  232. unsigned hash;
  233. @@ -2102,6 +2125,7 @@
  234. if (rth->fl.fl4_dst == daddr &&
  235. rth->fl.fl4_src == saddr &&
  236. rth->fl.iif == iif &&
  237. + rth->fl.fl4_lsrc == lsrc &&
  238. rth->fl.oif == 0 &&
  239. rth->fl.mark == skb->mark &&
  240. rth->fl.fl4_tos == tos) {
  241. @@ -2148,7 +2172,19 @@
  242. rcu_read_unlock();
  243. return -EINVAL;
  244. }
  245. - return ip_route_input_slow(skb, daddr, saddr, tos, dev);
  246. + return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc);
  247. +}
  248. +
  249. +int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
  250. + u8 tos, struct net_device *dev)
  251. +{
  252. + return ip_route_input_cached(skb, daddr, saddr, tos, dev, 0);
  253. +}
  254. +
  255. +int ip_route_input_lookup(struct sk_buff *skb, u32 daddr, u32 saddr,
  256. + u8 tos, struct net_device *dev, u32 lsrc)
  257. +{
  258. + return ip_route_input_cached(skb, daddr, saddr, tos, dev, lsrc);
  259. }
  260. static inline int __mkroute_output(struct rtable **result,
  261. @@ -2227,6 +2263,7 @@
  262. rth->fl.fl4_tos = tos;
  263. rth->fl.fl4_src = oldflp->fl4_src;
  264. rth->fl.oif = oldflp->oif;
  265. + rth->fl.fl4_gw = oldflp->fl4_gw;
  266. rth->fl.mark = oldflp->mark;
  267. rth->rt_dst = fl->fl4_dst;
  268. rth->rt_src = fl->fl4_src;
  269. @@ -2367,6 +2404,7 @@
  270. struct flowi fl = { .nl_u = { .ip4_u =
  271. { .daddr = oldflp->fl4_dst,
  272. .saddr = oldflp->fl4_src,
  273. + .gw = oldflp->fl4_gw,
  274. .tos = tos & IPTOS_RT_MASK,
  275. .scope = ((tos & RTO_ONLINK) ?
  276. RT_SCOPE_LINK :
  277. @@ -2470,6 +2508,7 @@
  278. dev_out = &loopback_dev;
  279. dev_hold(dev_out);
  280. fl.oif = loopback_dev.ifindex;
  281. + fl.fl4_gw = 0;
  282. res.type = RTN_LOCAL;
  283. flags |= RTCF_LOCAL;
  284. goto make_route;
  285. @@ -2477,7 +2516,7 @@
  286. if (fib_lookup(&fl, &res)) {
  287. res.fi = NULL;
  288. - if (oldflp->oif) {
  289. + if (oldflp->oif && dev_out->flags & IFF_UP) {
  290. /* Apparently, routing tables are wrong. Assume,
  291. that the destination is on link.
  292. @@ -2517,6 +2556,7 @@
  293. dev_out = &loopback_dev;
  294. dev_hold(dev_out);
  295. fl.oif = dev_out->ifindex;
  296. + fl.fl4_gw = 0;
  297. if (res.fi)
  298. fib_info_put(res.fi);
  299. res.fi = NULL;
  300. @@ -2524,13 +2564,12 @@
  301. goto make_route;
  302. }
  303. + if (res.type == RTN_UNICAST)
  304. + fib_select_default(&fl, &res);
  305. #ifdef CONFIG_IP_ROUTE_MULTIPATH
  306. - if (res.fi->fib_nhs > 1 && fl.oif == 0)
  307. + if (res.fi->fib_nhs > 1)
  308. fib_select_multipath(&fl, &res);
  309. - else
  310. #endif
  311. - if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
  312. - fib_select_default(&fl, &res);
  313. if (!fl.fl4_src)
  314. fl.fl4_src = FIB_RES_PREFSRC(res);
  315. @@ -2567,6 +2606,7 @@
  316. rth->fl.fl4_src == flp->fl4_src &&
  317. rth->fl.iif == 0 &&
  318. rth->fl.oif == flp->oif &&
  319. + rth->fl.fl4_gw == flp->fl4_gw &&
  320. rth->fl.mark == flp->mark &&
  321. !((rth->fl.fl4_tos ^ flp->fl4_tos) &
  322. (IPTOS_RT_MASK | RTO_ONLINK))) {
  323. @@ -3199,3 +3239,4 @@
  324. EXPORT_SYMBOL(__ip_select_ident);
  325. EXPORT_SYMBOL(ip_route_input);
  326. EXPORT_SYMBOL(ip_route_output_key);
  327. +EXPORT_SYMBOL(ip_route_input_lookup);