Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Mar 2007 13:56:48 +0100
From:      Roger Olofsson <raggen@passagen.se>
To:        Frank Knobbe <frank@knobbe.us>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Fix for bug in IPFilters ipfs tool
Message-ID:  <45F54E10.8090904@passagen.se>
In-Reply-To: <1173644486.23887.21.camel@localhost>
References:  <1173644486.23887.21.camel@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help
Hello Frank and thank you for your very inspiring post,

I have a similar setup, two machines, both dualhomed, connected to two 
small switches where only one machine has both nics active at the same time.

One diffence is that I use Freevrrpd as a heartbeat monitor which works 
excellent. The scripts you describe sounds similar to mine, I do some 
fiddling with cron as well and kick down and up some services.

When Freevrrpd makes the switch from one machine to the other all 
connections appear to remain unaltered. I have not tcpdumped to see how 
much gets lost in the 3 seconds or so that the switch is allowed to take 
but the transition appears to work.

I don't rely on ipfs at all, but your post made me realize that I should 
look into using it to complement freevrrpd.

Thank you,

/Roger

Frank Knobbe skrev:
> Greetings,
> 
> A couple years ago, I had sent a patch to Darren for ipfs in ipfilter
> (patched on FreeBSD 5.3). I never heard back from him, and assumed that
> either it wasn't in proper format or already being worked on or he was
> too busy.
> 
> Now that I'm upgrading my systems to FBSD 6.2, I encountered the same
> problem, and roughly the same fix has to be applied again, so it doesn't
> appear like it had been looked at. Hence I'm posting again (this time to
> the list).
> 
> My setup is such that I have two router connections from my hosting
> provider which I feed to two small switched which are linked with a
> cross-over cable. The server has two network cards which connect to each
> switch. Only one card is active at a time. I got a script running that
> pings the default gateway and when it fails, it does the following:
> - Bring interface A down, and B up.
> - Remove the IP address from i/f A and assign to i/f B.
> - Run sed over rc.conf, ipf.rules and ipnat.rules and change the
> interface name from A to B.
> - Save currently active ipfilter rules (using ipfstat), run sed over
> those to change the i/f name, and reload them.
> - And finally, save the ipfilter state table, run ipfs over it to change
> the i/f names, and reload the state table.
> 
> This way the server achieves complete redundancy. Any router, switch,
> cable, NIC can fail, and the server will switch to the other network
> card while preserving connection states. Works like a charm.
> 
> But only after I had worked on ipfs. Out of the box, ipfs did not
> properly make the interface change in the saved state files. In FBSD
> 6.2, the command to change the interfaces (-i) is even disabled,
> probably because it never worked :)
> 
> Below is a patch that will fix ipfs such that it is able to successfully
> change the interface names in the saved state files. The patch below
> also enables the -i flag again. After applying this patch, one can
> change interfaces as outlined above, and have ipfs rename them in the
> state files, allowing a clean fail-over between interfaces within
> ipfilter and also preserving the connection state. Any established
> connection will remain active.
> 
> This is my first bug/fix report, so please be gentle if I cross-posted
> too much. I would appreciate if someone could apply the patch to ipfs.c
> so that other users can make use of it. The version of ipfs this was
> diff'ed from is:
> 
> /*      $FreeBSD: src/contrib/ipfilter/tools/ipfs.c,v 1.3.2.1 2006/08/24
> 07:37:1
> 0 guido Exp $   */
> 
> ---8<------------------------------------------------------------------------
> --- ipfs.c.org  Sun Mar 11 14:19:32 2007
> +++ ipfs.c      Sun Mar 11 14:21:24 2007
> @@ -133,6 +133,14 @@
>                         strcpy(ips.ips_is.is_ifname[1], s);
>                         rw = 1;
>                 }
> +                if (!strncmp(ips.ips_is.is_ifname[2], ifs, olen + 1)) {
> +                        strcpy(ips.ips_is.is_ifname[2], s);
> +                        rw = 1;
> +                }
> +                if (!strncmp(ips.ips_is.is_ifname[3], ifs, olen + 1)) {
> +                        strcpy(ips.ips_is.is_ifname[3], s);
> +                        rw = 1;
> +                }
>                 if (rw == 1) {
>                         if (lseek(fd, pos, SEEK_SET) != pos) {
>                                 perror("lseek");
> @@ -190,6 +198,14 @@
>                         strcpy(nat->nat_ifnames[1], s);
>                         rw = 1;
>                 }
> +                if (!strncmp(nat->nat_ifnames[2], ifs, olen + 1)) {
> +                        strcpy(nat->nat_ifnames[2], s);
> +                        rw = 1;
> +                }
> +                if (!strncmp(nat->nat_ifnames[3], ifs, olen + 1)) {
> +                        strcpy(nat->nat_ifnames[3], s);
> +                        rw = 1;
> +                }
>                 if (rw == 1) {
>                         if (lseek(fd, pos, SEEK_SET) != pos) {
>                                 perror("lseek");
> @@ -216,7 +232,7 @@
>         char *dirname = NULL, *filename = NULL, *ifs = NULL;
>  
>         progname = argv[0];
> -       while ((c = getopt(argc, argv, "d:f:lNnSRruvWw")) != -1)
> +       while ((c = getopt(argc, argv, "d:f:i:lNnSRruvWw")) != -1)
>                 switch (c)
>                 {
>                 case 'd' :
> ---8<------------------------------------------------------------------------
> 
> 
> Regards,
> Frank
> 
> 
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?45F54E10.8090904>