diff options
author | <Eric.Cheng@Sun.COM> | 2009-11-09 20:01:32 -0800 |
---|---|---|
committer | <Eric.Cheng@Sun.COM> | 2009-11-09 20:01:32 -0800 |
commit | 8d4cf8d8d2965ea43bccdc838f15c18634fee02d (patch) | |
tree | 87ace970c3bc9c66d8b1d5fbe22559f3bc858ba4 | |
parent | bd9f6899328e19cbb74e3ad02f5c32002285887e (diff) | |
download | illumos-gate-8d4cf8d8d2965ea43bccdc838f15c18634fee02d.tar.gz |
6890826 DLPI consumers using IP receive only broadcast messages
6888482 failure to initialize link props should not be ignored
-rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_door.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/linkprop.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/io/dld/dld_proto.c | 13 | ||||
-rw-r--r-- | usr/src/uts/common/io/dld/dld_str.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/io/dls/dls.c | 11 | ||||
-rw-r--r-- | usr/src/uts/common/io/dls/dls_link.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/io/mac/mac_client.c | 23 | ||||
-rw-r--r-- | usr/src/uts/common/io/mac/mac_sched.c | 12 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dld_impl.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dls_impl.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mac_client_impl.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mac_client_priv.h | 2 |
12 files changed, 75 insertions, 21 deletions
diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c index ad59cfe190..904dcbbd98 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c @@ -1053,8 +1053,18 @@ dlmgmt_upcall_linkprop_init(void *argp, void *retp, zoneid_t zoneid, err = dlmgmt_checkprivs(linkp->ll_class, cred); dlmgmt_table_unlock(); - if (err == 0) - err = dladm_init_linkprop(dld_handle, lip->ld_linkid, B_TRUE); + if (err == 0) { + dladm_status_t s; + char buf[DLADM_STRSIZE]; + + s = dladm_init_linkprop(dld_handle, lip->ld_linkid, B_TRUE); + if (s != DLADM_STATUS_OK) { + dlmgmt_log(LOG_WARNING, + "linkprop initialization failed on link %d: %s", + lip->ld_linkid, dladm_status2str(s, buf)); + err = EINVAL; + } + } retvalp->lr_err = err; } diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index eca1aecd7f..bd4190b159 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -1211,8 +1211,9 @@ static int i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, const char *prop_name, void *arg) { - char *buf, **propvals; - uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; + char *buf, **propvals; + uint_t i, valcnt = DLADM_MAX_PROP_VALCNT; + dladm_status_t status, *retval = arg; if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT)) == NULL) { @@ -1231,8 +1232,10 @@ i_dladm_init_one_prop(dladm_handle_t handle, datalink_id_t linkid, goto done; } - (void) dladm_set_linkprop(handle, linkid, prop_name, propvals, valcnt, - DLADM_OPT_ACTIVE); + status = dladm_set_linkprop(handle, linkid, prop_name, propvals, + valcnt, DLADM_OPT_ACTIVE); + if (status != DLADM_STATUS_OK) + *retval = status; done: if (buf != NULL) @@ -1263,6 +1266,7 @@ dladm_status_t dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, boolean_t any_media) { + dladm_status_t status = DLADM_STATUS_OK; datalink_media_t dmedia; uint32_t media; @@ -1275,10 +1279,10 @@ dladm_init_linkprop(dladm_handle_t handle, datalink_id_t linkid, ((dladm_datalink_id2info(handle, linkid, NULL, NULL, &media, NULL, 0) == DLADM_STATUS_OK) && DATALINK_MEDIA_ACCEPTED(dmedia, media))) { - (void) dladm_walk_linkprop(handle, linkid, NULL, + (void) dladm_walk_linkprop(handle, linkid, &status, i_dladm_init_one_prop); } - return (DLADM_STATUS_OK); + return (status); } /* ARGSUSED */ diff --git a/usr/src/uts/common/io/dld/dld_proto.c b/usr/src/uts/common/io/dld/dld_proto.c index ecf8e27afd..338a1c96d0 100644 --- a/usr/src/uts/common/io/dld/dld_proto.c +++ b/usr/src/uts/common/io/dld/dld_proto.c @@ -45,6 +45,7 @@ static proto_reqfunc_t proto_info_req, proto_attach_req, proto_detach_req, static void proto_capability_advertise(dld_str_t *, mblk_t *); static int dld_capab_poll_disable(dld_str_t *, dld_capab_poll_t *); +static boolean_t check_mod_above(queue_t *, const char *); #define DL_ACK_PENDING(state) \ ((state) == DL_ATTACH_PENDING || \ @@ -446,6 +447,9 @@ proto_bind_req(dld_str_t *dsp, mblk_t *mp) * Bind the channel such that it can receive packets. */ sap = dlp->dl_sap; + dsp->ds_nonip = !check_mod_above(dsp->ds_rq, "ip") && + !check_mod_above(dsp->ds_rq, "arp"); + err = dls_bind(dsp, sap); if (err != 0) { switch (err) { @@ -993,14 +997,14 @@ failed: } static boolean_t -check_ip_above(queue_t *q) +check_mod_above(queue_t *q, const char *mod) { queue_t *next_q; boolean_t ret = B_TRUE; claimstr(q); next_q = q->q_next; - if (strcmp(next_q->q_qinfo->qi_minfo->mi_idname, "ip") != 0) + if (strcmp(next_q->q_qinfo->qi_minfo->mi_idname, mod) != 0) ret = B_FALSE; releasestr(q); return (ret); @@ -1506,7 +1510,8 @@ dld_capab(dld_str_t *dsp, uint_t type, void *data, uint_t flags) * completes. So we limit the check to DLD_ENABLE case. */ if ((flags == DLD_ENABLE && type != DLD_CAPAB_PERIM) && - (dsp->ds_sap != ETHERTYPE_IP || !check_ip_above(dsp->ds_rq))) { + (dsp->ds_sap != ETHERTYPE_IP || + !check_mod_above(dsp->ds_rq, "ip"))) { return (ENOTSUP); } @@ -1593,7 +1598,7 @@ proto_capability_advertise(dld_str_t *dsp, mblk_t *mp) /* * Direct capability negotiation interface between IP and DLD */ - if (dsp->ds_sap == ETHERTYPE_IP && check_ip_above(dsp->ds_rq)) { + if (dsp->ds_sap == ETHERTYPE_IP && check_mod_above(dsp->ds_rq, "ip")) { dld_capable = B_TRUE; subsize += sizeof (dl_capability_sub_t) + sizeof (dl_capab_dld_t); diff --git a/usr/src/uts/common/io/dld/dld_str.c b/usr/src/uts/common/io/dld/dld_str.c index 75845f3df0..63d2bb6511 100644 --- a/usr/src/uts/common/io/dld/dld_str.c +++ b/usr/src/uts/common/io/dld/dld_str.c @@ -681,6 +681,7 @@ dld_str_destroy(dld_str_t *dsp) dsp->ds_passivestate = DLD_UNINITIALIZED; dsp->ds_mode = DLD_UNITDATA; dsp->ds_native = B_FALSE; + dsp->ds_nonip = B_FALSE; ASSERT(dsp->ds_datathr_cnt == 0); ASSERT(dsp->ds_pending_head == NULL); diff --git a/usr/src/uts/common/io/dls/dls.c b/usr/src/uts/common/io/dls/dls.c index 4cf2efcccf..e29b1ee6ac 100644 --- a/usr/src/uts/common/io/dls/dls.c +++ b/usr/src/uts/common/io/dls/dls.c @@ -188,6 +188,11 @@ dls_bind(dld_str_t *dsp, uint32_t sap) err = mac_promisc_add(dsp->ds_mch, MAC_CLIENT_PROMISC_ALL, dls_rx_vlan_promisc, dsp, &dsp->ds_vlan_mph, MAC_PROMISC_FLAGS_NO_PHYS); + + if (err == 0 && dsp->ds_nonip && + dsp->ds_dlp->dl_nonip_cnt++ == 0) + mac_rx_bypass_disable(dsp->ds_mch); + return (err); } @@ -196,6 +201,9 @@ dls_bind(dld_str_t *dsp, uint32_t sap) * dls_link_t. */ dls_link_add(dsp->ds_dlp, dls_sap, dsp); + if (dsp->ds_nonip && dsp->ds_dlp->dl_nonip_cnt++ == 0) + mac_rx_bypass_disable(dsp->ds_mch); + return (0); } @@ -204,6 +212,9 @@ dls_unbind(dld_str_t *dsp) { ASSERT(MAC_PERIM_HELD(dsp->ds_mh)); + if (dsp->ds_nonip && --dsp->ds_dlp->dl_nonip_cnt == 0) + mac_rx_bypass_enable(dsp->ds_mch); + /* * For VLAN SAP, there was a promisc handle registered when dls_bind. * When unbind this dls link, we need to remove the promisc handle. diff --git a/usr/src/uts/common/io/dls/dls_link.c b/usr/src/uts/common/io/dls/dls_link.c index ed2746954f..d88005d57f 100644 --- a/usr/src/uts/common/io/dls/dls_link.c +++ b/usr/src/uts/common/io/dls/dls_link.c @@ -603,6 +603,7 @@ i_dls_link_destroy(dls_link_t *dlp) dlp->dl_mch = NULL; dlp->dl_mip = NULL; dlp->dl_unknowns = 0; + dlp->dl_nonip_cnt = 0; kmem_cache_free(i_dls_link_cachep, dlp); } diff --git a/usr/src/uts/common/io/mac/mac_client.c b/usr/src/uts/common/io/mac/mac_client.c index 0d1669b40e..421c3e9bbd 100644 --- a/usr/src/uts/common/io/mac/mac_client.c +++ b/usr/src/uts/common/io/mac/mac_client.c @@ -1394,7 +1394,7 @@ mac_client_close(mac_client_handle_t mch, uint16_t flags) } /* - * Enable bypass for the specified MAC client. + * Set the rx bypass receive callback. */ boolean_t mac_rx_bypass_set(mac_client_handle_t mch, mac_direct_rx_t rx_fn, void *arg1) @@ -1418,11 +1418,25 @@ mac_rx_bypass_set(mac_client_handle_t mch, mac_direct_rx_t rx_fn, void *arg1) */ mcip->mci_direct_rx_fn = rx_fn; mcip->mci_direct_rx_arg = arg1; - mcip->mci_state_flags |= MCIS_CLIENT_POLL_CAPABLE; return (B_TRUE); } /* + * Enable/Disable rx bypass. By default, bypass is assumed to be enabled. + */ +void +mac_rx_bypass_enable(mac_client_handle_t mch) +{ + ((mac_client_impl_t *)mch)->mci_state_flags &= ~MCIS_RX_BYPASS_DISABLE; +} + +void +mac_rx_bypass_disable(mac_client_handle_t mch) +{ + ((mac_client_impl_t *)mch)->mci_state_flags |= MCIS_RX_BYPASS_DISABLE; +} + +/* * Set the receive callback for the specified MAC client. There can be * at most one such callback per MAC client. */ @@ -3141,9 +3155,6 @@ mac_resource_set_common(mac_client_handle_t mch, mac_resource_add_t add, mcip->mci_resource_restart = restart; mcip->mci_resource_bind = bind; mcip->mci_resource_arg = arg; - - if (arg == NULL) - mcip->mci_state_flags &= ~MCIS_CLIENT_POLL_CAPABLE; } void @@ -3168,6 +3179,7 @@ mac_client_poll_enable(mac_client_handle_t mch) flent = mcip->mci_flent; ASSERT(flent != NULL); + mcip->mci_state_flags |= MCIS_CLIENT_POLL_CAPABLE; for (i = 0; i < flent->fe_rx_srs_cnt; i++) { mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i]; ASSERT(mac_srs->srs_mcip == mcip); @@ -3190,6 +3202,7 @@ mac_client_poll_disable(mac_client_handle_t mch) flent = mcip->mci_flent; ASSERT(flent != NULL); + mcip->mci_state_flags &= ~MCIS_CLIENT_POLL_CAPABLE; for (i = 0; i < flent->fe_rx_srs_cnt; i++) { mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i]; ASSERT(mac_srs->srs_mcip == mcip); diff --git a/usr/src/uts/common/io/mac/mac_sched.c b/usr/src/uts/common/io/mac/mac_sched.c index 74de880f3d..ff3cba81ed 100644 --- a/usr/src/uts/common/io/mac/mac_sched.c +++ b/usr/src/uts/common/io/mac/mac_sched.c @@ -550,9 +550,11 @@ mac_rx_srs_proto_fanout(mac_soft_ring_set_t *mac_srs, mblk_t *head) /* * Special clients (eg. VLAN, non ether, etc) need DLS * processing in the Rx path. SRST_DLS_BYPASS will be clear for - * such SRSs. + * such SRSs. Another way of disabling bypass is to set the + * MCIS_RX_BYPASS_DISABLE flag. */ - dls_bypass = ((mac_srs->srs_type & SRST_DLS_BYPASS) != 0); + dls_bypass = ((mac_srs->srs_type & SRST_DLS_BYPASS) != 0) && + ((mcip->mci_state_flags & MCIS_RX_BYPASS_DISABLE) == 0); bzero(headmp, MAX_SR_TYPES * sizeof (mblk_t *)); bzero(tailmp, MAX_SR_TYPES * sizeof (mblk_t *)); @@ -933,9 +935,11 @@ mac_rx_srs_fanout(mac_soft_ring_set_t *mac_srs, mblk_t *head) /* * Special clients (eg. VLAN, non ether, etc) need DLS * processing in the Rx path. SRST_DLS_BYPASS will be clear for - * such SRSs. + * such SRSs. Another way of disabling bypass is to set the + * MCIS_RX_BYPASS_DISABLE flag. */ - dls_bypass = ((mac_srs->srs_type & SRST_DLS_BYPASS) != 0); + dls_bypass = ((mac_srs->srs_type & SRST_DLS_BYPASS) != 0) && + ((mcip->mci_state_flags & MCIS_RX_BYPASS_DISABLE) == 0); /* * Since the softrings are never destroyed and we always diff --git a/usr/src/uts/common/sys/dld_impl.h b/usr/src/uts/common/sys/dld_impl.h index c244204727..b2da85ff31 100644 --- a/usr/src/uts/common/sys/dld_impl.h +++ b/usr/src/uts/common/sys/dld_impl.h @@ -219,6 +219,7 @@ struct dld_str_s { /* Protected by */ void *ds_private; boolean_t ds_lowlink; /* SL */ + boolean_t ds_nonip; /* SL */ }; diff --git a/usr/src/uts/common/sys/dls_impl.h b/usr/src/uts/common/sys/dls_impl.h index 8bcc048dd2..7f0a4d9ac9 100644 --- a/usr/src/uts/common/sys/dls_impl.h +++ b/usr/src/uts/common/sys/dls_impl.h @@ -62,6 +62,7 @@ struct dls_link_s { /* Protected by */ zoneid_t dl_zid; uint_t dl_zone_ref; link_tagmode_t dl_tagmode; /* atomic */ + uint_t dl_nonip_cnt; /* SL */ }; typedef struct dls_head_s { diff --git a/usr/src/uts/common/sys/mac_client_impl.h b/usr/src/uts/common/sys/mac_client_impl.h index 5bd36ad779..bcdeb1da46 100644 --- a/usr/src/uts/common/sys/mac_client_impl.h +++ b/usr/src/uts/common/sys/mac_client_impl.h @@ -292,6 +292,7 @@ extern int mac_tx_percpu_cnt; #define MCIS_USE_DATALINK_NAME 0x0400 #define MCIS_UNICAST_HW 0x0800 #define MCIS_REQ_HWRINGS 0x1000 +#define MCIS_RX_BYPASS_DISABLE 0x2000 /* in mac_client.c */ extern void mac_promisc_client_dispatch(mac_client_impl_t *, mblk_t *); diff --git a/usr/src/uts/common/sys/mac_client_priv.h b/usr/src/uts/common/sys/mac_client_priv.h index 6689d20f34..78421a3b80 100644 --- a/usr/src/uts/common/sys/mac_client_priv.h +++ b/usr/src/uts/common/sys/mac_client_priv.h @@ -50,6 +50,8 @@ extern "C" { extern boolean_t mac_rx_bypass_set(mac_client_handle_t, mac_direct_rx_t, void *); +extern void mac_rx_bypass_enable(mac_client_handle_t); +extern void mac_rx_bypass_disable(mac_client_handle_t); extern const mac_info_t *mac_info(mac_handle_t); extern boolean_t mac_info_get(const char *, mac_info_t *); |