Hi,

On Mon, Apr 27, 2009 at 09:17:28AM +0000, Andre, Pascal wrote:
> 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 ?

Definitely. Can you please open a bugzilla and attach the patch
below. The patch (many thanks!) looks sane, but passing the
interface name should probably be done in the same way as in
the IPaddr RA.

Cheers,

Dejan

> 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/
_______________________________________________________
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/

Reply via email to