Hi Dejan,

Thanks for your answer.

Concerning your last comment ("passing the interface name should probably be 
done in the same way as in the IPaddr RA"), could you tell me where to look at 
if I need to change the way to do this ? I'm a complete newbie with regard to 
Linux-HA's code ;)

Here is my understanding (correct me if I'm wrong). First, my assumptions:

- When you reference IPaddr, you mean the way it is done for IPv4 (i.e. IPaddr 
= IPv4, IPv6addr = IPv6).
- RA refers (among other things) to this document: 
http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD

Now, concerning parameter passing for IPv6 versus IPv4, I see no difference 
between them. From a user's point of view, if you want to associate Linux HA's 
virtual IP to a specific interface, you have to declare it in file 
/etc/ha.d/haresources. Here is an extract from this file:

[...]
#       The format is like this:
#
#node-name resource1 resource2 ... resourceN
#
#
[...]
#
#       If you wished to tell it that the interface to add the address to
#       is eth0, then you would need to specify it this way:
#               IPaddr::135.9.8.7/24/eth0

This extract explains how to specify the interface for IPv4. For IPv6, there is 
no difference:

IPv6addr::3ffe:1111:2222:3333:4444:5556:6666:7777/64/bond0


In Linux HA's code, this "string" is set in an environment variable 
(OCF_RESKEY_ipv6addr) and IPv6addr.c uses it to retrieve its parameters: the 
IPv6 address, the prefix length and (once my proposed patch is applied) the 
associated interface name.
So, as far as I can tell, I don't think I've changed the way parameters are 
passed, I just added one (that was already here but unused in IPv6).

Did I missed something ?

Regards,

Pascal ANDRE


> -----Original Message-----
> From: linux-ha-dev-boun...@lists.linux-ha.org
> [mailto:linux-ha-dev-boun...@lists.linux-ha.org] On Behalf Of
> Dejan Muhamedagic
> Sent: Wednesday, May 13, 2009 3:49 PM
> To: High-Availability Linux Development List
> Subject: Re: [Linux-ha-dev] Problem when selecting an IPv6
> interface to assign Linux-HA's virtual IP to
>
> 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/
>
_______________________________________________________
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