Tomato 1.25
[tomato.git] / release / src / linux / linux / net / ipv4 / netfilter / ipt_ROUTE.c
blobb97d7792604b39ccb0caf447c5c8201f5f2caae7
1 /*
2 * This implements the ROUTE target, which enables you to setup unusual
3 * routes not supported by the standard kernel routing table.
5 * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
7 * v 1.11 2004/11/23
9 * This software is distributed under GNU GPL v2, 1991
12 #include <linux/module.h>
13 #include <linux/skbuff.h>
14 #include <linux/ip.h>
15 #include <linux/netfilter_ipv4/ip_tables.h>
16 #include <linux/netfilter_ipv4/ip_conntrack.h>
17 #include <linux/netfilter_ipv4/ipt_ROUTE.h>
18 #include <linux/netdevice.h>
19 #include <linux/route.h>
20 #include <net/ip.h>
21 #include <net/route.h>
22 #include <net/icmp.h>
23 #include <net/checksum.h>
25 #if 0
26 #define DEBUGP printk
27 #else
28 #define DEBUGP(format, args...)
29 #endif
32 /* Try to route the packet according to the routing keys specified in
33 * route_info. Keys are :
34 * - ifindex :
35 * 0 if no oif preferred,
36 * otherwise set to the index of the desired oif
37 * - route_info->gw :
38 * 0 if no gateway specified,
39 * otherwise set to the next host to which the pkt must be routed
40 * If success, skb->dev is the output device to which the packet must
41 * be sent and skb->dst is not NULL
43 * RETURN: -1 if an error occured
44 * 1 if the packet was succesfully routed to the
45 * destination desired
46 * 0 if the kernel routing table could not route the packet
47 * according to the keys specified
49 static int route(struct sk_buff *skb,
50 unsigned int ifindex,
51 const struct ipt_route_target_info *route_info)
53 int err;
54 struct rtable *rt;
55 struct iphdr *iph = skb->nh.iph;
56 struct rt_key key = {
57 dst:iph->daddr,
58 src:0,
59 oif:ifindex,
60 tos:RT_TOS(iph->tos)
63 /* The destination address may be overloaded by the target */
64 if (route_info->gw)
65 key.dst = route_info->gw;
67 /* Trying to route the packet using the standard routing table. */
68 if ((err = ip_route_output_key(&rt, &key))) {
69 if (net_ratelimit())
70 DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
71 return -1;
74 /* Drop old route. */
75 dst_release(skb->dst);
76 skb->dst = NULL;
78 /* Success if no oif specified or if the oif correspond to the
79 * one desired */
80 if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
81 skb->dst = &rt->u.dst;
82 skb->dev = skb->dst->dev;
83 return 1;
86 /* The interface selected by the routing table is not the one
87 * specified by the user. This may happen because the dst address
88 * is one of our own addresses.
90 if (net_ratelimit())
91 DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n",
92 NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
94 return 0;
98 /* Stolen from ip_finish_output2
99 * PRE : skb->dev is set to the device we are leaving by
100 * skb->dst is not NULL
101 * POST: the packet is sent with the link layer header pushed
102 * the packet is destroyed
104 static void ip_direct_send(struct sk_buff *skb)
106 struct dst_entry *dst = skb->dst;
107 struct hh_cache *hh = dst->hh;
109 if (hh) {
110 read_lock_bh(&hh->hh_lock);
111 memcpy(skb->data - 16, hh->hh_data, 16);
112 read_unlock_bh(&hh->hh_lock);
113 skb_push(skb, hh->hh_len);
114 hh->hh_output(skb);
115 } else if (dst->neighbour)
116 dst->neighbour->output(skb);
117 else {
118 if (net_ratelimit())
119 DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
120 kfree_skb(skb);
125 /* PRE : skb->dev is set to the device we are leaving by
126 * POST: - the packet is directly sent to the skb->dev device, without
127 * pushing the link layer header.
128 * - the packet is destroyed
130 static inline int dev_direct_send(struct sk_buff *skb)
132 return dev_queue_xmit(skb);
136 static unsigned int route_oif(const struct ipt_route_target_info *route_info,
137 struct sk_buff *skb)
139 unsigned int ifindex = 0;
140 struct net_device *dev_out = NULL;
142 /* The user set the interface name to use.
143 * Getting the current interface index.
145 if ((dev_out = dev_get_by_name(route_info->oif))) {
146 ifindex = dev_out->ifindex;
147 } else {
148 /* Unknown interface name : packet dropped */
149 if (net_ratelimit())
150 DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
151 return NF_DROP;
154 /* Trying the standard way of routing packets */
155 switch (route(skb, ifindex, route_info)) {
156 case 1:
157 dev_put(dev_out);
158 if (route_info->flags & IPT_ROUTE_CONTINUE)
159 return IPT_CONTINUE;
161 ip_direct_send(skb);
162 return NF_STOLEN;
164 case 0:
165 /* Failed to send to oif. Trying the hard way */
166 if (route_info->flags & IPT_ROUTE_CONTINUE)
167 return NF_DROP;
169 if (net_ratelimit())
170 DEBUGP("ipt_ROUTE: forcing the use of %i\n",
171 ifindex);
173 /* We have to force the use of an interface.
174 * This interface must be a tunnel interface since
175 * otherwise we can't guess the hw address for
176 * the packet. For a tunnel interface, no hw address
177 * is needed.
179 if ((dev_out->type != ARPHRD_TUNNEL)
180 && (dev_out->type != ARPHRD_IPGRE)) {
181 if (net_ratelimit())
182 DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
183 dev_put(dev_out);
184 return NF_DROP;
187 /* Send the packet. This will also free skb
188 * Do not go through the POST_ROUTING hook because
189 * skb->dst is not set and because it will probably
190 * get confused by the destination IP address.
192 skb->dev = dev_out;
193 dev_direct_send(skb);
194 dev_put(dev_out);
195 return NF_STOLEN;
197 default:
198 /* Unexpected error */
199 dev_put(dev_out);
200 return NF_DROP;
205 static unsigned int route_iif(const struct ipt_route_target_info *route_info,
206 struct sk_buff *skb)
208 struct net_device *dev_in = NULL;
210 /* Getting the current interface index. */
211 if (!(dev_in = dev_get_by_name(route_info->iif))) {
212 if (net_ratelimit())
213 DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
214 return NF_DROP;
217 skb->dev = dev_in;
218 dst_release(skb->dst);
219 skb->dst = NULL;
221 netif_rx(skb);
222 dev_put(dev_in);
223 return NF_STOLEN;
227 static unsigned int route_gw(const struct ipt_route_target_info *route_info,
228 struct sk_buff *skb)
230 if (route(skb, 0, route_info)!=1)
231 return NF_DROP;
233 if (route_info->flags & IPT_ROUTE_CONTINUE)
234 return IPT_CONTINUE;
236 ip_direct_send(skb);
237 return NF_STOLEN;
240 /* To detect and deter routed packet loopback when using the --tee option,
241 * we take a page out of the raw.patch book: on the copied skb, we set up
242 * a fake ->nfct entry, pointing to the local &route_tee_track. We skip
243 * routing packets when we see they already have that ->nfct.
246 static struct ip_conntrack route_tee_track;
248 static unsigned int ipt_route_target(struct sk_buff **pskb,
249 unsigned int hooknum,
250 const struct net_device *in,
251 const struct net_device *out,
252 const void *targinfo,
253 void *userinfo)
255 const struct ipt_route_target_info *route_info = targinfo;
256 struct sk_buff *skb = *pskb;
257 unsigned int res;
259 /* If we are at PREROUTING or INPUT hook
260 * the TTL isn't decreased by the IP stack
262 if (hooknum == NF_IP_PRE_ROUTING ||
263 hooknum == NF_IP_LOCAL_IN) {
265 struct iphdr *iph = skb->nh.iph;
267 if (iph->ttl <= 1) {
268 struct rtable *rt;
270 if (ip_route_output(&rt, iph->saddr, iph->daddr,
271 RT_TOS(iph->tos) | RTO_CONN,
272 0)) {
273 return NF_DROP;
276 if (skb->dev == rt->u.dst.dev) {
277 /* Drop old route. */
278 dst_release(skb->dst);
279 skb->dst = &rt->u.dst;
281 /* this will traverse normal stack, and
282 * thus call conntrack on the icmp packet */
283 icmp_send(skb, ICMP_TIME_EXCEEDED,
284 ICMP_EXC_TTL, 0);
287 return NF_DROP;
291 * If we are at INPUT the checksum must be recalculated since
292 * the length could change as the result of a defragmentation.
293 * -- Rickard Molin
295 if(hooknum == NF_IP_LOCAL_IN) {
296 iph->ttl = iph->ttl - 1;
297 iph->check = 0;
298 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
299 } else {
300 ip_decrease_ttl(iph);
304 if ((route_info->flags & IPT_ROUTE_TEE)) {
306 * Copy the *pskb, and route the copy. Will later return
307 * IPT_CONTINUE for the original skb, which should continue
308 * on its way as if nothing happened. The copy should be
309 * independantly delivered to the ROUTE --gw.
311 skb = skb_copy(*pskb, GFP_ATOMIC);
312 if (!skb) {
313 if (net_ratelimit())
314 DEBUGP(KERN_DEBUG "ipt_ROUTE: copy failed!\n");
315 return IPT_CONTINUE;
319 /* Tell conntrack to forget this packet since it may get confused
320 * when a packet is leaving with dst address == our address.
321 * Good idea ? Dunno. Need advice.
323 * NEW: mark the skb with our &route_tee_track, so we avoid looping
324 * on any already routed packet.
326 if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
327 nf_conntrack_put(skb->nfct);
328 skb->nfct = &route_tee_track.infos[IP_CT_NEW];
329 nf_conntrack_get(skb->nfct);
330 skb->nfcache = 0;
331 #ifdef CONFIG_NETFILTER_DEBUG
332 skb->nf_debug = 0;
333 #endif
336 if (route_info->oif[0]) {
337 res = route_oif(route_info, skb);
338 } else if (route_info->iif[0]) {
339 res = route_iif(route_info, skb);
340 } else if (route_info->gw) {
341 res = route_gw(route_info, skb);
342 } else {
343 if (net_ratelimit())
344 DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
345 res = IPT_CONTINUE;
348 if ((route_info->flags & IPT_ROUTE_TEE))
349 res = IPT_CONTINUE;
351 return res;
355 static int ipt_route_checkentry(const char *tablename,
356 const struct ipt_entry *e,
357 void *targinfo,
358 unsigned int targinfosize,
359 unsigned int hook_mask)
361 if (strcmp(tablename, "mangle") != 0) {
362 printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
363 tablename);
364 return 0;
367 if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
368 | (1 << NF_IP_LOCAL_IN)
369 | (1 << NF_IP_FORWARD)
370 | (1 << NF_IP_LOCAL_OUT)
371 | (1 << NF_IP_POST_ROUTING))) {
372 printk("ipt_ROUTE: bad hook\n");
373 return 0;
376 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
377 printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
378 targinfosize,
379 IPT_ALIGN(sizeof(struct ipt_route_target_info)));
380 return 0;
383 return 1;
387 static struct ipt_target ipt_route_reg
388 = { { NULL, NULL }, "ROUTE", ipt_route_target, ipt_route_checkentry, NULL,
389 THIS_MODULE };
392 static int __init init(void)
394 /* Set up fake conntrack (stolen from raw.patch):
395 - to never be deleted, not in any hashes */
396 atomic_set(&route_tee_track.ct_general.use, 1);
397 /* - and look it like as a confirmed connection */
398 set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status);
399 /* - and prepare the ctinfo field for REJECT/NAT. */
400 route_tee_track.infos[IP_CT_NEW].master =
401 route_tee_track.infos[IP_CT_RELATED].master =
402 route_tee_track.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
403 &route_tee_track.ct_general;
404 /* Initialize fake conntrack so that NAT will skip it */
405 route_tee_track.nat.info.initialized |=
406 (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
408 if (ipt_register_target(&ipt_route_reg))
409 return -EINVAL;
411 return 0;
415 static void __exit fini(void)
417 ipt_unregister_target(&ipt_route_reg);
420 module_init(init);
421 module_exit(fini);
422 MODULE_LICENSE("GPL");