* [PATCH] MASQUERADE handling of device events
@ 2004-11-07 18:18 Phil Oester
2004-11-08 1:06 ` Henrik Nordstrom
` (3 more replies)
0 siblings, 4 replies; 17+ messages in thread
From: Phil Oester @ 2004-11-07 18:18 UTC (permalink / raw)
To: netfilter-devel; +Cc: linux-net
[-- Attachment #1: Type: text/plain, Size: 804 bytes --]
As discussed in recent days, MASQUERADE target handling of device events
is broken in a couple of ways:
1) when ppp interfaces cycle, conntracks with old ip addresses are not
flushed
2) an 'ip addr add' on an interface used for masquerading flushes all
conntracks associated with that interface
The below patch addresses these issues by changing from using ifindex
comparisons to verifying that the masquerading ip still exists on the
box.
To achieve this, two changes were required to core networking code (thus
the linux-net cc):
1) export inet_confirm_addr
2) change inet_ifa_match to use ifa_local instead of ifa_address.
Since ifa_local != ifa_address on ppp interfaces, inet_ifa_match
could not be used to verify ppp interface addresses without
this change.
Comments?
Phil
[-- Attachment #2: patch-masq2 --]
[-- Type: text/plain, Size: 2466 bytes --]
diff -ru linux-orig/include/linux/inetdevice.h linux-diff/include/linux/inetdevice.h
--- linux-orig/include/linux/inetdevice.h 2004-11-04 17:32:05.573870736 -0500
+++ linux-diff/include/linux/inetdevice.h 2004-11-07 12:57:50.674323160 -0500
@@ -114,7 +114,7 @@
static __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa)
{
- return !((addr^ifa->ifa_address)&ifa->ifa_mask);
+ return !((addr^ifa->ifa_local)&ifa->ifa_mask);
}
/*
diff -ru linux-orig/net/ipv4/devinet.c linux-diff/net/ipv4/devinet.c
--- linux-orig/net/ipv4/devinet.c 2004-11-04 17:32:05.000000000 -0500
+++ linux-diff/net/ipv4/devinet.c 2004-11-07 12:56:27.738931256 -0500
@@ -1493,6 +1493,7 @@
EXPORT_SYMBOL(devinet_ioctl);
EXPORT_SYMBOL(in_dev_finish_destroy);
+EXPORT_SYMBOL(inet_confirm_addr);
EXPORT_SYMBOL(inet_select_addr);
EXPORT_SYMBOL(inetdev_by_index);
EXPORT_SYMBOL(register_inetaddr_notifier);
diff -ru linux-orig/net/ipv4/netfilter/ipt_MASQUERADE.c linux-diff/net/ipv4/netfilter/ipt_MASQUERADE.c
--- linux-orig/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-04 17:32:05.000000000 -0500
+++ linux-diff/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-07 12:55:56.501680040 -0500
@@ -118,16 +118,15 @@
}
static inline int
-device_cmp(const struct ip_conntrack *i, void *_ina)
+device_cmp(const struct ip_conntrack *i, void *junk)
{
int ret = 0;
- struct in_ifaddr *ina = _ina;
READ_LOCK(&masq_lock);
- /* If it's masquerading out this interface with a different address,
- or we don't know the new address of this interface. */
- if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
- && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
+ /* If masquerading this conntrack but the masquerading ip
+ no longer exists locally, drop conntrack. */
+ if (i->nat.masq_index && !(inet_confirm_addr(NULL, 0,
+ i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip, RT_SCOPE_HOST)))
ret = 1;
READ_UNLOCK(&masq_lock);
@@ -150,11 +149,10 @@
unsigned long event,
void *ptr)
{
- /* For some configurations, interfaces often come back with
- * the same address. If not, clean up old conntrack
- * entries. */
+ /* In some configurations, interfaces come back with the
+ * same address. If not, clean up old conntrack entries. */
if (event == NETDEV_UP)
- ip_ct_selective_cleanup(device_cmp, ptr);
+ ip_ct_selective_cleanup(device_cmp, NULL);
else if (event == NETDEV_DOWN)
ip_ct_selective_cleanup(connect_unassure, ptr);
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH] MASQUERADE handling of device events 2004-11-07 18:18 [PATCH] MASQUERADE handling of device events Phil Oester @ 2004-11-08 1:06 ` Henrik Nordstrom 2004-11-08 13:50 ` Harald Welte ` (2 subsequent siblings) 3 siblings, 0 replies; 17+ messages in thread From: Henrik Nordstrom @ 2004-11-08 1:06 UTC (permalink / raw) To: Phil Oester; +Cc: netfilter-devel On Sun, 7 Nov 2004, Phil Oester wrote: > To achieve this, two changes were required to core networking code (thus > the linux-net cc): > > 1) export inet_confirm_addr > > 2) change inet_ifa_match to use ifa_local instead of ifa_address. > Since ifa_local != ifa_address on ppp interfaces, inet_ifa_match > could not be used to verify ppp interface addresses without > this change. > > Comments? Looks fine to me, but maybe we should also utilize the fact that nat.masq_index with this change only needs to be a boolean flag "this connection is masqueraded", allowing us to cut down a little on the conntrack entry size. Regards Henrik ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-07 18:18 [PATCH] MASQUERADE handling of device events Phil Oester 2004-11-08 1:06 ` Henrik Nordstrom @ 2004-11-08 13:50 ` Harald Welte 2004-11-11 22:58 ` David S. Miller 2004-11-08 16:05 ` Patrick McHardy 2004-11-21 2:58 ` Rusty Russell 3 siblings, 1 reply; 17+ messages in thread From: Harald Welte @ 2004-11-08 13:50 UTC (permalink / raw) To: Phil Oester; +Cc: linux-net, netfilter-devel [-- Attachment #1: Type: text/plain, Size: 1139 bytes --] [added explicit Cc to Dave] On Sun, Nov 07, 2004 at 10:18:25AM -0800, Phil Oester wrote: > The below patch addresses these issues by changing from using ifindex > comparisons to verifying that the masquerading ip still exists on the > box. > > To achieve this, two changes were required to core networking code (thus > the linux-net cc): Thanks, Phil. I think this solution is about the best we can get. Any other comments? Dave: would the two changes below be acceptable for you? > 1) export inet_confirm_addr > > 2) change inet_ifa_match to use ifa_local instead of ifa_address. > Since ifa_local != ifa_address on ppp interfaces, inet_ifa_match > could not be used to verify ppp interface addresses without > this change. -- - Harald Welte <laforge@netfilter.org> http://www.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: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 13:50 ` Harald Welte @ 2004-11-11 22:58 ` David S. Miller 0 siblings, 0 replies; 17+ messages in thread From: David S. Miller @ 2004-11-11 22:58 UTC (permalink / raw) To: Harald Welte; +Cc: linux-net, netfilter-devel On Mon, 8 Nov 2004 14:50:25 +0100 Harald Welte <laforge@netfilter.org> wrote: > Dave: would the two changes below be acceptable for you? > > > 1) export inet_confirm_addr This one I think is OK. > > 2) change inet_ifa_match to use ifa_local instead of ifa_address. > > Since ifa_local != ifa_address on ppp interfaces, inet_ifa_match > > could not be used to verify ppp interface addresses without > > this change. This one on the other hand is a serious semantic change and needs more careful thought. ifa_address is used for a reason, and people expecting that are going to break if we change things this way. A study of at least the net/ipv4/devinet.c shows that this ifa_address vs. ifa_local distinction is definitely on purpose. I really don't think we can make this suggested change therefore. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-07 18:18 [PATCH] MASQUERADE handling of device events Phil Oester 2004-11-08 1:06 ` Henrik Nordstrom 2004-11-08 13:50 ` Harald Welte @ 2004-11-08 16:05 ` Patrick McHardy 2004-11-08 16:15 ` Phil Oester 2004-11-21 2:58 ` Rusty Russell 3 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2004-11-08 16:05 UTC (permalink / raw) To: Phil Oester; +Cc: linux-net, netfilter-devel Phil Oester wrote: >As discussed in recent days, MASQUERADE target handling of device events >is broken in a couple of ways: > >1) when ppp interfaces cycle, conntracks with old ip addresses are not > flushed > >2) an 'ip addr add' on an interface used for masquerading flushes all > conntracks associated with that interface > >The below patch addresses these issues by changing from using ifindex >comparisons to verifying that the masquerading ip still exists on the >box. > But without the ifindex comparison, a situation like this can happen: ppp0 goes down ppp1 goes down ppp0 comes up again, same IP as before ppp1 connections get killed ppp1 comes up again So we should keep this. Regards Patrick > > >------------------------------------------------------------------------ > >diff -ru linux-orig/include/linux/inetdevice.h linux-diff/include/linux/inetdevice.h >--- linux-orig/include/linux/inetdevice.h 2004-11-04 17:32:05.573870736 -0500 >+++ linux-diff/include/linux/inetdevice.h 2004-11-07 12:57:50.674323160 -0500 >@@ -114,7 +114,7 @@ > > static __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa) > { >- return !((addr^ifa->ifa_address)&ifa->ifa_mask); >+ return !((addr^ifa->ifa_local)&ifa->ifa_mask); > } > > /* >diff -ru linux-orig/net/ipv4/devinet.c linux-diff/net/ipv4/devinet.c >--- linux-orig/net/ipv4/devinet.c 2004-11-04 17:32:05.000000000 -0500 >+++ linux-diff/net/ipv4/devinet.c 2004-11-07 12:56:27.738931256 -0500 >@@ -1493,6 +1493,7 @@ > > EXPORT_SYMBOL(devinet_ioctl); > EXPORT_SYMBOL(in_dev_finish_destroy); >+EXPORT_SYMBOL(inet_confirm_addr); > EXPORT_SYMBOL(inet_select_addr); > EXPORT_SYMBOL(inetdev_by_index); > EXPORT_SYMBOL(register_inetaddr_notifier); >diff -ru linux-orig/net/ipv4/netfilter/ipt_MASQUERADE.c linux-diff/net/ipv4/netfilter/ipt_MASQUERADE.c >--- linux-orig/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-04 17:32:05.000000000 -0500 >+++ linux-diff/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-07 12:55:56.501680040 -0500 >@@ -118,16 +118,15 @@ > } > > static inline int >-device_cmp(const struct ip_conntrack *i, void *_ina) >+device_cmp(const struct ip_conntrack *i, void *junk) > { > int ret = 0; >- struct in_ifaddr *ina = _ina; > > READ_LOCK(&masq_lock); >- /* If it's masquerading out this interface with a different address, >- or we don't know the new address of this interface. */ >- if (i->nat.masq_index == ina->ifa_dev->dev->ifindex >- && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address) >+ /* If masquerading this conntrack but the masquerading ip >+ no longer exists locally, drop conntrack. */ >+ if (i->nat.masq_index && !(inet_confirm_addr(NULL, 0, >+ i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip, RT_SCOPE_HOST))) > ret = 1; > READ_UNLOCK(&masq_lock); > >@@ -150,11 +149,10 @@ > unsigned long event, > void *ptr) > { >- /* For some configurations, interfaces often come back with >- * the same address. If not, clean up old conntrack >- * entries. */ >+ /* In some configurations, interfaces come back with the >+ * same address. If not, clean up old conntrack entries. */ > if (event == NETDEV_UP) >- ip_ct_selective_cleanup(device_cmp, ptr); >+ ip_ct_selective_cleanup(device_cmp, NULL); > else if (event == NETDEV_DOWN) > ip_ct_selective_cleanup(connect_unassure, ptr); > > > ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 16:05 ` Patrick McHardy @ 2004-11-08 16:15 ` Phil Oester 2004-11-08 16:24 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Phil Oester @ 2004-11-08 16:15 UTC (permalink / raw) To: Patrick McHardy; +Cc: linux-net, netfilter-devel On Mon, Nov 08, 2004 at 05:05:38PM +0100, Patrick McHardy wrote: > But without the ifindex comparison, a situation like this can happen: > > ppp0 goes down > ppp1 goes down > ppp0 comes up again, same IP as before > ppp1 connections get killed > ppp1 comes up again > > So we should keep this. But ifindex is meaningless on ppp interfaces - it is incremented on each cycle. So there is no way to say that the original ppp1 is the same interface as the new ppp1. ifindex just cannot be used reliably. Phil ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 16:15 ` Phil Oester @ 2004-11-08 16:24 ` Patrick McHardy 2004-11-08 16:34 ` Phil Oester 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2004-11-08 16:24 UTC (permalink / raw) To: Phil Oester; +Cc: netfilter-devel, linux-net Phil Oester wrote: >On Mon, Nov 08, 2004 at 05:05:38PM +0100, Patrick McHardy wrote: > >>But without the ifindex comparison, a situation like this can happen: >> >>ppp0 goes down >>ppp1 goes down >>ppp0 comes up again, same IP as before >>ppp1 connections get killed >>ppp1 comes up again >> >>So we should keep this. >> > >But ifindex is meaningless on ppp interfaces - it is incremented on each >cycle. So there is no way to say that the original ppp1 is the same >interface as the new ppp1. > >ifindex just cannot be used reliably. > Of course, I wasn't thinking :) Then what about Henrik's suggestion, replacing masq_index by a new status bit ? Regards Patrick ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 16:24 ` Patrick McHardy @ 2004-11-08 16:34 ` Phil Oester 2004-11-08 21:55 ` Phil Oester 0 siblings, 1 reply; 17+ messages in thread From: Phil Oester @ 2004-11-08 16:34 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Mon, Nov 08, 2004 at 05:24:52PM +0100, Patrick McHardy wrote: > >ifindex just cannot be used reliably. > > > Of course, I wasn't thinking :) Then what about Henrik's suggestion, > replacing masq_index by a new status bit ? It's a great idea, and will reduce the size of struct ip_conntrack. But I think it should be done in a separate cleanup patch - really would like to get this one merged up to fix the masq issues. Phil ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 16:34 ` Phil Oester @ 2004-11-08 21:55 ` Phil Oester 2004-11-09 11:04 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Phil Oester @ 2004-11-08 21:55 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Mon, Nov 08, 2004 at 08:34:57AM -0800, Phil Oester wrote: > It's a great idea, and will reduce the size of struct ip_conntrack. > But I think it should be done in a separate cleanup patch - really would > like to get this one merged up to fix the masq issues. Actually masq_index is still used in connect_unassure, and thus can't be removed completely. In cases where the interface goes down permanently, clearing the assured bit makes sense, so guess this behaviour should be maintained. Phil ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-08 21:55 ` Phil Oester @ 2004-11-09 11:04 ` Patrick McHardy 2004-11-09 16:53 ` Phil Oester 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2004-11-09 11:04 UTC (permalink / raw) To: Phil Oester; +Cc: netfilter-devel [-- Attachment #1: Type: text/plain, Size: 1444 bytes --] Phil Oester wrote: >On Mon, Nov 08, 2004 at 08:34:57AM -0800, Phil Oester wrote: > > >>It's a great idea, and will reduce the size of struct ip_conntrack. >>But I think it should be done in a separate cleanup patch - really would >>like to get this one merged up to fix the masq issues. >> >> > >Actually masq_index is still used in connect_unassure, and thus can't >be removed completely. In cases where the interface goes down permanently, >clearing the assured bit makes sense, so guess this behaviour should be >maintained. > > You're right. I have to admit, I'm not too happy about the unpredictable behaviour we get with this patch and multiple ppp devices. So one last attempt to convince people. The old behaviour was to kill conntracks once the device goes down. I think killing conntracks when the IP is deleted makes more sense. Since the IP has to be deleted manually, except when the device goes away, people can simply not delete IP addresses for devices that don't go away, than nothing will get removed. pppd can be taught to keep the device alive. The attached patch adds a program alloc-ppp to pre-allocate ppp-devices and teaches pppd to attach to them. The device never goes away, if ppp doesn't delete the IP address the conntracks won't be killed. It could easily be integrated in a more handy way in pppd. So this could also be done entirely in userspace, without the unpredictable behaviour. Regards Patrick [-- Attachment #2: ppp_attach.diff --] [-- Type: text/x-patch, Size: 3438 bytes --] diff -urN a/pppd/alloc-ppp.c b/pppd/alloc-ppp.c --- a/pppd/alloc-ppp.c 1970-01-01 01:00:00.000000000 +0100 +++ b/pppd/alloc-ppp.c 2004-11-04 17:09:35.804341216 +0100 @@ -0,0 +1,64 @@ + + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> + +#include <sys/ioctl.h> + +#include <asm/types.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/route.h> +#include <netinet/if_ether.h> + + +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> + + + +int main( int argc, char ** argv ) { + + int ndev = 0; + int n = 0; + int ppp_dev_fd = 0; + + if( argc != 2 ) { + fprintf(stderr,"use \"%s <n>\" to allocate n ppp devices\n", argv[0]); + exit(1); + } + + ndev = atoi(argv[1]); + + if( ndev <= 0 ) { + fprintf(stderr,"argument must b a number > 0 not %s\n", argv[1]); + exit(1); + } + + for( n = 0; n < ndev; n ++ ) { + int ifunit = n; + int res = 0; + + if( (ppp_dev_fd = open("/dev/ppp", O_RDWR )) < 0 ) { + perror("can not open /dev/ppp :"); + exit(2); + } + + res = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + if( res < 0 ) { + fprintf(stderr, "can not allocate ppp device %d : %s \n", + n , strerror(errno) ); + } + } + + while( 1 == 1 ) { + sleep(3600); + } + + exit(0); +} + diff -urN a/pppd/Makefile.linux b/pppd/Makefile.linux --- a/pppd/Makefile.linux 2003-11-27 22:55:19.000000000 +0100 +++ b/pppd/Makefile.linux 2004-11-04 17:09:35.804341216 +0100 @@ -8,7 +8,7 @@ MANDIR = $(DESTDIR)/usr/man INCDIR = $(DESTDIR)/usr/include -TARGETS = pppd +TARGETS = pppd alloc-ppp PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap-new.c md5.c ccp.c \ ecp.c ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c \ @@ -196,10 +196,11 @@ all: $(TARGETS) -install: pppd +install: pppd alloc-ppp mkdir -p $(BINDIR) $(MANDIR) $(EXTRAINSTALL) $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd + $(INSTALL) -s -c -m 555 alloc-ppp $(BINDIR)/alloc-ppp if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \ chmod o-rx,u+s $(BINDIR)/pppd; fi $(INSTALL) -c -m 444 pppd.8 $(MANDIR)/man8 @@ -207,6 +208,9 @@ pppd: $(PPPDOBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) +alloc-ppp: alloc-ppp.o + $(CC) $(CFLAGS) -o alloc-ppp alloc-ppp.o + srp-entry: srp-entry.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ srp-entry.c $(LIBS) @@ -216,6 +220,7 @@ clean: rm -f $(PPPDOBJS) $(EXTRACLEAN) $(TARGETS) *~ #* core + rm -f alloc-ppp.o alloc-ppp depend: $(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend diff -urN a/pppd/sys-linux.c b/pppd/sys-linux.c --- a/pppd/sys-linux.c 2004-01-13 05:05:20.000000000 +0100 +++ b/pppd/sys-linux.c 2004-11-04 17:10:06.951606112 +0100 @@ -639,6 +639,21 @@ warn("Couldn't set /dev/ppp to nonblock: %m"); ifunit = req_unit; + + /* + * try to attach to an alread existing ppp device. We should + * get an EFAULT if the ppp interface is in use by another pppd. + */ + if (ifunit >= 0) { + x = ioctl(ppp_dev_fd, PPPIOCATTACH , &ifunit); + if (x < 0) { + /* warn and continue to create a new device */ + warn("Couldn't attatch to unit %d as it does not exist", req_unit); + } else { + return x; + } + } + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); if (x < 0 && req_unit >= 0 && errno == EEXIST) { warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-09 11:04 ` Patrick McHardy @ 2004-11-09 16:53 ` Phil Oester 2004-11-09 17:44 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Phil Oester @ 2004-11-09 16:53 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Tue, Nov 09, 2004 at 12:04:47PM +0100, Patrick McHardy wrote: > You're right. I have to admit, I'm not too happy about the unpredictable > behaviour we get with this patch and multiple ppp devices. So one last > attempt to convince people. The old behaviour was to kill conntracks once > the device goes down. I think killing conntracks when the IP is deleted > makes more sense. Since the IP has to be deleted manually, except when > the device goes away, people can simply not delete IP addresses for > devices that don't go away, than nothing will get removed. pppd can be > taught to keep the device alive. The attached patch adds a program > alloc-ppp to pre-allocate ppp-devices and teaches pppd to attach to them. > The device never goes away, if ppp doesn't delete the IP address the > conntracks won't be killed. It could easily be integrated in a more handy > way in pppd. So this could also be done entirely in userspace, without > the unpredictable behaviour. Is this the unpredictable behaviour you refer to: ppp0 down -> clear assured bit on ppp0 conntracks ppp1 down -> clear assured bit on ppp1 conntracks ppp0 up with same ip -> all ppp1 conntracks get cleared since that ip no longer exists on box ppp1 up with same ip -> loser Not much we can do about that except revert to the old behaviour of dropping all conntracks on interface down, but that does seem silly for 'mostly static' pppoe users. Obviously I'd vote for the 'friendlier' method, but bottom line is current behaviour is broken and should be fixed somehow... Phil ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-09 16:53 ` Phil Oester @ 2004-11-09 17:44 ` Patrick McHardy 0 siblings, 0 replies; 17+ messages in thread From: Patrick McHardy @ 2004-11-09 17:44 UTC (permalink / raw) To: Phil Oester; +Cc: Harald Welte, netfilter-devel Phil Oester wrote: >On Tue, Nov 09, 2004 at 12:04:47PM +0100, Patrick McHardy wrote: > > >>You're right. I have to admit, I'm not too happy about the unpredictable >>behaviour we get with this patch and multiple ppp devices. So one last >>attempt to convince people. The old behaviour was to kill conntracks once >>the device goes down. I think killing conntracks when the IP is deleted >>makes more sense. Since the IP has to be deleted manually, except when >>the device goes away, people can simply not delete IP addresses for >>devices that don't go away, than nothing will get removed. pppd can be >>taught to keep the device alive. The attached patch adds a program >>alloc-ppp to pre-allocate ppp-devices and teaches pppd to attach to them. >>The device never goes away, if ppp doesn't delete the IP address the >>conntracks won't be killed. It could easily be integrated in a more handy >>way in pppd. So this could also be done entirely in userspace, without >>the unpredictable behaviour. >> >> > >Is this the unpredictable behaviour you refer to: > >ppp0 down -> clear assured bit on ppp0 conntracks >ppp1 down -> clear assured bit on ppp1 conntracks >ppp0 up with same ip -> all ppp1 conntracks get cleared since that ip > no longer exists on box >ppp1 up with same ip -> loser > > Yes. It gives unpredictable behaviour and no way to avoid it. If ppp1 comes up first - ppp0 is the loser. If only one goes down at a time - nobody looses. >Not much we can do about that except revert to the old behaviour of >dropping all conntracks on interface down, but that does seem silly >for 'mostly static' pppoe users. > >Obviously I'd vote for the 'friendlier' method, but bottom line is current >behaviour is broken and should be fixed somehow... > > I think deterministic behaviour is more friendly than something working only under certain conditions and doing strange stuff the remaining time. I would like to hear Harald's opinion. Regards Patrick ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-07 18:18 [PATCH] MASQUERADE handling of device events Phil Oester ` (2 preceding siblings ...) 2004-11-08 16:05 ` Patrick McHardy @ 2004-11-21 2:58 ` Rusty Russell 2004-11-23 21:16 ` Phil Oester 3 siblings, 1 reply; 17+ messages in thread From: Rusty Russell @ 2004-11-21 2:58 UTC (permalink / raw) To: Phil Oester; +Cc: linux-net, Netfilter development mailing list On Sun, 2004-11-07 at 10:18 -0800, Phil Oester wrote: > As discussed in recent days, MASQUERADE target handling of device events > is broken in a couple of ways: > > 1) when ppp interfaces cycle, conntracks with old ip addresses are not > flushed > > 2) an 'ip addr add' on an interface used for masquerading flushes all > conntracks associated with that interface Sorry, just caught up with this reversion in 2.6.10-rc2-bk* (was trying to figure out why my nfsim testcase was failing: this explains it). We had numerous complaints about the old behaviour: several people with small (or clever?) ISPs actually got the same IP address most of the time, and the old code was damaging them. It also registered two callbacks which AFAICT is unnecessary. This patch bloats conntrack, but is worth it IMHO. Most importantly, Phil, does it work for you? Rusty. Name: Reliable Masquerading Connection Removal Status: Compiles, Untested Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> The MASQUERADE target use to destroy connections when an interface went down. We changed this to merely remove the ASSURED bit, and destroy them if the same interface came up with a different IP address. Unfortunately, as Phil Oester pointed out, that code was crap for PPP connections, since we (1) compared ifa_address instead of ifa_local, (2) identified interfaces by ifindex, which increments as a PPP device downs and ups, and (3) caused all connections to be flushed when we added an IP address. So that code was reverted after 2.6.10-rc2. This code stores the interface name, rather than trying to use the ifindex, and only deletes connections if *no* ifa_local on the interface matches the connection, so simply adding a new IP address is a NOOP. Index: linux-2.6.10-rc2-bk1-Netfilter/include/linux/netfilter_ipv4/ip_conntrack.h =================================================================== --- linux-2.6.10-rc2-bk1-Netfilter.orig/include/linux/netfilter_ipv4/ip_conntrack.h 2004-11-20 17:53:54.000000000 +1100 +++ linux-2.6.10-rc2-bk1-Netfilter/include/linux/netfilter_ipv4/ip_conntrack.h 2004-11-20 17:55:40.000000000 +1100 @@ -193,7 +193,7 @@ union ip_conntrack_nat_help help; #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) - int masq_index; + char masq_iface[IFNAMSIZ]; #endif } nat; #endif /* CONFIG_IP_NF_NAT_NEEDED */ Index: linux-2.6.10-rc2-bk1-Netfilter/net/ipv4/netfilter/ipt_MASQUERADE.c =================================================================== --- linux-2.6.10-rc2-bk1-Netfilter.orig/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-19 16:51:36.000000000 +1100 +++ linux-2.6.10-rc2-bk1-Netfilter/net/ipv4/netfilter/ipt_MASQUERADE.c 2004-11-21 13:50:02.943750896 +1100 @@ -104,7 +104,7 @@ } WRITE_LOCK(&masq_lock); - ct->nat.masq_index = out->ifindex; + strcpy(ct->nat.masq_iface, out->name); WRITE_UNLOCK(&masq_lock); /* Transfer from original range. */ @@ -118,57 +118,61 @@ } static inline int -device_cmp(const struct ip_conntrack *i, void *ifindex) +no_address_matches(u32 dstip, struct in_device *in_dev) { - int ret; + struct in_ifaddr *i; + + for (i = in_dev->ifa_list; i; i = i->ifa_next) + if (i->ifa_local == dstip) + return 0; + return 1; +} + +static inline int +device_cmp(const struct ip_conntrack *i, void *_ina) +{ + int ret = 0; + struct in_ifaddr *ina = _ina; READ_LOCK(&masq_lock); - ret = (i->nat.masq_index == (int)(long)ifindex); + /* If it's masquerading out this interface with an address, + * which is not any of the existing ones, time to go. */ + if (strcmp(i->nat.masq_iface, ina->ifa_dev->dev->name) == 0 + && no_address_matches(i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip, + ina->ifa_dev)) + ret = 1; READ_UNLOCK(&masq_lock); return ret; } -static int masq_device_event(struct notifier_block *this, - unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - - if (event == NETDEV_DOWN) { - /* Device was downed. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } +static inline int +connect_unassure(const struct ip_conntrack *i, void *_ina) +{ + struct in_ifaddr *ina = _ina; - return NOTIFY_DONE; + /* We reset the ASSURED bit on all connections, so they will + * get reaped under memory pressure. */ + if (strcmp(i->nat.masq_iface, ina->ifa_dev->dev->name) == 0) + clear_bit(IPS_ASSURED_BIT, (unsigned long *)&i->status); + return 0; } static int masq_inet_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; - - if (event == NETDEV_DOWN) { - /* IP address was deleted. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } + /* For some configurations, interfaces often come back with + * the same address. If not, clean up old conntrack + * entries. */ + if (event == NETDEV_UP) + ip_ct_selective_cleanup(device_cmp, ptr); + else if (event == NETDEV_DOWN) + ip_ct_selective_cleanup(connect_unassure, ptr); return NOTIFY_DONE; } -static struct notifier_block masq_dev_notifier = { - .notifier_call = masq_device_event, -}; - static struct notifier_block masq_inet_notifier = { .notifier_call = masq_inet_event, }; @@ -187,8 +191,6 @@ ret = ipt_register_target(&masquerade); if (ret == 0) { - /* Register for device down reports */ - register_netdevice_notifier(&masq_dev_notifier); /* Register IP address change reports */ register_inetaddr_notifier(&masq_inet_notifier); } @@ -199,7 +201,6 @@ static void __exit fini(void) { ipt_unregister_target(&masquerade); - unregister_netdevice_notifier(&masq_dev_notifier); unregister_inetaddr_notifier(&masq_inet_notifier); } -- A bad analogy is like a leaky screwdriver -- Richard Braakman ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-21 2:58 ` Rusty Russell @ 2004-11-23 21:16 ` Phil Oester 2004-11-24 3:37 ` Rusty Russell 0 siblings, 1 reply; 17+ messages in thread From: Phil Oester @ 2004-11-23 21:16 UTC (permalink / raw) To: Rusty Russell; +Cc: Netfilter development mailing list On Sun, Nov 21, 2004 at 01:58:28PM +1100, Rusty Russell wrote: > The MASQUERADE target use to destroy connections when an interface > went down. We changed this to merely remove the ASSURED bit, and > destroy them if the same interface came up with a different IP > address. Unfortunately, as Phil Oester pointed out, that code was > crap for PPP connections, since we (1) compared ifa_address instead of > ifa_local, (2) identified interfaces by ifindex, which increments as a > PPP device downs and ups, and (3) caused all connections to be flushed > when we added an IP address. > > So that code was reverted after 2.6.10-rc2. > > This code stores the interface name, rather than trying to use the > ifindex, and only deletes connections if *no* ifa_local on the > interface matches the connection, so simply adding a new IP address is > a NOOP. But even using the interface name is unreliable. Consider the user who uses multiple PPP connections. Both go down at the same time, and come back with the 'old' ppp1 now named ppp0. Or consider a PopTop PPTP server which has dozens of ppp interfaces (although using masq here is admittedly unlikely). Perhaps my original patch which special-cased ppp would be better? http://lists.netfilter.org/pipermail/netfilter-devel/2004-November/017294.html Phil ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-23 21:16 ` Phil Oester @ 2004-11-24 3:37 ` Rusty Russell 2004-11-24 9:24 ` Henrik Nordstrom 0 siblings, 1 reply; 17+ messages in thread From: Rusty Russell @ 2004-11-24 3:37 UTC (permalink / raw) To: Phil Oester; +Cc: Netfilter development mailing list On Tue, 2004-11-23 at 13:16 -0800, Phil Oester wrote: > On Sun, Nov 21, 2004 at 01:58:28PM +1100, Rusty Russell wrote: > > The MASQUERADE target use to destroy connections when an interface > > went down. We changed this to merely remove the ASSURED bit, and > > destroy them if the same interface came up with a different IP > > address. Unfortunately, as Phil Oester pointed out, that code was > > crap for PPP connections, since we (1) compared ifa_address instead of > > ifa_local, (2) identified interfaces by ifindex, which increments as a > > PPP device downs and ups, and (3) caused all connections to be flushed > > when we added an IP address. > > > > So that code was reverted after 2.6.10-rc2. > > > > This code stores the interface name, rather than trying to use the > > ifindex, and only deletes connections if *no* ifa_local on the > > interface matches the connection, so simply adding a new IP address is > > a NOOP. > > But even using the interface name is unreliable. Consider the user who > uses multiple PPP connections. Both go down at the same time, and > come back with the 'old' ppp1 now named ppp0. Sure, in which case the connections will be dropped, as they would be in the naive case. This entire idea is best-effort, like NAT itself 8) I think it's worth trying, at least, but obviously the core team can override me. > Perhaps my original patch which special-cased ppp would be better? Drawing a link between point-to-point and addresses being static is wrong, IMHO. Rusty. -- A bad analogy is like a leaky screwdriver -- Richard Braakman ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-24 3:37 ` Rusty Russell @ 2004-11-24 9:24 ` Henrik Nordstrom 2004-11-24 15:39 ` Herve Eychenne 0 siblings, 1 reply; 17+ messages in thread From: Henrik Nordstrom @ 2004-11-24 9:24 UTC (permalink / raw) To: Rusty Russell; +Cc: Netfilter development mailing list On Wed, 24 Nov 2004, Rusty Russell wrote: > Drawing a link between point-to-point and addresses being static is > wrong, IMHO. Agreed. This discussion is equally important on Ethernet with dynamic IP assignment. Here the interface name is defenitely static. As already discussed very many times MASQUERADE is a best effort to handle the common "dial up like" with dynamic Internet IP assignment scenarios in an easy manner. A multiple PPP situation is more of an exception than rule to this, and in addition userspace has the option of using statically reserved PPP devices for the connections in question to make the proposed MASQUERADE fully predictable in such situations. Regards Henrik ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] MASQUERADE handling of device events 2004-11-24 9:24 ` Henrik Nordstrom @ 2004-11-24 15:39 ` Herve Eychenne 0 siblings, 0 replies; 17+ messages in thread From: Herve Eychenne @ 2004-11-24 15:39 UTC (permalink / raw) To: Henrik Nordstrom; +Cc: Rusty Russell, Netfilter development mailing list On Wed, Nov 24, 2004 at 10:24:34AM +0100, Henrik Nordstrom wrote: > On Wed, 24 Nov 2004, Rusty Russell wrote: > >Drawing a link between point-to-point and addresses being static is > >wrong, IMHO. > Agreed. > This discussion is equally important on Ethernet with dynamic IP > assignment. Here the interface name is defenitely static. > As already discussed very many times MASQUERADE is a best effort to handle > the common "dial up like" with dynamic Internet IP assignment scenarios in > an easy manner. A multiple PPP situation is more of an exception than > rule to this, and in addition userspace has the option of using statically > reserved PPP devices for the connections in question to make the proposed > MASQUERADE fully predictable in such situations. Being the guy who proposed the original change to Rusty during the workshop 2003, I eventually step up to support this view. :-) IMHO, the goal of the MASQUERADE target is trying to deal as nicely as possible with the common cases. I think it should be kept that way, no matter it may have some side effect for uncommon or obscur setups, as long as the potential corner cases are clearly documented. The more complex scenarios should always be able to use something else than MASQUERADE. Herve -- _ (°= Hervé Eychenne //) v_/_ WallFire project: http://www.wallfire.org/ ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2004-11-24 15:39 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-11-07 18:18 [PATCH] MASQUERADE handling of device events Phil Oester 2004-11-08 1:06 ` Henrik Nordstrom 2004-11-08 13:50 ` Harald Welte 2004-11-11 22:58 ` David S. Miller 2004-11-08 16:05 ` Patrick McHardy 2004-11-08 16:15 ` Phil Oester 2004-11-08 16:24 ` Patrick McHardy 2004-11-08 16:34 ` Phil Oester 2004-11-08 21:55 ` Phil Oester 2004-11-09 11:04 ` Patrick McHardy 2004-11-09 16:53 ` Phil Oester 2004-11-09 17:44 ` Patrick McHardy 2004-11-21 2:58 ` Rusty Russell 2004-11-23 21:16 ` Phil Oester 2004-11-24 3:37 ` Rusty Russell 2004-11-24 9:24 ` Henrik Nordstrom 2004-11-24 15:39 ` Herve Eychenne
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.