tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: point2point network interfaces cannot receive ipv6 packets
On Fri, 2015-04-10 at 17:27 +0100, Robert Swindells wrote:
> Kengo NAKAHARA <k-nakahara%iij.ad.jp@localhost> wrote:
> >On 2015/04/03 16:14, Takahiro HAYASHI wrote:
> >> It seems that IFF_POINTTOPOINT interfaces like tun and gif cannot
> >> receive ipv6 packets.
> >> This occurs on NetBSD/amd64 -current since Feb 27 2015.
> >>
> >> For example, establishing gif tunnnel between 2 hosts.
> >>
> >> [host1] <---> [host2]
> >> 192.168.0.1 192.168.0.2 ipv4 address of real interface
> >> fd00::1 fd00::2 gif address
> >>
> >> When I ping6, a host can send ICMPv6 ECHO(128), but the other host
> >> returns ICMPv6 DST_UNREACH(1) code UNREACH_ADDR(3) to pinging host.
> >
> >I think the reason of this issue is below commit:
> > http://www.nerv.org/netbsd/?q=id:20150226T095446Z.75354d997222ae09acc944ba1c6cf573c3ea724b
>
> The following patch helps for me. It results in the RTF_LLINFO flag getting
> set for the route for the interface.
>
> The comment looks to be incorrect in any case.
>
> Robert Swindells
>
> Index: in6.c
> ===================================================================
> RCS file: /cvsroot/src/sys/netinet6/in6.c,v
> retrieving revision 1.186
> diff -u -r1.186 in6.c
> --- in6.c 7 Apr 2015 23:30:36 -0000 1.186
> +++ in6.c 10 Apr 2015 16:10:31 -0000
> @@ -1695,7 +1695,7 @@
> /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
> if (newhost) {
> /* set the rtrequest function to create llinfo */
> - if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
> + if ((ifp->if_flags & IFF_LOOPBACK) == 0)
> ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
> in6_ifaddlocal(&ia->ia_ifa);
> } else {
>
We shouldn't really need the LLINFO flag on P2P interfaces.
Here is a patch which introduces p2p_rtrequest() which installs a
correct and working local route for P2P interfaces, based on an older
patch for OpenBSD.
I intend to commit this to fix the PR early next week when I can put
more testing into it. Commentary welcome as I can't test many P2P
interfaces.
Roy
Index: sys/net/if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.309
diff -u -r1.309 if.c
--- sys/net/if.c 7 Apr 2015 23:30:36 -0000 1.309
+++ sys/net/if.c 12 Apr 2015 15:57:09 -0000
@@ -1482,6 +1482,58 @@
}
/*
+ * Default action when installing a local route on a point-to-point
+ * interface.
+ */
+void
+p2p_rtrequest(int req, struct rtentry *rt,
+ __unused const struct rt_addrinfo *info)
+{
+ struct ifnet *ifp = rt->rt_ifp;
+ struct ifaddr *ifa, *lo0ifa;
+
+ switch (req) {
+ case RTM_ADD:
+ if ((rt->rt_flags & RTF_LOCAL) == 0)
+ break;
+
+ IFADDR_FOREACH(ifa, ifp) {
+ if (equal(rt_getkey(rt), ifa->ifa_addr))
+ break;
+ }
+ if (ifa == NULL)
+ break;
+
+ /*
+ * Ensure lo0 has an address of the same family.
+ */
+ IFADDR_FOREACH(lo0ifa, lo0ifp) {
+ if (lo0ifa->ifa_addr->sa_family ==
+ ifa->ifa_addr->sa_family)
+ break;
+ }
+ if (lo0ifa == NULL)
+ break;
+
+ rt->rt_ifp = lo0ifp;
+ rt->rt_flags &= ~RTF_LLINFO;
+
+ /*
+ * Make sure to set rt->rt_ifa to the interface
+ * address we are using, otherwise we will have trouble
+ * with source address selection.
+ */
+ if (ifa != rt->rt_ifa)
+ rt_replace_ifa(rt, ifa);
+ break;
+ case RTM_DELETE:
+ case RTM_RESOLVE:
+ default:
+ break;
+ }
+}
+
+/*
* Mark an interface down and notify protocols of
* the transition.
* NOTE: must be called at splsoftnet or equivalent.
Index: sys/net/if.h
===================================================================
RCS file: /cvsroot/src/sys/net/if.h,v
retrieving revision 1.187
diff -u -r1.187 if.h
--- sys/net/if.h 7 Apr 2015 23:30:36 -0000 1.187
+++ sys/net/if.h 12 Apr 2015 15:57:09 -0000
@@ -899,6 +899,7 @@
struct ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *);
void ifafree(struct ifaddr *);
void link_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
+void p2p_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
void if_clone_attach(struct if_clone *);
void if_clone_detach(struct if_clone *);
Index: sys/net/if_gif.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gif.c,v
retrieving revision 1.83
diff -u -r1.83 if_gif.c
--- sys/net/if_gif.c 5 Jun 2014 23:48:16 -0000 1.83
+++ sys/net/if_gif.c 12 Apr 2015 15:57:09 -0000
@@ -423,12 +423,14 @@
{
struct gif_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq*)data;
+ struct ifaddr *ifa = (struct ifaddr*)data;
int error = 0, size;
struct sockaddr *dst, *src;
switch (cmd) {
case SIOCINITIFADDR:
ifp->if_flags |= IFF_UP;
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCADDMULTI:
Index: sys/net/if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.162
diff -u -r1.162 if_gre.c
--- sys/net/if_gre.c 3 Apr 2015 20:01:07 -0000 1.162
+++ sys/net/if_gre.c 12 Apr 2015 15:57:09 -0000
@@ -1180,6 +1180,7 @@
gre_ioctl(struct ifnet *ifp, const u_long cmd, void *data)
{
struct ifreq *ifr;
+ struct ifaddr *ifa = (struct ifaddr *)data;
struct if_laddrreq *lifr = (struct if_laddrreq *)data;
struct gre_softc *sc = ifp->if_softc;
struct gre_soparm *sp;
@@ -1221,6 +1222,7 @@
break;
gre_clearconf(sp, false);
ifp->if_flags |= IFF_UP;
+ ifa->ifa_rtrequest = p2p_rtrequest;
goto mksocket;
case SIOCSIFFLAGS:
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
Index: sys/net/if_ppp.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ppp.c,v
retrieving revision 1.146
diff -u -r1.146 if_ppp.c
--- sys/net/if_ppp.c 1 Jul 2014 15:03:58 -0000 1.146
+++ sys/net/if_ppp.c 12 Apr 2015 15:57:09 -0000
@@ -767,6 +767,7 @@
error = EAFNOSUPPORT;
break;
}
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCADDMULTI:
Index: sys/net/if_spppsubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_spppsubr.c,v
retrieving revision 1.131
diff -u -r1.131 if_spppsubr.c
--- sys/net/if_spppsubr.c 28 Nov 2014 08:29:00 -0000 1.131
+++ sys/net/if_spppsubr.c 12 Apr 2015 15:57:10 -0000
@@ -1017,12 +1017,14 @@
{
struct lwp *l = curlwp; /* XXX */
struct ifreq *ifr = (struct ifreq *) data;
+ struct ifaddr *ifa = (struct ifaddr *) data;
struct sppp *sp = (struct sppp *) ifp;
int s, error=0, going_up, going_down, newmode;
s = splnet();
switch (cmd) {
case SIOCINITIFADDR:
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCSIFFLAGS:
Index: sys/net/if_tun.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_tun.c,v
retrieving revision 1.120
diff -u -r1.120 if_tun.c
--- sys/net/if_tun.c 25 Jul 2014 08:10:40 -0000 1.120
+++ sys/net/if_tun.c 12 Apr 2015 15:57:10 -0000
@@ -435,13 +435,15 @@
{
int error = 0, s;
struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
- struct ifreq *ifr = data;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ifaddr *ifa = (struct ifaddr *)data;
s = splnet();
switch (cmd) {
case SIOCINITIFADDR:
tuninit(tp);
+ ifa->ifa_rtrequest = p2p_rtrequest;
TUNDEBUG("%s: address set\n", ifp->if_xname);
break;
case SIOCSIFBRDADDR:
Index: sys/netinet6/in6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6.c,v
retrieving revision 1.186
diff -u -r1.186 in6.c
--- sys/netinet6/in6.c 7 Apr 2015 23:30:36 -0000 1.186
+++ sys/netinet6/in6.c 12 Apr 2015 15:57:11 -0000
@@ -1695,7 +1695,9 @@
/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
if (newhost) {
/* set the rtrequest function to create llinfo */
- if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ ia->ia_ifa.ifa_rtrequest = p2p_rtrequest;
+ else if ((ifp->if_flags & (IFF_LOOPBACK)) == 0)
ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
in6_ifaddlocal(&ia->ia_ifa);
} else {
Home |
Main Index |
Thread Index |
Old Index