• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/net/ipv4/netfilter/
1/*
2 * This implements the ROUTE target, which enables you to setup unusual
3 * routes not supported by the standard kernel routing table.
4 *
5 * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
6 * Fixed to compile with kernels >=2.6.24 by m0sia (m0sia@m0sia.ru)
7 *
8 * v 1.12 2009/03/20
9 * This software is distributed under GNU GPL v2, 1991
10 */
11
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/ip.h>
16#include <linux/netfilter_ipv4/ip_tables.h>
17#include <net/netfilter/nf_conntrack.h>
18#include <linux/netfilter_ipv4.h>
19#include <linux/netfilter_ipv4/ipt_ROUTE.h>
20#include <linux/netdevice.h>
21#include <linux/route.h>
22#include <linux/version.h>
23#include <linux/if_arp.h>
24#include <net/ip.h>
25#include <net/route.h>
26#include <net/icmp.h>
27#include <net/checksum.h>
28
29MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>");
31MODULE_DESCRIPTION("iptables ROUTE target module");
32
33/* Try to route the packet according to the routing keys specified in
34 * route_info. Keys are :
35 *  - ifindex :
36 *      0 if no oif preferred,
37 *      otherwise set to the index of the desired oif
38 *  - route_info->gw :
39 *      0 if no gateway specified,
40 *      otherwise set to the next host to which the pkt must be routed
41 * If success, skb->dev is the output device to which the packet must
42 * be sent and skb->dst is not NULL
43 *
44 * RETURN: -1 if an error occured
45 *          1 if the packet was succesfully routed to the
46 *            destination desired
47 *          0 if the kernel routing table could not route the packet
48 *            according to the keys specified
49 */
50static int route(struct sk_buff *skb,
51		 unsigned int ifindex,
52		 const struct ipt_route_target_info *route_info)
53{
54	int err;
55	struct rtable *rt;
56	struct iphdr *iph = ip_hdr(skb);
57	struct flowi fl = {
58		.oif = ifindex,
59		.nl_u = {
60			.ip4_u = {
61				.daddr = iph->daddr,
62				.saddr = 0,
63				.tos = RT_TOS(iph->tos),
64				.scope = RT_SCOPE_UNIVERSE,
65			}
66		}
67	};
68
69	/* The destination address may be overloaded by the target */
70	if (route_info->gw)
71		fl.fl4_dst = route_info->gw;
72
73	/* Trying to route the packet using the standard routing table. */
74	if ((err = ip_route_output_key(&init_net,&rt, &fl))) {
75		if (net_ratelimit())
76			pr_debug("ipt_ROUTE: couldn't route pkt (err: %i)",err);
77		return -1;
78	}
79
80	/* Drop old route. */
81	skb_dst_drop(skb);
82
83	/* Success if no oif specified or if the oif correspond to the
84	 * one desired */
85	if (!ifindex || rt->dst.dev->ifindex == ifindex) {
86		skb_dst_set(skb, &rt->dst);
87		skb->dev = skb_dst(skb)->dev;
88		skb->protocol = htons(ETH_P_IP);
89		return 1;
90	}
91
92	/* The interface selected by the routing table is not the one
93	 * specified by the user. This may happen because the dst address
94	 * is one of our own addresses.
95	 */
96	if (net_ratelimit())
97		pr_debug("ipt_ROUTE: failed to route as desired gw, oif=%i (got oif=%i)\n",
98		//pr_debug("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n",
99		       ifindex, rt->dst.dev->ifindex);
100		       //NIPQUAD(route_info->gw), ifindex, rt->dst.dev->ifindex);
101
102	return 0;
103}
104
105
106/* Stolen from ip_finish_output2
107 * PRE : skb->dev is set to the device we are leaving by
108 *       skb->dst is not NULL
109 * POST: the packet is sent with the link layer header pushed
110 *       the packet is destroyed
111 */
112static void ip_direct_send(struct sk_buff *skb)
113{
114	struct dst_entry *dst = skb_dst(skb);
115	struct hh_cache *hh = dst->hh;
116	struct net_device *dev = dst->dev;
117	int hh_len = LL_RESERVED_SPACE(dev);
118
119	/* Be paranoid, rather than too clever. */
120	if (unlikely(skb_headroom(skb) < hh_len )) {
121		struct sk_buff *skb2;
122
123		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
124		if (skb2 == NULL) {
125			kfree_skb(skb);
126			return;
127		}
128		if (skb->sk)
129			skb_set_owner_w(skb2, skb->sk);
130		kfree_skb(skb);
131		skb = skb2;
132	}
133
134	if (hh) {
135		int hh_alen;
136
137		write_seqlock_bh(&hh->hh_lock);
138		hh_alen = HH_DATA_ALIGN(hh->hh_len);
139		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
140		write_sequnlock_bh(&hh->hh_lock);
141		skb_push(skb, hh->hh_len);
142		hh->hh_output(skb);
143	} else if (dst->neighbour)
144		dst->neighbour->output(skb);
145	else {
146		if (net_ratelimit())
147			pr_debug(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
148		kfree_skb(skb);
149	}
150}
151
152
153/* PRE : skb->dev is set to the device we are leaving by
154 * POST: - the packet is directly sent to the skb->dev device, without
155 *         pushing the link layer header.
156 *       - the packet is destroyed
157 */
158static inline int dev_direct_send(struct sk_buff *skb)
159{
160	return dev_queue_xmit(skb);
161}
162
163
164static unsigned int route_oif(const struct ipt_route_target_info *route_info,
165			      struct sk_buff *skb)
166{
167	unsigned int ifindex = 0;
168	struct net_device *dev_out = NULL;
169
170	/* The user set the interface name to use.
171	 * Getting the current interface index.
172	 */
173	if ((dev_out = dev_get_by_name(&init_net,route_info->oif))) {
174		ifindex = dev_out->ifindex;
175	} else {
176		/* Unknown interface name : packet dropped */
177		if (net_ratelimit())
178			pr_debug("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
179		return NF_DROP;
180	}
181
182	/* Trying the standard way of routing packets */
183	switch (route(skb, ifindex, route_info)) {
184	case 1:
185		dev_put(dev_out);
186		if (route_info->flags & IPT_ROUTE_CONTINUE)
187			return IPT_CONTINUE;
188
189		ip_direct_send(skb);
190		return NF_STOLEN;
191
192	case 0:
193		/* Failed to send to oif. Trying the hard way */
194		if (route_info->flags & IPT_ROUTE_CONTINUE)
195			return NF_DROP;
196
197		if (net_ratelimit())
198			pr_debug("ipt_ROUTE: forcing the use of %i\n",
199			       ifindex);
200
201		/* We have to force the use of an interface.
202		 * This interface must be a tunnel interface since
203		 * otherwise we can't guess the hw address for
204		 * the packet. For a tunnel interface, no hw address
205		 * is needed.
206		 */
207		if ((dev_out->type != ARPHRD_TUNNEL)
208		    && (dev_out->type != ARPHRD_IPGRE)) {
209			if (net_ratelimit())
210				pr_debug("ipt_ROUTE: can't guess the hw addr !\n");
211			dev_put(dev_out);
212			return NF_DROP;
213		}
214
215		/* Send the packet. This will also free skb
216		 * Do not go through the POST_ROUTING hook because
217		 * skb->dst is not set and because it will probably
218		 * get confused by the destination IP address.
219		 */
220		skb->dev = dev_out;
221		dev_direct_send(skb);
222		dev_put(dev_out);
223		return NF_STOLEN;
224
225	default:
226		/* Unexpected error */
227		dev_put(dev_out);
228		return NF_DROP;
229	}
230}
231
232
233static unsigned int route_iif(const struct ipt_route_target_info *route_info,
234			      struct sk_buff *skb)
235{
236	struct net_device *dev_in = NULL;
237
238	/* Getting the current interface index. */
239	if (!(dev_in = dev_get_by_name(&init_net,route_info->iif))) {
240		if (net_ratelimit())
241			pr_debug("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
242		return NF_DROP;
243	}
244
245	skb->dev = dev_in;
246	skb_dst_drop(skb);
247
248	netif_rx(skb);
249	dev_put(dev_in);
250	return NF_STOLEN;
251}
252
253
254static unsigned int route_gw(const struct ipt_route_target_info *route_info,
255			     struct sk_buff *skb)
256{
257	if (route(skb, 0, route_info)!=1)
258		return NF_DROP;
259
260	if (route_info->flags & IPT_ROUTE_CONTINUE)
261		return IPT_CONTINUE;
262
263	ip_direct_send(skb);
264	return NF_STOLEN;
265}
266
267
268/* To detect and deter routed packet loopback when using the --tee option,
269 * we take a page out of the raw.patch book: on the copied skb, we set up
270 * a fake ->nfct entry, pointing to the local &route_tee_track. We skip
271 * routing packets when we see they already have that ->nfct.
272 */
273
274static struct nf_conn route_tee_track;
275
276static unsigned int ipt_route_target(struct sk_buff *skb,
277				     const struct xt_action_param *par)
278{
279	const struct ipt_route_target_info *route_info = par->targinfo;
280	//struct sk_buff *skb = *pskb;
281	unsigned int res;
282
283	if (skb->nfct == &route_tee_track.ct_general) {
284		/* Loopback - a packet we already routed, is to be
285		 * routed another time. Avoid that, now.
286		 */
287		if (net_ratelimit())
288			pr_debug(KERN_DEBUG "ipt_ROUTE: loopback - DROP!\n");
289		return NF_DROP;
290	}
291
292	/* If we are at PREROUTING or INPUT hook
293	 * the TTL isn't decreased by the IP stack
294	 */
295	if (par->hooknum == NF_INET_PRE_ROUTING ||
296	    par->hooknum == NF_INET_LOCAL_IN) {
297
298		struct iphdr *iph = ip_hdr(skb);
299
300		if (iph->ttl <= 1) {
301			struct rtable *rt;
302			struct flowi fl = {
303				.oif = 0,
304				.nl_u = {
305					.ip4_u = {
306						.daddr = iph->daddr,
307						.saddr = iph->saddr,
308						.tos = RT_TOS(iph->tos),
309						.scope = ((iph->tos & RTO_ONLINK) ?
310							  RT_SCOPE_LINK :
311							  RT_SCOPE_UNIVERSE)
312					}
313				}
314			};
315
316			if (ip_route_output_key(&init_net,&rt, &fl)) {
317				return NF_DROP;
318			}
319
320			if (skb->dev == rt->dst.dev) {
321				/* Drop old route. */
322				skb_dst_set(skb, &rt->dst);
323
324				/* this will traverse normal stack, and
325				 * thus call conntrack on the icmp packet */
326				icmp_send(skb, ICMP_TIME_EXCEEDED,
327					  ICMP_EXC_TTL, 0);
328			}
329
330			return NF_DROP;
331		}
332
333		/*
334		 * If we are at INPUT the checksum must be recalculated since
335		 * the length could change as the result of a defragmentation.
336		 */
337		if(par->hooknum == NF_INET_LOCAL_IN) {
338			iph->ttl = iph->ttl - 1;
339			iph->check = 0;
340			iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
341		} else {
342			ip_decrease_ttl(iph);
343		}
344	}
345
346	if ((route_info->flags & IPT_ROUTE_TEE)) {
347		/*
348		 * Copy the *pskb, and route the copy. Will later return
349		 * IPT_CONTINUE for the original skb, which should continue
350		 * on its way as if nothing happened. The copy should be
351		 * independantly delivered to the ROUTE --gw.
352		 */
353		skb = skb_copy(skb, GFP_ATOMIC);
354		if (!skb) {
355			if (net_ratelimit())
356				pr_debug(KERN_DEBUG "ipt_ROUTE: copy failed!\n");
357			return IPT_CONTINUE;
358		}
359	}
360
361	/* Tell conntrack to forget this packet since it may get confused
362	 * when a packet is leaving with dst address == our address.
363	 * Good idea ? Dunno. Need advice.
364	 *
365	 * NEW: mark the skb with our &route_tee_track, so we avoid looping
366	 * on any already routed packet.
367	 */
368	if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
369		nf_conntrack_put(skb->nfct);
370		skb->nfct = &route_tee_track.ct_general;
371		skb->nfctinfo = IP_CT_NEW;
372		nf_conntrack_get(skb->nfct);
373	}
374
375	if (route_info->oif[0] != '\0') {
376		res = route_oif(route_info, skb);
377	} else if (route_info->iif[0] != '\0') {
378		res = route_iif(route_info, skb);
379	} else if (route_info->gw) {
380		res = route_gw(route_info, skb);
381	} else {
382		if (net_ratelimit())
383			pr_debug(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
384		res = IPT_CONTINUE;
385	}
386
387	if ((route_info->flags & IPT_ROUTE_TEE))
388		res = IPT_CONTINUE;
389
390	return res;
391}
392static int ipt_route_checkentry(const struct xt_tgchk_param *par)
393{
394	return 0;
395}
396
397
398static struct ipt_target ipt_route_reg = {
399	.name = "ROUTE",
400	.family	= AF_INET,
401	.target = ipt_route_target,
402	.targetsize = sizeof(struct ipt_route_target_info),
403	.checkentry = ipt_route_checkentry,
404	.table	= "mangle",
405	.hooks	= 1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN | 1 << NF_INET_FORWARD | 1 << NF_INET_LOCAL_OUT | 1 << NF_INET_POST_ROUTING,
406	.me = THIS_MODULE,
407};
408
409static int __init init(void)
410{
411	/* Set up fake conntrack (stolen from raw.patch):
412	    - to never be deleted, not in any hashes */
413	atomic_set(&route_tee_track.ct_general.use, 1);
414	/*  - and look it like as a confirmed connection */
415	set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status);
416	/* Initialize fake conntrack so that NAT will skip it */
417	route_tee_track.status |= IPS_NAT_DONE_MASK;
418
419	return xt_register_target(&ipt_route_reg);
420}
421
422
423static void __exit fini(void)
424{
425	xt_unregister_target(&ipt_route_reg);
426}
427
428module_init(init);
429module_exit(fini);
430