Mercurial > illumos > illumos-gate
changeset 3909:9f4024db0edf
6521326 6391685 limits the usability of neighbour discovery in non-global zones
author | ja97890 |
---|---|
date | Wed, 28 Mar 2007 07:55:32 -0700 |
parents | 211a66d0821f |
children | 00586900e34c |
files | usr/src/uts/common/inet/ip/ip_ndp.c |
diffstat | 1 files changed, 21 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip_ndp.c Wed Mar 28 05:47:04 2007 -0700 +++ b/usr/src/uts/common/inet/ip/ip_ndp.c Wed Mar 28 07:55:32 2007 -0700 @@ -2289,6 +2289,7 @@ ip6i_t *ip6i; ipif_t *src_ipif = NULL; uint8_t *hw_addr; + zoneid_t zoneid = GLOBAL_ZONEID; /* * If we have a unspecified source(sender) address, select a @@ -2298,6 +2299,12 @@ * the whole group and the h/w address initialized from ill will * be wrong if the source address comes from a different ill. * + * If the sender is specified then we use this address in order + * to lookup the zoneid before calling ip_output_v6(). This is to + * enable unicast ND_NEIGHBOR_ADVERT packets to be routed correctly + * by IP (we cannot guarantee that the global zone has an interface + * route to the destination). + * * Note that the NA never comes here with the unspecified source * address. The following asserts that whenever the source * address is specified, the haddr also should be specified. @@ -2315,7 +2322,7 @@ * source address had better be a valid neighbor. */ src_ipif = ipif_select_source_v6(ill, target, RESTRICT_TO_ILL, - IPV6_PREFER_SRC_DEFAULT, GLOBAL_ZONEID); + IPV6_PREFER_SRC_DEFAULT, ALL_ZONES); if (src_ipif == NULL) { char buf[INET6_ADDRSTRLEN]; @@ -2326,6 +2333,16 @@ } sender = &src_ipif->ipif_v6src_addr; hwaddr_ill = src_ipif->ipif_ill; + } else if (!(IN6_IS_ADDR_UNSPECIFIED(sender))) { + zoneid = ipif_lookup_addr_zoneid_v6(sender, ill, ill->ill_ipst); + /* + * It's possible for ipif_lookup_addr_zoneid_v6() to return + * ALL_ZONES if it cannot find a matching ipif for the address + * we are trying to use. In this case we err on the side of + * trying to send the packet by defaulting to the GLOBAL_ZONEID. + */ + if (zoneid == ALL_ZONES) + zoneid = GLOBAL_ZONEID; } /* @@ -2424,12 +2441,9 @@ if (src_ipif != NULL) ipif_refrele(src_ipif); - if (canput(ill->ill_wq)) { - put(ill->ill_wq, mp); - return (B_FALSE); - } - freemsg(mp); - return (B_TRUE); + + ip_output_v6((void *)(uintptr_t)zoneid, mp, ill->ill_wq, IP_WPUT); + return (B_FALSE); } /*