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>