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;