kern/100532: Conflict between CARP and multicast routing on FreeBSD 6.1

Bohus Plucinsky plk at gtsnextra.sk
Wed Jul 19 12:20:19 UTC 2006


>Number:         100532
>Category:       kern
>Synopsis:       Conflict between CARP and multicast routing on FreeBSD 6.1
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 19 12:20:16 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Bohus Plucinsky <plk at gtsnextra.sk>
>Release:        FreeBSD 6.1-RELEASE i386
>Organization:
GTS Nextra, Slovakia
>Environment:

>Description:

 Because of wrong initialization of carp_softc structure 
 in carp_clone_create function (/sys/netinet/ip_carp.c), after 
 multicast routing is started and any interface is added to vif table, 
 the CARP starts send packets with source IP addresss of this interface
 on all interfaces. 

>How-To-Repeat:
 
 I've FreeBSD 6.1-RELEASE box  with 2 NICs (em0, em1) :

  ifconfig em0 10.0.0.1 netmask 255.255.255.0
  ifconfig em1 192.168.61.1 netmask 255.255.255.0
  
 
 I've configured CARP interface:
  
  ifconfig carp1 create
  ifconfig carp1 vhid 10 pass blabla advskew 50 192.168.61.3 255.255.255.0

  (Make sure the CARP is allowed) 
  sysctl -a | grep carp
	net.inet.ip.same_prefix_carp_only: 0
	net.inet.carp.allow: 1
	net.inet.carp.preempt: 1
	net.inet.carp.log: 1
	net.inet.carp.arpbalance: 0
	net.inet.carp.suppress_preempt: 0

 After multicast routing is started (setsockopt(socket, IPPROTO_IP, MRT_INIT, ...)
 and a vif is added to the vif table (setsockopt(socket, IPPROTO_IP, MRT_ADD_VIF, ...)
 the CARP starts send  packets with a wrong source IP address. (It uses 
 the IP address of the first interface in vif table. (The short dirty C code 
 to start multicast routing is attached)

 Here is the tcpdump on em1 interface. Until mrouter is not runing, the CARP sends packets
 with correct IP address (192.168.61.1) after that the source IP address is changed to IP address
 of first VIF added to vif_table. When the mrouter terminates, the source IP address comes back: 

 # tcpdump -n -i em1 proto 112
 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
 listening on em1, link-type EN10MB (Ethernet), capture size 96 bytes
 08:54:15.921662 IP 192.168.61.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:17.118790 IP 192.168.61.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:18.315948 IP 10.0.0.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:19.513083 IP 10.0.0.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:20.710212 IP 10.0.0.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:21.907341 IP 10.0.0.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:23.090169 IP 192.168.61.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 08:54:24.287288 IP 192.168.61.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 50, authtype none, intvl 1s, length 36
 ^C

 C code to start multicast routing:
 ---------------------------------
 
 /* 
   mrouter_start.c
 
   Dirty code to start mrouter.
   
 */
 
 #include <netinet/in.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <net/route.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 
 #define     MRT_INIT        100   
 #define     MRT_ADD_VIF     102
 
 typedef u_short vifi_t;         /* type of a vif index */
 
 struct vifctl {
   vifi_t  vifc_vifi;              /* the index of the vif to be added */
   u_char  vifc_flags;             /* VIFF_ flags defined below */
   u_char  vifc_threshold;         /* min ttl required to forward on vif */
   u_int   vifc_rate_limit;        /* max rate */
   struct  in_addr vifc_lcl_addr;  /* local interface address */
   struct  in_addr vifc_rmt_addr;  /* remote address (tunnels only) */
 };
                                                 
 int main ()
 {
   int s, i;
   int mrouter_version = 1;
   struct vifctl vc;
   
   int num_of_ifs = 2; /* number of interfaces  */
   char *if_addr[] = {"10.0.0.1", "192.168.61.1" };
   
   if ( (s=socket(PF_INET,SOCK_RAW,IPPROTO_IGMP)) < 0)
   {
     perror ("Cannot open socket. Error ");
     exit (-1);         
   }

   if (setsockopt(s, IPPROTO_IP, MRT_INIT, 
                     (void*)&mrouter_version, sizeof(int)) < 0) 
   {
     close(s);
     perror ("Cannot set socket option. Error:");
     exit (-1);
   }
   
   memset(&vc, 0, sizeof(vc));
   
   for (i=0; i< num_of_ifs ; i++)
   {
    
     vc.vifc_flags = 0;
     vc.vifc_vifi = i;
     vc.vifc_threshold = 1;
     vc.vifc_rate_limit = 0;
     
     vc.vifc_lcl_addr.s_addr = inet_addr(if_addr[i]);
     
     if (setsockopt(s, IPPROTO_IP, MRT_ADD_VIF,
                            (void *)&vc, sizeof(vc)) < 0) 
     {
        close(s);
        perror ("Cannot add VIF. Error ");
       exit (-1);
     }
     
   }                             
   
   fprintf (stdout,"Waiting 5s before terminate.\n");
   sleep(5);  
   close(s);
   return (0);
 }
 
 /* 
   End of mrouter_start.c
 */
 
 
 Kernel config:
 -------------
 
 
 machine	i386
 cpu		I586_CPU
 cpu		I686_CPU
 ident		FW-SMP
 maxusers	64
 
 
 makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
 makeoptions	KERNEL=kernel-fw-20060718-01
 
 options 	SCHED_4BSD		# 4BSD scheduler
 options 	PREEMPTION		# Enable kernel thread preemption
 options 	INET			# InterNETworking
 # options 	INET6			# IPv6 communications protocols
 options 	FFS			# Berkeley Fast Filesystem
 options 	SOFTUPDATES		# Enable FFS soft updates support
 options 	UFS_ACL			# Support for access control lists
 options 	UFS_DIRHASH		# Improve performance on big directories
 options 	NFSCLIENT		# Network Filesystem Client
 options 	NFSSERVER		# Network Filesystem Server
 options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
 options 	MSDOSFS			# MSDOS Filesystem
 options 	CD9660			# ISO 9660 Filesystem
 options 	PROCFS			# Process filesystem (requires PSEUDOFS)
 options 	PSEUDOFS		# Pseudo-filesystem framework
 options 	GEOM_GPT		# GUID Partition Tables.
 options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
 options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
 options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
 options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
 options 	KTRACE			# ktrace(1) support
 options 	SYSVSHM			# SYSV-style shared memory
 options 	SYSVMSG			# SYSV-style message queues
 options 	SYSVSEM			# SYSV-style semaphores
 options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
 options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
 options 	AHC_REG_PRETTY_PRINT	# Print register bitfields in debug
					# output.  Adds ~128k to driver.
 options 	AHD_REG_PRETTY_PRINT	# Print register bitfields in debug
					# output.  Adds ~215k to driver.


 options	MROUTING		# Multicast routing
 options	PIM

 options        IPSTEALTH               #support for stealth forwarding
 options	TCPDEBUG
 options 	TCP_DROP_SYNFIN		#drop TCP packets with SYN+FIN

 options 	INCLUDE_CONFIG_FILE     # Include this file in kernel

 options 	IPSEC			#IP security
 options 	IPSEC_ESP		#IP security (crypto; define w/ IPSEC)
 options 	IPSEC_DEBUG		#debug for IP security

 options	DEVICE_POLLING


 options 	ALTQ
 options 	ALTQ_CBQ	# Class Bases Queueing
 options 	ALTQ_RED	# Random Early Detection
 options 	ALTQ_RIO	# RED In/Out
 options 	ALTQ_HFSC	# Hierarchical Packet Scheduler
 options 	ALTQ_CDNR	# Traffic conditioner
 options 	ALTQ_PRIQ	# Priority Queueing
 options 	ALTQ_NOPCC	# Required for SMP build
 options 	ALTQ_DEBUG

 options 	SMP			# Symmetric MultiProcessor Kernel

 # Devices
 device		apic			# I/O APIC
 
 device		vlan			#VLAN support (needs miibus)
 device		gre			#IP over IP tunneling
 device		pf			#PF OpenBSD packet-filter firewall
 device		pflog			#logging support interface for PF
 device		pfsync			#synchronization interface for PF
 device		carp			#Common Address Redundancy Protocol
 
 ...



>Fix:

 I've very little developer skills, so this is only a HINT. I'm not sure
 if this not brings some other problems:

diff -u ip_carp.c.org ip_carp.c:
================================
--- ip_carp.c.org       Sun Dec 25 21:59:20 2005
+++ ip_carp.c   Tue Jul 18 18:15:09 2006
@@ -1,4 +1,4 @@
-/*     $FreeBSD: src/sys/netinet/ip_carp.c,v 1.27.2.6 2005/12/25 21:59:20 mlaier Exp $ */
+/*     $FreeBSD: src/sys/netinet/ip_carp.c,v 1.27.2.6 2005/12/25 21:59:20 mlaier (with change) Exp $ */
 
 /*
  * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -369,6 +369,8 @@
        sc->sc_advskew = 0;
        sc->sc_init_counter = 1;
        sc->sc_naddrs = sc->sc_naddrs6 = 0; /* M_ZERO? */
+       sc->sc_imo.imo_multicast_vif=-1;  /* inicialize to not existing index */
+       
 #ifdef INET6
        sc->sc_im6o.im6o_multicast_hlim = CARP_DFLTTL;
 #endif
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list