diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/inet/ip.h | 9 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6_input.c | 35 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6_ire.c | 40 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6_output.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_ftable.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_if.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_input.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_ire.c | 46 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_mroute.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_netinfo.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_output.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_rts.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/tn_ipopt.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip_ire.h | 14 |
14 files changed, 205 insertions, 111 deletions
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h index 5557f941e2..a8ccd69aea 100644 --- a/usr/src/uts/common/inet/ip.h +++ b/usr/src/uts/common/inet/ip.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -524,6 +524,13 @@ extern void ip_mcast_mapping(struct ill_s *, uchar_t *, uchar_t *); #define IRE_FLUSH_GWCHANGE 2 /* + * Flags to ire_route_recursive + */ +#define IRR_NONE 0 +#define IRR_ALLOCATE 1 /* OK to allocate IRE_IF_CLONE */ +#define IRR_INCOMPLETE 2 /* OK to return incomplete chain */ + +/* * Open/close synchronization flags. * These are kept in a separate field in the conn and the synchronization * depends on the atomic 32 bit access to that field. diff --git a/usr/src/uts/common/inet/ip/ip6_input.c b/usr/src/uts/common/inet/ip/ip6_input.c index 46dcacbaf4..70955faa55 100644 --- a/usr/src/uts/common/inet/ip/ip6_input.c +++ b/usr/src/uts/common/inet/ip/ip6_input.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -475,14 +475,14 @@ ip6_bad_address(in6_addr_t *addr, boolean_t is_src) */ static ire_t * ire_linklocal(const in6_addr_t *nexthop, ill_t *ill, ip_recv_attr_t *ira, - boolean_t allocate, ip_stack_t *ipst) + uint_t irr_flags, ip_stack_t *ipst) { int match_flags = MATCH_IRE_SECATTR | MATCH_IRE_ILL; ire_t *ire; ASSERT(IN6_IS_ADDR_LINKLOCAL(nexthop)); ire = ire_route_recursive_v6(nexthop, 0, ill, ALL_ZONES, ira->ira_tsl, - match_flags, allocate, ira->ira_xmit_hint, ipst, NULL, NULL, NULL); + match_flags, irr_flags, ira->ira_xmit_hint, ipst, NULL, NULL, NULL); if (!(ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) || !IS_UNDER_IPMP(ill)) return (ire); @@ -500,7 +500,7 @@ ire_linklocal(const in6_addr_t *nexthop, ill_t *ill, ip_recv_attr_t *ira, ire_refrele(ire); ire = ire_route_recursive_v6(nexthop, 0, ill, ALL_ZONES, ira->ira_tsl, - match_flags, allocate, ira->ira_xmit_hint, ipst, NULL, NULL, NULL); + match_flags, irr_flags, ira->ira_xmit_hint, ipst, NULL, NULL, NULL); ill_refrele(ill); return (ire); } @@ -521,6 +521,7 @@ ill_input_short_v6(mblk_t *mp, void *iph_arg, void *nexthop_arg, ip6_t *ip6h = (ip6_t *)iph_arg; in6_addr_t nexthop = *(in6_addr_t *)nexthop_arg; ilb_stack_t *ilbs = ipst->ips_netstack->netstack_ilb; + uint_t irr_flags; #define rptr ((uchar_t *)ip6h) ASSERT(DB_TYPE(mp) == M_DATA); @@ -755,19 +756,24 @@ ill_input_short_v6(mblk_t *mp, void *iph_arg, void *nexthop_arg, } } + if (ill->ill_flags & ILLF_ROUTER) + irr_flags = IRR_ALLOCATE; + else + irr_flags = IRR_NONE; + /* Can not use route cache with TX since the labels can differ */ if (ira->ira_flags & IRAF_SYSTEM_LABELED) { if (IN6_IS_ADDR_MULTICAST(&nexthop)) { ire = ire_multicast(ill); } else if (IN6_IS_ADDR_LINKLOCAL(&nexthop)) { - ire = ire_linklocal(&nexthop, ill, ira, - (ill->ill_flags & ILLF_ROUTER), ipst); + ire = ire_linklocal(&nexthop, ill, ira, irr_flags, + ipst); } else { /* Match destination and label */ ire = ire_route_recursive_v6(&nexthop, 0, NULL, - ALL_ZONES, ira->ira_tsl, MATCH_IRE_SECATTR, - (ill->ill_flags & ILLF_ROUTER), ira->ira_xmit_hint, - ipst, NULL, NULL, NULL); + ALL_ZONES, ira->ira_tsl, MATCH_IRE_SECATTR, + irr_flags, ira->ira_xmit_hint, ipst, NULL, NULL, + NULL); } /* Update the route cache so we do the ire_refrele */ ASSERT(ire != NULL); @@ -784,12 +790,11 @@ ill_input_short_v6(mblk_t *mp, void *iph_arg, void *nexthop_arg, if (IN6_IS_ADDR_MULTICAST(&nexthop)) { ire = ire_multicast(ill); } else if (IN6_IS_ADDR_LINKLOCAL(&nexthop)) { - ire = ire_linklocal(&nexthop, ill, ira, - (ill->ill_flags & ILLF_ROUTER), ipst); + ire = ire_linklocal(&nexthop, ill, ira, irr_flags, + ipst); } else { ire = ire_route_recursive_dstonly_v6(&nexthop, - (ill->ill_flags & ILLF_ROUTER), ira->ira_xmit_hint, - ipst); + irr_flags, ira->ira_xmit_hint, ipst); } ASSERT(ire != NULL); if (rtc->rtc_ire != NULL) @@ -917,8 +922,8 @@ ire_recv_forward_v6(ire_t *ire, mblk_t *mp, void *iph_arg, ip_recv_attr_t *ira) */ ire = ire_route_recursive_v6(&ip6h->ip6_dst, 0, NULL, GLOBAL_ZONEID, ira->ira_tsl, MATCH_IRE_SECATTR, - (ill->ill_flags & ILLF_ROUTER), ira->ira_xmit_hint, ipst, - NULL, NULL, NULL); + (ill->ill_flags & ILLF_ROUTER) ? IRR_ALLOCATE : IRR_NONE, + ira->ira_xmit_hint, ipst, NULL, NULL, NULL); ire->ire_ib_pkt_count++; (*ire->ire_recvfn)(ire, mp, ip6h, ira); ire_refrele(ire); diff --git a/usr/src/uts/common/inet/ip/ip6_ire.c b/usr/src/uts/common/inet/ip/ip6_ire.c index 533058ad1a..b24d859f4c 100644 --- a/usr/src/uts/common/inet/ip/ip6_ire.c +++ b/usr/src/uts/common/inet/ip/ip6_ire.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -235,7 +235,7 @@ ire_lookup_multi_ill_v6(const in6_addr_t *group, zoneid_t zoneid, ill_t *ill; ire = ire_route_recursive_v6(group, 0, NULL, zoneid, NULL, - MATCH_IRE_DSTONLY, B_FALSE, 0, ipst, setsrcp, NULL, NULL); + MATCH_IRE_DSTONLY, IRR_NONE, 0, ipst, setsrcp, NULL, NULL); ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { @@ -1130,9 +1130,11 @@ ip_select_route_v6(const in6_addr_t *dst, ip_xmit_attr_t *ixa, * * If ill is set this means we will match it by adding MATCH_IRE_ILL. * - * If allocate is not set then we will only inspect the existing IREs; never + * If IRR_ALLOCATE is not set then we will only inspect the existing IREs; never * create an IRE_IF_CLONE. This is used on the receive side when we are not * forwarding. + * If IRR_INCOMPLETE is set then we return the IRE even if we can't correctly + * resolve the gateway. * * Note that this function never returns NULL. It returns an IRE_NOROUTE * instead. @@ -1145,7 +1147,7 @@ ire_t * ire_route_recursive_impl_v6(ire_t *ire, const in6_addr_t *nexthop, uint_t ire_type, const ill_t *ill_arg, zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, - boolean_t allocate, uint32_t xmit_hint, ip_stack_t *ipst, + uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, in6_addr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) { int i, j; @@ -1206,7 +1208,12 @@ ire_route_recursive_impl_v6(ire_t *ire, (IRE_LOCAL|IRE_LOOPBACK|IRE_BROADCAST)) || prefs[i] <= prefs[i-1]) { ire_refrele(ire); - ire = ire_reject(ipst, B_TRUE); + if (irr_flags & IRR_INCOMPLETE) { + ire = ires[0]; + ire_refhold(ire); + } else { + ire = ire_reject(ipst, B_TRUE); + } goto error; } } @@ -1266,16 +1273,16 @@ ire_route_recursive_impl_v6(ire_t *ire, /* * In the case of ip_input and ILLF_FORWARDING not - * being set, and in the case of RTM_GET, - * there is no point in allocating - * an IRE_IF_CLONE. We return the IRE_INTERFACE. - * Note that !allocate can result in a ire_dep_parent - * which is IRE_IF_* without an IRE_IF_CLONE. + * being set, and in the case of RTM_GET, there is + * no point in allocating an IRE_IF_CLONE. We return + * the IRE_INTERFACE. Note that !IRR_ALLOCATE can + * result in a ire_dep_parent which is IRE_IF_* + * without an IRE_IF_CLONE. * We recover from that when we need to send packets * by ensuring that the generations become * IRE_GENERATION_VERIFY in this case. */ - if (!allocate) { + if (!(irr_flags & IRR_ALLOCATE)) { invalidate = B_TRUE; ire = NULL; goto done; @@ -1354,7 +1361,8 @@ cleanup: for (j = 0; j < i; j++) ire_refrele(ires[j]); - ASSERT(ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)); + ASSERT((ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) || + (irr_flags & IRR_INCOMPLETE)); /* * Use IRE_GENERATION_VERIFY to ensure that ip_output will redo the * ip_select_route since the reject or lack of memory might be gone. @@ -1417,11 +1425,11 @@ done: ire_t * ire_route_recursive_v6(const in6_addr_t *nexthop, uint_t ire_type, const ill_t *ill, zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, - boolean_t allocate, uint32_t xmit_hint, ip_stack_t *ipst, + uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, in6_addr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) { return (ire_route_recursive_impl_v6(NULL, nexthop, ire_type, ill, - zoneid, tsl, match_args, allocate, xmit_hint, ipst, setsrcp, + zoneid, tsl, match_args, irr_flags, xmit_hint, ipst, setsrcp, gwattrp, generationp)); } @@ -1438,7 +1446,7 @@ ire_route_recursive_v6(const in6_addr_t *nexthop, uint_t ire_type, * Allow at most one RTF_INDIRECT. */ ire_t * -ire_route_recursive_dstonly_v6(const in6_addr_t *nexthop, boolean_t allocate, +ire_route_recursive_dstonly_v6(const in6_addr_t *nexthop, uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst) { ire_t *ire; @@ -1477,7 +1485,7 @@ ire_route_recursive_dstonly_v6(const in6_addr_t *nexthop, boolean_t allocate, * we found. Normally this would return the same ire. */ ire1 = ire_route_recursive_impl_v6(ire, nexthop, 0, NULL, ALL_ZONES, - NULL, MATCH_IRE_DSTONLY, allocate, xmit_hint, ipst, NULL, NULL, + NULL, MATCH_IRE_DSTONLY, irr_flags, xmit_hint, ipst, NULL, NULL, &generation); ire_refrele(ire); return (ire1); diff --git a/usr/src/uts/common/inet/ip/ip6_output.c b/usr/src/uts/common/inet/ip/ip6_output.c index 50f9309586..6fdcfbc933 100644 --- a/usr/src/uts/common/inet/ip/ip6_output.c +++ b/usr/src/uts/common/inet/ip/ip6_output.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -1232,7 +1232,7 @@ ip_postfrag_multirt_v6(mblk_t *mp, nce_t *nce, iaflags_t ixaflags, ire2 = ire_route_recursive_impl_v6(ire1, &ire1->ire_addr_v6, ire1->ire_type, ire1->ire_ill, ire1->ire_zoneid, NULL, MATCH_IRE_DSTONLY, - B_TRUE, 0, ipst, NULL, NULL, NULL); + IRR_ALLOCATE, 0, ipst, NULL, NULL, NULL); if (ire2 != NULL) ire_refrele(ire2); ill1 = ire_nexthop_ill(ire1); diff --git a/usr/src/uts/common/inet/ip/ip_ftable.c b/usr/src/uts/common/inet/ip/ip_ftable.c index a84a15f513..0ee44e2c1e 100644 --- a/usr/src/uts/common/inet/ip/ip_ftable.c +++ b/usr/src/uts/common/inet/ip/ip_ftable.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -342,7 +342,7 @@ ire_lookup_multi_ill_v4(ipaddr_t group, zoneid_t zoneid, ip_stack_t *ipst, ill_t *ill; ire = ire_route_recursive_v4(group, 0, NULL, zoneid, NULL, - MATCH_IRE_DSTONLY, B_FALSE, 0, ipst, setsrcp, NULL, NULL); + MATCH_IRE_DSTONLY, IRR_NONE, 0, ipst, setsrcp, NULL, NULL); ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { ire_refrele(ire); @@ -524,13 +524,13 @@ route_to_dst(const struct sockaddr *dst_addr, zoneid_t zoneid, ip_stack_t *ipst) if (dst_addr->sa_family == AF_INET) { ire = ire_route_recursive_v4( ((struct sockaddr_in *)dst_addr)->sin_addr.s_addr, 0, NULL, - zoneid, NULL, match_flags, B_TRUE, 0, ipst, NULL, NULL, - NULL); + zoneid, NULL, match_flags, IRR_ALLOCATE, 0, ipst, NULL, + NULL, NULL); } else { ire = ire_route_recursive_v6( &((struct sockaddr_in6 *)dst_addr)->sin6_addr, 0, NULL, - zoneid, NULL, match_flags, B_TRUE, 0, ipst, NULL, NULL, - NULL); + zoneid, NULL, match_flags, IRR_ALLOCATE, 0, ipst, NULL, + NULL, NULL); } ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { @@ -1118,13 +1118,13 @@ ip_select_route(const in6_addr_t *v6dst, ip_xmit_attr_t *ixa, IN6_V4MAPPED_TO_IPADDR(&v6nexthop, v4nexthop); ire = ire_route_recursive_v4(v4nexthop, ire_type, ill, - ixa->ixa_zoneid, ixa->ixa_tsl, match_args, B_TRUE, + ixa->ixa_zoneid, ixa->ixa_tsl, match_args, IRR_ALLOCATE, ixa->ixa_xmit_hint, ipst, &v4setsrc, NULL, generationp); if (setsrcp != NULL) IN6_IPADDR_TO_V4MAPPED(v4setsrc, setsrcp); } else { ire = ire_route_recursive_v6(&v6nexthop, ire_type, ill, - ixa->ixa_zoneid, ixa->ixa_tsl, match_args, B_TRUE, + ixa->ixa_zoneid, ixa->ixa_tsl, match_args, IRR_ALLOCATE, ixa->ixa_xmit_hint, ipst, setsrcp, NULL, generationp); } @@ -1210,6 +1210,12 @@ ip_select_route_v4(ipaddr_t dst, ip_xmit_attr_t *ixa, uint_t *generationp, * * If ill is set this means we will match it by adding MATCH_IRE_ILL. * + * If IRR_ALLOCATE is not set then we will only inspect the existing IREs; never + * create an IRE_IF_CLONE. This is used on the receive side when we are not + * forwarding. + * If IRR_INCOMPLETE is set then we return the IRE even if we can't correctly + * resolve the gateway. + * * Note that this function never returns NULL. It returns an IRE_NOROUTE * instead. * @@ -1221,7 +1227,7 @@ ire_t * ire_route_recursive_impl_v4(ire_t *ire, ipaddr_t nexthop, uint_t ire_type, const ill_t *ill_arg, zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, - boolean_t allocate, uint32_t xmit_hint, ip_stack_t *ipst, ipaddr_t *setsrcp, + uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, ipaddr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) { int i, j; @@ -1280,7 +1286,12 @@ ire_route_recursive_impl_v4(ire_t *ire, (IRE_LOCAL|IRE_LOOPBACK|IRE_BROADCAST)) || prefs[i] <= prefs[i-1]) { ire_refrele(ire); - ire = ire_reject(ipst, B_FALSE); + if (irr_flags & IRR_INCOMPLETE) { + ire = ires[0]; + ire_refhold(ire); + } else { + ire = ire_reject(ipst, B_FALSE); + } goto error; } } @@ -1340,16 +1351,16 @@ ire_route_recursive_impl_v4(ire_t *ire, /* * In the case of ip_input and ILLF_FORWARDING not - * being set, and in the case of RTM_GET, - * there is no point in allocating - * an IRE_IF_CLONE. We return the IRE_INTERFACE. - * Note that !allocate can result in a ire_dep_parent - * which is IRE_IF_* without an IRE_IF_CLONE. + * being set, and in the case of RTM_GET, there is + * no point in allocating an IRE_IF_CLONE. We return + * the IRE_INTERFACE. Note that !IRR_ALLOCATE can + * result in a ire_dep_parent which is IRE_IF_* + * without an IRE_IF_CLONE. * We recover from that when we need to send packets * by ensuring that the generations become * IRE_GENERATION_VERIFY in this case. */ - if (!allocate) { + if (!(irr_flags & IRR_ALLOCATE)) { invalidate = B_TRUE; ire = NULL; goto done; @@ -1430,7 +1441,8 @@ cleanup: for (j = 0; j < i; j++) ire_refrele(ires[j]); - ASSERT(ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)); + ASSERT((ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) || + (irr_flags & IRR_INCOMPLETE)); /* * Use IRE_GENERATION_VERIFY to ensure that ip_output will redo the * ip_select_route since the reject or lack of memory might be gone. @@ -1495,11 +1507,11 @@ done: ire_t * ire_route_recursive_v4(ipaddr_t nexthop, uint_t ire_type, const ill_t *ill, zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, - boolean_t allocate, uint32_t xmit_hint, ip_stack_t *ipst, ipaddr_t *setsrcp, + uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, ipaddr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) { return (ire_route_recursive_impl_v4(NULL, nexthop, ire_type, ill, - zoneid, tsl, match_args, allocate, xmit_hint, ipst, setsrcp, + zoneid, tsl, match_args, irr_flags, xmit_hint, ipst, setsrcp, gwattrp, generationp)); } @@ -1516,7 +1528,7 @@ ire_route_recursive_v4(ipaddr_t nexthop, uint_t ire_type, const ill_t *ill, * Allow at most one RTF_INDIRECT. */ ire_t * -ire_route_recursive_dstonly_v4(ipaddr_t nexthop, boolean_t allocate, +ire_route_recursive_dstonly_v4(ipaddr_t nexthop, uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst) { ire_t *ire; @@ -1555,7 +1567,7 @@ ire_route_recursive_dstonly_v4(ipaddr_t nexthop, boolean_t allocate, * we found. Normally this would return the same ire. */ ire1 = ire_route_recursive_impl_v4(ire, nexthop, 0, NULL, ALL_ZONES, - NULL, MATCH_IRE_DSTONLY, allocate, xmit_hint, ipst, NULL, NULL, + NULL, MATCH_IRE_DSTONLY, irr_flags, xmit_hint, ipst, NULL, NULL, &generation); ire_refrele(ire); return (ire1); diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index 427bc588a0..a4ffac1638 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -7928,13 +7928,13 @@ ip_sioctl_dstinfo(queue_t *q, mblk_t *mp) IN6_V4MAPPED_TO_IPADDR(daddr, v4daddr); v4setsrc = INADDR_ANY; ire = ire_route_recursive_v4(v4daddr, 0, NULL, zoneid, - NULL, match_ire, B_TRUE, 0, ipst, &v4setsrc, NULL, - NULL); + NULL, match_ire, IRR_ALLOCATE, 0, ipst, &v4setsrc, + NULL, NULL); } else { v6setsrc = ipv6_all_zeros; ire = ire_route_recursive_v6(daddr, 0, NULL, zoneid, - NULL, match_ire, B_TRUE, 0, ipst, &v6setsrc, NULL, - NULL); + NULL, match_ire, IRR_ALLOCATE, 0, ipst, &v6setsrc, + NULL, NULL); } ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { diff --git a/usr/src/uts/common/inet/ip/ip_input.c b/usr/src/uts/common/inet/ip/ip_input.c index 65c566a3cb..e7cd69b0be 100644 --- a/usr/src/uts/common/inet/ip/ip_input.c +++ b/usr/src/uts/common/inet/ip/ip_input.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -564,6 +564,7 @@ ill_input_short_v4(mblk_t *mp, void *iph_arg, void *nexthop_arg, ipha_t *ipha = (ipha_t *)iph_arg; ipaddr_t nexthop = *(ipaddr_t *)nexthop_arg; ilb_stack_t *ilbs = ipst->ips_netstack->netstack_ilb; + uint_t irr_flags; #define rptr ((uchar_t *)ipha) ASSERT(DB_TYPE(mp) == M_DATA); @@ -769,6 +770,12 @@ after_ilb: return; } } + + if (ill->ill_flags & ILLF_ROUTER) + irr_flags = IRR_ALLOCATE; + else + irr_flags = IRR_NONE; + /* Can not use route cache with TX since the labels can differ */ if (ira->ira_flags & IRAF_SYSTEM_LABELED) { if (CLASSD(nexthop)) { @@ -777,8 +784,8 @@ after_ilb: /* Match destination and label */ ire = ire_route_recursive_v4(nexthop, 0, NULL, ALL_ZONES, ira->ira_tsl, MATCH_IRE_SECATTR, - (ill->ill_flags & ILLF_ROUTER), - ira->ira_xmit_hint, ipst, NULL, NULL, NULL); + irr_flags, ira->ira_xmit_hint, ipst, NULL, NULL, + NULL); } /* Update the route cache so we do the ire_refrele */ ASSERT(ire != NULL); @@ -796,9 +803,8 @@ after_ilb: ire = ire_multicast(ill); } else { /* Just match the destination */ - ire = ire_route_recursive_dstonly_v4(nexthop, - (ill->ill_flags & ILLF_ROUTER), ira->ira_xmit_hint, - ipst); + ire = ire_route_recursive_dstonly_v4(nexthop, irr_flags, + ira->ira_xmit_hint, ipst); } ASSERT(ire != NULL); if (rtc->rtc_ire != NULL) @@ -939,8 +945,8 @@ ire_recv_forward_v4(ire_t *ire, mblk_t *mp, void *iph_arg, ip_recv_attr_t *ira) } ire = ire_route_recursive_v4(dst, 0, NULL, GLOBAL_ZONEID, ira->ira_tsl, MATCH_IRE_SECATTR, - (ill->ill_flags & ILLF_ROUTER), ira->ira_xmit_hint, ipst, - NULL, NULL, NULL); + (ill->ill_flags & ILLF_ROUTER) ? IRR_ALLOCATE : IRR_NONE, + ira->ira_xmit_hint, ipst, NULL, NULL, NULL); ire->ire_ib_pkt_count++; (*ire->ire_recvfn)(ire, mp, ipha, ira); ire_refrele(ire); diff --git a/usr/src/uts/common/inet/ip/ip_ire.c b/usr/src/uts/common/inet/ip/ip_ire.c index cea86d7529..d195d2543b 100644 --- a/usr/src/uts/common/inet/ip/ip_ire.c +++ b/usr/src/uts/common/inet/ip/ip_ire.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -919,23 +919,49 @@ ire_walk_ill_match(uint_t match_flags, uint_t ire_type, ire_t *ire, /* * Except for ALL_ZONES, we only match the offlink routes * where ire_gateway_addr has an IRE_INTERFACE for the zoneid. + * Since we can have leftover routes after the IP addresses have + * changed, the global zone will also match offlink routes where the + * gateway is unreachable from any zone. */ if ((ire->ire_type & IRE_OFFLINK) && zoneid != ALL_ZONES) { in6_addr_t gw_addr_v6; + boolean_t reach; if (ire->ire_ipversion == IPV4_VERSION) { - if (!ire_gateway_ok_zone_v4(ire->ire_gateway_addr, - zoneid, dst_ill, NULL, ipst, B_FALSE)) - return (B_FALSE); + reach = ire_gateway_ok_zone_v4(ire->ire_gateway_addr, + zoneid, dst_ill, NULL, ipst, B_FALSE); } else { ASSERT(ire->ire_ipversion == IPV6_VERSION); mutex_enter(&ire->ire_lock); gw_addr_v6 = ire->ire_gateway_addr_v6; mutex_exit(&ire->ire_lock); - if (!ire_gateway_ok_zone_v6(&gw_addr_v6, zoneid, - dst_ill, NULL, ipst, B_FALSE)) + reach = ire_gateway_ok_zone_v6(&gw_addr_v6, zoneid, + dst_ill, NULL, ipst, B_FALSE); + } + if (!reach) { + if (zoneid != GLOBAL_ZONEID) + return (B_FALSE); + + /* + * Check if ALL_ZONES reachable - if not then let the + * global zone see it. + */ + if (ire->ire_ipversion == IPV4_VERSION) { + reach = ire_gateway_ok_zone_v4( + ire->ire_gateway_addr, ALL_ZONES, + dst_ill, NULL, ipst, B_FALSE); + } else { + reach = ire_gateway_ok_zone_v6(&gw_addr_v6, + ALL_ZONES, dst_ill, NULL, ipst, B_FALSE); + } + if (reach) { + /* + * Some other zone could see it, hence hide it + * in the global zone. + */ return (B_FALSE); + } } } @@ -2009,12 +2035,12 @@ ire_alt_local(ire_t *ire, zoneid_t zoneid, const ts_label_t *tsl, if (ire->ire_ipversion == IPV4_VERSION) { alt_ire = ire_route_recursive_v4(ire->ire_addr, ire_type, - ill, zoneid, tsl, match_flags, B_TRUE, 0, ipst, NULL, NULL, - &generation); + ill, zoneid, tsl, match_flags, IRR_ALLOCATE, 0, ipst, NULL, + NULL, &generation); } else { alt_ire = ire_route_recursive_v6(&ire->ire_addr_v6, ire_type, - ill, zoneid, tsl, match_flags, B_TRUE, 0, ipst, NULL, NULL, - &generation); + ill, zoneid, tsl, match_flags, IRR_ALLOCATE, 0, ipst, NULL, + NULL, &generation); } ASSERT(alt_ire != NULL); diff --git a/usr/src/uts/common/inet/ip/ip_mroute.c b/usr/src/uts/common/inet/ip/ip_mroute.c index 41f4f3f221..53df3bec4b 100644 --- a/usr/src/uts/common/inet/ip/ip_mroute.c +++ b/usr/src/uts/common/inet/ip/ip_mroute.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -2506,8 +2506,8 @@ register_mforward(mblk_t *mp, ip_recv_attr_t *ira) if (!CLASSD(ipha->ipha_dst)) { ire = ire_route_recursive_v4(ipha->ipha_dst, 0, NULL, ALL_ZONES, - ira->ira_tsl, MATCH_IRE_SECATTR, B_TRUE, 0, ipst, NULL, - NULL, NULL); + ira->ira_tsl, MATCH_IRE_SECATTR, IRR_ALLOCATE, 0, ipst, + NULL, NULL, NULL); } else { ire = ire_multicast(ill); } @@ -2720,7 +2720,7 @@ ip_mroute_decap(mblk_t *mp, ip_recv_attr_t *ira) ipst->ips_ipcl_proto_fanout_v4[IPPROTO_RSVP].connf_head != NULL) { ire = ire_route_recursive_v4(INADDR_BROADCAST, 0, ill, ALL_ZONES, ira->ira_tsl, MATCH_IRE_ILL|MATCH_IRE_SECATTR, - B_TRUE, 0, ipst, NULL, NULL, NULL); + IRR_ALLOCATE, 0, ipst, NULL, NULL, NULL); } else { ire = ire_multicast(ill); } diff --git a/usr/src/uts/common/inet/ip/ip_netinfo.c b/usr/src/uts/common/inet/ip/ip_netinfo.c index 33e791adac..0d0d943676 100644 --- a/usr/src/uts/common/inet/ip/ip_netinfo.c +++ b/usr/src/uts/common/inet/ip/ip_netinfo.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1077,12 +1077,12 @@ ip_routeto_impl(struct sockaddr *address, struct sockaddr *nexthop, if (address->sa_family == AF_INET6) { ire = ire_route_recursive_v6(&sin6->sin6_addr, 0, NULL, - zoneid, NULL, MATCH_IRE_DSTONLY, B_TRUE, 0, ipst, NULL, - NULL, NULL); + zoneid, NULL, MATCH_IRE_DSTONLY, IRR_ALLOCATE, 0, ipst, + NULL, NULL, NULL); } else { ire = ire_route_recursive_v4(sin->sin_addr.s_addr, 0, NULL, - zoneid, NULL, MATCH_IRE_DSTONLY, B_TRUE, 0, ipst, NULL, - NULL, NULL); + zoneid, NULL, MATCH_IRE_DSTONLY, IRR_ALLOCATE, 0, ipst, + NULL, NULL, NULL); } ASSERT(ire != NULL); /* diff --git a/usr/src/uts/common/inet/ip/ip_output.c b/usr/src/uts/common/inet/ip/ip_output.c index e5dd230ba6..59d95a4849 100644 --- a/usr/src/uts/common/inet/ip/ip_output.c +++ b/usr/src/uts/common/inet/ip/ip_output.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -2299,7 +2299,7 @@ ip_postfrag_multirt_v4(mblk_t *mp, nce_t *nce, iaflags_t ixaflags, ire2 = ire_route_recursive_impl_v4(ire1, ire1->ire_addr, ire1->ire_type, ire1->ire_ill, ire1->ire_zoneid, NULL, MATCH_IRE_DSTONLY, - B_TRUE, 0, ipst, NULL, NULL, NULL); + IRR_ALLOCATE, 0, ipst, NULL, NULL, NULL); if (ire2 != NULL) ire_refrele(ire2); ill1 = ire_nexthop_ill(ire1); diff --git a/usr/src/uts/common/inet/ip/ip_rts.c b/usr/src/uts/common/inet/ip/ip_rts.c index 1d2b405828..8a44a0bcd4 100644 --- a/usr/src/uts/common/inet/ip/ip_rts.c +++ b/usr/src/uts/common/inet/ip/ip_rts.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -88,7 +88,7 @@ static int rts_getaddrs(rt_msghdr_t *rtm, in6_addr_t *dst_addrp, in6_addr_t *if_addrp, in6_addr_t *src_addrp, ushort_t *indexp, sa_family_t *afp, tsol_rtsecattr_t *rtsecattr, int *error); static void rts_getifdata(if_data_t *if_data, const ipif_t *ipif); -static int rts_getmetrics(ire_t *ire, rt_metrics_t *metrics); +static int rts_getmetrics(ire_t *ire, ill_t *ill, rt_metrics_t *metrics); static mblk_t *rts_rtmget(mblk_t *mp, ire_t *ire, ire_t *ifire, const in6_addr_t *setsrc, tsol_ire_gw_secattr_t *attrp, sa_family_t af); static void rts_setmetrics(ire_t *ire, uint_t which, rt_metrics_t *metrics); @@ -1026,12 +1026,23 @@ ire_lookup_v4(ipaddr_t dst_addr, ipaddr_t net_mask, ipaddr_t gw_addr, dst_addr = ire->ire_gateway_addr; match_flags &= ~(MATCH_IRE_GW|MATCH_IRE_MASK); ifire = ire_route_recursive_v4(dst_addr, ire_type, ill, zoneid, - tsl, match_flags, B_FALSE, 0, ipst, v4setsrcp, gwattrp, - NULL); + tsl, match_flags, IRR_INCOMPLETE, 0, ipst, v4setsrcp, + gwattrp, NULL); + /* + * Don't allow anything unusual past the first + * iteration. Clearing ifire means caller will not see a + * complete response - there will be no RTA_IFP returned. + */ + if ((ifire->ire_type & + (IRE_LOCAL|IRE_LOOPBACK|IRE_BROADCAST)) || + ire_pref(ifire) <= ire_pref(ire)) { + ire_refrele(ifire); + ifire = NULL; + } } else { ire = ire_route_recursive_v4(dst_addr, ire_type, ill, zoneid, - tsl, match_flags, B_FALSE, 0, ipst, v4setsrcp, gwattrp, - NULL); + tsl, match_flags, IRR_INCOMPLETE, 0, ipst, v4setsrcp, + gwattrp, NULL); } *pifire = ifire; return (ire); @@ -1091,11 +1102,23 @@ ire_lookup_v6(const in6_addr_t *dst_addr_v6, mutex_exit(&ire->ire_lock); match_flags &= ~(MATCH_IRE_GW|MATCH_IRE_MASK); ifire = ire_route_recursive_v6(&dst, ire_type, ill, zoneid, tsl, - match_flags, B_FALSE, 0, ipst, v6setsrcp, gwattrp, NULL); + match_flags, IRR_INCOMPLETE, 0, ipst, v6setsrcp, gwattrp, + NULL); + /* + * Don't allow anything unusual past the first + * iteration. Clearing ifire means caller will not see a + * complete response - there will be no RTA_IFP returned. + */ + if ((ifire->ire_type & + (IRE_LOCAL|IRE_LOOPBACK|IRE_BROADCAST)) || + ire_pref(ifire) <= ire_pref(ire)) { + ire_refrele(ifire); + ifire = NULL; + } } else { ire = ire_route_recursive_v6(dst_addr_v6, ire_type, ill, zoneid, - tsl, match_flags, B_FALSE, 0, ipst, v6setsrcp, gwattrp, - NULL); + tsl, match_flags, IRR_INCOMPLETE, 0, ipst, v6setsrcp, + gwattrp, NULL); } *pifire = ifire; return (ire); @@ -1311,7 +1334,7 @@ rts_rtmget(mblk_t *mp, ire_t *ire, ire_t *ifire, const in6_addr_t *setsrc, new_rtm->rtm_use = rtm->rtm_use; new_rtm->rtm_addrs = rtm_addrs; new_rtm->rtm_flags = rtm_flags; - new_rtm->rtm_inits = rts_getmetrics(ire, &new_rtm->rtm_rmx); + new_rtm->rtm_inits = rts_getmetrics(ire, ill, &new_rtm->rtm_rmx); if (ill != NULL) ill_refrele(ill); return (new_mp); @@ -1466,7 +1489,7 @@ rts_setmetrics(ire_t *ire, uint_t which, rt_metrics_t *metrics) * Get the metrics from a forwarding table route. */ static int -rts_getmetrics(ire_t *ire, rt_metrics_t *metrics) +rts_getmetrics(ire_t *ire, ill_t *ill, rt_metrics_t *metrics) { int metrics_set = 0; @@ -1479,8 +1502,13 @@ rts_getmetrics(ire_t *ire, rt_metrics_t *metrics) */ metrics->rmx_rtt = ire->ire_metrics.iulp_rtt * 1000; metrics_set |= RTV_RTT; - metrics->rmx_mtu = ire->ire_metrics.iulp_mtu; - metrics_set |= RTV_MTU; + if (ire->ire_metrics.iulp_mtu != 0) { + metrics->rmx_mtu = ire->ire_metrics.iulp_mtu; + metrics_set |= RTV_MTU; + } else if (ill != NULL) { + metrics->rmx_mtu = ill->ill_mtu; + metrics_set |= RTV_MTU; + } metrics->rmx_ssthresh = ire->ire_metrics.iulp_ssthresh; metrics_set |= RTV_SSTHRESH; metrics->rmx_rttvar = ire->ire_metrics.iulp_rtt_sd * 1000; diff --git a/usr/src/uts/common/inet/ip/tn_ipopt.c b/usr/src/uts/common/inet/ip/tn_ipopt.c index 32d32470e4..fe92c91f7c 100644 --- a/usr/src/uts/common/inet/ip/tn_ipopt.c +++ b/usr/src/uts/common/inet/ip/tn_ipopt.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -493,7 +493,8 @@ tsol_compute_label_v4(const ts_label_t *tsl, zoneid_t zoneid, ipaddr_t dst, * next-hop gateway is labeled. */ ire = ire_route_recursive_v4(dst, 0, NULL, zoneid, tsl, - MATCH_IRE_SECATTR, B_TRUE, 0, ipst, NULL, &attrp, NULL); + MATCH_IRE_SECATTR, IRR_ALLOCATE, 0, ipst, NULL, &attrp, + NULL); ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { /* no route to destination */ @@ -1003,7 +1004,8 @@ tsol_compute_label_v6(const ts_label_t *tsl, zoneid_t zoneid, * next-hop gateway is labeled. */ ire = ire_route_recursive_v6(dst, 0, NULL, zoneid, tsl, - MATCH_IRE_SECATTR, B_TRUE, 0, ipst, NULL, &attrp, NULL); + MATCH_IRE_SECATTR, IRR_ALLOCATE, 0, ipst, NULL, &attrp, + NULL); ASSERT(ire != NULL); if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { /* no route to destination */ diff --git a/usr/src/uts/common/inet/ip_ire.h b/usr/src/uts/common/inet/ip_ire.h index bb27d8f766..b187f4eeb6 100644 --- a/usr/src/uts/common/inet/ip_ire.h +++ b/usr/src/uts/common/inet/ip_ire.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -262,20 +262,20 @@ extern ire_t *ire_round_robin(irb_t *, ire_ftable_args_t *, uint_t, ire_t *, ip_stack_t *); extern ire_t *ire_route_recursive_v4(ipaddr_t, uint_t, const ill_t *, - zoneid_t, const ts_label_t *, uint_t, boolean_t, uint32_t, ip_stack_t *, + zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t, ip_stack_t *, ipaddr_t *, tsol_ire_gw_secattr_t **, uint_t *); extern ire_t *ire_route_recursive_v6(const in6_addr_t *, uint_t, - const ill_t *, zoneid_t, const ts_label_t *, uint_t, boolean_t, uint32_t, + const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t, ip_stack_t *, in6_addr_t *, tsol_ire_gw_secattr_t **, uint_t *); -extern ire_t *ire_route_recursive_dstonly_v4(ipaddr_t, boolean_t, +extern ire_t *ire_route_recursive_dstonly_v4(ipaddr_t, uint_t, uint32_t, ip_stack_t *); -extern ire_t *ire_route_recursive_dstonly_v6(const in6_addr_t *, boolean_t, +extern ire_t *ire_route_recursive_dstonly_v6(const in6_addr_t *, uint_t, uint32_t, ip_stack_t *); extern ire_t *ire_route_recursive_impl_v4(ire_t *ire, ipaddr_t, uint_t, - const ill_t *, zoneid_t, const ts_label_t *, uint_t, boolean_t, uint32_t, + const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t, ip_stack_t *, ipaddr_t *, tsol_ire_gw_secattr_t **, uint_t *); extern ire_t *ire_route_recursive_impl_v6(ire_t *ire, const in6_addr_t *, - uint_t, const ill_t *, zoneid_t, const ts_label_t *, uint_t, boolean_t, + uint_t, const ill_t *, zoneid_t, const ts_label_t *, uint_t, uint_t, uint32_t, ip_stack_t *, in6_addr_t *, tsol_ire_gw_secattr_t **, uint_t *); /* The different ire_sendfn functions */ |