Gratuitous arp from virtual IPs?



  • My ISP maintains connections to my static IPs based on seeing periodic ARPs from each IP.

    My pfsense 2.1 seems to issue ARP requests from the WAN interface IP every 20 minutes, but not from virual IPs. There is a gratuitous ARP from each virual IP on initial connection, but I see nothing after that in tcpdump. After 1 hour my ISP stops routing to the virual IPs. They say it's in their router software and can't be changed.

    I installed the arping package into pfsense and have it sending ARP requests to the ISP's gateway from each VIP, done in a cron job every 20 minutes. This is working to keep connectivity, but I'd like to know if there is any less hacky way to do this.

    Also, arping is able to send ARP requests, but I can't seem to get it to issue gARPs. Is there a way to do this with arping, or is there another utility that will?

    Thanks for any help.


  • Banned

    The less hacky way would be taking a cluebat and paying a visit to your ISP.



  • Yep, one of my ISPs is doing the same thing. http://forum.pfsense.org/index.php/topic,67006.0.html

    Wasted a whole day on this. Cron job to run arping – so be it.

    Thanks for posting this.



  • "They say it's in their router software and can't be changed."  So just take it right?  Crazy…

    So is there a easy way to get pfsense to send ARP on a schedule?



  • Yeah, this was Charter Cable in LA. Done butting heads with them >:(.

    Whipped up this script and I run it from cron.

    Pass the gateway name to it as the argument. I don't know how often or if at all the cache on the router ever clears. I am running the script every 13 minutes.

    
    #!/usr/local/bin/php -f
    
    /* $Id$ */
    /*
            rc.viparp
            Shahid Sheikh
    
            requires arping package.
            generates unsolicited arp response to a gateway.
    */
    
    /* parse the configuration and include all functions used below */
    require_once("/etc/inc/config.inc");
    require_once("/etc/inc/gwlb.inc");
    require_once("/etc/inc/interfaces.inc");
    require_once("/etc/inc/pkg-utils.inc");
    
    $bad_arp_gw = trim($argv[1], " \n");
    $package_name = "arping";
    if (is_package_installed($package_name)) {
            $bad_arp_gw_int = lookup_gateway_interface_by_name($bad_arp_gw);
            $bad_arp_gw_ip = lookup_gateway_ip_by_name($bad_arp_gw);
            if (!empty($bad_arp_gw_int)) {
                    foreach ($config['virtualip']['vip'] as $vip) {
                            if ($vip['mode'] == "carp" && $vip['interface'] == $bad_arp_gw_int) {
                                    $vip_int = "{$vip['interface']}_vip{$vip['vhid']}";
                                    $status = get_carp_interface_status($vip_int);
                                    if ($status == "MASTER") {
                                            log_error("Sending ARP for CARP VIP {$vip['subnet']}'s MAC to {$bad_arp_gw_ip}");
                                            mwexec("/usr/local/sbin/arping -S {$vip['subnet']} -c 3 {$bad_arp_gw_ip}");
                                    }
                            }
                    }
            }
    } else {
            log_error($package_name . " package is not installed.");
    }
    ?>
    
    

    Shahid



  • I don't need but I'll press the thanks button anyway because I'm sure others do need it.



  • I fought with my setup for 5 hours before figuring out the problem.

    UPC (The Netherlands) seems to have similar problems with their small-business cable subscription. (Cisco EPC3925) After about 20 minutes, the modem/router forgets the CARP V-IP's and only the static IPs associated with the interfaces remain accessible.

    Your script helps a lot! Added it to cron, on 5 minutes interval. Works like a charm!



  • Why in the world would an ISP think this is a good idea?



  • I'm seeing the same thing with a Cisco cable modem / router.  The ISP says pfsense is sending a packet with the interface's MAC but the VIP's address, which they are loading into their ARP table.  They are also claiming pfsense is sending a packet with the first VIP's mac address, and the interface's IP.  As a result, they send nothing.  Just started happening a  week ago with no change I know about to pfsense.



  • Here's the culprit:

    http://unix.derkeiler.com/Mailing-Lists/FreeBSD/net/2011-10/msg00229.html
    "CARP arp replays with wrong src mac"  / CARP arp replies with wrong src mac

    I'm now working on major rewrite of CARP for FreeBSD 10, and
    I'd like to take all related PRs.

    http://www.freebsd.org/cgi/query-pr.cgi?pr=141023

    In the case of all Cisco routers sent out there by Mediacom.  It used to work, it worked two weeks ago, now it doesn't work.  The guy who works the noc desk at mediacom doesn't read the RFC, he just complains about alarms going off.  In the end, I just need it to work.



  • Hi

    I've the same issue. I've now adopted the script for pfsense 2.3 and also changes it in that way that it sends the virtual CARP MAC in the gratutious arp instead of the MAC of the physical Interface.

    
    #!/usr/local/bin/php -f
    
    /* $Id$ */
    /*
            rc.viparp
            Shahid Sheikh
    
            requires arping package.
            generates unsolicited arp response to a gateway.
    */
    /*
    Romeo Benzoni
    - adopted to run on 2.3 (get_carp_interface_status changes signature)
    - send arp response using the virtual MAC
    */
    
    /* parse the configuration and include all functions used below */
    require_once("/etc/inc/config.inc");
    require_once("/etc/inc/gwlb.inc");
    require_once("/etc/inc/interfaces.inc");
    require_once("/etc/inc/pkg-utils.inc");
    
    $bad_arp_gw = trim($argv[1], " \n");
    $package_name = "arping";
    if (is_package_installed($package_name)) {
            $bad_arp_gw_int = lookup_gateway_interface_by_name($bad_arp_gw);
            $bad_arp_gw_ip = lookup_gateway_ip_by_name($bad_arp_gw);
            if (!empty($bad_arp_gw_int)) {
                    foreach ($config['virtualip']['vip'] as $vip) {
                            if ($vip['mode'] == "carp" && $vip['interface'] == $bad_arp_gw_int) {
                                    $vip_int = "{$vip['interface']}_vip{$vip['vhid']}";
                                    $status = get_carp_interface_status("_vip{$vip['uniqid']}");
                                    if ($status == "MASTER") {
                                            $mac = sprintf("00:00:5E:00:01:%02X", $vip['vhid']);
                                            log_error("Sending ARP for CARP VIP {$vip['subnet']}'s MAC $mac to {$bad_arp_gw_ip}");
                                            mwexec("/usr/local/sbin/arping -s $mac -S {$vip['subnet']} -c 3 {$bad_arp_gw_ip}");
                                    }
                            }
                    }
            }
    } else {
            log_error($package_name . " package is not installed.");
    }
    ?>
    
    

    Regards

    Romeo

    @ssheikh:

    Yeah, this was Charter Cable in LA. Done butting heads with them >:(.

    Whipped up this script and I run it from cron.

    Pass the gateway name to it as the argument. I don't know how often or if at all the cache on the router ever clears. I am running the script every 13 minutes.



  • Thank you,solve my problem。

    [carp] CARP arp replays with wrong src mac
    https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=141023
    Who can patch this problem on freebsd 10 ?

    @roemel:

    Hi

    I've the same issue. I've now adopted the script for pfsense 2.3 and also changes it in that way that it sends the virtual CARP MAC in the gratutious arp instead of the MAC of the physical Interface.



  • Why net.link.ether.inet.carp_mac set to 1,can not fix src mac to carp vip mac?
    https://github.com/pfsense/FreeBSD-src/commit/f59b244dc6ec16616ed00a9cf33b4d1fcc839a36



  • @wiki345:

    Why net.link.ether.inet.carp_mac set to 1,can not fix src mac to carp vip mac?
    https://github.com/pfsense/FreeBSD-src/commit/f59b244dc6ec16616ed00a9cf33b4d1fcc839a36

    sorry for reviving thi thead, but how to apply this?



  • +1..
    Not quite fluent with php, but i saw a specific mac address in the script ?
    Where should i put mine ?

    ( our pfsense, master + slave are just another vm guest, so they have virtio mac addresses. )

    @broonu:

    @wiki345:

    Why net.link.ether.inet.carp_mac set to 1,can not fix src mac to carp vip mac?
    https://github.com/pfsense/FreeBSD-src/commit/f59b244dc6ec16616ed00a9cf33b4d1fcc839a36

    sorry for reviving thi thead, but how to apply this?



    • Install Arping
    • Install Cron
    • Save the latest 2.3 script to a php file
    • Transfer the php file to your pfsense box via winscp (in my case /scripts)
    • Services, Cron, Add (GATEWAYNAME IS CASESENSITIVE !!!)
      /usr/local/bin/php -f /scripts/arp_vip.php GATEWAYNAME

    Example

    • / 3 * * * * root /usr/local/bin/php -f /scripts/arp_vip.php Ziggo_KELDER_GW


  • Had the same problem with my Virtual IP Aliases. Couldn't get the script working for that so I in hurry needed to change it and simply it for my case. Maybe it can be of use  even though its made by a noob.

    
    #!/usr/local/bin/php -f
    
    require_once("/etc/inc/config.inc");
    require_once("/etc/inc/gwlb.inc");
    require_once("/etc/inc/interfaces.inc");
    require_once("/etc/inc/pkg-utils.inc");
    
    $gatewayName = trim($argv[1], " \n");
    
    $packageName = "arping";
    
    if (is_package_installed($packageName)) {
    	$gatewayInterface 	= lookup_gateway_interface_by_name($gatewayName);
        $gatewayIp 			= lookup_gateway_ip_by_name($gatewayName);
    
    	if (!empty($gatewayName)) {
    		$found = false;
    		foreach ($config['virtualip']['vip'] as $vip) {
    			if ($vip['interface'] == $gatewayInterface) {
    				log_error('Sending ARP for Virtual IP ' . $vip['subnet'] . ' to ' . $gatewayIp);
    				mwexec('/usr/local/sbin/arping -S ' . $vip['subnet'] . ' -c 3 ' . $gatewayIp);
    
    				$found = true;
    			}
    		}
    
    		if (!$found) log_error('Found no Virtual IP tied to this gateway: '  . $gatewayName . '\n');
    	} else  {
    		log_error('You forgot to supply the Gateway name.');
    	}
    } else {
    		log_error($packageName . " package is not installed.");
    }
    ?>
    
    

Log in to reply