* Re: [PATCH 06/13]: [IPV4/6]: Netfilter IPsec input hooks
From: Yasuyuki KOZAKAI @ 2005-11-21 4:42 UTC (permalink / raw)
To: kaber; +Cc: netdev, netfilter-devel, davem
In-Reply-To: <20051120163135.16666.76993.sendpatchset@localhost.localdomain>
Hi, Patrick,
From: Patrick McHardy <kaber@trash.net>
Date: Sun, 20 Nov 2005 17:31:36 +0100
> [IPV4/6]: Netfilter IPsec input hooks
>
> When the innermost transform uses transport mode the decapsulated packet
> is not visible to netfilter. Pass the packet through the PRE_ROUTING and
> LOCAL_IN hooks again before handing it to upper layer protocols to make
> netfilter-visibility symetrical to the output path.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
At first, now I could agree to use same name for hooks before/after xfrm
processing, if it's important to keep compatibility than to avoid difficulty
to use. Even now I think it's confusing to pass packets before/after xfrm to
same hook, and believe it's ideal to use different name for them.
But people can configure correctly according to you, then my concern might be
needless fear.
Next is about re-visiting stack, I'm beginning to understand your patch.
It looks natural to re-route after DNAT on input path of IPv4. That's really
needed if packets have been mangled.
But is there any reason that we have to allow packets to re-visit
ip_local_deliver_finish() in the case that they have not been mangled
at PRE_ROUTING ? I think no. This situation is like ip_nat_out().
And this can be said about IPv6 input path. If packets have not been mangled
(this is ordinary case because ip6tables doesn't have neither NAT nor
target module to mangle addresses directly), they don't have to re-route
and don't have to re-visit ip6_input_finish().
In the other way, if their addresses have been mangled, it's necessary to
re-route. I agree re-visiting ip6_input_finish() in this case.
Then, why don't we make xfrm{4,6}_rcv_spi() return 0 (1 if IPv6)
so that ip_local_deliver_finish()/ip6_input_finish() can continue to process
headers if packets have not been mangled ? Is this difficult or impossible to
implement ?
This can solve the issue about twice processing of statistics and IPv6
extension headers. Because ip_local_deliver_finish()/ip6_input_finish() can
continue to process extension headers after ESP/AH in ordinary case.
In special case, if some codes mangle IPv6 addresses, that's the codes
to take care of the possibility of re-visiting ip6_input_finish().
What do you think ?
# Please note that these are just my opinions and other USAGI guys might have
# other opinions.
Regards,
-- Yasuyuki Kozakai
^ permalink raw reply
* Judgement Processing Professional. High $ income
From: isaac hall @ 2005-11-20 23:33 UTC (permalink / raw)
To: Kimberlee Montgomery; +Cc: outgoing, netdev, fam-bounce
Hi Kim,
Before I joined you I found myself let go from a job I held for 26 years. I
can't thank you enough for introducting me in this business. You have given
me a bright lease on life. Already earning twice as much as I earned in my
old job.
I drive a 2005 Jaguar S Type. Taking home 6 digit level in 18 months.
Really having a ball in this business. It is fun and I am a hero to the
courts and to my clients. What an exciting job to be in.
Doing exactly what your training tells me to do, is working beautifully. I
go to the court and locate all of the clients I can handle.
I utilize your advanced reporting services to find all assets and
employment. Using your fill in the blank forms I send them out to the
appropriate firms. Then the funds arrive to my PO Box. Its like magic. I
love it.
I can take a holiday when ever I have a whim to do so. Hawaii and a 1050
footer to the Panama Canal etc. this year.
Please show this letter to others. This profession is so big it needs many
more of us assisting the courts and the people who have been damaged.
Sincerely,
Jesus A. Ohio
This could be you!
Go to our site below where we provide you more indepth details about our
system at 0 outlay or obligation. You do not have a thing to lose and lots
to gain.
http://it.geocities.com/woodsjeromue/?2=r.Challenge your brain. High $
Income
The soldiers made thrusts at him with their weapons, and an officer jabbed
at his breast with a glittering sword, but the Garment of Repulsion
protected him from these dangers as well as from a hail of bullets that
followed his advancing figure. He reached the entrance of the palace only to
face another group of guardsmen and a second order to halt, and as these
soldiers were over six feet tall and stood shoulder to shoulder Rob saw that
he could not hope to pass them without using his electric tube
Stand aside, you fellows! he ordered
Above to learn more or to bring an end to receiving more info and then to
see location
^ permalink raw reply
* [2.6 patch] kill drivers/net/irda/sir_core.c
From: Adrian Bunk @ 2005-11-20 23:29 UTC (permalink / raw)
To: Jean Tourrilhes; +Cc: jgarzik, netdev, linux-kernel
EXPORT_SYMBOL's do nowadays belong to the files where the actual
functions are.
Moving the module_init/module_exit to the file with the actual functions
has the advantage of saving a few bytes due to the removal of two
functions.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
drivers/net/irda/Makefile | 2 -
drivers/net/irda/sir-dev.h | 2 -
drivers/net/irda/sir_core.c | 56 ---------------------------------
drivers/net/irda/sir_dev.c | 10 +++++
drivers/net/irda/sir_dongle.c | 2 +
drivers/net/irda/sir_kthread.c | 11 +++++-
6 files changed, 21 insertions(+), 62 deletions(-)
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/Makefile.old 2005-11-20 20:22:17.000000000 +0100
+++ linux-2.6.15-rc1-mm2-full/drivers/net/irda/Makefile 2005-11-20 20:22:24.000000000 +0100
@@ -45,4 +45,4 @@
obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o
# The SIR helper module
-sir-dev-objs := sir_core.o sir_dev.o sir_dongle.o sir_kthread.o
+sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir-dev.h.old 2005-11-20 20:18:25.000000000 +0100
+++ linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir-dev.h 2005-11-20 20:18:37.000000000 +0100
@@ -133,8 +133,6 @@
extern void sirdev_enable_rx(struct sir_dev *dev);
extern int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param);
-extern int __init irda_thread_create(void);
-extern void __exit irda_thread_join(void);
/* inline helpers */
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_kthread.c.old 2005-11-20 20:18:47.000000000 +0100
+++ linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_kthread.c 2005-11-20 20:42:21.000000000 +0100
@@ -466,7 +466,7 @@
return 0;
}
-int __init irda_thread_create(void)
+static int __init irda_thread_create(void)
{
struct completion startup;
int pid;
@@ -488,7 +488,7 @@
return 0;
}
-void __exit irda_thread_join(void)
+static void __exit irda_thread_join(void)
{
if (irda_rq_queue.thread) {
flush_irda_queue();
@@ -499,3 +499,10 @@
}
}
+module_init(irda_thread_create);
+module_exit(irda_thread_join);
+
+MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>");
+MODULE_DESCRIPTION("IrDA SIR core");
+MODULE_LICENSE("GPL");
+
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_dongle.c.old 2005-11-20 20:21:23.000000000 +0100
+++ linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_dongle.c 2005-11-20 20:22:02.000000000 +0100
@@ -50,6 +50,7 @@
up(&dongle_list_lock);
return 0;
}
+EXPORT_SYMBOL(irda_register_dongle);
int irda_unregister_dongle(struct dongle_driver *drv)
{
@@ -58,6 +59,7 @@
up(&dongle_list_lock);
return 0;
}
+EXPORT_SYMBOL(irda_unregister_dongle);
int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
{
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_dev.c.old 2005-11-20 20:22:37.000000000 +0100
+++ linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_dev.c 2005-11-20 20:24:00.000000000 +0100
@@ -60,6 +60,7 @@
up(&dev->fsm.sem);
return err;
}
+EXPORT_SYMBOL(sirdev_set_dongle);
/* used by dongle drivers for dongle programming */
@@ -94,6 +95,7 @@
spin_unlock_irqrestore(&dev->tx_lock, flags);
return ret;
}
+EXPORT_SYMBOL(sirdev_raw_write);
/* seems some dongle drivers may need this */
@@ -116,6 +118,7 @@
return count;
}
+EXPORT_SYMBOL(sirdev_raw_read);
int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts)
{
@@ -124,7 +127,8 @@
ret = dev->drv->set_dtr_rts(dev, dtr, rts);
return ret;
}
-
+EXPORT_SYMBOL(sirdev_set_dtr_rts);
+
/**********************************************************************/
/* called from client driver - likely with bh-context - to indicate
@@ -227,6 +231,7 @@
done:
spin_unlock_irqrestore(&dev->tx_lock, flags);
}
+EXPORT_SYMBOL(sirdev_write_complete);
/* called from client driver - likely with bh-context - to give us
* some more received bytes. We put them into the rx-buffer,
@@ -279,6 +284,7 @@
return 0;
}
+EXPORT_SYMBOL(sirdev_receive);
/**********************************************************************/
@@ -641,6 +647,7 @@
out:
return NULL;
}
+EXPORT_SYMBOL(sirdev_get_instance);
int sirdev_put_instance(struct sir_dev *dev)
{
@@ -673,4 +680,5 @@
return 0;
}
+EXPORT_SYMBOL(sirdev_put_instance);
--- linux-2.6.15-rc1-mm2-full/drivers/net/irda/sir_core.c 2005-11-20 20:24:09.000000000 +0100
+++ /dev/null 2005-11-08 19:07:57.000000000 +0100
@@ -1,56 +0,0 @@
-/*********************************************************************
- *
- * sir_core.c: module core for irda-sir abstraction layer
- *
- * Copyright (c) 2002 Martin Diehl
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-
-#include "sir-dev.h"
-
-/***************************************************************************/
-
-MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>");
-MODULE_DESCRIPTION("IrDA SIR core");
-MODULE_LICENSE("GPL");
-
-/***************************************************************************/
-
-EXPORT_SYMBOL(irda_register_dongle);
-EXPORT_SYMBOL(irda_unregister_dongle);
-
-EXPORT_SYMBOL(sirdev_get_instance);
-EXPORT_SYMBOL(sirdev_put_instance);
-
-EXPORT_SYMBOL(sirdev_set_dongle);
-EXPORT_SYMBOL(sirdev_write_complete);
-EXPORT_SYMBOL(sirdev_receive);
-
-EXPORT_SYMBOL(sirdev_raw_write);
-EXPORT_SYMBOL(sirdev_raw_read);
-EXPORT_SYMBOL(sirdev_set_dtr_rts);
-
-static int __init sir_core_init(void)
-{
- return irda_thread_create();
-}
-
-static void __exit sir_core_exit(void)
-{
- irda_thread_join();
-}
-
-module_init(sir_core_init);
-module_exit(sir_core_exit);
-
^ permalink raw reply
* Re: [PATCH -mm2] net: Fix compiler-error on dgrs.c when !CONFIG_PCI
From: Herbert Xu @ 2005-11-20 20:40 UTC (permalink / raw)
To: Richard Knutsson; +Cc: akpm, linux-kernel, netdev, jgarzik, ashutosh.naik
In-Reply-To: <438097D2.9020607@student.ltu.se>
On Sun, Nov 20, 2005 at 04:35:46PM +0100, Richard Knutsson wrote:
>
> >-#ifdef CONFIG_EISA
> >- cardcount = eisa_driver_register(&dgrs_eisa_driver);
> >+ cardcount = dgrs_register_eisa();
> > if (cardcount < 0)
> > return cardcount;
> >-#endif
> >- cardcount = pci_register_driver(&dgrs_pci_driver);
> >- if (cardcount)
> >+ cardcount = dgrs_register_pci();
> >+ if (cardcount < 0) {
> Are you sure it should be "cardcount < 0" and not "cardcount"?
Yes if cardcount is >= 0 then the registration was successful.
> >+ dgrs_unregister_eisa();
> Why change the behaviour off this driver?
Because the driver was buggy. When this function returns a non-zero
value, it must return the system to its original state.
That means if the EISA driver has already been registered then it must
be unregistered.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH 00/13]: Netfilter IPsec support
From: Patrick McHardy @ 2005-11-20 18:07 UTC (permalink / raw)
To: jplatte; +Cc: netdev, netfilter-devel, davem
In-Reply-To: <200511201902.10179.lists@naasa.net>
Joerg Platte wrote:
> Am Sonntag, 20. November 2005 17:31 schrieb Patrick McHardy:
> Hi!
>
>>- policy lookups after NAT:
>>
>>When NAT changes a packet it already calls ip_route_me_harder, which
>>reroutes the packet and does a new policy lookup. It only looks at
>>the IP addresses however, changing the port numbers require a new
>>policy lookup as well. It also doesn't reroute in POST_ROUTING, since
>>the packet has already been routed. To behave more like a regular
>>tunnel device a policy lookup is now also done after SNAT and the
>>packet is passed to dst_output again if the lookup yielded a new
>>policy.
>
> I suppose, this is the reason, why masqueraded packages leave a recent kernel
> unencrypted, even if they would match the policy. It's still not implemented
> in mainline. Am I right? If yes, I hope your patches will be merged as soon
> as possible :-)
You're right, that's the reason. Since the patches touch quite a lot of
code they won't make it in 2.6.15, though.
^ permalink raw reply
* Re: [PATCH 09/13]: [NETFILTER]: Redo policy lookups after NAT when neccessary
From: Patrick McHardy @ 2005-11-20 16:43 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel
In-Reply-To: <20051120163139.16666.30437.sendpatchset@localhost.localdomain>
Patrick McHardy wrote:
> [NETFILTER]: Redo policy lookups after NAT when neccessary
>
> --- a/net/ipv4/ip_output.c
> +++ b/net/ipv4/ip_output.c
> @@ -195,13 +195,18 @@ static inline int ip_finish_output2(stru
> return dst->neighbour->output(skb);
>
> if (net_ratelimit())
> - printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
> + printk(KERN_DEBUG "ip_finish_output3: No header cache and no neighbour!\n");
> kfree_skb(skb);
> return -EINVAL;
> }
Damnit .. if you apply the patches please edit out this chunk,
its a remnant from an earlier series.
Thanks.
^ permalink raw reply
* [PATCH 13/13]: [NETFILTER]: Add ipt_policy/ip6t_policy matches
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Add ipt_policy/ip6t_policy matches
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit ff88b88efc987d1267eccf01e16880458d189a25
tree 53c34259c195cf64903940f151becd967bcce74d
parent 055c50b770e63ced784808ae22ef339724b1a44c
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:10:02 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:10:02 +0100
include/linux/netfilter_ipv4/ipt_policy.h | 52 ++++++++
include/linux/netfilter_ipv6/ip6t_policy.h | 52 ++++++++
net/ipv4/netfilter/Kconfig | 10 ++
net/ipv4/netfilter/Makefile | 1
net/ipv4/netfilter/ipt_policy.c | 170 +++++++++++++++++++++++++++
net/ipv6/netfilter/Kconfig | 10 ++
net/ipv6/netfilter/Makefile | 1
net/ipv6/netfilter/ip6t_policy.c | 175 ++++++++++++++++++++++++++++
8 files changed, 471 insertions(+), 0 deletions(-)
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h
new file mode 100644
index 0000000..7fd1bec
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_policy.h
@@ -0,0 +1,52 @@
+#ifndef _IPT_POLICY_H
+#define _IPT_POLICY_H
+
+#define IPT_POLICY_MAX_ELEM 4
+
+enum ipt_policy_flags
+{
+ IPT_POLICY_MATCH_IN = 0x1,
+ IPT_POLICY_MATCH_OUT = 0x2,
+ IPT_POLICY_MATCH_NONE = 0x4,
+ IPT_POLICY_MATCH_STRICT = 0x8,
+};
+
+enum ipt_policy_modes
+{
+ IPT_POLICY_MODE_TRANSPORT,
+ IPT_POLICY_MODE_TUNNEL
+};
+
+struct ipt_policy_spec
+{
+ u_int8_t saddr:1,
+ daddr:1,
+ proto:1,
+ mode:1,
+ spi:1,
+ reqid:1;
+};
+
+struct ipt_policy_elem
+{
+ u_int32_t saddr;
+ u_int32_t smask;
+ u_int32_t daddr;
+ u_int32_t dmask;
+ u_int32_t spi;
+ u_int32_t reqid;
+ u_int8_t proto;
+ u_int8_t mode;
+
+ struct ipt_policy_spec match;
+ struct ipt_policy_spec invert;
+};
+
+struct ipt_policy_info
+{
+ struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM];
+ u_int16_t flags;
+ u_int16_t len;
+};
+
+#endif /* _IPT_POLICY_H */
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h
new file mode 100644
index 0000000..5a93afc
--- /dev/null
+++ b/include/linux/netfilter_ipv6/ip6t_policy.h
@@ -0,0 +1,52 @@
+#ifndef _IP6T_POLICY_H
+#define _IP6T_POLICY_H
+
+#define IP6T_POLICY_MAX_ELEM 4
+
+enum ip6t_policy_flags
+{
+ IP6T_POLICY_MATCH_IN = 0x1,
+ IP6T_POLICY_MATCH_OUT = 0x2,
+ IP6T_POLICY_MATCH_NONE = 0x4,
+ IP6T_POLICY_MATCH_STRICT = 0x8,
+};
+
+enum ip6t_policy_modes
+{
+ IP6T_POLICY_MODE_TRANSPORT,
+ IP6T_POLICY_MODE_TUNNEL
+};
+
+struct ip6t_policy_spec
+{
+ u_int8_t saddr:1,
+ daddr:1,
+ proto:1,
+ mode:1,
+ spi:1,
+ reqid:1;
+};
+
+struct ip6t_policy_elem
+{
+ struct in6_addr saddr;
+ struct in6_addr smask;
+ struct in6_addr daddr;
+ struct in6_addr dmask;
+ u_int32_t spi;
+ u_int32_t reqid;
+ u_int8_t proto;
+ u_int8_t mode;
+
+ struct ip6t_policy_spec match;
+ struct ip6t_policy_spec invert;
+};
+
+struct ip6t_policy_info
+{
+ struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM];
+ u_int16_t flags;
+ u_int16_t len;
+};
+
+#endif /* _IP6T_POLICY_H */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 9d3c8b5..5e8189f 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -487,6 +487,16 @@ config IP_NF_MATCH_STRING
To compile it as a module, choose M here. If unsure, say N.
+config IP_NF_MATCH_POLICY
+ tristate "IPsec policy match support"
+ depends on IP_NF_IPTABLES && XFRM
+ help
+ Policy matching allows you to match packets based on the
+ IPsec policy that was used during decapsulation/will
+ be used during encapsulation.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# `filter', generic and specific targets
config IP_NF_FILTER
tristate "Packet filtering"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 058c48e..2202517 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_
obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
+obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
new file mode 100644
index 0000000..709debc
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -0,0 +1,170 @@
+/* IP tables module for matching IPsec policy
+ *
+ * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <net/xfrm.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_policy.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
+MODULE_LICENSE("GPL");
+
+
+static inline int
+match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
+{
+#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
+
+ return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
+ MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+ MATCH(proto, x->id.proto) &&
+ MATCH(mode, x->props.mode) &&
+ MATCH(spi, x->id.spi) &&
+ MATCH(reqid, x->props.reqid);
+}
+
+static int
+match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
+{
+ const struct ipt_policy_elem *e;
+ struct sec_path *sp = skb->sp;
+ int strict = info->flags & IPT_POLICY_MATCH_STRICT;
+ int i, pos;
+
+ if (sp == NULL)
+ return -1;
+ if (strict && info->len != sp->len)
+ return 0;
+
+ for (i = sp->len - 1; i >= 0; i--) {
+ pos = strict ? i - sp->len + 1 : 0;
+ if (pos >= info->len)
+ return 0;
+ e = &info->pol[pos];
+
+ if (match_xfrm_state(sp->x[i].xvec, e)) {
+ if (!strict)
+ return 1;
+ } else if (strict)
+ return 0;
+ }
+
+ return strict ? 1 : 0;
+}
+
+static int
+match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
+{
+ const struct ipt_policy_elem *e;
+ struct dst_entry *dst = skb->dst;
+ int strict = info->flags & IPT_POLICY_MATCH_STRICT;
+ int i, pos;
+
+ if (dst->xfrm == NULL)
+ return -1;
+
+ for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
+ pos = strict ? i : 0;
+ if (pos >= info->len)
+ return 0;
+ e = &info->pol[pos];
+
+ if (match_xfrm_state(dst->xfrm, e)) {
+ if (!strict)
+ return 1;
+ } else if (strict)
+ return 0;
+ }
+
+ return strict ? 1 : 0;
+}
+
+static int match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *matchinfo, int offset, int *hotdrop)
+{
+ const struct ipt_policy_info *info = matchinfo;
+ int ret;
+
+ if (info->flags & IPT_POLICY_MATCH_IN)
+ ret = match_policy_in(skb, info);
+ else
+ ret = match_policy_out(skb, info);
+
+ if (ret < 0)
+ ret = info->flags & IPT_POLICY_MATCH_NONE ? 1 : 0;
+ else if (info->flags & IPT_POLICY_MATCH_NONE)
+ ret = 0;
+
+ return ret;
+}
+
+static int checkentry(const char *tablename, const struct ipt_ip *ip,
+ void *matchinfo, unsigned int matchsize,
+ unsigned int hook_mask)
+{
+ struct ipt_policy_info *info = matchinfo;
+
+ if (matchsize != IPT_ALIGN(sizeof(*info))) {
+ printk(KERN_ERR "ipt_policy: matchsize %u != %zu\n",
+ matchsize, IPT_ALIGN(sizeof(*info)));
+ return 0;
+ }
+ if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) {
+ printk(KERN_ERR "ipt_policy: neither incoming nor "
+ "outgoing policy selected\n");
+ return 0;
+ }
+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+ && info->flags & IPT_POLICY_MATCH_OUT) {
+ printk(KERN_ERR "ipt_policy: output policy not valid in "
+ "PRE_ROUTING and INPUT\n");
+ return 0;
+ }
+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+ && info->flags & IPT_POLICY_MATCH_IN) {
+ printk(KERN_ERR "ipt_policy: input policy not valid in "
+ "POST_ROUTING and OUTPUT\n");
+ return 0;
+ }
+ if (info->len > IPT_POLICY_MAX_ELEM) {
+ printk(KERN_ERR "ipt_policy: too many policy elements\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ipt_match policy_match = {
+ .name = "policy",
+ .match = match,
+ .checkentry = checkentry,
+ .me = THIS_MODULE,
+};
+
+static int __init init(void)
+{
+ return ipt_register_match(&policy_match);
+}
+
+static void __exit fini(void)
+{
+ ipt_unregister_match(&policy_match);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 060d612..96eae96 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -179,6 +179,16 @@ config IP6_NF_MATCH_PHYSDEV
To compile it as a module, choose M here. If unsure, say N.
+config IP6_NF_MATCH_POLICY
+ tristate "IPsec policy match support"
+ depends on IP6_NF_IPTABLES && XFRM
+ help
+ Policy matching allows you to match packets based on the
+ IPsec policy that was used during decapsulation/will
+ be used during encapsulation.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# The targets
config IP6_NF_FILTER
tristate "Packet filtering"
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 9ab5b2c..c0c809b 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
+obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
new file mode 100644
index 0000000..13fedad
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -0,0 +1,175 @@
+/* IP tables module for matching IPsec policy
+ *
+ * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <net/xfrm.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_policy.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
+MODULE_LICENSE("GPL");
+
+
+static inline int
+match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
+{
+#define MATCH_ADDR(x,y,z) (!e->match.x || \
+ ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
+#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
+
+ return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
+ MATCH_ADDR(daddr, dmask, (struct in6_addr *)&x->id.daddr.a6) &&
+ MATCH(proto, x->id.proto) &&
+ MATCH(mode, x->props.mode) &&
+ MATCH(spi, x->id.spi) &&
+ MATCH(reqid, x->props.reqid);
+}
+
+static int
+match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info)
+{
+ const struct ip6t_policy_elem *e;
+ struct sec_path *sp = skb->sp;
+ int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
+ int i, pos;
+
+ if (sp == NULL)
+ return -1;
+ if (strict && info->len != sp->len)
+ return 0;
+
+ for (i = sp->len - 1; i >= 0; i--) {
+ pos = strict ? i - sp->len + 1 : 0;
+ if (pos >= info->len)
+ return 0;
+ e = &info->pol[pos];
+
+ if (match_xfrm_state(sp->x[i].xvec, e)) {
+ if (!strict)
+ return 1;
+ } else if (strict)
+ return 0;
+ }
+
+ return strict ? 1 : 0;
+}
+
+static int
+match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
+{
+ const struct ip6t_policy_elem *e;
+ struct dst_entry *dst = skb->dst;
+ int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
+ int i, pos;
+
+ if (dst->xfrm == NULL)
+ return -1;
+
+ for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
+ pos = strict ? i : 0;
+ if (pos >= info->len)
+ return 0;
+ e = &info->pol[pos];
+
+ if (match_xfrm_state(dst->xfrm, e)) {
+ if (!strict)
+ return 1;
+ } else if (strict)
+ return 0;
+ }
+
+ return strict ? 1 : 0;
+}
+
+static int match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *matchinfo,
+ int offset,
+ unsigned int protoff,
+ int *hotdrop)
+{
+ const struct ip6t_policy_info *info = matchinfo;
+ int ret;
+
+ if (info->flags & IP6T_POLICY_MATCH_IN)
+ ret = match_policy_in(skb, info);
+ else
+ ret = match_policy_out(skb, info);
+
+ if (ret < 0)
+ ret = info->flags & IP6T_POLICY_MATCH_NONE ? 1 : 0;
+ else if (info->flags & IP6T_POLICY_MATCH_NONE)
+ ret = 0;
+
+ return ret;
+}
+
+static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+ void *matchinfo, unsigned int matchsize,
+ unsigned int hook_mask)
+{
+ struct ip6t_policy_info *info = matchinfo;
+
+ if (matchsize != IP6T_ALIGN(sizeof(*info))) {
+ printk(KERN_ERR "ip6t_policy: matchsize %u != %zu\n",
+ matchsize, IP6T_ALIGN(sizeof(*info)));
+ return 0;
+ }
+ if (!(info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT))) {
+ printk(KERN_ERR "ip6t_policy: neither incoming nor "
+ "outgoing policy selected\n");
+ return 0;
+ }
+ if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN)
+ && info->flags & IP6T_POLICY_MATCH_OUT) {
+ printk(KERN_ERR "ip6t_policy: output policy not valid in "
+ "PRE_ROUTING and INPUT\n");
+ return 0;
+ }
+ if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT)
+ && info->flags & IP6T_POLICY_MATCH_IN) {
+ printk(KERN_ERR "ip6t_policy: input policy not valid in "
+ "POST_ROUTING and OUTPUT\n");
+ return 0;
+ }
+ if (info->len > IP6T_POLICY_MAX_ELEM) {
+ printk(KERN_ERR "ip6t_policy: too many policy elements\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ip6t_match policy_match = {
+ .name = "policy",
+ .match = match,
+ .checkentry = checkentry,
+ .me = THIS_MODULE,
+};
+
+static int __init init(void)
+{
+ return ip6t_register_match(&policy_match);
+}
+
+static void __exit fini(void)
+{
+ ip6t_unregister_match(&policy_match);
+}
+
+module_init(init);
+module_exit(fini);
^ permalink raw reply related
* [PATCH 12/13]: [NETFILTER]: Export ip6_masked_addrcmp, don't pass IPv6 addresses on stack
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Export ip6_masked_addrcmp, don't pass IPv6 addresses on stack
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 055c50b770e63ced784808ae22ef339724b1a44c
tree b8dc07727bb80b83c5b236f4157ed588927f46da
parent 8b46eb2d8365ab18cc965f37681033162a834fe5
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:09:28 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:09:28 +0100
include/linux/netfilter_ipv6/ip6_tables.h | 4 ++++
net/ipv6/netfilter/ip6_tables.c | 18 ++++++++++--------
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 2efc046..1e11010 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -476,6 +476,10 @@ extern int ip6t_ext_hdr(u8 nexthdr);
extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
u8 target);
+extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
+ const struct in6_addr *mask,
+ const struct in6_addr *addr2);
+
#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
#endif /*__KERNEL__*/
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 7d49222..71a80e0 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -128,13 +128,14 @@ static LIST_HEAD(ip6t_tables);
#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0)
#endif
-static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask,
- struct in6_addr addr2)
+int
+ip6_masked_addrcmp(const struct in6_addr *addr1, const struct in6_addr *mask,
+ const struct in6_addr *addr2)
{
int i;
for( i = 0; i < 16; i++){
- if((addr1.s6_addr[i] & mask.s6_addr[i]) !=
- (addr2.s6_addr[i] & mask.s6_addr[i]))
+ if((addr1->s6_addr[i] & mask->s6_addr[i]) !=
+ (addr2->s6_addr[i] & mask->s6_addr[i]))
return 1;
}
return 0;
@@ -168,10 +169,10 @@ ip6_packet_match(const struct sk_buff *s
#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
- if (FWINV(ip6_masked_addrcmp(ipv6->saddr,ip6info->smsk,ip6info->src),
- IP6T_INV_SRCIP)
- || FWINV(ip6_masked_addrcmp(ipv6->daddr,ip6info->dmsk,ip6info->dst),
- IP6T_INV_DSTIP)) {
+ if (FWINV(ip6_masked_addrcmp(&ipv6->saddr, &ip6info->smsk,
+ &ip6info->src), IP6T_INV_SRCIP)
+ || FWINV(ip6_masked_addrcmp(&ipv6->daddr, &ip6info->dmsk,
+ &ip6info->dst), IP6T_INV_DSTIP)) {
dprintf("Source or dest mismatch.\n");
/*
dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
@@ -2094,6 +2095,7 @@ EXPORT_SYMBOL(ip6t_register_target);
EXPORT_SYMBOL(ip6t_unregister_target);
EXPORT_SYMBOL(ip6t_ext_hdr);
EXPORT_SYMBOL(ipv6_find_hdr);
+EXPORT_SYMBOL(ip6_masked_addrcmp);
module_init(init);
module_exit(fini);
^ permalink raw reply related
* [PATCH 11/13]: [NETFILTER]: Handle NAT in IPsec policy checks
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Handle NAT in IPsec policy checks
Handle NAT of decapsulated IPsec packets by reconstructing the struct flowi
of the original packet from the conntrack information for IPsec policy
checks.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 8b46eb2d8365ab18cc965f37681033162a834fe5
tree 5e8b46d5acd6fa4b1445f181fcf8bce94cade5b0
parent 3f615f37e68903f0eea66f5b242bfbb1875ee204
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:09:15 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:09:15 +0100
include/linux/netfilter.h | 16 ++++++++++
net/ipv4/netfilter.c | 3 ++
net/ipv4/netfilter/ip_nat_standalone.c | 50 +++++++++++++++++++++++++++++++-
net/xfrm/xfrm_policy.c | 2 +
4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index be365e7..cc9ee97 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -261,6 +261,20 @@ struct nf_queue_rerouter {
extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer);
extern int nf_unregister_queue_rerouter(int pf);
+#include <net/flow.h>
+extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
+
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
+{
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+ void (*decodefn)(struct sk_buff *, struct flowi *);
+
+ if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
+ decodefn(skb, fl);
+#endif
+}
+
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
extern struct proc_dir_entry *proc_net_netfilter;
@@ -269,6 +283,8 @@ extern struct proc_dir_entry *proc_net_n
#else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
#endif /*CONFIG_NETFILTER*/
#endif /*__KERNEL__*/
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 8fda96a..b66856d 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -134,6 +134,9 @@ drop:
}
#endif /* CONFIG_XFRM */
+void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
+EXPORT_SYMBOL(ip_nat_decode_session);
+
/*
* Extra routing may needed on local out, as the QUEUE target never
* returns control to the table.
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index b518697..8b8a1f0 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -55,6 +55,44 @@
: ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \
: "*ERROR*")))
+#ifdef CONFIG_XFRM
+static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
+{
+ struct ip_conntrack *ct;
+ struct ip_conntrack_tuple *t;
+ enum ip_conntrack_info ctinfo;
+ enum ip_conntrack_dir dir;
+ unsigned long statusbit;
+
+ ct = ip_conntrack_get(skb, &ctinfo);
+ if (ct == NULL)
+ return;
+ dir = CTINFO2DIR(ctinfo);
+ t = &ct->tuplehash[dir].tuple;
+
+ if (dir == IP_CT_DIR_ORIGINAL)
+ statusbit = IPS_DST_NAT;
+ else
+ statusbit = IPS_SRC_NAT;
+
+ if (ct->status & statusbit) {
+ fl->fl4_dst = t->dst.ip;
+ if (t->dst.protonum == IPPROTO_TCP ||
+ t->dst.protonum == IPPROTO_UDP)
+ fl->fl_ip_dport = t->dst.u.tcp.port;
+ }
+
+ statusbit ^= IPS_NAT_MASK;
+
+ if (ct->status & statusbit) {
+ fl->fl4_src = t->src.ip;
+ if (t->dst.protonum == IPPROTO_TCP ||
+ t->dst.protonum == IPPROTO_UDP)
+ fl->fl_ip_sport = t->src.u.tcp.port;
+ }
+}
+#endif
+
static unsigned int
ip_nat_fn(unsigned int hooknum,
struct sk_buff **pskb,
@@ -330,10 +368,14 @@ static int init_or_cleanup(int init)
if (!init) goto cleanup;
+#ifdef CONFIG_XFRM
+ BUG_ON(ip_nat_decode_session != NULL);
+ ip_nat_decode_session = nat_decode_session;
+#endif
ret = ip_nat_rule_init();
if (ret < 0) {
printk("ip_nat_init: can't setup rules.\n");
- goto cleanup_nothing;
+ goto cleanup_decode_session;
}
ret = nf_register_hook(&ip_nat_in_ops);
if (ret < 0) {
@@ -381,7 +423,11 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_nat_in_ops);
cleanup_rule_init:
ip_nat_rule_cleanup();
- cleanup_nothing:
+ cleanup_decode_session:
+#ifdef CONFIG_XFRM
+ ip_nat_decode_session = NULL;
+ synchronize_net();
+#endif
return ret;
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e441f35..8351bb0 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -22,6 +22,7 @@
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
+#include <linux/netfilter.h>
#include <linux/module.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -938,6 +939,7 @@ int __xfrm_policy_check(struct sock *sk,
if (xfrm_decode_session(skb, &fl, family) < 0)
return 0;
+ nf_nat_decode_session(skb, &fl, family);
/* First, check used SA against their selectors. */
if (skb->sp) {
^ permalink raw reply related
* [PATCH 10/13]: [NETFILTER]: Keep the conntrack reference until after policy checks
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Keep the conntrack reference until after policy checks
Keep the conntrack reference until policy checks have been performed for
IPsec NAT support. The reference needs to be dropped before a packet is
queued to avoid having the conntrack module unloadable and before icmp_send
is called to avoid having the reference attached manually to the outgoing
ICMP packet and the conntrack entry confirmed when ICMP packets leaves the
machine.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 3f615f37e68903f0eea66f5b242bfbb1875ee204
tree 4c3f9966a01f44784b9cd42e8f7091dbbc09fe5a
parent 8cb6cfa80dd5dc4da1de280a0278746c262a2d8d
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:08:45 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:08:45 +0100
net/dccp/ipv4.c | 1 +
net/ipv4/ip_input.c | 15 +++++++--------
net/ipv4/raw.c | 1 +
net/ipv4/tcp_ipv4.c | 1 +
net/ipv4/udp.c | 2 ++
net/sctp/input.c | 1 +
6 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index ca03521..0030923 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1147,6 +1147,7 @@ int dccp_v4_rcv(struct sk_buff *skb)
dccp_pr_debug("xfrm4_policy_check failed\n");
goto discard_and_relse;
}
+ nf_reset(skb);
if (sk_filter(sk, skb, 0)) {
dccp_pr_debug("sk_filter failed\n");
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 473d0f2..1757778 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -203,10 +203,6 @@ static inline int ip_local_deliver_finis
__skb_pull(skb, ihl);
- /* Free reference early: we don't need it any more, and it may
- hold ip_conntrack module loaded indefinitely. */
- nf_reset(skb);
-
/* Point into the IP datagram, just past the header. */
skb->h.raw = skb->data;
@@ -231,10 +227,12 @@ static inline int ip_local_deliver_finis
if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
int ret;
- if (!ipprot->no_policy &&
- !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
- kfree_skb(skb);
- goto out;
+ if (!ipprot->no_policy) {
+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+ kfree_skb(skb);
+ goto out;
+ }
+ nf_reset(skb);
}
ret = ipprot->handler(skb);
if (ret < 0) {
@@ -246,6 +244,7 @@ static inline int ip_local_deliver_finis
if (!raw_sk) {
if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
IP_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
+ nf_reset(skb);
icmp_send(skb, ICMP_DEST_UNREACH,
ICMP_PROT_UNREACH, 0);
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 421538a..8251a28 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -255,6 +255,7 @@ int raw_rcv(struct sock *sk, struct sk_b
kfree_skb(skb);
return NET_RX_DROP;
}
+ nf_reset(skb);
skb_push(skb, skb->data - skb->nh.raw);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 4d5021e..66300f9 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1238,6 +1238,7 @@ process:
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse;
+ nf_reset(skb);
if (sk_filter(sk, skb, 0))
goto discard_and_relse;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2422a5f..483ca69 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1001,6 +1001,7 @@ static int udp_queue_rcv_skb(struct sock
kfree_skb(skb);
return -1;
}
+ nf_reset(skb);
if (up->encap_type) {
/*
@@ -1163,6 +1164,7 @@ int udp_rcv(struct sk_buff *skb)
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
goto drop;
+ nf_reset(skb);
/* No socket. Drop packet silently, if checksum is wrong */
if (udp_checksum_complete(skb))
diff --git a/net/sctp/input.c b/net/sctp/input.c
index b24ff2c..100f577 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -225,6 +225,7 @@ int sctp_rcv(struct sk_buff *skb)
if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
goto discard_release;
+ nf_reset(skb);
ret = sk_filter(sk, skb, 1);
if (ret)
^ permalink raw reply related
* [PATCH 09/13]: [NETFILTER]: Redo policy lookups after NAT when neccessary
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Redo policy lookups after NAT when neccessary
When NAT changes the key used for the xfrm lookup it needs to be done again.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 8cb6cfa80dd5dc4da1de280a0278746c262a2d8d
tree efffac2335bd21d0a0c2aa848df544002e4316f4
parent 864cef1bc7d011f4a07b01043786107ad570c820
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:07:34 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:07:34 +0100
include/net/dst.h | 1 +
net/ipv4/ip_output.c | 7 ++++++-
net/ipv4/netfilter.c | 2 +-
net/ipv4/netfilter/ip_nat_standalone.c | 27 +++++++++++++++++++++++++--
4 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 7eadd0c..4630e17 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -237,6 +237,7 @@ static inline int dst_output(struct sk_b
}
#if defined(CONFIG_XFRM) && defined(CONFIG_NETFILTER)
+extern int __ip_dst_output(struct sk_buff *skb);
extern int ip_dst_output(struct sk_buff *skb);
extern int ip6_dst_output(struct sk_buff *skb);
#else
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 2c91f03..6836389 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -195,13 +195,18 @@ static inline int ip_finish_output2(stru
return dst->neighbour->output(skb);
if (net_ratelimit())
- printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
+ printk(KERN_DEBUG "ip_finish_output3: No header cache and no neighbour!\n");
kfree_skb(skb);
return -EINVAL;
}
static inline int ip_finish_output(struct sk_buff *skb)
{
+#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
+ /* Policy lookup after SNAT yielded a new policy */
+ if (skb->dst->xfrm != NULL)
+ return __ip_dst_output(skb);
+#endif
if (skb->len > dst_mtu(skb->dst) &&
!(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
return ip_fragment(skb, ip_finish_output2);
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index db330b6..8fda96a 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -87,7 +87,7 @@ int ip_route_me_harder(struct sk_buff **
EXPORT_SYMBOL(ip_route_me_harder);
#ifdef CONFIG_XFRM
-static inline int __ip_dst_output(struct sk_buff *skb)
+inline int __ip_dst_output(struct sk_buff *skb)
{
int err;
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 1bb5089..b518697 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -187,12 +187,30 @@ ip_nat_out(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ struct ip_conntrack *ct;
+ enum ip_conntrack_info ctinfo;
+ unsigned int ret;
+
/* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
return NF_ACCEPT;
- return ip_nat_fn(hooknum, pskb, in, out, okfn);
+ ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+ if (ret != NF_DROP && ret != NF_STOLEN
+ && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+ if (ct->tuplehash[dir].tuple.src.ip !=
+ ct->tuplehash[!dir].tuple.dst.ip
+#ifdef CONFIG_XFRM
+ || ct->tuplehash[dir].tuple.src.u.all !=
+ ct->tuplehash[!dir].tuple.dst.u.all
+#endif
+ )
+ return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ }
+ return ret;
}
static unsigned int
@@ -217,7 +235,12 @@ ip_nat_local_fn(unsigned int hooknum,
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.dst.ip !=
- ct->tuplehash[!dir].tuple.src.ip)
+ ct->tuplehash[!dir].tuple.src.ip
+#ifdef CONFIG_XFRM
+ || ct->tuplehash[dir].tuple.dst.u.all !=
+ ct->tuplehash[dir].tuple.src.u.all
+#endif
+ )
return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
}
return ret;
^ permalink raw reply related
* [PATCH 08/13]: [NETFILTER]: Use conntrack information to determine if packet was NATed
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Use conntrack information to determine if packet was NATed
Preparation for full IPsec support for NAT:
Use conntrack information instead of saving the saving and comparing the
addresses to determine if a packet was NATed and needs to be rerouted to
make it easier to extend the key.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 864cef1bc7d011f4a07b01043786107ad570c820
tree dbf671924ab6eb7bd87baaae9118bb57d7b3ab8e
parent ffa4445cd4284d3d9b688c80f5a3b9f8b26d59e6
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:05:26 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:05:26 +0100
net/ipv4/netfilter/ip_nat_standalone.c | 34 ++++++++++++++++++--------------
1 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index f04111f..1bb5089 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -162,18 +162,20 @@ ip_nat_in(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- u_int32_t saddr, daddr;
+ struct ip_conntrack *ct;
+ enum ip_conntrack_info ctinfo;
unsigned int ret;
- saddr = (*pskb)->nh.iph->saddr;
- daddr = (*pskb)->nh.iph->daddr;
-
ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN
- && ((*pskb)->nh.iph->saddr != saddr
- || (*pskb)->nh.iph->daddr != daddr)) {
- dst_release((*pskb)->dst);
- (*pskb)->dst = NULL;
+ && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+ if (ct->tuplehash[dir].tuple.src.ip !=
+ ct->tuplehash[!dir].tuple.dst.ip) {
+ dst_release((*pskb)->dst);
+ (*pskb)->dst = NULL;
+ }
}
return ret;
}
@@ -200,7 +202,8 @@ ip_nat_local_fn(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- u_int32_t saddr, daddr;
+ struct ip_conntrack *ct;
+ enum ip_conntrack_info ctinfo;
unsigned int ret;
/* root is playing with raw sockets. */
@@ -208,14 +211,15 @@ ip_nat_local_fn(unsigned int hooknum,
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
return NF_ACCEPT;
- saddr = (*pskb)->nh.iph->saddr;
- daddr = (*pskb)->nh.iph->daddr;
-
ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN
- && ((*pskb)->nh.iph->saddr != saddr
- || (*pskb)->nh.iph->daddr != daddr))
- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+ if (ct->tuplehash[dir].tuple.dst.ip !=
+ ct->tuplehash[!dir].tuple.src.ip)
+ return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ }
return ret;
}
^ permalink raw reply related
* [PATCH 07/13]: [NETFILTER]: Fix xfrm lookup in ip_route_me_harder/ip6_route_me_harder
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Fix xfrm lookup in ip_route_me_harder/ip6_route_me_harder
ip_route_me_harder doesn't use the port numbers of the xfrm lookup and
uses ip_route_input for non-local addresses which doesn't do a xfrm
lookup, ip6_route_me_harder doesn't do a xfrm lookup at all.
Use xfrm_decode_session and do the lookup manually, make sure both
only do the lookup if the packet hasn't been transformed already.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit ffa4445cd4284d3d9b688c80f5a3b9f8b26d59e6
tree 3edbdce75cc680c51e38697d45479dbfd4404452
parent 08cf39d5d7d8b942431a6529daa3ab69ecfb34b5
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:05:08 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 22:05:08 +0100
include/linux/ipv6.h | 2 ++
include/net/ip.h | 1 +
include/net/xfrm.h | 2 +-
net/ipv4/netfilter.c | 9 ++++++++-
net/ipv4/xfrm4_output.c | 1 +
net/ipv6/netfilter.c | 8 +++++++-
net/ipv6/xfrm6_output.c | 1 +
net/xfrm/xfrm_policy.c | 9 +++++----
8 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e0b9227..d7b3fac 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -190,6 +190,8 @@ struct inet6_skb_parm {
__u16 srcrt;
__u16 dst1;
__u16 lastopt;
+ __u16 flags;
+#define IP6SKB_XFRM_TRANSFORMED 1
};
#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
diff --git a/include/net/ip.h b/include/net/ip.h
index 9f09882..377036b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -45,6 +45,7 @@ struct inet_skb_parm
#define IPSKB_TRANSLATED 2
#define IPSKB_FORWARDED 4
#define IPSKB_XFRM_TUNNEL_SIZE 8
+#define IPSKB_XFRM_TRANSFORMED 16
};
struct ipcm_cookie
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5beae1c..19d6aa0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -644,7 +644,7 @@ static inline int xfrm6_policy_check(str
return xfrm_policy_check(sk, dir, skb, AF_INET6);
}
-
+extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 3c39296..db330b6 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -13,6 +13,7 @@
#include <linux/ip.h>
#include <net/route.h>
#include <net/xfrm.h>
+#include <net/ip.h>
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
int ip_route_me_harder(struct sk_buff **pskb)
@@ -34,7 +35,6 @@ int ip_route_me_harder(struct sk_buff **
#ifdef CONFIG_IP_ROUTE_FWMARK
fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
#endif
- fl.proto = iph->protocol;
if (ip_route_output_key(&rt, &fl) != 0)
return -1;
@@ -61,6 +61,13 @@ int ip_route_me_harder(struct sk_buff **
if ((*pskb)->dst->error)
return -1;
+#ifdef CONFIG_XFRM
+ if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+ xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
+ if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
+ return -1;
+#endif
+
/* Change in oif may mean change in hh_len. */
hh_len = (*pskb)->dst->dev->hard_header_len;
if (skb_headroom(*pskb) < hh_len) {
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c135746..9e49eeb 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -133,6 +133,7 @@ int xfrm4_output(struct sk_buff *skb)
err = -EHOSTUNREACH;
goto error_nolock;
}
+ IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
nf_reset(skb);
err = NET_XMIT_BYPASS;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 06b275e..8bc6305 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -22,7 +22,6 @@ int ip6_route_me_harder(struct sk_buff *
{ .ip6_u =
{ .daddr = iph->daddr,
.saddr = iph->saddr, } },
- .proto = iph->nexthdr,
};
dst = ip6_route_output(skb->sk, &fl);
@@ -34,6 +33,13 @@ int ip6_route_me_harder(struct sk_buff *
return -EINVAL;
}
+#ifdef CONFIG_XFRM
+ if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
+ xfrm_decode_session(skb, &fl, AF_INET6) == 0)
+ if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
+ return -1;
+#endif
+
/* Drop old route. */
dst_release(skb->dst);
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index a566d25..929e4eb 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -132,6 +132,7 @@ int xfrm6_output(struct sk_buff *skb)
err = -EHOSTUNREACH;
goto error_nolock;
}
+ IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
nf_reset(skb);
err = NET_XMIT_BYPASS;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 0db9e57..e441f35 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -906,8 +906,8 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, s
return start;
}
-static int
-_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
+int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+ unsigned short family)
{
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
@@ -918,6 +918,7 @@ _decode_session(struct sk_buff *skb, str
xfrm_policy_put_afinfo(afinfo);
return 0;
}
+EXPORT_SYMBOL(xfrm_decode_session);
static inline int secpath_has_tunnel(struct sec_path *sp, int k)
{
@@ -935,7 +936,7 @@ int __xfrm_policy_check(struct sock *sk,
struct xfrm_policy *pol;
struct flowi fl;
- if (_decode_session(skb, &fl, family) < 0)
+ if (xfrm_decode_session(skb, &fl, family) < 0)
return 0;
/* First, check used SA against their selectors. */
@@ -1007,7 +1008,7 @@ int __xfrm_route_forward(struct sk_buff
{
struct flowi fl;
- if (_decode_session(skb, &fl, family) < 0)
+ if (xfrm_decode_session(skb, &fl, family) < 0)
return 0;
return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
^ permalink raw reply related
* [PATCH 06/13]: [IPV4/6]: Netfilter IPsec input hooks
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[IPV4/6]: Netfilter IPsec input hooks
When the innermost transform uses transport mode the decapsulated packet
is not visible to netfilter. Pass the packet through the PRE_ROUTING and
LOCAL_IN hooks again before handing it to upper layer protocols to make
netfilter-visibility symetrical to the output path.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 08cf39d5d7d8b942431a6529daa3ab69ecfb34b5
tree 6f2a1a85f915b1b6f89ad50cf3d8855f21a561b6
parent b847425c693f43a63137d18e36e5c8cf0187c175
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:50:22 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:50:22 +0100
include/linux/netfilter_ipv4.h | 2 +-
include/net/ipv6.h | 2 ++
net/ipv4/netfilter.c | 20 ++++++++++++++++++++
net/ipv4/xfrm4_input.c | 14 ++++++++++++++
net/ipv6/ip6_input.c | 2 +-
net/ipv6/xfrm6_input.c | 13 +++++++++++++
6 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index fdc4a95..e9103fe 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -79,7 +79,7 @@ enum nf_ip_hook_priorities {
#ifdef __KERNEL__
extern int ip_route_me_harder(struct sk_buff **pskb);
-
+extern int ip_xfrm_transport_hook(struct sk_buff *skb);
#endif /*__KERNEL__*/
#endif /*__LINUX_IP_NETFILTER_H*/
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 6addb4d..4fbfe43 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -414,6 +414,8 @@ extern int ipv6_rcv(struct sk_buff *sk
struct packet_type *pt,
struct net_device *orig_dev);
+extern int ip6_rcv_finish(struct sk_buff *skb);
+
/*
* upper-layer output functions
*/
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index b93e7cd..3c39296 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -105,6 +105,26 @@ int ip_dst_output(struct sk_buff *skb)
return dst_output(skb);
}
EXPORT_SYMBOL(ip_dst_output);
+
+/*
+ * okfn for transport mode xfrm_input.c hook. Basically a copy of
+ * ip_rcv_finish without statistics and option parsing.
+ */
+int ip_xfrm_transport_hook(struct sk_buff *skb)
+{
+ struct iphdr *iph = skb->nh.iph;
+
+ if (likely(skb->dst == NULL)) {
+ int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
+ skb->dev);
+ if (unlikely(err))
+ goto drop;
+ }
+ return dst_input(skb);
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
#endif /* CONFIG_XFRM */
/*
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 2d3849c..d90cd93 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
#include <net/xfrm.h>
@@ -137,6 +139,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb,
memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state));
skb->sp->len += xfrm_nr;
+ nf_reset(skb);
+
if (decaps) {
if (!(skb->dev->flags&IFF_LOOPBACK)) {
dst_release(skb->dst);
@@ -145,7 +149,17 @@ int xfrm4_rcv_encap(struct sk_buff *skb,
netif_rx(skb);
return 0;
} else {
+#ifdef CONFIG_NETFILTER
+ __skb_push(skb, skb->data - skb->nh.raw);
+ skb->nh.iph->tot_len = htons(skb->len);
+ ip_send_check(skb->nh.iph);
+
+ NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+ ip_xfrm_transport_hook);
+ return 0;
+#else
return -skb->nh.iph->protocol;
+#endif
}
drop_unlock:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 33d3b0e..e84b3cd 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -48,7 +48,7 @@
-static inline int ip6_rcv_finish( struct sk_buff *skb)
+inline int ip6_rcv_finish(struct sk_buff *skb)
{
if (skb->dst == NULL)
ip6_route_input(skb);
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 28c29d7..9987416 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv6.h>
#include <net/dsfield.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
@@ -121,6 +123,8 @@ int xfrm6_rcv_spi(struct sk_buff **pskb,
skb->sp->len += xfrm_nr;
skb->ip_summed = CHECKSUM_NONE;
+ nf_reset(skb);
+
if (decaps) {
if (!(skb->dev->flags&IFF_LOOPBACK)) {
dst_release(skb->dst);
@@ -129,7 +133,16 @@ int xfrm6_rcv_spi(struct sk_buff **pskb,
netif_rx(skb);
return -1;
} else {
+#ifdef CONFIG_NETFILTER
+ skb->nh.ipv6h->payload_len = htons(skb->len);
+ __skb_push(skb, skb->data - skb->nh.raw);
+
+ NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+ ip6_rcv_finish);
+ return -1;
+#else
return 1;
+#endif
}
drop_unlock:
^ permalink raw reply related
* [PATCH 05/13]: [IPV4/6]: Netfilter IPsec output hooks
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[IPV4/6]: Netfilter IPsec output hooks
Add alternative ip_dst_output/ip6_dst_output functions to call netfilter
hooks between xfrm transforms. Packets visit the FORWARD/LOCAL_OUT and
POST_ROUTING hook before encapsulation and the LOCAL_OUT and POST_ROUTING
hook after each tunnel mode transform.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit b847425c693f43a63137d18e36e5c8cf0187c175
tree a811e8c573150bc279a9df53958270f25cb531bc
parent 73f59ffcebcd0a08f6a405c8522074e8b5892b73
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:58 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:58 +0100
include/net/dst.h | 5 +++++
net/ipv4/netfilter.c | 31 ++++++++++++++++++++++++++++++-
net/ipv4/xfrm4_output.c | 1 +
net/ipv6/netfilter.c | 29 +++++++++++++++++++++++++++++
net/ipv6/xfrm6_output.c | 1 +
5 files changed, 66 insertions(+), 1 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 4886f25..7eadd0c 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -236,8 +236,13 @@ static inline int dst_output(struct sk_b
}
}
+#if defined(CONFIG_XFRM) && defined(CONFIG_NETFILTER)
+extern int ip_dst_output(struct sk_buff *skb);
+extern int ip6_dst_output(struct sk_buff *skb);
+#else
#define ip_dst_output dst_output
#define ip6_dst_output dst_output
+#endif
/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb)
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index ae0779d..b93e7cd 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -10,8 +10,9 @@
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
-#include <net/route.h>
#include <linux/ip.h>
+#include <net/route.h>
+#include <net/xfrm.h>
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
int ip_route_me_harder(struct sk_buff **pskb)
@@ -78,6 +79,34 @@ int ip_route_me_harder(struct sk_buff **
}
EXPORT_SYMBOL(ip_route_me_harder);
+#ifdef CONFIG_XFRM
+static inline int __ip_dst_output(struct sk_buff *skb)
+{
+ int err;
+
+ do {
+ err = skb->dst->output(skb);
+
+ if (likely(err == 0))
+ return err;
+ if (unlikely(err != NET_XMIT_BYPASS))
+ return err;
+ } while (skb->dst->xfrm && !skb->dst->xfrm->props.mode);
+
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev,
+ ip_dst_output);
+}
+
+int ip_dst_output(struct sk_buff *skb)
+{
+ if (skb->dst->xfrm != NULL)
+ return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
+ skb->dst->dev, __ip_dst_output);
+ return dst_output(skb);
+}
+EXPORT_SYMBOL(ip_dst_output);
+#endif /* CONFIG_XFRM */
+
/*
* Extra routing may needed on local out, as the QUEUE target never
* returns control to the table.
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 66620a9..c135746 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -133,6 +133,7 @@ int xfrm4_output(struct sk_buff *skb)
err = -EHOSTUNREACH;
goto error_nolock;
}
+ nf_reset(skb);
err = NET_XMIT_BYPASS;
out_exit:
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index f8626eb..06b275e 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -10,6 +10,7 @@
#include <net/dst.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
+#include <net/xfrm.h>
int ip6_route_me_harder(struct sk_buff *skb)
{
@@ -41,6 +42,34 @@ int ip6_route_me_harder(struct sk_buff *
}
EXPORT_SYMBOL(ip6_route_me_harder);
+#ifdef CONFIG_XFRM
+static inline int __ip6_dst_output(struct sk_buff *skb)
+{
+ int err;
+
+ do {
+ err = skb->dst->output(skb);
+
+ if (likely(err == 0))
+ return err;
+ if (unlikely(err != NET_XMIT_BYPASS))
+ return err;
+ } while (skb->dst->xfrm && !skb->dst->xfrm->props.mode);
+
+ return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev,
+ ip6_dst_output);
+}
+
+int ip6_dst_output(struct sk_buff *skb)
+{
+ if (skb->dst->xfrm != NULL)
+ return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
+ skb->dst->dev, __ip6_dst_output);
+ return dst_output(skb);
+}
+EXPORT_SYMBOL(ip6_dst_output);
+#endif /* CONFIG_XFRM */
+
/*
* Extra routing may needed on local out, as the QUEUE target never
* returns control to the table.
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6b98677..a566d25 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -132,6 +132,7 @@ int xfrm6_output(struct sk_buff *skb)
err = -EHOSTUNREACH;
goto error_nolock;
}
+ nf_reset(skb);
err = NET_XMIT_BYPASS;
out_exit:
^ permalink raw reply related
* [PATCH 04/13]: [IPV6]: Replace dst_output by ip6_dst_output
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[IPV6]: Replace dst_output by ip6_dst_output
Preparation for netfilter IPsec support.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 73f59ffcebcd0a08f6a405c8522074e8b5892b73
tree 4be1e3bb174f611fa57ee6e1b8d9187e784c85ad
parent 4eb320a6444a9035da8a83e4886b3691a2ea98f7
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:40 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:40 +0100
include/net/dst.h | 1 +
net/ipv6/ip6_input.c | 4 ++--
net/ipv6/ip6_output.c | 7 ++++---
net/ipv6/ip6_tunnel.c | 2 +-
net/ipv6/ndisc.c | 8 ++++----
net/ipv6/netfilter/ip6t_REJECT.c | 2 +-
net/ipv6/raw.c | 2 +-
7 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 07f552b..4886f25 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -237,6 +237,7 @@ static inline int dst_output(struct sk_b
}
#define ip_dst_output dst_output
+#define ip6_dst_output dst_output
/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a6026d2..33d3b0e 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -255,9 +255,9 @@ int ip6_mc_input(struct sk_buff *skb)
if (deliver) {
skb2 = skb_clone(skb, GFP_ATOMIC);
- dst_output(skb2);
+ ip6_dst_output(skb2);
} else {
- dst_output(skb);
+ ip6_dst_output(skb);
return 0;
}
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c1fa693..c270798 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -230,7 +230,7 @@ int ip6_xmit(struct sock *sk, struct sk_
if ((skb->len <= mtu) || ipfragok) {
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
- dst_output);
+ ip6_dst_output);
}
if (net_ratelimit())
@@ -308,7 +308,7 @@ static int ip6_call_ra_chain(struct sk_b
static inline int ip6_forward_finish(struct sk_buff *skb)
{
- return dst_output(skb);
+ return ip6_dst_output(skb);
}
int ip6_forward(struct sk_buff *skb)
@@ -1181,7 +1181,8 @@ int ip6_push_pending_frames(struct sock
skb->dst = dst_clone(&rt->u.dst);
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev,
+ ip6_dst_output);
if (err) {
if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e315d0f..7c01eaf 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -746,7 +746,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
nf_reset(skb);
pkt_len = skb->len;
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
- skb->dst->dev, dst_output);
+ skb->dst->dev, ip6_dst_output);
if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) {
stats->tx_bytes += pkt_len;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 305d9ee..287170f 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -499,7 +499,7 @@ static void ndisc_send_na(struct net_dev
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_dst_output);
if (!err) {
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -582,7 +582,7 @@ void ndisc_send_ns(struct net_device *de
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_dst_output);
if (!err) {
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -654,7 +654,7 @@ void ndisc_send_rs(struct net_device *de
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_dst_output);
if (!err) {
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -1438,7 +1438,7 @@ void ndisc_send_redirect(struct sk_buff
buff->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
+ err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, ip6_dst_output);
if (!err) {
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index b03e87a..8579eaa 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -161,7 +161,7 @@ static void send_reset(struct sk_buff *o
sizeof(struct tcphdr), 0));
NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
- dst_output);
+ ip6_dst_output);
}
static inline void
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 8e9628f..e7fd031 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -571,7 +571,7 @@ static int rawv6_send_hdrinc(struct sock
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- dst_output);
+ ip6_dst_output);
if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0;
if (err)
^ permalink raw reply related
* [PATCH 03/13]: [IPV4]: Replace dst_output by ip_dst_output
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[IPV4]: Replace dst_output by ip_dst_output
Preparation for netfilter IPsec support.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 4eb320a6444a9035da8a83e4886b3691a2ea98f7
tree d31f7b331e06e1e598593c4095be7713e6fd3ba0
parent d3c70d774e32c4d6f4cc6b8b0b73678aa14a9932
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:28 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:28 +0100
include/net/dst.h | 2 ++
include/net/ipip.h | 2 +-
net/ipv4/igmp.c | 4 ++--
net/ipv4/ip_forward.c | 2 +-
net/ipv4/ip_output.c | 6 +++---
net/ipv4/ipmr.c | 2 +-
net/ipv4/ipvs/ip_vs_xmit.c | 2 +-
net/ipv4/netfilter/ipt_REJECT.c | 2 +-
net/ipv4/raw.c | 2 +-
9 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 6c196a5..07f552b 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -236,6 +236,8 @@ static inline int dst_output(struct sk_b
}
}
+#define ip_dst_output dst_output
+
/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb)
{
diff --git a/include/net/ipip.h b/include/net/ipip.h
index f490c3c..b267496 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -34,7 +34,7 @@ struct ip_tunnel
ip_select_ident(iph, &rt->u.dst, NULL); \
ip_send_check(iph); \
\
- err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ip_dst_output);\
if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { \
stats->tx_bytes += pkt_len; \
stats->tx_packets++; \
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c04607b..55779dc 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -343,7 +343,7 @@ static int igmpv3_sendpack(struct sk_buf
pig->csum = ip_compute_csum((void *)skb->h.igmph, igmplen);
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
- dst_output);
+ ip_dst_output);
}
static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
@@ -674,7 +674,7 @@ static int igmp_send_report(struct in_de
ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- dst_output);
+ ip_dst_output);
}
static void igmp_gq_timer_expire(unsigned long data)
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 0923add..486355d 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -51,7 +51,7 @@ static inline int ip_forward_finish(stru
if (unlikely(opt->optlen))
ip_forward_options(skb);
- return dst_output(skb);
+ return ip_dst_output(skb);
}
int ip_forward(struct sk_buff *skb)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 946e812..2c91f03 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -155,7 +155,7 @@ int ip_build_and_send_pkt(struct sk_buff
/* Send it out. */
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- dst_output);
+ ip_dst_output);
}
EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
@@ -360,7 +360,7 @@ packet_routed:
skb->priority = sk->sk_priority;
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- dst_output);
+ ip_dst_output);
no_route:
IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
@@ -1251,7 +1251,7 @@ int ip_push_pending_frames(struct sock *
/* Netfilter gets whole the not fragmented skb. */
err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
- skb->dst->dev, dst_output);
+ skb->dst->dev, ip_dst_output);
if (err) {
if (err > 0)
err = inet->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 302b7eb..40af27f 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1125,7 +1125,7 @@ static inline int ipmr_forward_finish(st
if (unlikely(opt->optlen))
ip_forward_options(skb);
- return dst_output(skb);
+ return ip_dst_output(skb);
}
/*
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 3b87482..b66c3da 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -130,7 +130,7 @@ do { \
(skb)->ipvs_property = 1; \
(skb)->ip_summed = CHECKSUM_NONE; \
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \
- (rt)->u.dst.dev, dst_output); \
+ (rt)->u.dst.dev, ip_dst_output); \
} while (0)
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f057025..55b601b 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -220,7 +220,7 @@ static void send_reset(struct sk_buff *o
nf_ct_attach(nskb, oldskb);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
- dst_output);
+ ip_dst_output);
return;
free_nskb:
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 4b0d7e4..421538a 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -313,7 +313,7 @@ static int raw_send_hdrinc(struct sock *
}
err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- dst_output);
+ ip_dst_output);
if (err > 0)
err = inet->recverr ? net_xmit_errno(err) : 0;
if (err)
^ permalink raw reply related
* [PATCH 02/13]: [NETFILTER]: Call POST_ROUTING hook before fragmentation
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Call POST_ROUTING hook before fragmentation
Call POST_ROUTING hook before fragmentation to get rid of the okfn use
in ip_refrag and save the useless fragmentation/defragmentation step
when NAT is used.
The patch introduces one user-visible change, the POSTROUTING chain
in the mangle table gets entire packets, not fragments, which should
simplify use of the MARK and CLASSIFY targets for queueing as a nice
side-effect.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit d3c70d774e32c4d6f4cc6b8b0b73678aa14a9932
tree 16b82a0bedbb29b6a709140a7047ce2d52bb776f
parent ebb0baec0a5e909d4acf16a15601f013093fefb3
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:11 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:49:11 +0100
include/net/ip.h | 1 -
net/ipv4/ip_output.c | 30 +++++++++++-------------
net/ipv4/netfilter/ip_conntrack_standalone.c | 26 +--------------------
net/ipv4/netfilter/ip_nat_standalone.c | 17 --------------
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 26 +--------------------
5 files changed, 16 insertions(+), 84 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index e4563bb..9f09882 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -310,7 +310,6 @@ enum ip_defrag_users
IP_DEFRAG_CALL_RA_CHAIN,
IP_DEFRAG_CONNTRACK_IN,
IP_DEFRAG_CONNTRACK_OUT,
- IP_DEFRAG_NAT_OUT,
IP_DEFRAG_VS_IN,
IP_DEFRAG_VS_OUT,
IP_DEFRAG_VS_FWD
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 11c2f68..946e812 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -202,13 +202,11 @@ static inline int ip_finish_output2(stru
static inline int ip_finish_output(struct sk_buff *skb)
{
- struct net_device *dev = skb->dst->dev;
-
- skb->dev = dev;
- skb->protocol = htons(ETH_P_IP);
-
- return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
- ip_finish_output2);
+ if (skb->len > dst_mtu(skb->dst) &&
+ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+ return ip_fragment(skb, ip_finish_output2);
+ else
+ return ip_finish_output2(skb);
}
int ip_mc_output(struct sk_buff *skb)
@@ -265,21 +263,21 @@ int ip_mc_output(struct sk_buff *skb)
newskb->dev, ip_dev_loopback_xmit);
}
- if (skb->len > dst_mtu(&rt->u.dst))
- return ip_fragment(skb, ip_finish_output);
- else
- return ip_finish_output(skb);
+ return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+ ip_finish_output);
}
int ip_output(struct sk_buff *skb)
{
+ struct net_device *dev = skb->dst->dev;
+
IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- if (skb->len > dst_mtu(skb->dst) &&
- !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
- return ip_fragment(skb, ip_finish_output);
- else
- return ip_finish_output(skb);
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_IP);
+
+ return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+ ip_finish_output);
}
int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index dd476b1..13ed18a 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -450,30 +450,6 @@ static unsigned int ip_conntrack_defrag(
return NF_ACCEPT;
}
-static unsigned int ip_refrag(unsigned int hooknum,
- struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
- /* We've seen it coming out the other side: confirm */
- if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
- return NF_DROP;
-
- /* Local packets are never produced too large for their
- interface. We degfragment them at LOCAL_OUT, however,
- so we have to refragment them here. */
- if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
- !skb_shinfo(*pskb)->tso_size) {
- /* No hook can be after us, so this should be OK. */
- ip_fragment(*pskb, okfn);
- return NF_STOLEN;
- }
- return NF_ACCEPT;
-}
-
static unsigned int ip_conntrack_local(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
@@ -543,7 +519,7 @@ static struct nf_hook_ops ip_conntrack_h
/* Refragmenter; last chance. */
static struct nf_hook_ops ip_conntrack_out_ops = {
- .hook = ip_refrag,
+ .hook = ip_confirm,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 30cd4e1..f04111f 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -190,23 +190,6 @@ ip_nat_out(unsigned int hooknum,
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
return NF_ACCEPT;
- /* We can hit fragment here; forwarded packets get
- defragmented by connection tracking coming in, then
- fragmented (grr) by the forward code.
-
- In future: If we have nfct != NULL, AND we have NAT
- initialized, AND there is no helper, then we can do full
- NAPT on the head, and IP-address-only NAT on the rest.
-
- I'm starting to have nightmares about fragments. */
-
- if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
- *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
-
- if (!*pskb)
- return NF_STOLEN;
- }
-
return ip_nat_fn(hooknum, pskb, in, out, okfn);
}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8202c1c..818ba72 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -180,30 +180,6 @@ static unsigned int ipv4_conntrack_defra
return NF_ACCEPT;
}
-static unsigned int ipv4_refrag(unsigned int hooknum,
- struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
- /* We've seen it coming out the other side: confirm */
- if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
- return NF_DROP;
-
- /* Local packets are never produced too large for their
- interface. We degfragment them at LOCAL_OUT, however,
- so we have to refragment them here. */
- if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
- !skb_shinfo(*pskb)->tso_size) {
- /* No hook can be after us, so this should be OK. */
- ip_fragment(*pskb, okfn);
- return NF_STOLEN;
- }
- return NF_ACCEPT;
-}
-
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
@@ -283,7 +259,7 @@ static struct nf_hook_ops ipv4_conntrack
/* Refragmenter; last chance. */
static struct nf_hook_ops ipv4_conntrack_out_ops = {
- .hook = ipv4_refrag,
+ .hook = ipv4_confirm,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
^ permalink raw reply related
* [PATCH 01/13]: [NETFILTER]: Remove okfn usage in ip_vs_core.c
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
In-Reply-To: <20051120163128.16666.38111.sendpatchset@localhost.localdomain>
[NETFILTER]: Remove okfn usage in ip_vs_core.c
okfn should only be used from different contexts to avoid deep call stacks,
i.e. by nf_queue.
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit ebb0baec0a5e909d4acf16a15601f013093fefb3
tree da877af1ad83666e8ccd54dd94da485444e6b37b
parent b286e39207237e2f6929959372bf66d9a8d05a82
author Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:48:33 +0100
committer Patrick McHardy <kaber@trash.net> Sat, 19 Nov 2005 21:48:33 +0100
net/ipv4/ipvs/ip_vs_core.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 1a0843c..b63bb28 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -532,11 +532,8 @@ static unsigned int ip_vs_post_routing(u
{
if (!((*pskb)->ipvs_property))
return NF_ACCEPT;
-
/* The packet was sent from IPVS, exit this chain */
- (*okfn)(*pskb);
-
- return NF_STOLEN;
+ return NF_STOP;
}
u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
^ permalink raw reply related
* [PATCH 00/13]: Netfilter IPsec support
From: Patrick McHardy @ 2005-11-20 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Patrick McHardy
This is the latest netfilter/IPsec patchset. Its purpose is to make
IPsec look as much as a normal tunnel device to netfilter as possible
and to enable NAT support.
It consists of basically five parts:
- output hooks:
Currently on the output path netfilter sees the plain text packet in
LOCAL_OUT and FORWARD and the encapsulated packet in POST_ROUTING.
For connection tracking and NAT the plain text packets need to be
visible on POST_ROUTING and the encapsulated packets on LOCAL_OUT as
well. The patchset adds two new functions, ip_dst_output and
ip6_dst_output that call the appropriate netfilter hooks for the
plain text packet before encapsulation and for the encapsulated
packets once for each tunnel mode transform.
- input hooks:
The input path is already mostly symetrical to the output path with
the new output hooks, except for one case, if the innermost transform
uses transport mode the decapsulated packets will not hit netfilter
again. New hooks are added to xfrm{4,6}_input to handle this case.
The hooks are only called if the _last_ transform is transport mode,
otherwise decapsulated transport mode packets are not visible to
netfilter.
- policy lookups after NAT:
When NAT changes a packet it already calls ip_route_me_harder, which
reroutes the packet and does a new policy lookup. It only looks at
the IP addresses however, changing the port numbers require a new
policy lookup as well. It also doesn't reroute in POST_ROUTING, since
the packet has already been routed. To behave more like a regular
tunnel device a policy lookup is now also done after SNAT and the
packet is passed to dst_output again if the lookup yielded a new
policy.
- policy checks after NAT:
Policy checks look up the policy of the decapsulated packet and check
that all decapsulations match what has been specified by the policy.
If the packet has been NATed before policy checks the policy lookup
might return a different policy from what was actually used. To handle
this a new function nf_nat_decode_session reconstructs a struct flowi
for the original packet which is then used for policy lookups.
- policy match:
To allow matching on the policy or the decapsulations done on the input
path a new match is added. It can be used to replace rules like
"-i ipsec0" or "-o ipsec0" which were commonly used with KLIPS, but can
also be used for more fine-grained filtering.
Changes this last post:
- updated to apply to latest kernel
- the defered fragmentation patch has been replaced by a new patch
which moves the POST_ROUTING hook before fragmentation
- added missing EXPORT_SYMBOL(xfrm_decode_session) for IPv6
- moving nf_reset from ip_local_deliver_finish to the upper protocols
has been split into a seperate patch, unnecessary nf_reset's on
paths were the packet is dropped have been removed and a missing
nf_reset before icmp_send in ip_local_deliver_finish has been added.
The patches are now in a state in which I think they could be merged in
the net-2.6.16 tree. Unfortunately cloning the tree fails for me, so
they are still based on Linus's tree, but I don't think there are any
changes in net-2.6.16 yet which conflict.
The patches are also available in a git-tree:
http://people.netfilter.org/kaber/nf-2.6-xfrm.git/
[NETFILTER]: Remove okfn usage in ip_vs_core.c
[NETFILTER]: Call POST_ROUTING hook before fragmentation
[IPV4]: Replace dst_output by ip_dst_output
[IPV6]: Replace dst_output by ip6_dst_output
[IPV4/6]: Netfilter IPsec output hooks
[IPV4/6]: Netfilter IPsec input hooks
[NETFILTER]: Fix xfrm lookup in ip_route_me_harder/ip6_route_me_harder
[NETFILTER]: Use conntrack information to determine if packet was NATed
[NETFILTER]: Redo policy lookups after NAT when neccessary
[NETFILTER]: Keep the conntrack reference until after policy checks
[NETFILTER]: Handle NAT in IPsec policy checks
[NETFILTER]: Export ip6_masked_addrcmp, don't pass IPv6 addresses on stack
[NETFILTER]: Add ipt_policy/ip6t_policy matches
^ permalink raw reply
* Re: [PATCH -mm2] net: Fix compiler-error on dgrs.c when !CONFIG_PCI
From: Richard Knutsson @ 2005-11-20 15:35 UTC (permalink / raw)
To: Herbert Xu; +Cc: akpm, linux-kernel, netdev, jgarzik, ashutosh.naik
In-Reply-To: <E1EdmMo-00020b-00@gondolin.me.apana.org.au>
Herbert Xu wrote:
>Richard Knutsson <ricknu-0@student.ltu.se> wrote:
>
>
>>diff -Narup a/drivers/net/dgrs.c b/drivers/net/dgrs.c
>>--- a/drivers/net/dgrs.c 2005-11-19 20:17:51.000000000 +0100
>>+++ b/drivers/net/dgrs.c 2005-11-19 20:29:52.000000000 +0100
>>@@ -1458,6 +1458,8 @@ static struct pci_driver dgrs_pci_driver
>> .probe = dgrs_pci_probe,
>> .remove = __devexit_p(dgrs_pci_remove),
>>};
>>+#else
>>+static struct pci_driver dgrs_pci_driver = {};
>>#endif
>>
>>
>
>How about something like this?
>
>[NETDRV] dgrs: Fix compiler-error on dgrs.c when !CONFIG_PCI
>
>
[NETDRV], is that "standard" formating? If so, is there any more? Thanks :)
>The previous patch on this driver removed the #ifdef CONFIG_PCI
>around the pci_register_driver call in order to avoid a warning
>about an unused variable. This produces an error since the PCI
>driver object is undefined if CONFIG_PCI is not set.
>
>
Well, not really. The removal of CONFIG_PCI was just a final touch by
Andrew Morton. The only real change were from having two variables, for
eisa and pci, to having one common.
>Instead of doing that, we should simply make sure that the
>cardcount variable is always used.
>
>
Is it not? The problem were that dgrs_pci_driver was not defined if
!CONFIG_PCI, and because the pci_*-functions have empty shells if
!CONFIG_PCI, it is quite nice to use them without #ifdef.
So the simplest solution (as I saw it) was to define an empty
dgrs_pci_driver when CONFIG_PCI is not set.
On the design perspective, I would argue that struct's is more
appropriate within #ifdef's then functions.
>The following patch does this by making inline function wrappers
>to do the actual registration/deregistration.
>
>
I must say, I like that eisa gets addressed in the same manner as pci.
But is it not more appropriate to implement empty eisa-functions if
!CONFIG_EISA in linux/eisa.h (or equal)?
>This problem was reported by Richard Knutsson.
>
>Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
>Cheers,
>
>
Thank you for the review,
Richard Knutsson
PS
You realize you have not tushed the cardcount-"problem"? ;)
DS
> diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
> --- a/drivers/net/dgrs.c
> +++ b/drivers/net/dgrs.c
> @@ -1458,6 +1458,25 @@ static struct pci_driver dgrs_pci_driver
> .probe = dgrs_pci_probe,
> .remove = __devexit_p(dgrs_pci_remove),
> };
> +
> +static inline int dgrs_register_pci(void)
> +{
> + return pci_register_driver(&dgrs_pci_driver);
> +}
> +
> +static inline void dgrs_unregister_pci(void)
> +{
> + pci_unregister_driver(&dgrs_pci_driver);
> +}
> +#else
> +static inline int dgrs_register_pci(void)
> +{
> + return 0;
> +}
> +
> +static inline int dgrs_unregister_pci(void)
> +{
> +}
> #endif
>
>
> @@ -1520,6 +1539,25 @@ static struct eisa_driver dgrs_eisa_driv
> .remove = __devexit_p(dgrs_eisa_remove),
> }
> };
> +
> +static inline int dgrs_register_eisa(void)
> +{
> + return eisa_driver_register(&dgrs_eisa_driver);
> +}
> +
> +static inline void dgrs_unregister_eisa(void)
> +{
> + eisa_driver_unregister(&dgrs_eisa_driver);
> +}
> +#else
> +static inline int dgrs_register_eisa(void)
> +{
> + return 0;
> +}
> +
> +static inline void dgrs_unregister_eisa(void)
> +{
> +}
> #endif
>
> /*
> @@ -1590,25 +1628,21 @@ static int __init dgrs_init_module (void
> /*
> * Find and configure all the cards
> */
> -#ifdef CONFIG_EISA
> - cardcount = eisa_driver_register(&dgrs_eisa_driver);
> + cardcount = dgrs_register_eisa();
> if (cardcount < 0)
> return cardcount;
> -#endif
> - cardcount = pci_register_driver(&dgrs_pci_driver);
> - if (cardcount)
> + cardcount = dgrs_register_pci();
> + if (cardcount < 0) {
Are you sure it should be "cardcount < 0" and not "cardcount"?
> + dgrs_unregister_eisa();
Why change the behaviour off this driver?
> return cardcount;
> + }
> return 0;
> }
>
> static void __exit dgrs_cleanup_module (void)
> {
> -#ifdef CONFIG_EISA
> - eisa_driver_unregister (&dgrs_eisa_driver);
> -#endif
> -#ifdef CONFIG_PCI
> - pci_unregister_driver (&dgrs_pci_driver);
> -#endif
> + dgrs_unregister_pci();
> + dgrs_unregister_eisa();
> }
>
> module_init(dgrs_init_module);
^ permalink raw reply
* Re: [PATCH -mm2] net: Fix compiler-error on dgrs.c when !CONFIG_PCI
From: Herbert Xu @ 2005-11-20 10:24 UTC (permalink / raw)
To: Richard Knutsson
Cc: akpm, linux-kernel, ricknu-0, netdev, jgarzik, ashutosh.naik
In-Reply-To: <20051120014408.20407.66374.sendpatchset@thinktank.campus.ltu.se>
Richard Knutsson <ricknu-0@student.ltu.se> wrote:
>
> diff -Narup a/drivers/net/dgrs.c b/drivers/net/dgrs.c
> --- a/drivers/net/dgrs.c 2005-11-19 20:17:51.000000000 +0100
> +++ b/drivers/net/dgrs.c 2005-11-19 20:29:52.000000000 +0100
> @@ -1458,6 +1458,8 @@ static struct pci_driver dgrs_pci_driver
> .probe = dgrs_pci_probe,
> .remove = __devexit_p(dgrs_pci_remove),
> };
> +#else
> +static struct pci_driver dgrs_pci_driver = {};
> #endif
How about something like this?
[NETDRV] dgrs: Fix compiler-error on dgrs.c when !CONFIG_PCI
The previous patch on this driver removed the #ifdef CONFIG_PCI
around the pci_register_driver call in order to avoid a warning
about an unused variable. This produces an error since the PCI
driver object is undefined if CONFIG_PCI is not set.
Instead of doing that, we should simply make sure that the
cardcount variable is always used.
The following patch does this by making inline function wrappers
to do the actual registration/deregistration.
This problem was reported by Richard Knutsson.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1458,6 +1458,25 @@ static struct pci_driver dgrs_pci_driver
.probe = dgrs_pci_probe,
.remove = __devexit_p(dgrs_pci_remove),
};
+
+static inline int dgrs_register_pci(void)
+{
+ return pci_register_driver(&dgrs_pci_driver);
+}
+
+static inline void dgrs_unregister_pci(void)
+{
+ pci_unregister_driver(&dgrs_pci_driver);
+}
+#else
+static inline int dgrs_register_pci(void)
+{
+ return 0;
+}
+
+static inline int dgrs_unregister_pci(void)
+{
+}
#endif
@@ -1520,6 +1539,25 @@ static struct eisa_driver dgrs_eisa_driv
.remove = __devexit_p(dgrs_eisa_remove),
}
};
+
+static inline int dgrs_register_eisa(void)
+{
+ return eisa_driver_register(&dgrs_eisa_driver);
+}
+
+static inline void dgrs_unregister_eisa(void)
+{
+ eisa_driver_unregister(&dgrs_eisa_driver);
+}
+#else
+static inline int dgrs_register_eisa(void)
+{
+ return 0;
+}
+
+static inline void dgrs_unregister_eisa(void)
+{
+}
#endif
/*
@@ -1590,25 +1628,21 @@ static int __init dgrs_init_module (void
/*
* Find and configure all the cards
*/
-#ifdef CONFIG_EISA
- cardcount = eisa_driver_register(&dgrs_eisa_driver);
+ cardcount = dgrs_register_eisa();
if (cardcount < 0)
return cardcount;
-#endif
- cardcount = pci_register_driver(&dgrs_pci_driver);
- if (cardcount)
+ cardcount = dgrs_register_pci();
+ if (cardcount < 0) {
+ dgrs_unregister_eisa();
return cardcount;
+ }
return 0;
}
static void __exit dgrs_cleanup_module (void)
{
-#ifdef CONFIG_EISA
- eisa_driver_unregister (&dgrs_eisa_driver);
-#endif
-#ifdef CONFIG_PCI
- pci_unregister_driver (&dgrs_pci_driver);
-#endif
+ dgrs_unregister_pci();
+ dgrs_unregister_eisa();
}
module_init(dgrs_init_module);
^ permalink raw reply
* Re: [DEBUG INFO]IPv6: sleeping function called from invalid context.
From: Herbert Xu @ 2005-11-19 22:38 UTC (permalink / raw)
To: Thomas Graf; +Cc: yoshfuji, yanzheng, netdev, linux-kernel
In-Reply-To: <20051119210411.GE20395@postel.suug.ch>
On Sat, Nov 19, 2005 at 10:04:11PM +0100, Thomas Graf wrote:
>
> The continued dumps wouldn't be the problem, the walker is allocated
> on the initial dump call. It was a mistake though, nlk->cb_lock spin
> lock is always held for cb->dump() even though it should only be
> required during the nlk->cb != NULL check. netlink_dump_start()
> guarantees to only allow one dumper per socket at a time.
You're certainly right that the initial dump is what's causing the
problem.
I think the spin lock is still required though because we also need
to guard against netlink_release which can occur at any time since
the packet processing could be occuring in a different thread from
the one that did the sendmsg.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: build bug: ipt_CONNMARK.c: undefined reference to `need_ip_conntrack'
From: Harald Welte @ 2005-11-19 22:23 UTC (permalink / raw)
To: Yasuyuki KOZAKAI; +Cc: khc, netfilter-devel, netdev, linux-kernel
In-Reply-To: <200511191930.jAJJUJ2n022269@toshiba.co.jp>
[-- Attachment #1: Type: text/plain, Size: 525 bytes --]
On Sun, Nov 20, 2005 at 04:30:18AM +0900, Yasuyuki KOZAKAI wrote:
> Thanks for report. Could you check this patch ?
thanks, applied and forwarded.
--
- Harald Welte <laforge@netfilter.org> http://netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: build bug: ipt_CONNMARK.c: undefined reference to `need_ip_conntrack'
From: Krzysztof Halasa @ 2005-11-19 21:56 UTC (permalink / raw)
To: Yasuyuki KOZAKAI; +Cc: laforge, netfilter-devel, netdev, linux-kernel
In-Reply-To: <200511191930.jAJJUJEv022269@toshiba.co.jp>
Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp> writes:
>> LD init/built-in.o
>> LD .tmp_vmlinux1
>> net/built-in.o(.init.text+0x1adb): In function `init':
>> ipt_CONNMARK.c: undefined reference to `need_ip_conntrack'
>> make[2]: *** [.tmp_vmlinux1] Error 1
>>
>> Last merged Linus' git: b286e39207237e2f6929959372bf66d9a8d05a82
>> (i.e., current 2.6.15rc1+).
>
> Thanks for report. Could you check this patch ?
Builds correctly. Thanks.
--
Krzysztof Halasa
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox