Fix for bug in IPFilters ipfs tool
Roger Olofsson
raggen at passagen.se
Mon Mar 12 12:58:57 UTC 2007
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
>
>
>
More information about the freebsd-hackers
mailing list