Fix treatment of link local ipv6 addresses: set the scope id.
authorMichael Adam <obnox@samba.org>
Mon, 19 Jan 2009 14:33:24 +0000 (15:33 +0100)
committerMichael Adam <obnox@samba.org>
Mon, 19 Jan 2009 21:50:53 +0000 (22:50 +0100)
metze / Michael

Signed-off-by: Michael Adam <obnox@samba.org>
common/ctdb_util.c
include/ctdb_private.h
server/ctdb_recover.c
server/ctdb_takeover.c
server/ctdbd.c
tcp/tcp_connect.c
tools/ctdb.c

index 00a9c8c984cb816f8b57ad9becd8b682be840478..33d30e2108447535d062154cd5661e308e8d52fb 100644 (file)
@@ -381,7 +381,7 @@ bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin)
        return true;
 }
 
-static bool parse_ipv6(const char *s, unsigned port, ctdb_sock_addr *saddr)
+static bool parse_ipv6(const char *s, const char *iface, unsigned port, ctdb_sock_addr *saddr)
 {
        saddr->ip6.sin6_family   = AF_INET6;
        saddr->ip6.sin6_port     = htons(port);
@@ -393,6 +393,10 @@ static bool parse_ipv6(const char *s, unsigned port, ctdb_sock_addr *saddr)
                return false;
        }
 
+       if (iface && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) {
+               saddr->ip6.sin6_scope_id = if_nametoindex(iface);
+       }
+
        return true;
 }
 /*
@@ -431,7 +435,7 @@ bool parse_ip_port(const char *addr, ctdb_sock_addr *saddr)
 
 
        /* now is this a ipv4 or ipv6 address ?*/
-       ret = parse_ip(s, addr);
+       ret = parse_ip(s, NULL, addr);
 
        talloc_free(tmp_ctx);
        return ret;
@@ -440,7 +444,7 @@ bool parse_ip_port(const char *addr, ctdb_sock_addr *saddr)
 /*
   parse an ip
  */
-bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
+bool parse_ip(const char *addr, const char *iface, ctdb_sock_addr *saddr)
 {
        char *p;
        bool ret;
@@ -450,7 +454,7 @@ bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
        if (p == NULL) {
                ret = parse_ipv4(addr, 0, &saddr->ip);
        } else {
-               ret = parse_ipv6(addr, 0, saddr);
+               ret = parse_ipv6(addr, iface, 0, saddr);
        }
 
        return ret;
@@ -459,7 +463,7 @@ bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
 /*
   parse a ip/mask pair
  */
-bool parse_ip_mask(const char *str, ctdb_sock_addr *addr, unsigned *mask)
+bool parse_ip_mask(const char *str, const char *iface, ctdb_sock_addr *addr, unsigned *mask)
 {
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        char *s, *p;
@@ -492,7 +496,7 @@ bool parse_ip_mask(const char *str, ctdb_sock_addr *addr, unsigned *mask)
 
 
        /* now is this a ipv4 or ipv6 address ?*/
-       ret = parse_ip(s, addr);
+       ret = parse_ip(s, iface, addr);
 
        talloc_free(tmp_ctx);
        return ret;
index 49e7a3e26b82517fd7a1612b333eb4d4f32fca8f..ceac3842bd72c10ac7352a81d79dd7c11849fcde 100644 (file)
@@ -1281,9 +1281,9 @@ int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
 
 void ctdb_start_freeze(struct ctdb_context *ctdb);
 
-bool parse_ip_mask(const char *s, ctdb_sock_addr *addr, unsigned *mask);
+bool parse_ip_mask(const char *s, const char *iface, ctdb_sock_addr *addr, unsigned *mask);
 bool parse_ip_port(const char *s, ctdb_sock_addr *addr);
-bool parse_ip(const char *s, ctdb_sock_addr *addr);
+bool parse_ip(const char *s, const char *iface, ctdb_sock_addr *addr);
 bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin);
  
 
index 8bed9e6aea706319ed51f0f08726fb3936040ac4..2d95b184666262cdae85c43b1fc9cf7f241f1539 100644 (file)
@@ -163,7 +163,10 @@ ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA ind
        node_map = (struct ctdb_node_map *)outdata->dptr;
        node_map->num = num_nodes;
        for (i=0; i<num_nodes; i++) {
-               if (parse_ip(ctdb->nodes[i]->address.address, &node_map->nodes[i].addr) == 0) {
+               if (parse_ip(ctdb->nodes[i]->address.address,
+                            NULL, /* TODO: pass in the correct interface here*/
+                            &node_map->nodes[i].addr) == 0)
+               {
                        DEBUG(DEBUG_ERR, (__location__ " Failed to parse %s into a sockaddr\n", ctdb->nodes[i]->address.address));
                }
 
index fa9bd7719bfee1c7bb947412ed702f1965a1a05c..4b32c6e6ff6f848ae0ef59a56892a1bdd5d6b0b7 100644 (file)
@@ -485,6 +485,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
        for (i=0;i<nlines;i++) {
                unsigned mask;
                ctdb_sock_addr addr;
+               const char *addrstr;
                const char *iface;
                char *tok, *line;
 
@@ -499,11 +500,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
                        continue;
                }
                tok = strtok(line, " \t");
-               if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
-                       DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
-                       talloc_free(lines);
-                       return -1;
-               }
+               addrstr = tok;
                tok = strtok(NULL, " \t");
                if (tok == NULL) {
                        if (NULL == ctdb->default_public_interface) {
@@ -517,6 +514,11 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
                        iface = tok;
                }
 
+               if (!addrstr || !parse_ip_mask(addrstr, iface, &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)) {
                        DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
                        talloc_free(lines);
index 351948c9e5b371e7ce14066c5153dddc71dc6386..ee433da2eb6342bd8353c70d80df4b99eda2c6dc 100644 (file)
@@ -280,6 +280,7 @@ int main(int argc, const char *argv[])
                CTDB_NO_MEMORY(ctdb, svnn->iface);
 
                if (parse_ip(options.single_public_ip, 
+                               svnn->iface,
                                &svnn->public_address) == 0) {
                        DEBUG(DEBUG_ALERT,("Invalid --single-public-ip argument : %s . This is not a valid ip address. Exiting.\n", options.single_public_ip));
                        exit(10);
index 6aa377bb405ee387338fe5558e7725ee9d427f3a..8efb5974438206748ea9f78e20470945d09ac23e 100644 (file)
@@ -109,7 +109,7 @@ static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *f
 static int ctdb_tcp_get_address(struct ctdb_context *ctdb,
                                const char *address, ctdb_sock_addr *addr)
 {
-       if (parse_ip(address, addr) == 0) {
+       if (parse_ip(address, NULL, addr) == 0) {
                DEBUG(DEBUG_CRIT, (__location__ " Unparsable address : %s.\n", address));
                return -1;
        }
index 4ba351c921c6e62e44d2560b287a5262b25fd59c..b2014f0eb6917ce9caee00f9829918bd7b5cc358 100644 (file)
@@ -502,7 +502,7 @@ static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char *
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL, &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -574,7 +574,7 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL,  &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -809,7 +809,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
                usage();
        }
 
-       if (!parse_ip_mask(argv[0], &addr, &mask)) {
+       if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
                DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
                talloc_free(tmp_ctx);
                return -1;
@@ -950,7 +950,7 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL, &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -1048,7 +1048,7 @@ static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char
                usage();
        }
 
-       if (!parse_ip(argv[0], &addr)) {
+       if (!parse_ip(argv[0], NULL, &addr)) {
                DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
                return -1;
        }