Re: svn commit: r192282 - head/sys/netinet6

2009-05-17 Thread Bjoern A. Zeeb

On Mon, 18 May 2009, Qing Li wrote:


Author: qingli
Date: Mon May 18 02:25:45 2009
New Revision: 192282
URL: http://svn.freebsd.org/changeset/base/192282

Log:
 This patch resolves the following issues:

 -- A routing socket message is not generated when an IPv6 address is
either inserted or deleted from an interface. The missing routing
message problem was discovered by Randall Stewart and Michael Tuxen
during SCTP testing.

 -- Previously when an IPv6 address is configured on an interface, if the
prefix length is /128, then a host route is instaleld in the kernel
for this address. But this host route is not deleted when that IPv6
address is removed from the interface.

 -- Routes to the link-local all-nodes multicast address and the
interface-local all-nodes multicast address are not removed when
the last IPv6 address is removed from an interface.

 Reviewed by:   bz, gnn


I guess that should have been:

Discussed with: gnn, rrs, bz, tuexen
Tested by:  tuexen


And thanks a lot for fixing all this!



Modified:
 head/sys/netinet6/in6.c

--
Bjoern A. Zeeb  The greatest risk is not taking one.
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org


svn commit: r192282 - head/sys/netinet6

2009-05-17 Thread Qing Li
Author: qingli
Date: Mon May 18 02:25:45 2009
New Revision: 192282
URL: http://svn.freebsd.org/changeset/base/192282

Log:
  This patch resolves the following issues:
  
  -- A routing socket message is not generated when an IPv6 address is
 either inserted or deleted from an interface. The missing routing
 message problem was discovered by Randall Stewart and Michael Tuxen
 during SCTP testing.
  
  -- Previously when an IPv6 address is configured on an interface, if the
 prefix length is /128, then a host route is instaleld in the kernel
 for this address. But this host route is not deleted when that IPv6
 address is removed from the interface.
  
  -- Routes to the link-local all-nodes multicast address and the
 interface-local all-nodes multicast address are not removed when
 the last IPv6 address is removed from an interface.
  
  Reviewed by:  bz, gnn

Modified:
  head/sys/netinet6/in6.c

Modified: head/sys/netinet6/in6.c
==
--- head/sys/netinet6/in6.c Mon May 18 01:51:52 2009(r192281)
+++ head/sys/netinet6/in6.c Mon May 18 02:25:45 2009(r192282)
@@ -1151,6 +1151,28 @@ in6_purgeaddr(struct ifaddr *ifa)
struct ifnet *ifp = ifa-ifa_ifp;
struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
struct in6_multi_mship *imm;
+   struct sockaddr_in6 mltaddr, mltmask;
+   struct rtentry rt0;
+   struct sockaddr_dl gateway;
+   struct sockaddr_in6 mask, addr;
+   int plen, error;
+   struct rtentry *rt;
+   struct ifaddr *ifa0, *nifa;
+
+   /*
+* find another IPv6 address as the gateway for the
+* link-local and node-local all-nodes multicast
+* address routes
+*/
+   TAILQ_FOREACH_SAFE(ifa0, ifp-if_addrhead, ifa_link, nifa) {
+   if ((ifa0-ifa_addr-sa_family != AF_INET6) ||
+   memcmp(satosin6(ifa0-ifa_addr)-sin6_addr,
+  ia-ia_addr.sin6_addr, 
+  sizeof(struct in6_addr)) == 0)
+   continue;
+   else
+   break;
+   }
 
/* stop DAD processing */
nd6_dad_stop(ifa);
@@ -1159,7 +1181,25 @@ in6_purgeaddr(struct ifaddr *ifa)
lla_lookup(LLTABLE6(ifp), (LLE_DELETE | LLE_IFADDR),
(struct sockaddr *)ia-ia_addr);
IF_AFDATA_UNLOCK(ifp);
-   
+
+   /*
+* initialize for rtmsg generation
+*/
+   bzero(gateway, sizeof(gateway));
+   gateway.sdl_len = sizeof(gateway);
+   gateway.sdl_family = AF_LINK;
+   gateway.sdl_nlen = 0;
+   gateway.sdl_alen = ifp-if_addrlen;
+   /* */
+   bzero(rt0, sizeof(rt0));
+   rt0.rt_gateway = (struct sockaddr *)gateway;
+   memcpy(mask, ia-ia_prefixmask, sizeof(ia-ia_prefixmask));
+   memcpy(addr, ia-ia_addr, sizeof(ia-ia_addr));
+   rt_mask(rt0) = (struct sockaddr *)mask;
+   rt_key(rt0) = (struct sockaddr *)addr;
+   rt0.rt_flags = RTF_HOST | RTF_STATIC;
+   rt_newaddrmsg(RTM_DELETE, ifa, 0, rt0);
+
/*
 * leave from multicast groups we have joined for the interface
 */
@@ -1168,6 +1208,139 @@ in6_purgeaddr(struct ifaddr *ifa)
in6_leavegroup(imm);
}
 
+   /*
+* remove the link-local all-nodes address
+*/
+   bzero(mltmask, sizeof(mltmask));
+   mltmask.sin6_len = sizeof(struct sockaddr_in6);
+   mltmask.sin6_family = AF_INET6;
+   mltmask.sin6_addr = in6mask32;
+
+   bzero(mltaddr, sizeof(mltaddr));
+   mltaddr.sin6_len = sizeof(struct sockaddr_in6);
+   mltaddr.sin6_family = AF_INET6;
+   mltaddr.sin6_addr = in6addr_linklocal_allnodes;
+
+   if ((error = in6_setscope(mltaddr.sin6_addr, ifp, NULL)) !=
+   0)
+   goto cleanup; 
+
+   rt = rtalloc1((struct sockaddr *)mltaddr, 0, 0UL);
+   if (rt != NULL  rt-rt_gateway != NULL 
+   (memcmp(satosin6(rt-rt_gateway)-sin6_addr, 
+   ia-ia_addr.sin6_addr,
+   sizeof(ia-ia_addr.sin6_addr)) == 0)) {
+   /* 
+* if no more IPv6 address exists on this interface
+* then remove the multicast address route
+*/
+   if (ifa0 == NULL) {
+   memcpy(mltaddr.sin6_addr, 
satosin6(rt_key(rt))-sin6_addr, 
+  sizeof(mltaddr.sin6_addr));
+   RTFREE_LOCKED(rt);
+   error = rtrequest(RTM_DELETE, (struct sockaddr 
*)mltaddr,
+ (struct sockaddr *)ia-ia_addr,
+ (struct sockaddr *)mltmask, RTF_UP,
+ (struct rtentry **)0);
+   if (error)
+   log(LOG_INFO, in6_purgeaddr: link-local 
all-nodes
+