[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-ha-dev
Subject:    [Linux-ha-dev] Problem when selecting an IPv6 interface to assign
From:       "Andre, Pascal" <Pascal.Andre () hp ! com>
Date:       2009-04-27 9:17:28
Message-ID: 1ECCB54AA3207547BEF1BD5E75A56930400DC526AA () GVW1163EXB ! americas ! hpqcorp ! net
[Download RAW message or body]

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: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic