Hi,

I recently noticed that its not possible to set ipv6 lladdr for ip6gre tunnels using iproute2.

That is because the parser (int ll_addr_a2n()) treats ipv6 addresses as mac addresses because of the ":".

I dont know iproute2 good enough to say if the patch below breaks anything so please only look at this as a proof of concept.

Thanks for reading.


Best regards,

Etienne Muesse


// Testing:

ip nei add fdaa::6 lladdr fdbb::6 dev ip6gre123

-> "fdbb" is invalid lladdr.

Does not work with current version of iproute2 but with patch below.


---
 lib/ll_addr.c | 60 ++++++++++++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/lib/ll_addr.c b/lib/ll_addr.c
index 00b562ae..996901bf 100644
--- a/lib/ll_addr.c
+++ b/lib/ll_addr.c
@@ -49,41 +49,37 @@ const char *ll_addr_n2a(const unsigned char *addr, int alen, int type,  /*NB: lladdr is char * (rather than u8 *) because sa_data is char * (1003.1g) */
 int ll_addr_a2n(char *lladdr, int len, const char *arg)
 {
-    if (strchr(arg, '.')) {
-        inet_prefix pfx;
-        if (get_addr_1(&pfx, arg, AF_INET)) {
-            fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg);
+    inet_prefix pfx;
+    int i;
+
+    if (get_addr_1(&pfx, arg, AF_UNSPEC) == 0) {
+        if (len < pfx.bytelen)
             return -1;
+        memcpy(lladdr, pfx.data, pfx.bytelen);
+        return pfx.bytelen;
+    }
+
+    for (i = 0; i < len; i++) {
+        int temp;
+        char *cp = strchr(arg, ':');
+        if (cp) {
+            *cp = 0;
+            cp++;
         }
-        if (len < 4)
+        if (sscanf(arg, "%x", &temp) != 1) {
+            fprintf(stderr, "\"%s\" is invalid lladdr.\n",
+                arg);
+            return -1;
+        }
+        if (temp < 0 || temp > 255) {
+            fprintf(stderr, "\"%s\" is invalid lladdr.\n",
+                arg);
             return -1;
-        memcpy(lladdr, pfx.data, 4);
-        return 4;
-    } else {
-        int i;
-
-        for (i = 0; i < len; i++) {
-            int temp;
-            char *cp = strchr(arg, ':');
-            if (cp) {
-                *cp = 0;
-                cp++;
-            }
-            if (sscanf(arg, "%x", &temp) != 1) {
-                fprintf(stderr, "\"%s\" is invalid lladdr.\n",
-                    arg);
-                return -1;
-            }
-            if (temp < 0 || temp > 255) {
-                fprintf(stderr, "\"%s\" is invalid lladdr.\n",
-                    arg);
-                return -1;
-            }
-            lladdr[i] = temp;
-            if (!cp)
-                break;
-            arg = cp;
         }
-        return i + 1;
+        lladdr[i] = temp;
+        if (!cp)
+            break;
+        arg = cp;
     }
+    return i + 1;
 }
--


Reply via email to