Partial IPv6 support

Gilles Diribarne <[email protected]>
Newsgroups gmane.linux.keepalived.devel
Message-ID <[email protected]>
Hi,

I've the current configuration file, using the native_ipv6 (keepalived 
version 1.2.12). I read in a previous mail that the IPv6 generated 
packet did not include any IP address. I've tried to make it work, as 
wireshark would expect it.
My patch I submit in this mail proposes the following solution:
- In IPv4 protocol, it only inserts IPv4 address (thus, same as before)
- In IPv6 protocol, it inserts all IPv4/IPV6 addresses and IPv4 are 
converted to IPv6
Please find attached the patch contribution for this IPv4 solution.


Here is the configuration I used to make it work:
vrrp_instance 1 {
   interface eth0
   native_ipv6
   virtual_router_id 135
   priority 100
   virtual_ipaddress {
     10.5.109.136/16 dev eth0
     10.5.109.135/16 dev eth0
     fd1d:263b:f7b9:2::a05:6d87/64 dev eth0
     fd1d:263b:f7b9:2::a05:6d88/64 dev eth0
   }
   virtual_routes {
     src 10.5.109.136 10.5.0.0/16 dev eth0 table 5 scope link
     src 10.5.109.135 10.5.0.0/16 dev eth0 table 5 scope link
   }
}

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech

_______________________________________________
Keepalived-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/keepalived-devel
keepalived-1.2.12-ipv6.patch (text/x-patch, 3.9 KB)
diff -Naur keepalived-1.2.12.orig/keepalived/vrrp/vrrp.c keepalived-1.2.12/keepalived/vrrp/vrrp.c
--- keepalived-1.2.12.orig/keepalived/vrrp/vrrp.c	2014-01-28 14:48:39.000000000 +0100
+++ keepalived-1.2.12/keepalived/vrrp/vrrp.c	2014-03-18 16:40:52.263257764 +0100
@@ -89,8 +89,21 @@
 vrrp_hd_len(vrrp_t * vrrp)
 {
 	int len = sizeof(vrrphdr_t);
-	if (vrrp->family == AF_INET)
-		len += VRRP_AUTH_LEN + ((!LIST_ISEMPTY(vrrp->vip)) ? LIST_SIZE(vrrp->vip) * sizeof (uint32_t) : 0);
+        element e;
+
+        if (vrrp->auth_type > 0)
+                len += VRRP_AUTH_LEN;
+        
+        for (e = LIST_HEAD(vrrp->vip); e; ELEMENT_NEXT(e)) {
+                ip_address_t *ip_addr = ELEMENT_DATA(e);
+
+                if (vrrp->family == AF_INET) {
+                        if (!IP_IS6(ip_addr)) 
+                                len += sizeof(struct in_addr);
+                }
+                else if (vrrp->family == AF_INET6)
+                        len += sizeof(struct in6_addr);
+        }
         return len;
 }
 
@@ -433,7 +446,6 @@
 	   SPI uniquely identify the Security Association (SA). This value
 	   is chosen by the recipient itself when setting up the SA. In a 
 	   multicast environment, this becomes unfeasible.
-
 	   If left to the sender, the choice of the SPI value should be done
 	   so by the sender that it cannot possibly conflict with SPI values
 	   chosen by other entities sending IPSEC traffic to any of the receivers.
@@ -481,7 +493,6 @@
 static int
 vrrp_build_vrrp(vrrp_t * vrrp, int prio, char *buffer)
 {
-	int i = 0;
 	vrrphdr_t *hd = (vrrphdr_t *) buffer;
 	uint32_t *iparr;
 	element e;
@@ -490,32 +501,37 @@
 	/* Family independant */
 	hd->vers_type = (VRRP_VERSION << 4) | VRRP_PKT_ADVERT;
 	hd->vrid = vrrp->vrid;
+        hd->naddr = 0;
 	hd->priority = prio;
-	hd->naddr = (!LIST_ISEMPTY(vrrp->vip)) ? LIST_SIZE(vrrp->vip) : 0;
 	hd->auth_type = vrrp->auth_type;
 	hd->adver_int = vrrp->adver_int / TIMER_HZ;
 
-	/* Family specific */
-	if (vrrp->family == AF_INET) {
-		/* copy the ip addresses */
-		iparr = (uint32_t *) ((char *) hd + sizeof (*hd));
-		if (!LIST_ISEMPTY(vrrp->vip)) {
-			for (e = LIST_HEAD(vrrp->vip); e; ELEMENT_NEXT(e)) {
-				ip_addr = ELEMENT_DATA(e);
-				if (IP_IS6(ip_addr))
-					continue;
-				else
-					iparr[i++] = ip_addr->u.sin.sin_addr.s_addr;
-			}
-		}
-
-		/* copy the passwd if the authentication is VRRP_AH_PASS */
-		if (vrrp->auth_type == VRRP_AUTH_PASS) {
-			int vip_count = (!LIST_ISEMPTY(vrrp->vip)) ? LIST_SIZE(vrrp->vip) : 0;
-			char *pw = (char *) hd + sizeof (*hd) + vip_count * 4;
-			memcpy(pw, vrrp->auth_data, sizeof (vrrp->auth_data));
-		}
-	}
+        /* Copy the ip addresses */
+        iparr = (uint32_t *) ((char *) hd + sizeof (*hd));
+        for (e = LIST_HEAD(vrrp->vip); e; ELEMENT_NEXT(e)) {
+                ip_addr = ELEMENT_DATA(e);
+
+                if (vrrp->family == AF_INET) {
+                        if (!IP_IS6(ip_addr))
+                                memcpy(&iparr[hd->naddr++], &ip_addr->u.sin, sizeof(struct in_addr)); 
+                }
+                else if (vrrp->family == AF_INET6) {
+                        struct in6_addr addr;
+
+                        bzero(&addr, sizeof(struct in6_addr));
+                        if (!IP_IS6(ip_addr))
+                                memcpy(&addr.s6_addr32[3], &ip_addr->u.sin, sizeof(struct in_addr));
+                        else 
+                                memcpy(&addr, &ip_addr->u.sin6_addr, sizeof(struct in6_addr));
+                        memcpy(&iparr[hd->naddr++ * sizeof(uint32_t)], &addr, sizeof(struct in6_addr));
+                }
+        }
+
+        /* copy the passwd if the authentication is VRRP_AH_PASS */
+        if (vrrp->auth_type == VRRP_AUTH_PASS) {
+                char *pw = (char *) hd + sizeof (*hd) + hd->naddr * 4;
+                memcpy(pw, vrrp->auth_data, sizeof (vrrp->auth_data));
+        }
 
 	/* finaly compute vrrp checksum */
 	hd->chksum = 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.