diff options
-rw-r--r-- | sys/netinet6/in6.c | 12 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 29 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 7 |
3 files changed, 39 insertions, 9 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index c4ba2ff1fa2..529e59eb0b9 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.14 2000/02/28 11:55:21 itojun Exp $ */ +/* $OpenBSD: in6.c,v 1.15 2000/03/02 09:44:28 itojun Exp $ */ /* $KAME: in6.c,v 1.55 2000/02/25 00:32:23 itojun Exp $ */ /* @@ -448,11 +448,14 @@ in6_control(so, cmd, data, ifp, p) ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ia->ia_addr.sin6_family = AF_INET6; ia->ia_addr.sin6_len = sizeof(ia->ia_addr); - ia->ia_ifa.ifa_dstaddr - = (struct sockaddr *)&ia->ia_dstaddr; if (ifp->if_flags & IFF_POINTOPOINT) { + ia->ia_ifa.ifa_dstaddr + = (struct sockaddr *)&ia->ia_dstaddr; ia->ia_dstaddr.sin6_family = AF_INET6; ia->ia_dstaddr.sin6_len = sizeof(ia->ia_dstaddr); + } else { + ia->ia_ifa.ifa_dstaddr = NULL; + bzero(&ia->ia_dstaddr, sizeof(ia->ia_dstaddr)); } ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; @@ -1073,6 +1076,9 @@ in6_lifaddr_ioctl(so, cmd, data, ifp, p) if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, ia->ia_dstaddr.sin6_len); + } else { + bzero(&ifra.ifra_dstaddr, + sizeof(ifra.ifra_dstaddr)); } bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr, ia->ia_prefixmask.sin6_len); diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 16dcb3894aa..8a981dd412c 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,4 +1,5 @@ -/* $OpenBSD: in6_ifattach.c,v 1.6 2000/02/07 06:09:10 itojun Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.7 2000/03/02 09:44:28 itojun Exp $ */ +/* $KAME: in6_ifattach.c,v 1.39 2000/03/02 09:24:45 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -49,7 +50,6 @@ #include <netinet/ip6.h> #include <netinet6/ip6_var.h> #include <netinet6/in6_ifattach.h> -#include <netinet/ip6.h> #include <netinet6/ip6_var.h> #include <netinet6/nd6.h> @@ -339,11 +339,15 @@ in6_ifattach(ifp, type, laddr, noloop) ia = (struct in6_ifaddr *)malloc(sizeof(*ia), M_IFADDR, M_WAITOK); bzero((caddr_t)ia, sizeof(*ia)); ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; - ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; + if (ifp->if_flags & IFF_POINTOPOINT) + ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; + else + ia->ia_ifa.ifa_dstaddr = NULL; ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; ia->ia_ifp = ifp; TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list); + ia->ia_ifa.ifa_refcnt++; /* * Also link into the IPv6 address chain beginning with in6_ifaddr. @@ -355,6 +359,7 @@ in6_ifattach(ifp, type, laddr, noloop) oia->ia_next = ia; } else in6_ifaddr = ia; + ia->ia_ifa.ifa_refcnt++; ia->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6); ia->ia_prefixmask.sin6_family = AF_INET6; @@ -441,11 +446,12 @@ in6_ifattach(ifp, type, laddr, noloop) /* undo changes */ TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list); + IFAFREE(&ia->ia_ifa); if (oia) oia->ia_next = ia->ia_next; else in6_ifaddr = ia->ia_next; - free(ia, M_IFADDR); + IFAFREE(&ia->ia_ifa); return; } } @@ -495,6 +501,7 @@ in6_ifattach(ifp, type, laddr, noloop) ia->ia_next = ib; TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ib, ifa_list); + ib->ia_ifa.ifa_refcnt++; ib->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6); ib->ia_prefixmask.sin6_family = AF_INET6; @@ -502,6 +509,20 @@ in6_ifattach(ifp, type, laddr, noloop) ib->ia_addr.sin6_len = sizeof(struct sockaddr_in6); ib->ia_addr.sin6_family = AF_INET6; ib->ia_addr.sin6_addr = in6addr_loopback; + + /* + * Always initialize ia_dstaddr (= broadcast address) + * to loopback address, to make getifaddr happier. + * + * For BSDI, it is mandatory. The BSDI version of + * ifa_ifwithroute() rejects to add a route to the loopback + * interface. Even for other systems, loopback looks somewhat + * special. + */ + ib->ia_dstaddr.sin6_len = sizeof(struct sockaddr_in6); + ib->ia_dstaddr.sin6_family = AF_INET6; + ib->ia_dstaddr.sin6_addr = in6addr_loopback; + ib->ia_ifa.ifa_metric = ifp->if_metric; rtrequest(RTM_ADD, diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 2a1db314c7c..2207fb8f6d2 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.5 2000/02/28 11:55:23 itojun Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.6 2000/03/02 09:44:28 itojun Exp $ */ /* $KAME: nd6_rtr.c,v 1.27 2000/02/26 06:53:11 itojun Exp $ */ /* @@ -1223,7 +1223,10 @@ in6_ifadd(ifp, in6, addr, prefixlen) bzero((caddr_t)ia, sizeof(*ia)); ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; - ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; + if (ifp->if_flags & IFF_POINTOPOINT) + ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; + else + ia->ia_ifa.ifa_dstaddr = NULL; ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; ia->ia_ifp = ifp; |