[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