diff options
-rw-r--r-- | usr/src/uts/common/inet/ip/ip.c | 43 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip6_if.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_ftable.c | 42 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_if.c | 7 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_ire.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip_ftable.h | 14 |
6 files changed, 77 insertions, 42 deletions
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 77beff2c4c..72e29875f2 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -13619,8 +13619,8 @@ ip_rput_noire(queue_t *q, mblk_t *mp, int ll_multicast, ipaddr_t dst) ipha_t *ipha; ill_t *ill; ire_t *ire; - boolean_t check_multirt = B_FALSE; ip_stack_t *ipst; + enum ire_forward_action ret_action; ipha = (ipha_t *)mp->b_rptr; ill = (ill_t *)q->q_ptr; @@ -13668,10 +13668,10 @@ ip_rput_noire(queue_t *q, mblk_t *mp, int ll_multicast, ipaddr_t dst) */ DB_CKSUMFLAGS(mp) = 0; - ire = ire_forward(dst, &check_multirt, NULL, NULL, + ire = ire_forward(dst, &ret_action, NULL, NULL, MBLK_GETLABEL(mp), ipst); - if (ire == NULL && check_multirt) { + if (ire == NULL && ret_action == Forward_check_multirt) { /* Let ip_newroute handle CGTP */ ip_newroute(q, mp, dst, NULL, GLOBAL_ZONEID, ipst); return (NULL); @@ -13681,6 +13681,11 @@ ip_rput_noire(queue_t *q, mblk_t *mp, int ll_multicast, ipaddr_t dst) return (ire); mp->b_prev = mp->b_next = 0; + + if (ret_action == Forward_blackhole) { + freemsg(mp); + return (NULL); + } /* send icmp unreachable */ q = WR(q); /* Sent by forwarding path, and router is global zone */ @@ -13857,6 +13862,7 @@ ip_fast_forward(ire_t *ire, ipaddr_t dst, ill_t *ill, mblk_t *mp) queue_t *dev_q; ip_stack_t *ipst = ill->ill_ipst; mblk_t *fpmp; + enum ire_forward_action ret_action; ipha = (ipha_t *)mp->b_rptr; @@ -13882,14 +13888,15 @@ ip_fast_forward(ire_t *ire, ipaddr_t dst, ill_t *ill, mblk_t *mp) /* No ire cache of nexthop. So first create one */ if (ire == NULL) { - boolean_t check_multirt; - ire = ire_forward(dst, &check_multirt, NULL, NULL, NULL, ipst); + ire = ire_forward(dst, &ret_action, NULL, NULL, + NULL, ipst); /* - * We only come to ip_fast_forward if ip_cgtp_filter is - * is not set. So upon return from ire_forward - * check_multirt should remain as false. + * We only come to ip_fast_forward if ip_cgtp_filter + * is not set. So ire_forward() should not return with + * Forward_check_multirt as the next action. */ + ASSERT(ret_action != Forward_check_multirt); if (ire == NULL) { /* An attempt was made to forward the packet */ BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInForwDatagrams); @@ -13897,16 +13904,20 @@ ip_fast_forward(ire_t *ire, ipaddr_t dst, ill_t *ill, mblk_t *mp) mp->b_prev = mp->b_next = 0; /* send icmp unreachable */ /* Sent by forwarding path, and router is global zone */ - if (ip_source_routed(ipha, ipst)) { - icmp_unreachable(ill->ill_wq, mp, - ICMP_SOURCE_ROUTE_FAILED, GLOBAL_ZONEID, - ipst); + if (ret_action == Forward_ret_icmp_err) { + if (ip_source_routed(ipha, ipst)) { + icmp_unreachable(ill->ill_wq, mp, + ICMP_SOURCE_ROUTE_FAILED, + GLOBAL_ZONEID, ipst); + } else { + icmp_unreachable(ill->ill_wq, mp, + ICMP_HOST_UNREACHABLE, + GLOBAL_ZONEID, ipst); + } } else { - icmp_unreachable(ill->ill_wq, mp, - ICMP_HOST_UNREACHABLE, GLOBAL_ZONEID, - ipst); + freemsg(mp); } - return (ire); + return (NULL); } } diff --git a/usr/src/uts/common/inet/ip/ip6_if.c b/usr/src/uts/common/inet/ip/ip6_if.c index 1a9b7876fa..51bb0cbe67 100644 --- a/usr/src/uts/common/inet/ip/ip6_if.c +++ b/usr/src/uts/common/inet/ip/ip6_if.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -661,7 +661,9 @@ ip_rt_add_v6(const in6_addr_t *dst_addr, const in6_addr_t *mask, * to create (what amount to) IRE_PREFIX routes with the * loopback address as the gateway. This is primarily done to * set up prefixes with the RTF_REJECT flag set (for example, - * when generating aggregate routes.) + * when generating aggregate routes). We also OR in the + * RTF_BLACKHOLE flag as these interface routes, by + * definition, can only be that. * * If the IRE type (as defined by ipif->ipif_net_type) is * IRE_LOOPBACK, then we map the request into a @@ -670,8 +672,10 @@ ip_rt_add_v6(const in6_addr_t *dst_addr, const in6_addr_t *mask, * Needless to say, the real IRE_LOOPBACK is NOT created by this * routine, but rather using ire_create_v6() directly. */ - if (ipif->ipif_net_type == IRE_LOOPBACK) + if (ipif->ipif_net_type == IRE_LOOPBACK) { ire->ire_type = IRE_IF_NORESOLVER; + ire->ire_flags |= RTF_BLACKHOLE; + } error = ire_add(&ire, q, mp, func, B_FALSE); if (error == 0) goto save_ire; diff --git a/usr/src/uts/common/inet/ip/ip_ftable.c b/usr/src/uts/common/inet/ip/ip_ftable.c index 6d68d81951..325f5afe1d 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 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -790,8 +790,9 @@ ire_forward_src_ipif(ipaddr_t dst, ire_t *sire, ire_t *ire, ill_t *dst_ill, */ ire_t * -ire_forward(ipaddr_t dst, boolean_t *check_multirt, ire_t *supplied_ire, - ire_t *supplied_sire, const struct ts_label_s *tsl, ip_stack_t *ipst) +ire_forward(ipaddr_t dst, enum ire_forward_action *ret_action, + ire_t *supplied_ire, ire_t *supplied_sire, const struct ts_label_s *tsl, + ip_stack_t *ipst) { ipaddr_t gw = 0; ire_t *ire = NULL; @@ -842,12 +843,10 @@ ire_forward(ipaddr_t dst, boolean_t *check_multirt, ire_t *supplied_ire, * Inform caller about encountering of multirt so that * ip_newroute() can be called. */ - *check_multirt = B_TRUE; + *ret_action = Forward_check_multirt; return (NULL); } - *check_multirt = B_FALSE; - /* * Verify that the returned IRE does not have either * the RTF_REJECT or RTF_BLACKHOLE flags set and that the IRE is @@ -938,6 +937,15 @@ create_irecache: switch (ire->ire_type) { case IRE_IF_NORESOLVER: /* create ire_cache for ire_addr endpoint */ + if (dst_ill->ill_phys_addr_length != IP_ADDR_LEN && + dst_ill->ill_resolver_mp == NULL) { + ip1dbg(("ire_forward: dst_ill %p " + "for IRE_IF_NORESOLVER ire %p has " + "no ill_resolver_mp\n", + (void *)dst_ill, (void *)ire)); + goto icmp_err_ret; + } + /* FALLTHRU */ case IRE_IF_RESOLVER: /* * We have the IRE_IF_RESOLVER of the nexthop gateway @@ -961,9 +969,7 @@ create_irecache: res_mp = dst_ill->ill_resolver_mp; if (ire->ire_type == IRE_IF_RESOLVER && (!OK_RESOLVER_MP(res_mp))) { - ire_refrele(ire); - ire = NULL; - goto out; + goto icmp_err_ret; } /* * To be at this point in the code with a non-zero gw @@ -1058,7 +1064,7 @@ create_irecache: break; } -out: + *ret_action = Forward_ok; if (sire != NULL) ire_refrele(sire); if (dst_ill != NULL) @@ -1067,16 +1073,18 @@ out: ipif_refrele(src_ipif); return (ire); icmp_err_ret: - if (src_ipif != NULL) - ipif_refrele(src_ipif); - if (dst_ill != NULL) - ill_refrele(dst_ill); + *ret_action = Forward_ret_icmp_err; if (sire != NULL) ire_refrele(sire); + if (dst_ill != NULL) + ill_refrele(dst_ill); + if (src_ipif != NULL) + ipif_refrele(src_ipif); if (ire != NULL) { + if (ire->ire_flags & RTF_BLACKHOLE) + *ret_action = Forward_blackhole; ire_refrele(ire); } - /* caller needs to send icmp error message */ return (NULL); } @@ -1257,12 +1265,12 @@ ipfil_sendpkt(const struct sockaddr *dst_addr, mblk_t *mp, uint_t ifindex, { ire_t *ire = NULL, *sire = NULL; ire_t *ire_cache = NULL; - boolean_t check_multirt = B_FALSE; int value; int match_flags; ipaddr_t dst; netstack_t *ns; ip_stack_t *ipst; + enum ire_forward_action ret_action; ASSERT(mp != NULL); @@ -1407,7 +1415,7 @@ ipfil_sendpkt(const struct sockaddr *dst_addr, mblk_t *mp, uint_t ifindex, * the nexthop and adds this incomplete ire * to the ire cache table */ - ire_cache = ire_forward(dst, &check_multirt, ire, sire, + ire_cache = ire_forward(dst, &ret_action, ire, sire, MBLK_GETLABEL(mp), ipst); if (ire_cache == NULL) { ip1dbg(("ipfil_sendpkt: failed to create the" diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index fde1ec4d19..be97d6bbbe 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -7057,14 +7057,17 @@ ip_rt_add(ipaddr_t dst_addr, ipaddr_t mask, ipaddr_t gw_addr, * * If the IRE type (as defined by ipif->ipif_net_type) is * IRE_LOOPBACK, then we map the request into a - * IRE_IF_NORESOLVER. + * IRE_IF_NORESOLVER. We also OR in the RTF_BLACKHOLE flag as + * these interface routes, by definition, can only be that. * * Needless to say, the real IRE_LOOPBACK is NOT created by this * routine, but rather using ire_create() directly. * */ - if (ipif->ipif_net_type == IRE_LOOPBACK) + if (ipif->ipif_net_type == IRE_LOOPBACK) { ire->ire_type = IRE_IF_NORESOLVER; + ire->ire_flags |= RTF_BLACKHOLE; + } error = ire_add(&ire, q, mp, func, B_FALSE); if (error == 0) diff --git a/usr/src/uts/common/inet/ip/ip_ire.c b/usr/src/uts/common/inet/ip/ip_ire.c index ec877b6043..d8613ecd0f 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 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -1524,6 +1524,7 @@ ire_init(ire_t *ire, uchar_t *addr, uchar_t *mask, uchar_t *src_addr, uint32_t ihandle, uint32_t flags, const iulp_t *ulp_info, tsol_gc_t *gc, tsol_gcgrp_t *gcgrp, ip_stack_t *ipst) { + ASSERT(type != IRE_CACHE || stq != NULL); /* * Reject IRE security attribute creation/initialization * if system is not running in Trusted mode. diff --git a/usr/src/uts/common/inet/ip_ftable.h b/usr/src/uts/common/inet/ip_ftable.h index ed6e4c9876..e729761147 100644 --- a/usr/src/uts/common/inet/ip_ftable.h +++ b/usr/src/uts/common/inet/ip_ftable.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -76,6 +76,14 @@ int rtfunc(struct radix_node *, void *); typedef struct rt_entry rt_t; typedef struct rtfuncarg rtf_t; +/* For ire_forward() */ +enum ire_forward_action { + Forward_ok, /* OK to use this IRE to forward */ + Forward_check_multirt, /* CGTP multirt check required */ + Forward_ret_icmp_err, /* Callers to return an ICMP error */ + Forward_blackhole /* Packet is silently discarded */ +}; + struct ts_label_s; extern ire_t *ire_ftable_lookup(ipaddr_t, ipaddr_t, ipaddr_t, int, const ipif_t *, ire_t **, zoneid_t, uint32_t, @@ -84,8 +92,8 @@ extern ire_t *ire_lookup_multi(ipaddr_t, zoneid_t, ip_stack_t *); extern ire_t *ipif_lookup_multi_ire(ipif_t *, ipaddr_t); extern void ire_delete_host_redirects(ipaddr_t, ip_stack_t *); extern ire_t *ire_ihandle_lookup_onlink(ire_t *); -extern ire_t *ire_forward(ipaddr_t, boolean_t *, ire_t *, ire_t *, - const struct ts_label_s *, ip_stack_t *); +extern ire_t *ire_forward(ipaddr_t, enum ire_forward_action *, ire_t *, + ire_t *, const struct ts_label_s *, ip_stack_t *); extern irb_t *ire_get_bucket(ire_t *); extern uint_t ifindex_lookup(const struct sockaddr *, zoneid_t); extern int ipfil_sendpkt(const struct sockaddr *, mblk_t *, uint_t, zoneid_t); |