]> git.pld-linux.org Git - packages/kernel.git/blob - 05_nf_reroute-2.6.7-10.diff
- update for cset 20040707_...
[packages/kernel.git] / 05_nf_reroute-2.6.7-10.diff
1 diff -ur v2.6.7-before-nf_reroute/linux/include/linux/netfilter_ipv4/ip_nat.h linux/include/linux/netfilter_ipv4/ip_nat.h
2 --- v2.6.7-before-nf_reroute/linux/include/linux/netfilter_ipv4/ip_nat.h        2004-03-11 23:48:04.000000000 +0200
3 +++ linux/include/linux/netfilter_ipv4/ip_nat.h 2004-06-17 01:02:46.811977384 +0300
4 @@ -121,5 +121,13 @@
5  extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
6                                     u_int32_t newval,
7                                     u_int16_t oldcheck);
8 +
9 +/* Call input routing for SNAT-ed traffic */
10 +extern unsigned int ip_nat_route_input(unsigned int hooknum,
11 +                                      struct sk_buff **pskb,
12 +                                      const struct net_device *in,
13 +                                      const struct net_device *out,
14 +                                      int (*okfn)(struct sk_buff *));
15 +
16  #endif /*__KERNEL__*/
17  #endif
18 diff -ur v2.6.7-before-nf_reroute/linux/include/net/flow.h linux/include/net/flow.h
19 --- v2.6.7-before-nf_reroute/linux/include/net/flow.h   2004-04-04 09:43:36.000000000 +0300
20 +++ linux/include/net/flow.h    2004-06-17 01:02:46.812977232 +0300
21 @@ -19,6 +19,8 @@
22                         __u32                   daddr;
23                         __u32                   saddr;
24                         __u32                   fwmark;
25 +                       __u32                   lsrc;
26 +                       __u32                   gw;
27                         __u8                    tos;
28                         __u8                    scope;
29                 } ip4_u;
30 @@ -46,6 +48,8 @@
31  #define fl4_dst                nl_u.ip4_u.daddr
32  #define fl4_src                nl_u.ip4_u.saddr
33  #define fl4_fwmark     nl_u.ip4_u.fwmark
34 +#define fl4_lsrc       nl_u.ip4_u.lsrc
35 +#define fl4_gw         nl_u.ip4_u.gw
36  #define fl4_tos                nl_u.ip4_u.tos
37  #define fl4_scope      nl_u.ip4_u.scope
38  
39 diff -ur v2.6.7-before-nf_reroute/linux/include/net/route.h linux/include/net/route.h
40 --- v2.6.7-before-nf_reroute/linux/include/net/route.h  2004-06-16 23:54:05.000000000 +0300
41 +++ linux/include/net/route.h   2004-06-17 01:02:46.812977232 +0300
42 @@ -124,6 +124,7 @@
43  extern int             ip_route_output_key(struct rtable **, struct flowi *flp);
44  extern int             ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
45  extern int             ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
46 +extern int             ip_route_input_lookup(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin, u32 lsrc);
47  extern unsigned short  ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
48  extern void            ip_rt_send_redirect(struct sk_buff *skb);
49  
50 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/fib_hash.c linux/net/ipv4/fib_hash.c
51 --- v2.6.7-before-nf_reroute/linux/net/ipv4/fib_hash.c  2004-06-17 01:01:41.000000000 +0300
52 +++ linux/net/ipv4/fib_hash.c   2004-06-17 01:02:46.813977080 +0300
53 @@ -352,6 +352,9 @@
54         for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) {
55                 if (flp->oif && flp->oif != nh->nh_oif)
56                         continue;
57 +               if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && nh->nh_gw &&
58 +                   nh->nh_scope == RT_SCOPE_LINK)
59 +                       continue;
60                 if (nh->nh_flags & RTNH_F_DEAD)
61                         continue;
62  
63 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
64 --- v2.6.7-before-nf_reroute/linux/net/ipv4/fib_semantics.c     2004-06-17 01:01:41.000000000 +0300
65 +++ linux/net/ipv4/fib_semantics.c      2004-06-17 01:02:46.814976928 +0300
66 @@ -674,8 +674,12 @@
67                         for_nexthops(fi) {
68                                 if (nh->nh_flags&RTNH_F_DEAD)
69                                         continue;
70 -                               if (!flp->oif || flp->oif == nh->nh_oif)
71 -                                       break;
72 +                               if (flp->oif && flp->oif != nh->nh_oif)
73 +                                       continue;
74 +                               if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw &&
75 +                                   nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
76 +                                       continue;
77 +                               break;
78                         }
79  #ifdef CONFIG_IP_ROUTE_MULTIPATH
80                         if (nhsel < fi->fib_nhs) {
81 @@ -1068,6 +1072,9 @@
82                 change_nexthops(fi) {
83                         if (flp->oif != nh->nh_oif)
84                                 continue;
85 +                       if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw &&
86 +                           nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
87 +                               continue;
88                         if (!(nh->nh_flags&RTNH_F_BADSTATE)) {
89                                 if (nh->nh_power > w) {
90                                         w = nh->nh_power;
91 @@ -1126,11 +1133,14 @@
92  
93         for_nexthops(fi) {
94                 if (!(nh->nh_flags&RTNH_F_DEAD)) {
95 -                       if (!flp->oif || flp->oif == nh->nh_oif) {
96 -                               spin_unlock_bh(&fib_multipath_lock);
97 -                               res->nh_sel = nhsel;
98 -                               return;
99 -                       }
100 +                       if (flp->oif && flp->oif != nh->nh_oif)
101 +                               continue;
102 +                       if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw &&
103 +                           nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
104 +                               continue;
105 +                       spin_unlock_bh(&fib_multipath_lock);
106 +                       res->nh_sel = nhsel;
107 +                       return;
108                 }
109         } endfor_nexthops(fi);
110  
111 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_fw_compat_masq.c linux/net/ipv4/netfilter/ip_fw_compat_masq.c
112 --- v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_fw_compat_masq.c       2004-04-04 09:43:37.000000000 +0300
113 +++ linux/net/ipv4/netfilter/ip_fw_compat_masq.c        2004-06-17 01:02:46.814976928 +0300
114 @@ -44,15 +44,20 @@
115  unsigned int
116  do_masquerade(struct sk_buff **pskb, const struct net_device *dev)
117  {
118 +       struct iphdr *iph = (*pskb)->nh.iph;
119         struct ip_nat_info *info;
120         enum ip_conntrack_info ctinfo;
121         struct ip_conntrack *ct;
122         unsigned int ret;
123 +       struct rtable *rt, *skb_rt;
124 +       struct net_device *skb_dev;
125 +       __u32 saddr;
126 +       int new;
127  
128         /* Sorry, only ICMP, TCP and UDP. */
129 -       if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP
130 -           && (*pskb)->nh.iph->protocol != IPPROTO_TCP
131 -           && (*pskb)->nh.iph->protocol != IPPROTO_UDP)
132 +       if (iph->protocol != IPPROTO_ICMP
133 +           && iph->protocol != IPPROTO_TCP
134 +           && iph->protocol != IPPROTO_UDP)
135                 return NF_DROP;
136  
137         /* Feed it to connection tracking; in fact we're in NF_IP_FORWARD,
138 @@ -71,23 +76,30 @@
139         }
140  
141         info = &ct->nat.info;
142 +       iph = (*pskb)->nh.iph;
143 +       saddr = iph->saddr;
144 +       new = 0;
145  
146         WRITE_LOCK(&ip_nat_lock);
147         /* Setup the masquerade, if not already */
148         if (!info->initialized) {
149                 u_int32_t newsrc;
150                 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = (*pskb)->nh.iph->daddr } } };
151 -               struct rtable *rt;
152                 struct ip_nat_multi_range range;
153  
154 +               skb_rt = (struct rtable *) (*pskb)->dst;
155 +               skb_dev = skb_rt->u.dst.dev;
156                 /* Pass 0 instead of saddr, since it's going to be changed
157                    anyway. */
158 +               fl.fl4_tos = RT_TOS(iph->tos);
159 +               fl.fl4_gw = skb_dev? skb_rt->rt_gateway : 0;
160 +               fl.oif = skb_dev? skb_dev->ifindex : 0;
161                 if (ip_route_output_key(&rt, &fl) != 0) {
162 +                       WRITE_UNLOCK(&ip_nat_lock);
163                         DEBUGP("ipnat_rule_masquerade: Can't reroute.\n");
164                         return NF_DROP;
165                 }
166 -               newsrc = inet_select_addr(rt->u.dst.dev, rt->rt_gateway,
167 -                                         RT_SCOPE_UNIVERSE);
168 +               newsrc = rt->rt_src;
169                 ip_rt_put(rt);
170                 range = ((struct ip_nat_multi_range)
171                          { 1,
172 @@ -100,11 +112,36 @@
173                         WRITE_UNLOCK(&ip_nat_lock);
174                         return ret;
175                 }
176 +               new = 1;
177         } else
178                 DEBUGP("Masquerading already done on this conn.\n");
179         WRITE_UNLOCK(&ip_nat_lock);
180  
181 -       return do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
182 +       ret = do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
183 +       if (ret != NF_ACCEPT || saddr == (*pskb)->nh.iph->saddr || new)
184 +               return ret;
185 +
186 +       iph = (*pskb)->nh.iph;
187 +       {
188 +               struct flowi fl = { .nl_u = { .ip4_u =
189 +                                             { .saddr = iph->saddr,
190 +                                               .daddr = iph->daddr,
191 +                                               .tos = RT_TOS(iph->tos) } } };
192 +               if (ip_route_output_key(&rt, &fl) != 0)
193 +                       return NF_DROP;
194 +       }
195 +       skb_rt = (struct rtable *) (*pskb)->dst;
196 +       skb_dev = skb_rt->u.dst.dev;
197 +       if (skb_dev != rt->u.dst.dev || rt->rt_gateway != skb_rt->rt_gateway) {
198 +               if (skb_dev != rt->u.dst.dev) {
199 +                       /* TODO: check the new mtu and reply FRAG_NEEDED */
200 +               }
201 +               dst_release((*pskb)->dst);
202 +               (*pskb)->dst = &rt->u.dst;
203 +       } else {
204 +               ip_rt_put(rt);
205 +       }
206 +       return NF_ACCEPT;
207  }
208  
209  void
210 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_nat_core.c linux/net/ipv4/netfilter/ip_nat_core.c
211 --- v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_nat_core.c     2004-05-11 02:09:54.000000000 +0300
212 +++ linux/net/ipv4/netfilter/ip_nat_core.c      2004-06-17 01:02:46.815976776 +0300
213 @@ -987,6 +987,60 @@
214         return 0;
215  }
216  
217 +unsigned int
218 +ip_nat_route_input(unsigned int hooknum,
219 +               struct sk_buff **pskb,
220 +               const struct net_device *in,
221 +               const struct net_device *out,
222 +               int (*okfn)(struct sk_buff *))
223 +{
224 +       struct sk_buff *skb = *pskb;
225 +       struct iphdr *iph;
226 +       struct ip_conntrack *ct;
227 +       enum ip_conntrack_info ctinfo;
228 +       struct ip_nat_info *info;
229 +       enum ip_conntrack_dir dir;
230 +       __u32 saddr;
231 +       int i;
232 +
233 +       if (!(ct = ip_conntrack_get(skb, &ctinfo)))
234 +               return NF_ACCEPT;
235 +
236 +       info = &ct->nat.info;
237 +       if (!info->initialized)
238 +               return NF_ACCEPT;
239 +
240 +       if (skb->dst)
241 +               return NF_ACCEPT;
242 +
243 +       if (skb->len < sizeof(struct iphdr))
244 +               return NF_ACCEPT;
245 +
246 +       iph = skb->nh.iph;
247 +       saddr = iph->saddr;
248 +       hooknum = NF_IP_POST_ROUTING;
249 +       dir = CTINFO2DIR(ctinfo);
250 +
251 +       READ_LOCK(&ip_nat_lock);
252 +       for (i = 0; i < info->num_manips; i++) {
253 +               if (info->manips[i].direction == dir
254 +                   && info->manips[i].hooknum == hooknum
255 +                   && info->manips[i].maniptype == IP_NAT_MANIP_SRC) {
256 +                       saddr = info->manips[i].manip.ip;
257 +               }
258 +       }
259 +       READ_UNLOCK(&ip_nat_lock);
260 +
261 +       if (saddr == iph->saddr)
262 +               return NF_ACCEPT;
263 +
264 +       if (ip_route_input_lookup(skb, iph->daddr, iph->saddr, iph->tos,
265 +           skb->dev, saddr))
266 +               return NF_DROP;
267 +
268 +       return NF_ACCEPT;
269 +}
270 +
271  int __init ip_nat_init(void)
272  {
273         size_t i;
274 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_nat_standalone.c linux/net/ipv4/netfilter/ip_nat_standalone.c
275 --- v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ip_nat_standalone.c       2004-06-16 23:54:06.000000000 +0300
276 +++ linux/net/ipv4/netfilter/ip_nat_standalone.c        2004-06-17 01:02:46.816976624 +0300
277 @@ -247,6 +247,14 @@
278         .priority       = NF_IP_PRI_NAT_DST,
279  };
280  
281 +/* Before routing, route before mangling */
282 +static struct nf_hook_ops ip_nat_inr_ops = {
283 +       .hook           = ip_nat_route_input,
284 +       .pf             = PF_INET,
285 +       .hooknum        = NF_IP_PRE_ROUTING,
286 +       .priority       = NF_IP_PRI_LAST-1,
287 +};
288 +
289  /* After packet filtering, change source */
290  static struct nf_hook_ops ip_nat_out_ops = {
291         .hook           = ip_nat_out,
292 @@ -331,10 +339,15 @@
293                 printk("ip_nat_init: can't register in hook.\n");
294                 goto cleanup_nat;
295         }
296 +       ret = nf_register_hook(&ip_nat_inr_ops);
297 +       if (ret < 0) {
298 +               printk("ip_nat_init: can't register inr hook.\n");
299 +               goto cleanup_inops;
300 +       }
301         ret = nf_register_hook(&ip_nat_out_ops);
302         if (ret < 0) {
303                 printk("ip_nat_init: can't register out hook.\n");
304 -               goto cleanup_inops;
305 +               goto cleanup_inrops;
306         }
307  #ifdef CONFIG_IP_NF_NAT_LOCAL
308         ret = nf_register_hook(&ip_nat_local_out_ops);
309 @@ -358,6 +371,8 @@
310   cleanup_outops:
311  #endif
312         nf_unregister_hook(&ip_nat_out_ops);
313 + cleanup_inrops:
314 +       nf_unregister_hook(&ip_nat_inr_ops);
315   cleanup_inops:
316         nf_unregister_hook(&ip_nat_in_ops);
317   cleanup_nat:
318 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ipt_MASQUERADE.c linux/net/ipv4/netfilter/ipt_MASQUERADE.c
319 --- v2.6.7-before-nf_reroute/linux/net/ipv4/netfilter/ipt_MASQUERADE.c  2004-05-11 02:09:54.000000000 +0300
320 +++ linux/net/ipv4/netfilter/ipt_MASQUERADE.c   2004-06-17 01:02:46.816976624 +0300
321 @@ -101,10 +101,12 @@
322                                               { .daddr = (*pskb)->nh.iph->daddr,
323                                                 .tos = (RT_TOS((*pskb)->nh.iph->tos) |
324                                                         RTO_CONN),
325 +                                               .gw = ((struct rtable *) (*pskb)->dst)->rt_gateway,
326  #ifdef CONFIG_IP_ROUTE_FWMARK
327                                                 .fwmark = (*pskb)->nfmark
328  #endif
329 -                                             } } };
330 +                                             } },
331 +                                   .oif = out->ifindex };
332                 if (ip_route_output_key(&rt, &fl) != 0) {
333                         /* Funky routing can do this. */
334                         if (net_ratelimit())
335 @@ -112,13 +114,6 @@
336                                        " No route: Rusty's brain broke!\n");
337                         return NF_DROP;
338                 }
339 -               if (rt->u.dst.dev != out) {
340 -                       if (net_ratelimit())
341 -                               printk("MASQUERADE:"
342 -                                      " Route sent us somewhere else.\n");
343 -                       ip_rt_put(rt);
344 -                       return NF_DROP;
345 -               }
346         }
347  
348         newsrc = rt->rt_src;
349 diff -ur v2.6.7-before-nf_reroute/linux/net/ipv4/route.c linux/net/ipv4/route.c
350 --- v2.6.7-before-nf_reroute/linux/net/ipv4/route.c     2004-06-17 01:01:41.000000000 +0300
351 +++ linux/net/ipv4/route.c      2004-06-17 01:03:04.388305376 +0300
352 @@ -1055,6 +1055,7 @@
353  
354                                 /* Gateway is different ... */
355                                 rt->rt_gateway          = new_gw;
356 +                               if (rt->fl.fl4_gw) rt->fl.fl4_gw = new_gw;
357  
358                                 /* Redirect received -> path was valid */
359                                 dst_confirm(&rth->u.dst);
360 @@ -1496,6 +1497,7 @@
361         rth->fl.fl4_fwmark= skb->nfmark;
362  #endif
363         rth->fl.fl4_src = saddr;
364 +       rth->fl.fl4_lsrc = 0;
365         rth->rt_src     = saddr;
366  #ifdef CONFIG_IP_ROUTE_NAT
367         rth->rt_dst_map = daddr;
368 @@ -1510,6 +1512,7 @@
369         dev_hold(rth->u.dst.dev);
370         rth->idev       = in_dev_get(rth->u.dst.dev);
371         rth->fl.oif     = 0;
372 +       rth->fl.fl4_gw  = 0;
373         rth->rt_gateway = daddr;
374         rth->rt_spec_dst= spec_dst;
375         rth->rt_type    = RTN_MULTICAST;
376 @@ -1549,21 +1552,21 @@
377   */
378  
379  static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
380 -                       u8 tos, struct net_device *dev)
381 +                       u8 tos, struct net_device *dev, u32 lsrc)
382  {
383         struct fib_result res;
384         struct in_device *in_dev = in_dev_get(dev);
385         struct in_device *out_dev = NULL;
386         struct flowi fl = { .nl_u = { .ip4_u =
387                                       { .daddr = daddr,
388 -                                       .saddr = saddr,
389 +                                       .saddr = lsrc? : saddr,
390                                         .tos = tos,
391                                         .scope = RT_SCOPE_UNIVERSE,
392  #ifdef CONFIG_IP_ROUTE_FWMARK
393                                         .fwmark = skb->nfmark
394  #endif
395                                       } },
396 -                           .iif = dev->ifindex };
397 +                           .iif = lsrc? loopback_dev.ifindex : dev->ifindex };
398         unsigned        flags = 0;
399         u32             itag = 0;
400         struct rtable * rth;
401 @@ -1577,7 +1580,7 @@
402         if (!in_dev)
403                 goto out;
404  
405 -       hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5), tos);
406 +       hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos);
407  
408         /* Check for the most weird martians, which can be not detected
409            by fib_lookup.
410 @@ -1598,6 +1601,12 @@
411         if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
412                 goto martian_destination;
413  
414 +       if (lsrc) {
415 +               if (MULTICAST(lsrc) || BADCLASS(lsrc) ||
416 +                   ZERONET(lsrc) || LOOPBACK(lsrc))
417 +                       goto e_inval;
418 +       }
419 +
420         /*
421          *      Now we are ready to route packet.
422          */
423 @@ -1607,6 +1616,10 @@
424                 goto no_route;
425         }
426         free_res = 1;
427 +       if (lsrc && res.type != RTN_UNICAST && res.type != RTN_NAT)
428 +               goto e_inval;
429 +       fl.iif = dev->ifindex;
430 +       fl.fl4_src = saddr;
431  
432         RT_CACHE_STAT_INC(in_slow_tot);
433  
434 @@ -1617,7 +1630,7 @@
435  
436         if (1) {
437                 u32 src_map = saddr;
438 -               if (res.r)
439 +               if (res.r && !lsrc)
440                         src_map = fib_rules_policy(saddr, &res, &flags);
441  
442                 if (res.type == RTN_NAT) {
443 @@ -1678,6 +1691,7 @@
444                 flags |= RTCF_DIRECTSRC;
445  
446         if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
447 +           !lsrc &&
448             (IN_DEV_SHARED_MEDIA(out_dev) ||
449              inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res))))
450                 flags |= RTCF_DOREDIRECT;
451 @@ -1708,6 +1722,7 @@
452  #endif
453         rth->fl.fl4_src = saddr;
454         rth->rt_src     = saddr;
455 +       rth->fl.fl4_lsrc        = lsrc;
456         rth->rt_gateway = daddr;
457  #ifdef CONFIG_IP_ROUTE_NAT
458         rth->rt_src_map = fl.fl4_src;
459 @@ -1721,6 +1736,7 @@
460         dev_hold(rth->u.dst.dev);
461         rth->idev       = in_dev_get(rth->u.dst.dev);
462         rth->fl.oif     = 0;
463 +       rth->fl.fl4_gw  = 0;
464         rth->rt_spec_dst= spec_dst;
465  
466         rth->u.dst.input = ip_forward;
467 @@ -1731,7 +1747,8 @@
468         rth->rt_flags = flags;
469  
470  #ifdef CONFIG_NET_FASTROUTE
471 -       if (netdev_fastroute && !(flags&(RTCF_NAT|RTCF_MASQ|RTCF_DOREDIRECT))) {
472 +       if (netdev_fastroute && !(flags&(RTCF_NAT|RTCF_MASQ|RTCF_DOREDIRECT)) &&
473 +           !lsrc) {
474                 struct net_device *odev = rth->u.dst.dev;
475                 if (odev != dev &&
476                     dev->accept_fastpath &&
477 @@ -1754,6 +1771,8 @@
478  brd_input:
479         if (skb->protocol != htons(ETH_P_IP))
480                 goto e_inval;
481 +       if (lsrc)
482 +               goto e_inval;
483  
484         if (ZERONET(saddr))
485                 spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
486 @@ -1800,6 +1819,7 @@
487         rth->u.dst.dev  = &loopback_dev;
488         dev_hold(rth->u.dst.dev);
489         rth->idev       = in_dev_get(rth->u.dst.dev);
490 +       rth->fl.fl4_gw  = 0;
491         rth->rt_gateway = daddr;
492         rth->rt_spec_dst= spec_dst;
493         rth->u.dst.input= ip_local_deliver;
494 @@ -1865,8 +1885,9 @@
495         goto e_inval;
496  }
497  
498 -int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
499 -                  u8 tos, struct net_device *dev)
500 +static inline int
501 +ip_route_input_cached(struct sk_buff *skb, u32 daddr, u32 saddr,
502 +                     u8 tos, struct net_device *dev, u32 lsrc)
503  {
504         struct rtable * rth;
505         unsigned        hash;
506 @@ -1881,6 +1902,7 @@
507                 if (rth->fl.fl4_dst == daddr &&
508                     rth->fl.fl4_src == saddr &&
509                     rth->fl.iif == iif &&
510 +                   rth->fl.fl4_lsrc == lsrc &&
511                     rth->fl.oif == 0 &&
512  #ifdef CONFIG_IP_ROUTE_FWMARK
513                     rth->fl.fl4_fwmark == skb->nfmark &&
514 @@ -1929,9 +1951,21 @@
515                 read_unlock(&inetdev_lock);
516                 return -EINVAL;
517         }
518 -       return ip_route_input_slow(skb, daddr, saddr, tos, dev);
519 +       return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc);
520  }
521  
522 +int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
523 +                  u8 tos, struct net_device *dev)
524 +{
525 +       return ip_route_input_cached(skb, daddr, saddr, tos, dev, 0);
526 +}
527 +
528 +int ip_route_input_lookup(struct sk_buff *skb, u32 daddr, u32 saddr,
529 +                         u8 tos, struct net_device *dev, u32 lsrc)
530 +{
531 +       return ip_route_input_cached(skb, daddr, saddr, tos, dev, lsrc);
532 +}
533
534  /*
535   * Major route resolver routine.
536   */
537 @@ -1942,6 +1976,7 @@
538         struct flowi fl = { .nl_u = { .ip4_u =
539                                       { .daddr = oldflp->fl4_dst,
540                                         .saddr = oldflp->fl4_src,
541 +                                       .gw = oldflp->fl4_gw,
542                                         .tos = tos & IPTOS_RT_MASK,
543                                         .scope = ((tos & RTO_ONLINK) ?
544                                                   RT_SCOPE_LINK :
545 @@ -2045,6 +2080,7 @@
546                 dev_out = &loopback_dev;
547                 dev_hold(dev_out);
548                 fl.oif = loopback_dev.ifindex;
549 +               fl.fl4_gw = 0;
550                 res.type = RTN_LOCAL;
551                 flags |= RTCF_LOCAL;
552                 goto make_route;
553 @@ -2095,6 +2131,7 @@
554                 dev_out = &loopback_dev;
555                 dev_hold(dev_out);
556                 fl.oif = dev_out->ifindex;
557 +               fl.fl4_gw = 0;
558                 if (res.fi)
559                         fib_info_put(res.fi);
560                 res.fi = NULL;
561 @@ -2170,6 +2207,7 @@
562         rth->fl.fl4_tos = tos;
563         rth->fl.fl4_src = oldflp->fl4_src;
564         rth->fl.oif     = oldflp->oif;
565 +       rth->fl.fl4_gw  = oldflp->fl4_gw;
566  #ifdef CONFIG_IP_ROUTE_FWMARK
567         rth->fl.fl4_fwmark= oldflp->fl4_fwmark;
568  #endif
569 @@ -2249,6 +2287,7 @@
570                     rth->fl.fl4_src == flp->fl4_src &&
571                     rth->fl.iif == 0 &&
572                     rth->fl.oif == flp->oif &&
573 +                   rth->fl.fl4_gw == flp->fl4_gw &&
574  #ifdef CONFIG_IP_ROUTE_FWMARK
575                     rth->fl.fl4_fwmark == flp->fl4_fwmark &&
576  #endif
577 @@ -2862,3 +2901,4 @@
578  EXPORT_SYMBOL(__ip_select_ident);
579  EXPORT_SYMBOL(ip_route_input);
580  EXPORT_SYMBOL(ip_route_output_key);
581 +EXPORT_SYMBOL(ip_route_input_lookup);
This page took 0.064999 seconds and 3 git commands to generate.