Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: prefixlen of IPv6 over PPP



In article <20091108.114051.241895082.nagae%eagan.jp@localhost>,
Nagae Hidetake  <nagae%eagan.jp@localhost> wrote:
>-=-=-=-=-=-
>
>I think it's time to move to tech-net.
>
>From: Nagae Hidetake <nagae%eagan.jp@localhost>
>Subject: prefixlen of IPv6 over PPP
>Date: Fri, 06 Nov 2009 08:08:11 +0900 (JST)
>
>> My ISP provides IPv6 tunneling service over PPTP
>> (Point to Point Tunneling Protocol). 
>> Supported platform of clients is Windows Vista.
>> IPv6 address is assigned with Router Advertisement.
>> 
>> I'm trying to use this service with NetBSD/i386 5.0.1.
>> PPTP tunnel is successfully opened with pkgsrc/net/pptp as below.
>> (ppp1 is a PPTP tunnel)
>> 
>> ppp0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
>>         inet aaa.aaa.aaa.aaa -> bbb.bbb.bbb.bbb netmask 0xffffff00
>>         inet6 fe80::xxxxx:xxxx:xxxx:xxxx%ppp0 ->  prefixlen 64 scopeid 0x5
>> ppp1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
>>         inet6 fe80::yyyy:yyyy:yyyy:yyyy%ppp1 ->
>fe80::zzzz:zzzz:zzzz:zzzz prefixlen 128 scopeid 0x6
>> 
>> Next, I call rtsol command and the router returns rtadv.
>> But my NetBSD box ignores it.
>> It seems going into the path 'in6_ifadd: wrong prefixlen for %s'
>> of src/sys/netinet6/nd6_rtr.c.
>> 
>> I guess that the problem is prefixlen of ppp1.
>> All 128 bits of link-local address are prefix.
>> On the other hand, prefixlen of IPv6 over PPP looks like set always
>> 128 in 'sif6addr' of src/usr.sbin/pppd/pppd/sys-bsd.c.
>
>I attached a patch to src/usr.sbin/pppd/pppd/sys-bsd.c.
>It makes pppd not to set destination address and set prefixlen 64.
>Setting destination address with prefix 64 is rejected by
>in6_update_ifa1 defined in src/sys/netinet6/in6.c.
>PPTP connection with this patch accepts prefix advertised through RA.
>
>I think this is the way pppoe handles IPv6 Link-Local address.
>Is this a correct solution?
>
>-- 

Does this patch work for you? Linux uses a 10 bit prefixlen...

Index: sys-bsd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pppd/pppd/sys-bsd.c,v
retrieving revision 1.56
diff -u -u -r1.56 sys-bsd.c
--- sys-bsd.c   27 May 2007 18:11:38 -0000      1.56
+++ sys-bsd.c   10 Nov 2009 22:13:53 -0000
@@ -121,6 +121,27 @@
 #endif
 #include <ifaddrs.h>
 
+#ifndef IN6_LLADDR_FROM_EUI64
+#ifdef __KAME__
+#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {                        \
+       sin6.sin6_family = AF_INET6;                            \
+       sin6.sin6_len = sizeof(struct sockaddr_in6);            \
+       sin6.sin6_addr.s6_addr[0] = 0xfe;                       \
+       sin6.sin6_addr.s6_addr[1] = 0x80;                       \
+       eui64_copy(eui64, sin6.sin6_addr.s6_addr[8]);           \
+} while (/*CONSTCOND*/0)
+#define IN6_IFINDEX(sin6, ifindex)                             \
+    /* KAME ifindex hack */                                    \
+    *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] = htons(ifindex)
+#else
+#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {                        \
+       memset(&sin6.s6_addr, 0, sizeof(struct in6_addr));      \
+       sin6.s6_addr16[0] = htons(0xfe80);                      \
+       eui64_copy(eui64, sin6.s6_addr32[2]);                   \
+} while (/*CONSTCOND*/0)
+#endif
+#endif
+
 #if RTM_VERSION >= 3
 #include <sys/param.h>
 #if defined(NetBSD) && (NetBSD >= 199703)
@@ -748,30 +769,22 @@
     strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name));
 
     /* my addr */
-    addreq6.ifra_addr.sin6_family = AF_INET6;
-    addreq6.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
-    addreq6.ifra_addr.sin6_addr.s6_addr[0] = 0xfe;
-    addreq6.ifra_addr.sin6_addr.s6_addr[1] = 0x80;
-    memcpy(&addreq6.ifra_addr.sin6_addr.s6_addr[8], &our_eui64,
-       sizeof(our_eui64));
-    /* KAME ifindex hack */
-    *(u_int16_t *)&addreq6.ifra_addr.sin6_addr.s6_addr[2] = htons(ifindex);
+    IN6_LLADDR_FROM_EUI64(addreq6.ifra_addr, our_eui64);
+    IN6_IFINDEX(addreq6.ifra_addr, ifindex);
 
+#ifdef notdef
     /* his addr */
-    addreq6.ifra_dstaddr.sin6_family = AF_INET6;
-    addreq6.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
-    addreq6.ifra_dstaddr.sin6_addr.s6_addr[0] = 0xfe;
-    addreq6.ifra_dstaddr.sin6_addr.s6_addr[1] = 0x80;
-    memcpy(&addreq6.ifra_dstaddr.sin6_addr.s6_addr[8], &his_eui64,
-       sizeof(our_eui64));
-    /* KAME ifindex hack */
-    *(u_int16_t *)&addreq6.ifra_dstaddr.sin6_addr.s6_addr[2] = htons(ifindex);
+    IN6_LLADDR_FROM_EUI64(addreq6.ifra_dstaddr, his_eui64);
+    IN6_IFINDEX(addreq6.ifra_dstaddr, ifindex);
+#endif
 
-    /* prefix mask: 128bit */
+    /* prefix mask: 112bit */
     addreq6.ifra_prefixmask.sin6_family = AF_INET6;
     addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
     memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff,
-       sizeof(addreq6.ifra_prefixmask.sin6_addr));
+       sizeof(addreq6.ifra_prefixmask.sin6_addr) - sizeof(our_eui64));
+    memset(&addreq6.ifra_prefixmask.sin6_addr+sizeof(our_eui64), 0x00,
+       sizeof(our_eui64));
 
     /* address lifetime (infty) */
     addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
@@ -814,8 +827,8 @@
     /* Route to remote host */
     memset(&rt6, 0, sizeof(rt6));
     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
-    rt6.rtmsg_flags = RTF_UP | RTF_HOST;
-    rt6.rtmsg_dst_len = 128;
+    rt6.rtmsg_flags = RTF_UP;
+    rt6.rtmsg_dst_len = 10;
     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
     rt6.rtmsg_metric = 1;
     
@@ -855,15 +868,8 @@
     strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name));
 
     /* my addr */
-    delreq6.ifr_ifru.ifru_addr.sin6_family = AF_INET6;
-    delreq6.ifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
-    delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[0] = 0xfe;
-    delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[1] = 0x80;
-    memcpy(&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[8], &our_eui64,
-       sizeof(our_eui64));
-    /* KAME ifindex hack */
-    *(u_int16_t *)&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[2] =
-       htons(ifindex);
+    IN6_LLADDR_FROM_EUI64(delreq6.ifr_ifru.ifru_addr, our_eui64);
+    IN6_IFINDEX(delreq6.ifr_ifru.ifru_addr, ifindex);
 
     if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) {
        error("cif6addr: ioctl(SIOCDIFADDR_IN6): %m");



Home | Main Index | Thread Index | Old Index