server: allow multiple interfaces comma separated in public_addresses
authorStefan Metzmacher <metze@samba.org>
Mon, 14 Dec 2009 17:52:06 +0000 (18:52 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 20 Jan 2010 10:10:58 +0000 (11:10 +0100)
metze

common/ctdb_util.c
include/ctdb_private.h
server/ctdb_takeover.c

index 88e8aa8429ae781feed4342634eb9a5a8d2121b3..efc22de791ff4d398709fc927d9deb036a200390 100644 (file)
@@ -367,7 +367,7 @@ bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin)
        return true;
 }
 
-static bool parse_ipv6(const char *s, const char *iface, unsigned port, ctdb_sock_addr *saddr)
+static bool parse_ipv6(const char *s, const char *ifaces, unsigned port, ctdb_sock_addr *saddr)
 {
        saddr->ip6.sin6_family   = AF_INET6;
        saddr->ip6.sin6_port     = htons(port);
@@ -379,8 +379,14 @@ static bool parse_ipv6(const char *s, const char *iface, unsigned port, ctdb_soc
                return false;
        }
 
-       if (iface && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) {
-               saddr->ip6.sin6_scope_id = if_nametoindex(iface);
+       if (ifaces && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) {
+               if (strchr(ifaces, ',')) {
+                       DEBUG(DEBUG_ERR, (__location__ " Link local address %s "
+                                         "is specified for multiple ifaces %s\n",
+                                         s, ifaces));
+                       return false;
+               }
+               saddr->ip6.sin6_scope_id = if_nametoindex(ifaces);
        }
 
        return true;
@@ -430,7 +436,7 @@ bool parse_ip_port(const char *addr, ctdb_sock_addr *saddr)
 /*
   parse an ip
  */
-bool parse_ip(const char *addr, const char *iface, unsigned port, ctdb_sock_addr *saddr)
+bool parse_ip(const char *addr, const char *ifaces, unsigned port, ctdb_sock_addr *saddr)
 {
        char *p;
        bool ret;
@@ -440,7 +446,7 @@ bool parse_ip(const char *addr, const char *iface, unsigned port, ctdb_sock_addr
        if (p == NULL) {
                ret = parse_ipv4(addr, port, &saddr->ip);
        } else {
-               ret = parse_ipv6(addr, iface, port, saddr);
+               ret = parse_ipv6(addr, ifaces, port, saddr);
        }
 
        return ret;
@@ -449,7 +455,7 @@ bool parse_ip(const char *addr, const char *iface, unsigned port, ctdb_sock_addr
 /*
   parse a ip/mask pair
  */
-bool parse_ip_mask(const char *str, const char *iface, ctdb_sock_addr *addr, unsigned *mask)
+bool parse_ip_mask(const char *str, const char *ifaces, ctdb_sock_addr *addr, unsigned *mask)
 {
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        char *s, *p;
@@ -482,7 +488,7 @@ bool parse_ip_mask(const char *str, const char *iface, ctdb_sock_addr *addr, uns
 
 
        /* now is this a ipv4 or ipv6 address ?*/
-       ret = parse_ip(s, iface, 0, addr);
+       ret = parse_ip(s, ifaces, 0, addr);
 
        talloc_free(tmp_ctx);
        return ret;
index 729837239d762b7131b6892b96b1d014736624a5..aaae250f400d70badbc1d64fa15371dcdbf7f590 100644 (file)
@@ -187,6 +187,7 @@ struct ctdb_vnn {
        struct ctdb_vnn *prev, *next;
 
        const char *iface;
+       const char **ifaces;
        ctdb_sock_addr public_address;
        uint8_t public_netmask_bits;
 
index 6fc433f8c96dcfc9f7e161fd5f38901a56d9d96f..9711f42f2201f270539609006bc190b79eb6ceec 100644 (file)
@@ -445,9 +445,16 @@ int32_t ctdb_control_release_ipv4(struct ctdb_context *ctdb,
 }
 
 
-static int ctdb_add_public_address(struct ctdb_context *ctdb, ctdb_sock_addr *addr, unsigned mask, const char *iface)
+static int ctdb_add_public_address(struct ctdb_context *ctdb,
+                                  ctdb_sock_addr *addr,
+                                  unsigned mask, const char *ifaces)
 {
        struct ctdb_vnn      *vnn;
+       uint32_t num = 0;
+       char *tmp;
+       const char *iface;
+       int i;
+       int ret;
 
        /* Verify that we dont have an entry for this ip yet */
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
@@ -461,8 +468,19 @@ static int ctdb_add_public_address(struct ctdb_context *ctdb, ctdb_sock_addr *ad
        /* create a new vnn structure for this ip address */
        vnn = talloc_zero(ctdb, struct ctdb_vnn);
        CTDB_NO_MEMORY_FATAL(ctdb, vnn);
-       vnn->iface = talloc_strdup(vnn, iface);
-       CTDB_NO_MEMORY(ctdb, vnn->iface);
+       vnn->ifaces = talloc_array(vnn, const char *, num + 2);
+       tmp = talloc_strdup(vnn, ifaces);
+       CTDB_NO_MEMORY_FATAL(ctdb, tmp);
+       for (iface = strtok(tmp, ","); iface; iface = strtok(NULL, ",")) {
+               vnn->ifaces = talloc_realloc(vnn, vnn->ifaces, const char *, num + 2);
+               CTDB_NO_MEMORY_FATAL(ctdb, vnn->ifaces);
+               vnn->ifaces[num] = talloc_strdup(vnn, iface);
+               CTDB_NO_MEMORY_FATAL(ctdb, vnn->ifaces[num]);
+               num++;
+       }
+       talloc_free(tmp);
+       vnn->ifaces[num] = NULL;
+       vnn->iface = vnn->ifaces[0];
        vnn->public_address      = *addr;
        vnn->public_netmask_bits = mask;
        vnn->pnn                 = -1;
@@ -505,7 +523,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
                unsigned mask;
                ctdb_sock_addr addr;
                const char *addrstr;
-               const char *iface;
+               const char *ifaces;
                char *tok, *line;
 
                line = lines[i];
@@ -528,17 +546,17 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
                                talloc_free(lines);
                                return -1;
                        }
-                       iface = ctdb->default_public_interface;
+                       ifaces = ctdb->default_public_interface;
                } else {
-                       iface = tok;
+                       ifaces = tok;
                }
 
-               if (!addrstr || !parse_ip_mask(addrstr, iface, &addr, &mask)) {
+               if (!addrstr || !parse_ip_mask(addrstr, ifaces, &addr, &mask)) {
                        DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
                        talloc_free(lines);
                        return -1;
                }
-               if (ctdb_add_public_address(ctdb, &addr, mask, iface)) {
+               if (ctdb_add_public_address(ctdb, &addr, mask, ifaces)) {
                        DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
                        talloc_free(lines);
                        return -1;
@@ -559,8 +577,13 @@ int ctdb_set_single_public_ip(struct ctdb_context *ctdb,
        svnn = talloc_zero(ctdb, struct ctdb_vnn);
        CTDB_NO_MEMORY(ctdb, svnn);
 
-       svnn->iface = talloc_strdup(svnn, iface);
-       CTDB_NO_MEMORY(ctdb, svnn->iface);
+       svnn->ifaces = talloc_array(svnn, const char *, 2);
+       CTDB_NO_MEMORY(ctdb, svnn->ifaces);
+       svnn->ifaces[0] = talloc_strdup(svnn->ifaces, iface);
+       CTDB_NO_MEMORY(ctdb, svnn->ifaces[0]);
+       svnn->ifaces[1] = NULL;
+
+       svnn->iface = svnn->ifaces[0];
 
        ok = parse_ip(ip, iface, 0, &svnn->public_address);
        if (!ok) {