summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorsommerfe <none@none>2006-06-22 12:52:27 -0700
committersommerfe <none@none>2006-06-22 12:52:27 -0700
commit5d0bc3ededb82d77f7c33d8f58e517a837ba5140 (patch)
treef3b0f2cc21773e13d562f20191626012f1201473 /usr/src
parentabf8481b415d552f9b7ab854dd6032fd972a49ac (diff)
downloadillumos-joyent-5d0bc3ededb82d77f7c33d8f58e517a837ba5140.tar.gz
PSARC 2006/073 PF_ROUTE: Include interface name with RTM_NEWADDR/RTM_DELADDR
PSARC 2006/084 SO_ALLZONES 4963315 Should make IKE work for non-global zones 4984263 in.iked removes server entities when unnumbered interfaces go away 5024997 system daemons need a way to receive packets from all zones 6218993 PF_ROUTE: RTM_NEWADDR/RTM_DELADDR should include interface name via RTA_IFP 6422023 sctp doesn't need shadow copies of conn_t socket option bits 6426542 Comment about ipp_use_min_mtu got lost and wandered into conn_t 6430869 in.iked should ignore loopback addresses, not loopback interfaces 6438186 SCTP handling of getsockopt( .. SO_MAC_EXEMPT) is oddly inconsistent with TCP, UDP
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/mdb/common/modules/sctp/sctp.c7
-rw-r--r--usr/src/cmd/ptools/pfiles/pfiles.c7
-rw-r--r--usr/src/cmd/truss/print.c1
-rw-r--r--usr/src/uts/common/inet/ip/icmp.c10
-rw-r--r--usr/src/uts/common/inet/ip/icmp_opt_data.c5
-rw-r--r--usr/src/uts/common/inet/ip/ip.c29
-rw-r--r--usr/src/uts/common/inet/ip/ip_multi.c4
-rw-r--r--usr/src/uts/common/inet/ip/ip_opt_data.c4
-rw-r--r--usr/src/uts/common/inet/ip/ip_rts.c6
-rw-r--r--usr/src/uts/common/inet/ip/ipclassifier.c17
-rw-r--r--usr/src/uts/common/inet/ipclassifier.h33
-rw-r--r--usr/src/uts/common/inet/sctp/sctp.c21
-rw-r--r--usr/src/uts/common/inet/sctp/sctp_addr.c31
-rw-r--r--usr/src/uts/common/inet/sctp/sctp_hash.c8
-rw-r--r--usr/src/uts/common/inet/sctp/sctp_impl.h16
-rw-r--r--usr/src/uts/common/inet/sctp/sctp_opt_data.c44
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c16
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_opt_data.c6
-rw-r--r--usr/src/uts/common/inet/udp/udp.c12
-rw-r--r--usr/src/uts/common/inet/udp/udp_opt_data.c2
-rw-r--r--usr/src/uts/common/sys/socket.h2
21 files changed, 177 insertions, 104 deletions
diff --git a/usr/src/cmd/mdb/common/modules/sctp/sctp.c b/usr/src/cmd/mdb/common/modules/sctp/sctp.c
index 83904321bb..c40d3249e1 100644
--- a/usr/src/cmd/mdb/common/modules/sctp/sctp.c
+++ b/usr/src/cmd/mdb/common/modules/sctp/sctp.c
@@ -540,13 +540,8 @@ show_sctp_flags(sctp_t *sctp)
mdb_printf("\tunderstands_asconf\t%d\n",
sctp->sctp_understands_asconf);
mdb_printf("\tdebug\t\t\t%d\n", sctp->sctp_debug);
- mdb_printf("\tdontroute\t\t%d\n", sctp->sctp_dontroute);
- mdb_printf("\tbroadcast\t\t%d\n", sctp->sctp_broadcast);
-
- mdb_printf("\tuseloopback\t\t%d\n", sctp->sctp_useloopback);
mdb_printf("\tcchunk_pend\t\t%d\n", sctp->sctp_cchunk_pend);
mdb_printf("\tdgram_errind\t\t%d\n", sctp->sctp_dgram_errind);
- mdb_printf("\treuseaddr\t\t%d\n", sctp->sctp_reuseaddr);
mdb_printf("\tlinger\t\t\t%d\n", sctp->sctp_linger);
if (sctp->sctp_lingering)
@@ -572,8 +567,8 @@ show_sctp_flags(sctp_t *sctp)
mdb_printf("\tprsctp_aware\t\t%d\n", sctp->sctp_prsctp_aware);
mdb_printf("\tlinklocal\t\t%d\n", sctp->sctp_linklocal);
- mdb_printf("\tmac_exempt\t\t%d\n", sctp->sctp_mac_exempt);
mdb_printf("\trexmitting\t\t%d\n", sctp->sctp_rexmitting);
+ mdb_printf("\tzero_win_probe\t\t%d\n", sctp->sctp_zero_win_probe);
mdb_printf("\trecvsndrcvinfo\t\t%d\n", sctp->sctp_recvsndrcvinfo);
mdb_printf("\trecvassocevnt\t\t%d\n", sctp->sctp_recvassocevnt);
diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c
index 634736cf7b..80fdaa3e46 100644
--- a/usr/src/cmd/ptools/pfiles/pfiles.c
+++ b/usr/src/cmd/ptools/pfiles/pfiles.c
@@ -544,11 +544,12 @@ show_sockopts(struct ps_prochandle *Pr, int fd)
{ SO_DONTROUTE, "SO_DONTROUTE," },
{ SO_BROADCAST, "SO_BROADCAST," },
{ SO_OOBINLINE, "SO_OOBINLINE," },
- { SO_DGRAM_ERRIND, "SO_DGRAM_ERRIND,"}
+ { SO_DGRAM_ERRIND, "SO_DGRAM_ERRIND,"},
+ { SO_ALLZONES, "SO_ALLZONES," },
};
struct linger l;
- buf[0] = ',';
+ buf[0] = '!'; /* sentinel value, never printed */
buf[1] = '\0';
for (i = 0; i < sizeof (boolopts) / sizeof (boolopts[0]); i++) {
@@ -588,7 +589,7 @@ show_sockopts(struct ps_prochandle *Pr, int fd)
}
}
- buf[strlen(buf) - 1] = '\0';
+ buf[strlen(buf) - 1] = '\0'; /* overwrites sentinel if no options */
if (buf[1] != '\0')
(void) printf("\t%s\n", buf+1);
}
diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c
index 7ab35fd3b5..d8fc6fc08a 100644
--- a/usr/src/cmd/truss/print.c
+++ b/usr/src/cmd/truss/print.c
@@ -1758,6 +1758,7 @@ sol_optname(private_t *pri, long val)
case SO_ERROR: return ("SO_ERROR");
case SO_TYPE: return ("SO_TYPE");
case SO_PROTOTYPE: return ("SO_PROTOTYPE");
+ case SO_ALLZONES: return ("SO_ALLZONES");
default: (void) snprintf(pri->code_buf, CBSIZE,
"0x%lx", val);
diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c
index df8c33bb4b..d79cfce076 100644
--- a/usr/src/uts/common/inet/ip/icmp.c
+++ b/usr/src/uts/common/inet/ip/icmp.c
@@ -1567,12 +1567,13 @@ icmp_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
*i1 = icmp->icmp_mac_exempt;
break;
/*
- * Following three not meaningful for icmp
+ * Following four not meaningful for icmp
* Action is same as "default" to which we fallthrough
* so we keep them in comments.
* case SO_LINGER:
* case SO_KEEPALIVE:
* case SO_OOBINLINE:
+ * case SO_ALLZONES:
*/
default:
return (-1);
@@ -2024,6 +2025,13 @@ icmp_opt_set(queue_t *q, uint_t optset_context, int level, int name,
if (!checkonly)
icmp->icmp_dgram_errind = onoff;
break;
+ case SO_ALLZONES:
+ /*
+ * "soft" error (negative)
+ * option not handled at this level
+ * Note: Do not modify *outlenp
+ */
+ return (-EINVAL);
case SO_TIMESTAMP:
if (!checkonly) {
icmp->icmp_timestamp = onoff;
diff --git a/usr/src/uts/common/inet/ip/icmp_opt_data.c b/usr/src/uts/common/inet/ip/icmp_opt_data.c
index 515880c03d..41d3278422 100644
--- a/usr/src/uts/common/inet/ip/icmp_opt_data.c
+++ b/usr/src/uts/common/inet/ip/icmp_opt_data.c
@@ -88,7 +88,10 @@ opdes_t icmp_opt_arr[] = {
{ SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0
},
{ SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int),
- 0 },
+ 0 },
+
+{ SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, OP_PASSNEXT, sizeof (int),
+ 0 },
{ IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
(OP_PASSNEXT|OP_VARLEN|OP_NODEFAULT),
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 3f59b430a5..7ba17444f3 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -4245,7 +4245,7 @@ ip_bind_laddr(conn_t *connp, mblk_t *mp, ipaddr_t src_addr, uint16_t lport,
src_ire = NULL;
ipif = NULL;
- zoneid = connp->conn_zoneid;
+ zoneid = IPCL_ZONEID(connp);
if (src_addr) {
src_ire = ire_route_lookup(src_addr, 0, 0, 0,
@@ -4431,7 +4431,7 @@ ip_bind_connected(conn_t *connp, mblk_t *mp, ipaddr_t *src_addrp,
policy_mp = mp->b_cont;
}
- zoneid = connp->conn_zoneid;
+ zoneid = IPCL_ZONEID(connp);
if (CLASSD(dst_addr)) {
/* Pick up an IRE_BROADCAST */
@@ -6353,7 +6353,8 @@ ip_fanout_udp(queue_t *q, mblk_t *mp, ill_t *ill, ipha_t *ipha,
*/
while ((connp != NULL) &&
(!IPCL_UDP_MATCH(connp, dstport, dst,
- srcport, src) || connp->conn_zoneid != zoneid)) {
+ srcport, src) ||
+ (connp->conn_zoneid != zoneid && !connp->conn_allzones))) {
connp = connp->conn_next;
}
@@ -6499,7 +6500,7 @@ notfound:
if (!broadcast && !CLASSD(dst)) {
while (connp != NULL) {
if (IPCL_UDP_MATCH_V6(connp, dstport, ipv6_all_zeros,
- srcport, v6src) && connp->conn_zoneid == zoneid &&
+ srcport, v6src) && IPCL_ZONE_MATCH(connp, zoneid) &&
conn_wantpacket(connp, ill, ipha, flags, zoneid) &&
!connp->conn_ipv6_v6only)
break;
@@ -9666,16 +9667,17 @@ ip_opt_set_ipif(conn_t *connp, ipaddr_t addr, boolean_t checkonly, int option,
ipif_t *ipif = NULL;
int error;
ill_t *ill;
+ int zoneid;
ip2dbg(("ip_opt_set_ipif: ipaddr %X\n", addr));
if (addr != INADDR_ANY || checkonly) {
ASSERT(connp != NULL);
+ zoneid = IPCL_ZONEID(connp);
if (option == IP_NEXTHOP) {
- ipif =
- ipif_lookup_onlink_addr(addr, connp->conn_zoneid);
+ ipif = ipif_lookup_onlink_addr(addr, zoneid);
} else {
- ipif = ipif_lookup_addr(addr, NULL, connp->conn_zoneid,
+ ipif = ipif_lookup_addr(addr, NULL, zoneid,
CONNP_TO_WQ(connp), first_mp, ip_restart_optmgmt,
&error);
}
@@ -10057,6 +10059,17 @@ ip_opt_set(queue_t *q, uint_t optset_context, int level, int name,
mutex_exit(&connp->conn_lock);
}
break; /* goto sizeof (int) option return */
+ case SO_ALLZONES:
+ if (!checkonly) {
+ mutex_enter(&connp->conn_lock);
+ if (IPCL_IS_BOUND(connp)) {
+ mutex_exit(&connp->conn_lock);
+ return (EINVAL);
+ }
+ connp->conn_allzones = *i1 != 0 ? 1 : 0;
+ mutex_exit(&connp->conn_lock);
+ }
+ break; /* goto sizeof (int) option return */
case SO_ANON_MLP:
if (!checkonly) {
mutex_enter(&connp->conn_lock);
@@ -26384,7 +26397,7 @@ conn_wantpacket(conn_t *connp, ill_t *ill, ipha_t *ipha, int fanout_flags,
}
if (!CLASSD(dst)) {
- if (connp->conn_zoneid == zoneid)
+ if (IPCL_ZONE_MATCH(connp, zoneid))
return (B_TRUE);
/*
* The conn is in a different zone; we need to check that this
diff --git a/usr/src/uts/common/inet/ip/ip_multi.c b/usr/src/uts/common/inet/ip/ip_multi.c
index 3586b89d24..d95b8fdaf3 100644
--- a/usr/src/uts/common/inet/ip/ip_multi.c
+++ b/usr/src/uts/common/inet/ip/ip_multi.c
@@ -1858,13 +1858,15 @@ ip_opt_check(conn_t *connp, ipaddr_t group, ipaddr_t src, ipaddr_t ifaddr,
{
ipif_t *ipif;
int err = 0;
- zoneid_t zoneid = connp->conn_zoneid;
+ zoneid_t zoneid;
if (!CLASSD(group) || CLASSD(src)) {
return (EINVAL);
}
*ipifpp = NULL;
+ zoneid = IPCL_ZONEID(connp);
+
ASSERT(!(ifaddr != INADDR_ANY && ifindexp != NULL && *ifindexp != 0));
if (ifaddr != INADDR_ANY) {
ipif = ipif_lookup_addr(ifaddr, NULL, zoneid,
diff --git a/usr/src/uts/common/inet/ip/ip_opt_data.c b/usr/src/uts/common/inet/ip/ip_opt_data.c
index 6f9f7c0f0e..86e146a5b6 100644
--- a/usr/src/uts/common/inet/ip/ip_opt_data.c
+++ b/usr/src/uts/common/inet/ip/ip_opt_data.c
@@ -66,6 +66,10 @@ opdes_t ip_opt_arr[] = {
{ SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0
},
+{ SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, OP_PASSNEXT, sizeof (int),
+ 0 },
+
+
{ IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
(OP_PASSNEXT|OP_VARLEN|OP_NODEFAULT), 40, -1 /* not initialized */ },
{ T_IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
diff --git a/usr/src/uts/common/inet/ip/ip_rts.c b/usr/src/uts/common/inet/ip/ip_rts.c
index 9312ee37c2..7a78143e6c 100644
--- a/usr/src/uts/common/inet/ip/ip_rts.c
+++ b/usr/src/uts/common/inet/ip/ip_rts.c
@@ -1805,7 +1805,7 @@ ip_rts_newaddrmsg(int cmd, int error, const ipif_t *ipif)
(cmd == RTM_DELETE && pass == 2)) {
ncmd = ((cmd == RTM_ADD) ? RTM_NEWADDR : RTM_DELADDR);
- rtm_addrs = (RTA_IFA | RTA_NETMASK | RTA_BRD);
+ rtm_addrs = (RTA_IFA | RTA_NETMASK | RTA_BRD | RTA_IFP);
mp = rts_alloc_msg(ncmd, rtm_addrs, af, 0);
if (mp == NULL)
continue;
@@ -1813,7 +1813,7 @@ ip_rts_newaddrmsg(int cmd, int error, const ipif_t *ipif)
case AF_INET:
rts_fill_msg(ncmd, rtm_addrs, 0,
ipif->ipif_net_mask, 0, ipif->ipif_lcl_addr,
- ipif->ipif_pp_dst_addr, 0, NULL, mp,
+ ipif->ipif_pp_dst_addr, 0, ipif, mp,
0, NULL);
break;
case AF_INET6:
@@ -1821,7 +1821,7 @@ ip_rts_newaddrmsg(int cmd, int error, const ipif_t *ipif)
&ipv6_all_zeros, &ipif->ipif_v6net_mask,
&ipv6_all_zeros, &ipif->ipif_v6lcl_addr,
&ipif->ipif_v6pp_dst_addr, &ipv6_all_zeros,
- NULL, mp, 0, NULL);
+ ipif, mp, 0, NULL);
break;
}
ifam = (ifa_msghdr_t *)mp->b_rptr;
diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c
index 9983068c64..74bc792c80 100644
--- a/usr/src/uts/common/inet/ip/ipclassifier.c
+++ b/usr/src/uts/common/inet/ip/ipclassifier.c
@@ -1362,8 +1362,7 @@ ipcl_classify_v4(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
for (connp = bind_connfp->connf_head; connp != NULL;
connp = connp->conn_next) {
if (IPCL_BIND_MATCH(connp, protocol, ipha->ipha_dst,
- lport) &&
- (connp->conn_zoneid == zoneid ||
+ lport) && (IPCL_ZONE_MATCH(connp, zoneid) ||
(unlabeled && connp->conn_mac_exempt)))
break;
}
@@ -1432,7 +1431,7 @@ ipcl_classify_v4(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
connp = connp->conn_next) {
if (IPCL_UDP_MATCH(connp, lport, ipha->ipha_dst,
fport, ipha->ipha_src) &&
- (connp->conn_zoneid == zoneid ||
+ (IPCL_ZONE_MATCH(connp, zoneid) ||
(unlabeled && connp->conn_mac_exempt)))
break;
}
@@ -1546,7 +1545,7 @@ ipcl_classify_v6(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
connp = connp->conn_next) {
if (IPCL_BIND_MATCH_V6(connp, protocol,
ip6h->ip6_dst, lport) &&
- (connp->conn_zoneid == zoneid ||
+ (IPCL_ZONE_MATCH(connp, zoneid) ||
(unlabeled && connp->conn_mac_exempt)))
break;
}
@@ -1617,7 +1616,7 @@ ipcl_classify_v6(mblk_t *mp, uint8_t protocol, uint_t hdr_len, zoneid_t zoneid)
connp = connp->conn_next) {
if (IPCL_UDP_MATCH_V6(connp, lport, ip6h->ip6_dst,
fport, ip6h->ip6_src) &&
- (connp->conn_zoneid == zoneid ||
+ (IPCL_ZONE_MATCH(connp, zoneid) ||
(unlabeled && connp->conn_mac_exempt)))
break;
}
@@ -1755,7 +1754,7 @@ ipcl_classify_raw(mblk_t *mp, uint8_t protocol, zoneid_t zoneid,
}
}
- if (connp->conn_zoneid == zoneid ||
+ if (IPCL_ZONE_MATCH(connp, zoneid) ||
(unlabeled && connp->conn_mac_exempt))
break;
}
@@ -1784,7 +1783,7 @@ ipcl_classify_raw(mblk_t *mp, uint8_t protocol, zoneid_t zoneid,
connp = connp->conn_next) {
/* We don't allow v4 fallback for v6 raw socket. */
if ((af == (connp->conn_af_isv6 ? IPV4_VERSION :
- IPV6_VERSION)) || (connp->conn_zoneid != zoneid)) {
+ IPV6_VERSION)) || !IPCL_ZONE_MATCH(connp, zoneid)) {
continue;
}
if (af == IPV4_VERSION) {
@@ -2163,7 +2162,7 @@ ipcl_lookup_listener_v4(uint16_t lport, ipaddr_t laddr, zoneid_t zoneid)
connp = connp->conn_next) {
tcp = connp->conn_tcp;
if (IPCL_BIND_MATCH(connp, IPPROTO_TCP, laddr, lport) &&
- connp->conn_zoneid == zoneid &&
+ IPCL_ZONE_MATCH(connp, zoneid) &&
(tcp->tcp_listener == NULL)) {
CONN_INC_REF(connp);
mutex_exit(&bind_connfp->connf_lock);
@@ -2201,7 +2200,7 @@ ipcl_lookup_listener_v6(uint16_t lport, in6_addr_t *laddr, uint_t ifindex,
connp = connp->conn_next) {
tcp = connp->conn_tcp;
if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP, *laddr, lport) &&
- connp->conn_zoneid == zoneid &&
+ IPCL_ZONE_MATCH(connp, zoneid) &&
(tcp->tcp_bound_if == 0 ||
tcp->tcp_bound_if == ifindex) &&
tcp->tcp_listener == NULL) {
diff --git a/usr/src/uts/common/inet/ipclassifier.h b/usr/src/uts/common/inet/ipclassifier.h
index e11e1caf77..f424dbe78d 100644
--- a/usr/src/uts/common/inet/ipclassifier.h
+++ b/usr/src/uts/common/inet/ipclassifier.h
@@ -165,18 +165,13 @@ struct conn_s {
conn_pathmtu_valid : 1, /* The cached mtu is valid. */
conn_ipv6_dontfrag : 1, /* IPV6_DONTFRAG */
- /*
- * This option can take on values in [-1, 1] so we store it
- * +1. Manifest constants IPV6_USE_MIN_MTU_* describe these
- * values.
- */
conn_fully_bound : 1, /* Fully bound connection */
conn_recvif : 1, /* IP_RECVIF option */
conn_recvslla : 1, /* IP_RECVSLLA option */
conn_mdt_ok : 1, /* MDT is permitted */
conn_nexthop_set : 1,
- pad_to_bit_31 : 1;
+ conn_allzones : 1; /* SO_ALLZONES */
tcp_t *conn_tcp; /* Pointer to the tcp struct */
struct udp_s *conn_udp; /* Pointer to the udp struct */
@@ -332,12 +327,28 @@ struct connf_s {
} \
}
+/*
+ * For use with subsystems within ip which use ALL_ZONES as a wildcard
+ */
+#define IPCL_ZONEID(connp) \
+ ((connp)->conn_allzones ? ALL_ZONES : (connp)->conn_zoneid)
+
+/*
+ * For matching between a conn_t and a zoneid.
+ */
+#define IPCL_ZONE_MATCH(connp, zoneid) \
+ (((connp)->conn_allzones) || \
+ ((zoneid) == ALL_ZONES) || \
+ (connp)->conn_zoneid == (zoneid))
+
+
#define _IPCL_V4_MATCH(v6addr, v4addr) \
(V4_PART_OF_V6((v6addr)) == (v4addr) && IN6_IS_ADDR_V4MAPPED(&(v6addr)))
#define _IPCL_V4_MATCH_ANY(addr) \
(IN6_IS_ADDR_V4MAPPED_ANY(&(addr)) || IN6_IS_ADDR_UNSPECIFIED(&(addr)))
+
/*
* IPCL_PROTO_MATCH() only matches conns with the specified zoneid, while
* IPCL_PROTO_MATCH_V6() can match other conns in the multicast case, see
@@ -347,12 +358,12 @@ struct connf_s {
fanout_flags, zoneid) \
((((connp)->conn_src == INADDR_ANY) || \
(((connp)->conn_src == ((ipha)->ipha_dst)) && \
- (((connp)->conn_rem == INADDR_ANY) || \
+ (((connp)->conn_rem == INADDR_ANY) || \
((connp)->conn_rem == ((ipha)->ipha_src))))) && \
- ((zoneid) == ALL_ZONES || (connp)->conn_zoneid == (zoneid)) && \
- (conn_wantpacket((connp), (ill), (ipha), \
- (fanout_flags), (zoneid)) || ((protocol) == IPPROTO_PIM) || \
- ((protocol) == IPPROTO_RSVP)))
+ IPCL_ZONE_MATCH(connp, zoneid) && \
+ (conn_wantpacket((connp), (ill), (ipha), (fanout_flags), \
+ (zoneid)) || ((protocol) == IPPROTO_PIM) || \
+ ((protocol) == IPPROTO_RSVP)))
#define IPCL_PROTO_MATCH_V6(connp, protocol, ip6h, ill, \
fanout_flags, zoneid) \
diff --git a/usr/src/uts/common/inet/sctp/sctp.c b/usr/src/uts/common/inet/sctp/sctp.c
index cc9c1345ad..f42afa0d2c 100644
--- a/usr/src/uts/common/inet/sctp/sctp.c
+++ b/usr/src/uts/common/inet/sctp/sctp.c
@@ -239,7 +239,10 @@ sctp_create_eager(sctp_t *psctp)
if (getpflags(NET_MAC_AWARE, credp) != 0)
connp->conn_mac_exempt = B_TRUE;
}
- connp->conn_zoneid = psctp->sctp_zoneid;
+
+ connp->conn_allzones = pconnp->conn_allzones;
+ connp->conn_zoneid = pconnp->conn_zoneid;
+
sctp->sctp_mss = psctp->sctp_mss;
sctp->sctp_detached = B_TRUE;
/*
@@ -853,6 +856,7 @@ sctp_init_values(sctp_t *sctp, sctp_t *psctp, int sleep)
{
int err;
int cnt;
+ conn_t *connp, *pconnp;
ASSERT((sctp->sctp_family == AF_INET &&
sctp->sctp_ipversion == IPV4_VERSION) ||
@@ -954,16 +958,22 @@ sctp_init_values(sctp_t *sctp, sctp_t *psctp, int sleep)
/* xxx should be a better way to copy these flags xxx */
sctp->sctp_debug = psctp->sctp_debug;
- sctp->sctp_dontroute = psctp->sctp_dontroute;
- sctp->sctp_useloopback = psctp->sctp_useloopback;
- sctp->sctp_broadcast = psctp->sctp_broadcast;
- sctp->sctp_reuseaddr = psctp->sctp_reuseaddr;
sctp->sctp_bound_to_all = psctp->sctp_bound_to_all;
sctp->sctp_cansleep = psctp->sctp_cansleep;
sctp->sctp_send_adaption = psctp->sctp_send_adaption;
sctp->sctp_ndelay = psctp->sctp_ndelay;
sctp->sctp_events = psctp->sctp_events;
sctp->sctp_ipv6_recvancillary = psctp->sctp_ipv6_recvancillary;
+
+ /* Copy IP-layer options */
+ connp = sctp->sctp_connp;
+ pconnp = psctp->sctp_connp;
+
+ connp->conn_broadcast = pconnp->conn_broadcast;
+ connp->conn_loopback = pconnp->conn_loopback;
+ connp->conn_dontroute = pconnp->conn_dontroute;
+ connp->conn_reuseaddr = pconnp->conn_reuseaddr;
+
} else {
/*
* Initialize the header template
@@ -1369,6 +1379,7 @@ sctp_create(void *sctp_ulpd, sctp_t *parent, int family, int flags,
*/
sctp->sctp_lport = psctp->sctp_lport;
sctp->sctp_state = SCTPS_BOUND;
+ sctp->sctp_allzones = psctp->sctp_allzones;
sctp->sctp_zoneid = psctp->sctp_zoneid;
WAKE_SCTP(psctp);
} else {
diff --git a/usr/src/uts/common/inet/sctp/sctp_addr.c b/usr/src/uts/common/inet/sctp/sctp_addr.c
index 089ac791a8..a4bef74443 100644
--- a/usr/src/uts/common/inet/sctp/sctp_addr.c
+++ b/usr/src/uts/common/inet/sctp/sctp_addr.c
@@ -50,7 +50,7 @@
static void sctp_ipif_inactive(sctp_ipif_t *);
static sctp_ipif_t *sctp_lookup_ipif_addr(in6_addr_t *, boolean_t,
- zoneid_t zoneid, uint_t);
+ sctp_t *, uint_t);
static int sctp_get_all_ipifs(sctp_t *, int);
int sctp_valid_addr_list(sctp_t *, const void *, uint32_t,
uchar_t *, size_t);
@@ -94,6 +94,9 @@ void sctp_saddr_fini();
((!(ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V4)) || \
((ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V6)))
+#define SCTP_IPIF_ZONE_MATCH(sctp, ipif) \
+ IPCL_ZONE_MATCH((sctp)->sctp_connp, (ipif)->sctp_ipif_zoneid)
+
#define SCTP_ILL_HASH_FN(index) ((index) % SCTP_ILL_HASH)
#define SCTP_IPIF_HASH_FN(seqid) ((seqid) % SCTP_IPIF_HASH)
#define SCTP_ILL_TO_PHYINDEX(ill) ((ill)->ill_phyint->phyint_ifindex)
@@ -167,14 +170,14 @@ sctp_ipif_inactive(sctp_ipif_t *sctp_ipif)
* Called with no locks held.
*/
static sctp_ipif_t *
-sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid,
+sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, sctp_t *sctp,
uint_t ifindex)
{
int i;
int j;
sctp_ipif_t *sctp_ipif;
- ASSERT(zoneid != ALL_ZONES);
+ ASSERT(sctp->sctp_zoneid != ALL_ZONES);
rw_enter(&sctp_g_ipifs_lock, RW_READER);
for (i = 0; i < SCTP_IPIF_HASH; i++) {
if (sctp_g_ipifs[i].ipif_count == 0)
@@ -182,8 +185,7 @@ sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid,
sctp_ipif = list_head(&sctp_g_ipifs[i].sctp_ipif_list);
for (j = 0; j < sctp_g_ipifs[i].ipif_count; j++) {
rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
- if ((zoneid == sctp_ipif->sctp_ipif_zoneid ||
- sctp_ipif->sctp_ipif_zoneid == ALL_ZONES) &&
+ if (SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) &&
SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) &&
(ifindex == 0 || ifindex ==
sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
@@ -226,8 +228,7 @@ sctp_get_all_ipifs(sctp_t *sctp, int sleep)
rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
!SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
- (sctp_ipif->sctp_ipif_zoneid != ALL_ZONES &&
- sctp_ipif->sctp_ipif_zoneid != sctp->sctp_zoneid) ||
+ !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
(sctp->sctp_ipversion == IPV4_VERSION &&
sctp_ipif->sctp_ipif_isv6) ||
(sctp->sctp_connp->conn_ipv6_v6only &&
@@ -359,8 +360,8 @@ sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt,
goto free_ret;
}
if (lookup_saddr) {
- ipif = sctp_lookup_ipif_addr(&addr, B_TRUE,
- sctp->sctp_zoneid, ifindex);
+ ipif = sctp_lookup_ipif_addr(&addr, B_TRUE, sctp,
+ ifindex);
if (ipif == NULL) {
/* Address not in the list */
err = EINVAL;
@@ -974,8 +975,8 @@ sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt,
ifindex = sin6->sin6_scope_id;
break;
}
- sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE,
- sctp->sctp_zoneid, ifindex);
+ sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE, sctp,
+ ifindex);
ASSERT(sctp_ipif != NULL);
sctp_ipif_hash_remove(sctp, sctp_ipif);
}
@@ -1000,8 +1001,7 @@ sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
sctp_saddr_ipif_t *saddr_ipifs;
sctp_ipif_t *sctp_ipif;
- sctp_ipif = sctp_lookup_ipif_addr(addr, B_FALSE, sctp->sctp_zoneid,
- ifindex);
+ sctp_ipif = sctp_lookup_ipif_addr(addr, B_FALSE, sctp, ifindex);
if (sctp_ipif == NULL)
return (NULL);
@@ -1015,8 +1015,7 @@ sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
{
sctp_ipif_t *sctp_ipif;
- sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp->sctp_zoneid,
- ifindex);
+ sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp, ifindex);
if (sctp_ipif == NULL)
return (EINVAL);
@@ -1447,7 +1446,7 @@ get_all_addrs:
!SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
SCTP_IS_IPIF_LOOPBACK(sctp_ipif) ||
SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) ||
- sctp_ipif->sctp_ipif_zoneid != sctp->sctp_zoneid ||
+ !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
(sctp->sctp_ipversion == IPV4_VERSION &&
sctp_ipif->sctp_ipif_isv6) ||
(sctp->sctp_connp->conn_ipv6_v6only &&
diff --git a/usr/src/uts/common/inet/sctp/sctp_hash.c b/usr/src/uts/common/inet/sctp/sctp_hash.c
index 2efd771f9e..ff21e9c950 100644
--- a/usr/src/uts/common/inet/sctp/sctp_hash.c
+++ b/usr/src/uts/common/inet/sctp/sctp_hash.c
@@ -286,8 +286,8 @@ sctp_conn_match(in6_addr_t *faddr, in6_addr_t *laddr, uint32_t ports,
mutex_enter(&tf->tf_lock);
for (sctp = tf->tf_sctp; sctp; sctp = sctp->sctp_conn_hash_next) {
- if (ports != sctp->sctp_ports || (zoneid != ALL_ZONES &&
- zoneid != sctp->sctp_zoneid)) {
+ if (ports != sctp->sctp_ports ||
+ !IPCL_ZONE_MATCH(sctp->sctp_connp, zoneid)) {
continue;
}
@@ -337,8 +337,8 @@ listen_match(in6_addr_t *laddr, uint32_t ports, uint_t ipif_seqid,
mutex_enter(&tf->tf_lock);
for (sctp = tf->tf_sctp; sctp; sctp = sctp->sctp_listen_hash_next) {
- if (lport != sctp->sctp_lport || (zoneid != ALL_ZONES &&
- zoneid != sctp->sctp_zoneid)) {
+ if (lport != sctp->sctp_lport ||
+ !IPCL_ZONE_MATCH(sctp->sctp_connp, zoneid)) {
continue;
}
diff --git a/usr/src/uts/common/inet/sctp/sctp_impl.h b/usr/src/uts/common/inet/sctp/sctp_impl.h
index fbc157f682..fd934ab482 100644
--- a/usr/src/uts/common/inet/sctp/sctp_impl.h
+++ b/usr/src/uts/common/inet/sctp/sctp_impl.h
@@ -633,7 +633,10 @@ typedef struct sctp_s {
conn_t *sctp_connp; /* conn_t stuff */
#define sctp_zoneid sctp_connp->conn_zoneid
+#define sctp_allzones sctp_connp->conn_allzones
+#define sctp_mac_exempt sctp_connp->conn_mac_exempt
#define sctp_credp sctp_connp->conn_cred
+#define sctp_reuseaddr sctp_connp->conn_reuseaddr
/* Peer address tracking */
sctp_faddr_t *sctp_lastfaddr; /* last faddr in list */
@@ -743,13 +746,8 @@ typedef struct sctp_s {
sctp_understands_asconf : 1, /* Peer handles ASCONF chunks */
sctp_debug : 1, /* SO_DEBUG "socket" option. */
- sctp_dontroute : 1, /* SO_DONTROUTE "socket" option. */
- sctp_broadcast : 1, /* SO_BROADCAST "socket" option. */
-
- sctp_useloopback : 1, /* SO_USELOOPBACK "socket" option. */
sctp_cchunk_pend : 1, /* Control chunk in flight. */
sctp_dgram_errind : 1, /* SO_DGRAM_ERRIND option */
- sctp_reuseaddr : 1, /* SO_REUSEADDR "socket" option. */
sctp_linger : 1, /* SO_LINGER turned on */
sctp_lingering : 1, /* Lingering in close */
@@ -773,11 +771,10 @@ typedef struct sctp_s {
sctp_prsctp_aware : 1, /* is peer PR-SCTP aware? */
sctp_linklocal : 1, /* is linklocal assoc. */
- sctp_mac_exempt : 1, /* SO_MAC_EXEMPT */
sctp_rexmitting : 1, /* SCTP is retransmitting */
sctp_zero_win_probe : 1, /* doing zero win probe */
- sctp_dummy : 3;
+ sctp_dummy : 8;
} sctp_bits;
struct {
uint32_t
@@ -795,12 +792,8 @@ typedef struct sctp_s {
#define sctp_priv_stream sctp_bits.sctp_priv_stream
#define sctp_understands_asconf sctp_bits.sctp_understands_asconf
#define sctp_debug sctp_bits.sctp_debug
-#define sctp_dontroute sctp_bits.sctp_dontroute
-#define sctp_broadcast sctp_bits.sctp_broadcast
-#define sctp_useloopback sctp_bits.sctp_useloopback
#define sctp_cchunk_pend sctp_bits.sctp_cchunk_pend
#define sctp_dgram_errind sctp_bits.sctp_dgram_errind
-#define sctp_reuseaddr sctp_bits.sctp_reuseaddr
#define sctp_linger sctp_bits.sctp_linger
#define sctp_lingering sctp_bits.sctp_lingering
#define sctp_loopback sctp_bits.sctp_loopback
@@ -819,7 +812,6 @@ typedef struct sctp_s {
#define sctp_chk_fast_rexmit sctp_bits.sctp_chk_fast_rexmit
#define sctp_prsctp_aware sctp_bits.sctp_prsctp_aware
#define sctp_linklocal sctp_bits.sctp_linklocal
-#define sctp_mac_exempt sctp_bits.sctp_mac_exempt
#define sctp_rexmitting sctp_bits.sctp_rexmitting
#define sctp_zero_win_probe sctp_bits.sctp_zero_win_probe
diff --git a/usr/src/uts/common/inet/sctp/sctp_opt_data.c b/usr/src/uts/common/inet/sctp/sctp_opt_data.c
index 89ffd6ae60..c670fecbb9 100644
--- a/usr/src/uts/common/inet/sctp/sctp_opt_data.c
+++ b/usr/src/uts/common/inet/sctp/sctp_opt_data.c
@@ -701,16 +701,16 @@ sctp_get_opt(sctp_t *sctp, int level, int name, void *ptr, socklen_t *optlen)
*i1 = sctp->sctp_debug ? SO_DEBUG : 0;
break;
case SO_DONTROUTE:
- *i1 = sctp->sctp_dontroute ? SO_DONTROUTE : 0;
+ *i1 = connp->conn_dontroute ? SO_DONTROUTE : 0;
break;
case SO_USELOOPBACK:
- *i1 = sctp->sctp_useloopback ? SO_USELOOPBACK : 0;
+ *i1 = connp->conn_loopback ? SO_USELOOPBACK : 0;
break;
case SO_BROADCAST:
- *i1 = sctp->sctp_broadcast ? SO_BROADCAST : 0;
+ *i1 = connp->conn_broadcast ? SO_BROADCAST : 0;
break;
case SO_REUSEADDR:
- *i1 = sctp->sctp_reuseaddr ? SO_REUSEADDR : 0;
+ *i1 = connp->conn_reuseaddr ? SO_REUSEADDR : 0;
break;
case SO_DGRAM_ERRIND:
*i1 = sctp->sctp_dgram_errind ? SO_DGRAM_ERRIND : 0;
@@ -721,8 +721,11 @@ sctp_get_opt(sctp_t *sctp, int level, int name, void *ptr, socklen_t *optlen)
case SO_RCVBUF:
*i1 = sctp->sctp_rwnd;
break;
+ case SO_ALLZONES:
+ *i1 = connp->conn_allzones;
+ break;
case SO_MAC_EXEMPT:
- *i1 = sctp->sctp_mac_exempt ? SO_MAC_EXEMPT : 0;
+ *i1 = connp->conn_mac_exempt;
break;
default:
retval = EINVAL;
@@ -1160,22 +1163,17 @@ sctp_set_opt(sctp_t *sctp, int level, int name, const void *invalp,
case SO_DONTROUTE:
/*
* SO_DONTROUTE, SO_USELOOPBACK and SO_BROADCAST are
- * only of interest to IP. We track them here only so
- * that we can report their current value.
+ * only of interest to IP.
*/
- sctp->sctp_dontroute = onoff;
connp->conn_dontroute = onoff;
break;
case SO_USELOOPBACK:
- sctp->sctp_useloopback = onoff;
connp->conn_loopback = onoff;
break;
case SO_BROADCAST:
- sctp->sctp_broadcast = onoff;
connp->conn_broadcast = onoff;
break;
case SO_REUSEADDR:
- sctp->sctp_reuseaddr = onoff;
connp->conn_reuseaddr = onoff;
break;
case SO_DGRAM_ERRIND:
@@ -1220,14 +1218,28 @@ sctp_set_opt(sctp_t *sctp, int level, int name, const void *invalp,
* and sctp_opt_get ?
*/
break;
+ case SO_ALLZONES:
+ if (secpolicy_net(sctp->sctp_credp, OP_CONFIG,
+ B_TRUE)) {
+ retval = EACCES;
+ break;
+ }
+ if (sctp->sctp_state >= SCTPS_BOUND) {
+ retval = EINVAL;
+ break;
+ }
+ sctp->sctp_allzones = onoff;
+ break;
case SO_MAC_EXEMPT:
- if (secpolicy_net_mac_aware(sctp->sctp_credp) != 0 ||
- sctp->sctp_state >= SCTPS_BOUND) {
+ if (secpolicy_net_mac_aware(sctp->sctp_credp) != 0) {
retval = EACCES;
- } else {
- sctp->sctp_mac_exempt = onoff;
- connp->conn_mac_exempt = onoff;
+ break;
+ }
+ if (sctp->sctp_state >= SCTPS_BOUND) {
+ retval = EINVAL;
+ break;
}
+ connp->conn_mac_exempt = onoff;
break;
default:
retval = EINVAL;
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index 17a35961d8..5ae25e49d5 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -3511,7 +3511,7 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr,
* privilege as being in all zones, as there's
* otherwise no way to identify the right receiver.
*/
- if (lconnp->conn_zoneid != zoneid &&
+ if (!IPCL_ZONE_MATCH(ltcp->tcp_connp, zoneid) &&
!lconnp->conn_mac_exempt &&
!connp->conn_mac_exempt)
continue;
@@ -5341,7 +5341,7 @@ tcp_update_label(tcp_t *tcp, const cred_t *cr)
* reference is dropped by the squeue framework.
*
* 3) The ref on listener placed in 1 above is dropped in tcp_accept_finish
- *
+ *
* The reference must be released by the same entity that added the reference
* In the above scheme, the eager is the entity that adds and releases the
* references. Note that tcp_accept_finish executes in the squeue of the eager
@@ -5373,10 +5373,10 @@ tcp_update_label(tcp_t *tcp, const cred_t *cr)
* based on the ref placed on eager before sending T_conn_ind.
* The only entity that can negate this refhold is a listener close
* which is mutually exclusive with an active acceptor stream.
- *
+ *
* Eager's reference on the listener
* ===================================
- *
+ *
* If the accept happens (even on a closed eager) the eager drops its
* reference on the listener at the start of tcp_accept_finish. If the
* eager is killed due to an incoming RST before the T_conn_ind is sent up,
@@ -9587,6 +9587,9 @@ tcp_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
*i1 = tcp->tcp_snd_zcopy_on ?
SO_SND_COPYAVOID : 0;
break;
+ case SO_ALLZONES:
+ *i1 = connp->conn_allzones ? 1 : 0;
+ break;
case SO_ANON_MLP:
*i1 = connp->conn_anon_mlp;
break;
@@ -10072,6 +10075,9 @@ tcp_opt_set(queue_t *q, uint_t optset_context, int level, int name,
tcp->tcp_snd_zcopy_aware = 1;
}
break;
+ case SO_ALLZONES:
+ /* Handled at the IP level */
+ return (-EINVAL);
case SO_ANON_MLP:
if (!checkonly) {
mutex_enter(&connp->conn_lock);
@@ -22613,7 +22619,7 @@ tcp_reserved_port_add(int size, in_port_t *lo_port, in_port_t *hi_port)
mutex_enter(&tbf->tf_lock);
for (tcp = tbf->tf_tcp; tcp != NULL;
tcp = tcp->tcp_bind_hash) {
- if (zoneid == tcp->tcp_connp->conn_zoneid &&
+ if (IPCL_ZONE_MATCH(tcp->tcp_connp, zoneid) &&
net_port == tcp->tcp_lport) {
/*
* A port is already bound. Search again
diff --git a/usr/src/uts/common/inet/tcp/tcp_opt_data.c b/usr/src/uts/common/inet/tcp/tcp_opt_data.c
index 2f4139405a..350ff7ec30 100644
--- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c
+++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c
@@ -75,9 +75,11 @@ opdes_t tcp_opt_arr[] = {
},
{ SO_SND_COPYAVOID, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
{ SO_ANON_MLP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int),
- 0 },
+ 0 },
{ SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int),
- 0 },
+ 0 },
+{ SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, OP_PASSNEXT, sizeof (int),
+ 0 },
{ TCP_NODELAY, IPPROTO_TCP, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0
},
{ TCP_MAXSEG, IPPROTO_TCP, OA_R, OA_R, OP_NP, OP_PASSNEXT, sizeof (uint_t),
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 2c8a401c05..c2213c446b 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -3104,13 +3104,16 @@ udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr)
break; /* goto sizeof (int) option return */
case SO_TIMESTAMP:
*i1 = udp->udp_timestamp;
- break;
+ break; /* goto sizeof (int) option return */
case SO_ANON_MLP:
*i1 = udp->udp_anon_mlp;
break; /* goto sizeof (int) option return */
case SO_MAC_EXEMPT:
*i1 = udp->udp_mac_exempt;
break; /* goto sizeof (int) option return */
+ case SO_ALLZONES:
+ *i1 = connp->conn_allzones;
+ break; /* goto sizeof (int) option return */
default:
return (-1);
}
@@ -3477,6 +3480,13 @@ udp_opt_set(queue_t *q, uint_t optset_context, int level,
if (!checkonly)
udp->udp_recvucred = onoff;
break;
+ case SO_ALLZONES:
+ /*
+ * "soft" error (negative)
+ * option not handled at this level
+ * Do not modify *outlenp.
+ */
+ return (-EINVAL);
case SO_TIMESTAMP:
if (!checkonly)
udp->udp_timestamp = onoff;
diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c
index 58836f3cb1..0ac5bb9a62 100644
--- a/usr/src/uts/common/inet/udp/udp_opt_data.c
+++ b/usr/src/uts/common/inet/udp/udp_opt_data.c
@@ -71,6 +71,8 @@ opdes_t udp_opt_arr[] = {
0 },
{ SO_RECVUCRED, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0
},
+{ SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, OP_PASSNEXT, sizeof (int),
+ 0 },
{ SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0
},
{ SO_ANON_MLP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int),
diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h
index a43edfd1ce..2d6b58d8c3 100644
--- a/usr/src/uts/common/sys/socket.h
+++ b/usr/src/uts/common/sys/socket.h
@@ -153,6 +153,8 @@ typedef void *_RESTRICT_KYWD Psocklen_t;
#define SO_TIMESTAMP 0x1013 /* socket-level timestamp option */
#define SCM_TIMESTAMP SO_TIMESTAMP /* socket control message timestamp */
+#define SO_ALLZONES 0x1014 /* bind in all zones */
+
#ifdef _KERNEL
#define SO_SRCADDR 0x2001 /* Internal: AF_UNIX source address */
#define SO_FILEP 0x2002 /* Internal: AF_UNIX file pointer */