Hi,

On a RHEL5 machine (heartbeat 2.1.4 used in active/standby mode), I would like 
to associate Linux-HA virtual IP (IPv6) to a bonded interface. In 
/etc/ha.d/haresources, this is declared via following line:

<hostname>  <vip>/<prefix-len>/<bonded-interface>  <start-stop-script>

ex: myhost.example.com  
IPv6addr::3ffe:1111:2222:3333:4444:5556:6666:7777/64/bond0  myapp.sh

Unfortunately, IPv6addr does not take into account this "bonded-interface" when 
assigning the vip. It selects the first interface declared in 
/proc/net/if_inet6 matching provided IPv6 prefix. In our case, this interface 
is not bond0. An example of such configuration may be: eth1, eth2 and eth3 use 
the same IPv6 prefix and bond0 uses eth2 and eth3. In this case, IPv6addr will 
always assign the vip to eth1 (eventhough we "requested" bond0), loosing (among 
other things) the benefits of a bonded interface.

I've made a modification in resources/OCF/IPv6addr.c in order to take into 
account provided interface (when user provides one).
What is your opinion on this ? Should it be reported in Linux-HA's bug list ?

Thanks & regards,

Pascal ANDRE


-------------------------------------------------------------


--- resources/OCF/IPv6addr.c.old 2009-04-24 15:46:55.000000000 +0200
+++ resources/OCF/IPv6addr.c 2009-04-24 16:01:23.000000000 +0200
@@ -145,11 +145,11 @@
  unsigned int ifr6_ifindex;
 };

-static int start_addr6(struct in6_addr* addr6, int prefix_len);
-static int stop_addr6(struct in6_addr* addr6, int prefix_len);
-static int status_addr6(struct in6_addr* addr6, int prefix_len);
+static int start_addr6(struct in6_addr* addr6, int prefix_len, char * 
prov_ifname);
+static int stop_addr6(struct in6_addr* addr6, int prefix_len, char * 
prov_ifname);
+static int status_addr6(struct in6_addr* addr6, int prefix_len, char * 
prov_ifname);
 static int monitor_addr6(struct in6_addr* addr6, int prefix_len);
-static int advt_addr6(struct in6_addr* addr6, int prefix_len);
+static int advt_addr6(struct in6_addr* addr6, int prefix_len, char * 
prov_ifname);
 static int meta_data_addr6(void);


@@ -159,9 +159,9 @@
 static void byebye(int nsig);

 static char* scan_if(struct in6_addr* addr_target, int* plen_target,
-       int use_mask);
-static char* find_if(struct in6_addr* addr_target, int* plen_target);
-static char* get_if(struct in6_addr* addr_target, int* plen_target);
+       int use_mask, char * prov_ifname);
+static char* find_if(struct in6_addr* addr_target, int* plen_target, char * 
prov_ifname);
+static char* get_if(struct in6_addr* addr_target, int* plen_target, char * 
prov_ifname);
 static int assign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name);
 static int unassign_addr6(struct in6_addr* addr6, int prefix_len, char* 
if_name);
 int is_addr6_available(struct in6_addr* addr6);
@@ -174,6 +174,7 @@
  char*  ipv6addr;
  int  ret;
  char*  cp;
+ char*  prov_ifname = NULL;
  int  prefix_len;
  struct in6_addr addr6;

@@ -212,6 +213,12 @@
    return OCF_ERR_ARGS;
   }
   *cp=0;
+
+  /* get provided interface name (optional) */
+  cp++;
+  if ((cp = strchr(cp, '/'))) {
+   prov_ifname = cp + 1;
+  }
  } else {
   prefix_len = 0;
  }
@@ -244,11 +251,11 @@

  /* switch the command */
  if (0 == strncmp(START_CMD,argv[1], strlen(START_CMD))) {
-  ret = start_addr6(&addr6, prefix_len);
+  ret = start_addr6(&addr6, prefix_len, prov_ifname);
  }else if (0 == strncmp(STOP_CMD,argv[1], strlen(STOP_CMD))) {
-  ret = stop_addr6(&addr6, prefix_len);
+  ret = stop_addr6(&addr6, prefix_len, prov_ifname);
  }else if (0 == strncmp(STATUS_CMD,argv[1], strlen(STATUS_CMD))) {
-  ret = status_addr6(&addr6, prefix_len);
+  ret = status_addr6(&addr6, prefix_len, prov_ifname);
  }else if (0 ==strncmp(MONITOR_CMD,argv[1], strlen(MONITOR_CMD))) {
   ret = monitor_addr6(&addr6, prefix_len);
  }else if (0 ==strncmp(RELOAD_CMD,argv[1], strlen(RELOAD_CMD))) {
@@ -259,7 +266,7 @@
  /* ipv6addr has been validated by inet_pton, hence a valid IPv6 address */
   ret = OCF_SUCCESS;
  }else if (0 ==strncmp(ADVT_CMD,argv[1], strlen(MONITOR_CMD))) {
-  ret = advt_addr6(&addr6, prefix_len);
+  ret = advt_addr6(&addr6, prefix_len, prov_ifname);
  }else{
   usage(argv[0]);
   ret = OCF_ERR_ARGS;
@@ -271,16 +278,16 @@
  return ret;
 }
 int
-start_addr6(struct in6_addr* addr6, int prefix_len)
+start_addr6(struct in6_addr* addr6, int prefix_len, char * prov_ifname)
 {
  int i;
  char* if_name;
- if(OCF_SUCCESS == status_addr6(addr6,prefix_len)) {
+ if(OCF_SUCCESS == status_addr6(addr6,prefix_len,prov_ifname)) {
   return OCF_SUCCESS;
  }

  /* we need to find a proper device to assign the address */
- if_name = find_if(addr6, &prefix_len);
+ if_name = find_if(addr6, &prefix_len, prov_ifname);
  if (NULL == if_name) {
   cl_log(LOG_ERR, "no valid mecahnisms");
   return OCF_ERR_GENERIC;
@@ -313,10 +320,10 @@
 }

 int
-advt_addr6(struct in6_addr* addr6, int prefix_len)
+advt_addr6(struct in6_addr* addr6, int prefix_len, char * prov_ifname)
 {
  /* First, we need to find a proper device to assign the address */
- char* if_name = get_if(addr6, &prefix_len);
+ char* if_name = get_if(addr6, &prefix_len, prov_ifname);
  int i;
  if (NULL == if_name) {
   cl_log(LOG_ERR, "no valid mecahnisms");
@@ -331,14 +338,14 @@
 }

 int
-stop_addr6(struct in6_addr* addr6, int prefix_len)
+stop_addr6(struct in6_addr* addr6, int prefix_len, char * prov_ifname)
 {
  char* if_name;
- if(OCF_NOT_RUNNING == status_addr6(addr6,prefix_len)) {
+ if(OCF_NOT_RUNNING == status_addr6(addr6,prefix_len,prov_ifname)) {
   return OCF_SUCCESS;
  }

- if_name = get_if(addr6, &prefix_len);
+ if_name = get_if(addr6, &prefix_len, prov_ifname);

  if (NULL == if_name) {
   cl_log(LOG_ERR, "no valid mechanisms.");
@@ -356,9 +363,9 @@
 }

 int
-status_addr6(struct in6_addr* addr6, int prefix_len)
+status_addr6(struct in6_addr* addr6, int prefix_len, char * prov_ifname)
 {
- char* if_name = get_if(addr6, &prefix_len);
+ char* if_name = get_if(addr6, &prefix_len, prov_ifname);
  if (NULL == if_name) {
   return OCF_NOT_RUNNING;
  }
@@ -429,7 +436,7 @@

 /* find the network interface associated with an address */
 char*
-scan_if(struct in6_addr* addr_target, int* plen_target, int use_mask)
+scan_if(struct in6_addr* addr_target, int* plen_target, int use_mask, char * 
prov_ifname)
 {
  FILE *f;
  static char devname[21]="";
@@ -477,6 +484,15 @@
   }
   *plen_target = plen;

+  /* If interface name provided, only same devname entry
+   * would be considered
+   */
+  if (prov_ifname!=0 && *prov_ifname!=0)
+  {
+   if (strcmp(devname, prov_ifname))
+    continue;
+  }
+
   for (i = 0; i< 4; i++) {
    addr.s6_addr32[i] = htonl(addr6p[i]);
   }
@@ -515,15 +531,15 @@
 }
 /* find a proper network interface to assign the address */
 char*
-find_if(struct in6_addr* addr_target, int* plen_target)
+find_if(struct in6_addr* addr_target, int* plen_target, char * prov_ifname)
 {
- return scan_if(addr_target, plen_target, 1);
+ return scan_if(addr_target, plen_target, 1, prov_ifname);
 }
 /* get the device name and the plen_target of a special address */
 char*
-get_if(struct in6_addr* addr_target, int* plen_target)
+get_if(struct in6_addr* addr_target, int* plen_target, char * prov_ifname)
 {
- return scan_if(addr_target, plen_target, 0);
+ return scan_if(addr_target, plen_target, 0, prov_ifname);
 }
 int
 assign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name)

_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to