Hi,
authorAlina Friedrichsen <x-alina@gmx.net>
Thu, 27 Nov 2008 19:34:38 +0000 (20:34 +0100)
committerAlina Friedrichsen <x-alina@gmx.net>
Thu, 27 Nov 2008 19:34:38 +0000 (20:34 +0100)
with this patch you can now select an ULA (RFC 4193 --> replacement of the
site-local addresses) for the OLSR meshing by setting Ip6AddrType to
"unique-local".

And it has now an auto mode, too. If you set Ip6AddrType to "auto", it
try to find a site-local first, then an unique-local, then a global. Good
as the default config, so that you can easy setup an IPv6 mesh.

Warning: The *BSD code is untested, because I don't have this OS here.

src/bsd/net.c
src/cfgparser/cfgfile_gen.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/linux/net.c
src/olsr_cfg.h
src/unix/ifnet.c

index 2044d91..ad3646a 100644 (file)
@@ -562,17 +562,19 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
       if ((flags6 & IN6_IFF_ANYCAST) != 0)
        continue;
       if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
-       if (scope_in) {
-         memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
-         found = 1;
-         break;
-       }
+        if (addrtype6 == OLSR_IP6T_SITELOCAL) found = 1;
       } else {
-       if (scope_in == 0) {
-         memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
-         found = 1;
-         break;
-       }
+        if (addrtype6 == OLSR_IP6T_GLOBAL &&
+            (sin6->sin6_addr->s6_addr[0] != 0xfc &&
+             sin6->sin6_addr->s6_addr[0] != 0xfd)) found = 1;
+      }
+      else if (addrtype6 == OLSR_IP6T_UNIQUELOCAL &&
+               (sin6->sin6_addr->s6_addr[0] == 0xfc ||
+                sin6->sin6_addr->s6_addr[0] == 0xfd)) found = 1;
+      }
+      if (found) {
+        memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+        break;
       }
     }
   }
index 791fe4b..f7bee33 100644 (file)
@@ -87,6 +87,7 @@ void
 olsrd_write_cnf_buf(struct autobuf *abuf, const struct olsrd_config *cnf, olsr_bool write_more_comments)
 {
   char ipv6_buf[INET6_ADDRSTRLEN];             /* buffer for IPv6 inet_ntop */
+  const char *s;
 
   abuf_appendf(abuf, "#\n"
                      "# Configuration file for %s\n"
@@ -294,10 +295,14 @@ olsrd_write_cnf_buf(struct autobuf *abuf, const struct olsrd_config *cnf, olsr_b
       }
           
       if (first) {
-        abuf_appendf(abuf, "\n    # IPv6 address scope to use.\n"
-                           "    # Must be 'site-local' or 'global'\n\n");
+        abuf_appendf(abuf, "\n    # IPv6 address type to use.\n"
+                           "    # Must be 'auto', 'site-local', 'unique-local' or 'global'\n\n");
       }
-      abuf_appendf(abuf, "    Ip6AddrType \t%s\n", in->cnf->ipv6_addrtype ? "site-local" : "global");
+      if (in->cnf->ipv6_addrtype == OLSR_IP6T_SITELOCAL) s = CFG_IP6T_SITELOCAL;
+      else if(in->cnf->ipv6_addrtype == OLSR_IP6T_UNIQUELOCAL) s = CFG_IP6T_UNIQUELOCAL;
+      else if(in->cnf->ipv6_addrtype == OLSR_IP6T_GLOBAL) s = CFG_IP6T_GLOBAL;
+      else s = CFG_IP6T_AUTO;
+      abuf_appendf(abuf, "    Ip6AddrType\t%s\n\n", s);
 
       if (first) {
         abuf_appendf(abuf, "\n"
index b128b0f..c7cdd09 100644 (file)
@@ -459,20 +459,11 @@ isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
   int ifcnt = ifs_in_curr_cfg;
   struct olsr_if *ifs = olsr_cnf->interfaces;
 
-  if ($2->boolean) {
-    while (ifcnt) {
-      ifs->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
-         
-      ifs = ifs->next;
-      ifcnt--;
-    }
-  } else {
-    while (ifcnt) {
-      ifs->cnf->ipv6_addrtype = 0;
-         
-      ifs = ifs->next;
-      ifcnt--;
-    }
+  while (ifcnt) {
+    ifs->cnf->ipv6_addrtype = $2->integer;
+
+    ifs = ifs->next;
+    ifcnt--;
   }
 
   free($2);
index 8dcc001..df34d6b 100644 (file)
@@ -100,15 +100,20 @@ static struct conf_token *get_string_token(const char * const s, const size_t n)
     return rv;
 }
 
-static struct conf_token *get_integer_token(const char * const s)
+static struct conf_token *_get_integer_token(olsr_32_t i)
 {
     struct conf_token *rv = get_conf_token();
     if (rv != NULL) {
-        rv->integer = strtol(s, NULL, 0);
+        rv->integer = i;
     }
     return rv;
 }
 
+static struct conf_token *get_integer_token(const char * const s)
+{
+    return _get_integer_token(strtol(s, NULL, 0));
+}
+
 static struct conf_token *get_floating_token(const char * const s)
 {
     struct conf_token *rv = get_conf_token();
@@ -233,13 +238,23 @@ IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{
     return TOK_BOOLEAN;
 }
 
+"auto" {
+    yylval = _get_integer_token(OLSR_IP6T_AUTO);
+    return TOK_IP6TYPE;
+}
+
 "site-local" {
-    yylval = get_boolean_token(OLSR_TRUE);
+    yylval = _get_integer_token(OLSR_IP6T_SITELOCAL);
+    return TOK_IP6TYPE;
+}
+
+"unique-local" {
+    yylval = _get_integer_token(OLSR_IP6T_UNIQUELOCAL);
     return TOK_IP6TYPE;
 }
 
 "global" {
-    yylval = get_boolean_token(OLSR_FALSE);
+    yylval = _get_integer_token(OLSR_IP6T_GLOBAL);
     return TOK_IP6TYPE;
 }
 
index f8bd7a1..0f401f6 100644 (file)
@@ -636,7 +636,7 @@ join_mcast(struct interface *ifs, int sock)
  *
  */
 int
-get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
+get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int addrtype6)
 {
   int rv = 0;
   FILE *f = fopen(_PATH_PROCNET_IFINET6, "r");
@@ -644,6 +644,7 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
     char devname[IFNAMSIZ];
     char addr6p[8][5];
     int plen, scope, dad_status, if_idx;
+    olsr_bool found = OLSR_FALSE;
     while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
                  addr6p[0], addr6p[1], addr6p[2], addr6p[3],
                  addr6p[4], addr6p[5], addr6p[6], addr6p[7],
@@ -655,14 +656,31 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
                addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
        OLSR_PRINTF(5, "\tinet6 addr: %s\n", addr6);
        OLSR_PRINTF(5, "\tScope: %d\n", scope);
-       if (scope == scope_in) {
+
+        if (addrtype6 == OLSR_IP6T_SITELOCAL && scope == IPV6_ADDR_SITELOCAL) found = OLSR_TRUE;
+        else if (addrtype6 == OLSR_IP6T_UNIQUELOCAL && scope == IPV6_ADDR_GLOBAL) found = OLSR_TRUE;
+        else if (addrtype6 == OLSR_IP6T_GLOBAL && scope == IPV6_ADDR_GLOBAL) found = OLSR_TRUE;
+
+        if (found == OLSR_TRUE) {
+          found = OLSR_FALSE;
+          if (addr6p[0][0] == 'F' || addr6p[0][0] == 'f') {
+            if (addr6p[0][1] == 'C' || addr6p[0][1] == 'c' ||
+                addr6p[0][1] == 'D' || addr6p[0][1] == 'd') found = OLSR_TRUE;
+          }
+          if(addrtype6 == OLSR_IP6T_SITELOCAL) found = OLSR_TRUE;
+          else if(addrtype6 == OLSR_IP6T_UNIQUELOCAL && found == OLSR_TRUE) found = OLSR_TRUE;
+          else if(addrtype6 == OLSR_IP6T_GLOBAL && found == OLSR_FALSE) found = OLSR_TRUE;
+          else found = OLSR_FALSE;
+        }
+
+       if (found == OLSR_TRUE) {
          OLSR_PRINTF(4, "Found addr: %s:%s:%s:%s:%s:%s:%s:%s\n",
                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
                      addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
          inet_pton(AF_INET6, addr6, saddr6);
          rv = 1;
+         break;
        }
-       break;
       }
     }
     fclose(f);
index b5cc997..751cb6f 100644 (file)
 #define CFG_FIBM_CORRECT       "correct"
 #define CFG_FIBM_APPROX        "approx"
 
+#define CFG_IP6T_AUTO          "auto"
+#define CFG_IP6T_SITELOCAL     "site-local"
+#define CFG_IP6T_UNIQUELOCAL   "unique-local"
+#define CFG_IP6T_GLOBAL        "global"
+
+#define OLSR_IP6T_AUTO         0
+#define OLSR_IP6T_SITELOCAL    1
+#define OLSR_IP6T_UNIQUELOCAL  2
+#define OLSR_IP6T_GLOBAL       3
+
+#ifndef IPV6_ADDR_GLOBAL
+#define IPV6_ADDR_GLOBAL       0x0000U
+#endif
+
 #ifndef IPV6_ADDR_SITELOCAL
 #define IPV6_ADDR_SITELOCAL    0x0040U
 #endif
index 37b2db2..ae1e13d 100644 (file)
@@ -231,9 +231,17 @@ chk_if_changed(struct olsr_if *iface)
   /* IP version 6 */
   if (olsr_cnf->ip_version == AF_INET6) {
     struct sockaddr_in6 tmp_saddr6;
+
     /* Get interface address */
     if (get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0) {
-      OLSR_PRINTF(3, "\tCould not find %s IPv6 address for %s\n", iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL ? "site-local" : "global", ifr.ifr_name);
+      if (iface->cnf->ipv6_addrtype == OLSR_IP6T_SITELOCAL)
+         OLSR_PRINTF(1, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
+      else if(iface->cnf->ipv6_addrtype == OLSR_IP6T_UNIQUELOCAL)
+         OLSR_PRINTF(1, "\tCould not find unique-local IPv6 address for %s\n", ifr.ifr_name);
+      else if(iface->cnf->ipv6_addrtype == OLSR_IP6T_GLOBAL)
+         OLSR_PRINTF(1, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
+      else
+         OLSR_PRINTF(1, "\tCould not find an IPv6 address for %s\n", ifr.ifr_name);
       goto remove_interface;
     }
       
@@ -631,8 +639,33 @@ chk_if_up(struct olsr_if *iface, int debuglvl __attribute__((unused)))
   if (olsr_cnf->ip_version == AF_INET6) {
     /* Get interface address */
     struct ipaddr_str buf;
-    if (get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0) {
-      OLSR_PRINTF(debuglvl, "\tCould not find %s IPv6 address for %s\n", iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL ? "site-local" : "global", ifr.ifr_name);
+    int result;
+
+    if (iface->cnf->ipv6_addrtype == OLSR_IP6T_AUTO) {
+      if ((result = get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, OLSR_IP6T_SITELOCAL)) > 0) {
+        iface->cnf->ipv6_addrtype = OLSR_IP6T_SITELOCAL;
+      } else {
+        if ((result = get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, OLSR_IP6T_UNIQUELOCAL)) > 0) {
+          iface->cnf->ipv6_addrtype = OLSR_IP6T_UNIQUELOCAL;
+        } else {
+          if ((result = get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, OLSR_IP6T_GLOBAL)) > 0) {
+            iface->cnf->ipv6_addrtype = OLSR_IP6T_GLOBAL;
+          }
+        }
+      }
+    } else {
+      result = get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype);
+    }
+
+    if(result <= 0) {
+      if (iface->cnf->ipv6_addrtype == OLSR_IP6T_SITELOCAL)
+         OLSR_PRINTF(1, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
+      else if(iface->cnf->ipv6_addrtype == OLSR_IP6T_UNIQUELOCAL)
+         OLSR_PRINTF(1, "\tCould not find unique-local IPv6 address for %s\n", ifr.ifr_name);
+      else if(iface->cnf->ipv6_addrtype == OLSR_IP6T_GLOBAL)
+         OLSR_PRINTF(1, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
+      else
+         OLSR_PRINTF(1, "\tCould not find an IPv6 address for %s\n", ifr.ifr_name);
       return 0;
     }
 
@@ -644,7 +677,7 @@ chk_if_up(struct olsr_if *iface, int debuglvl __attribute__((unused)))
     ifs.int6_multaddr.sin6_flowinfo = htonl(0);
     ifs.int6_multaddr.sin6_scope_id = if_nametoindex(ifr.ifr_name);
     ifs.int6_multaddr.sin6_port     = htons(OLSRPORT);
-    ifs.int6_multaddr.sin6_addr = iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL
+    ifs.int6_multaddr.sin6_addr = iface->cnf->ipv6_addrtype == OLSR_IP6T_SITELOCAL
         ? iface->cnf->ipv6_multi_site.v6
         : iface->cnf->ipv6_multi_glbl.v6;