Mercurial > illumos > illumos-gate
changeset 5113:aed655dd7790
6602811 GLDv3 MAC has references to an ill after the ill is long gone
author | yz147064 |
---|---|
date | Fri, 21 Sep 2007 07:56:36 -0700 |
parents | 7fcdd39ee1af |
children | 0dab8b69b8f2 |
files | usr/src/uts/common/inet/ip.h usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/ip/ip_if.c usr/src/uts/common/io/dld/dld_proto.c usr/src/uts/common/io/dld/dld_str.c usr/src/uts/common/sys/dld_impl.h |
diffstat | 6 files changed, 69 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip.h Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/inet/ip.h Fri Sep 21 07:56:36 2007 -0700 @@ -1836,8 +1836,8 @@ ill_up_ipifs : 1, ill_note_link : 1, /* supports link-up notification */ - - ill_pad_to_bit_31 : 19; + ill_capab_reneg : 1, /* capability renegotiation to be done */ + ill_pad_to_bit_31 : 18; /* Following bit fields protected by ill_lock */ uint_t @@ -2146,7 +2146,6 @@ #define IDS_INPROGRESS 1 /* DLPI request sent */ #define IDS_OK 2 /* DLPI request completed successfully */ #define IDS_FAILED 3 /* DLPI request failed */ -#define IDS_RENEG 4 /* Driver asked for a renegotiation */ /* Named Dispatch Parameter Management Structure */ typedef struct ipparam_s {
--- a/usr/src/uts/common/inet/ip/ip.c Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/inet/ip/ip.c Fri Sep 21 07:56:36 2007 -0700 @@ -15678,24 +15678,20 @@ ip_dlpi_error(ill, dlea->dl_error_primitive, dlea->dl_errno, dlea->dl_unix_errno); break; - case DL_CAPABILITY_ACK: { - boolean_t reneg_flag = B_FALSE; + case DL_CAPABILITY_ACK: /* Call a routine to handle this one. */ ill_dlpi_done(ill, DL_CAPABILITY_REQ); - /* - * Check if the ACK is due to renegotiation case since we - * will need to send a new CAPABILITY_REQ later. - */ - if (ill->ill_dlpi_capab_state == IDS_RENEG) { - /* This is the ack for a renogiation case */ - reneg_flag = B_TRUE; - ill->ill_dlpi_capab_state = IDS_UNKNOWN; - } ill_capability_ack(ill, mp); - if (reneg_flag) + + /* + * If the ack is due to renegotiation, we will need to send + * a new CAPABILITY_REQ to start the renegotiation. + */ + if (ill->ill_capab_reneg) { + ill->ill_capab_reneg = B_FALSE; ill_capability_probe(ill); - break; - } + } + break; case DL_CONTROL_ACK: /* We treat all of these as "fire and forget" */ ill_dlpi_done(ill, DL_CONTROL_REQ); @@ -15996,17 +15992,26 @@ /* * Something changed on the driver side. * It wants us to renegotiate the capabilities - * on this ill. The most likely cause is the - * aggregation interface under us where a - * port got added or went away. - * - * We reset the capabilities and set the - * state to IDS_RENG so that when the ack - * comes back, we can start the - * renegotiation process. - */ - ill_capability_reset(ill); - ill->ill_dlpi_capab_state = IDS_RENEG; + * on this ill. One possible cause is the aggregation + * interface under us where a port got added or + * went away. + * + * If the capability negotiation is already done + * or is in progress, reset the capabilities and + * mark the ill's ill_capab_reneg to be B_TRUE, + * so that when the ack comes back, we can start + * the renegotiation process. + * + * Note that if ill_capab_reneg is already B_TRUE + * (ill_dlpi_capab_state is IDS_UNKNOWN in this case), + * the capability resetting request has been sent + * and the renegotiation has not been started yet; + * nothing needs to be done in this case. + */ + if (ill->ill_dlpi_capab_state != IDS_UNKNOWN) { + ill_capability_reset(ill); + ill->ill_capab_reneg = B_TRUE; + } break; default: ip0dbg(("ip_rput_dlpi_writer: unknown notification "
--- a/usr/src/uts/common/inet/ip/ip_if.c Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/inet/ip/ip_if.c Fri Sep 21 07:56:36 2007 -0700 @@ -1737,11 +1737,9 @@ ill_capability_probe(ill_t *ill) { /* - * Do so only if negotiation is enabled, capabilities are unknown, - * and a capability negotiation is not already in progress. - */ - if (ill->ill_dlpi_capab_state != IDS_UNKNOWN && - ill->ill_dlpi_capab_state != IDS_RENEG) + * Do so only if capabilities are still unknown. + */ + if (ill->ill_dlpi_capab_state != IDS_UNKNOWN) return; ill->ill_dlpi_capab_state = IDS_INPROGRESS; @@ -1767,6 +1765,7 @@ * features are turned off until the state reaches IDS_OK. */ ill->ill_dlpi_capab_state = IDS_UNKNOWN; + ill->ill_capab_reneg = B_FALSE; /* * Disable sub-capabilities and request a list of sub-capability @@ -18143,8 +18142,20 @@ mutex_enter(&ill->ill_lock); ill->ill_state_flags |= ILL_DL_UNBIND_IN_PROGRESS; mutex_exit(&ill->ill_lock); - if (ill->ill_dlpi_capab_state == IDS_OK) + /* + * Reset the capabilities if the negotiation is done or is + * still in progress. Note that ill_capability_reset() will + * set ill_dlpi_capab_state to IDS_UNKNOWN, so the subsequent + * DL_CAPABILITY_ACK and DL_NOTE_CAPAB_RENEG will be ignored. + * + * Further, reset ill_capab_reneg to be B_FALSE so that the + * subsequent DL_CAPABILITY_ACK can be ignored, to prevent + * the capabilities renegotiation from happening. + */ + if (ill->ill_dlpi_capab_state != IDS_UNKNOWN) ill_capability_reset(ill); + ill->ill_capab_reneg = B_FALSE; + ill_dlpi_send(ill, mp); }
--- a/usr/src/uts/common/io/dld/dld_proto.c Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/io/dld/dld_proto.c Fri Sep 21 07:56:36 2007 -0700 @@ -1692,7 +1692,7 @@ if (type == SOFT_RING_NONE) { rx = (dsp->ds_mode == DLD_FASTPATH) ? - dld_str_rx_fastpath : dld_str_rx_unitdata; + dld_str_rx_fastpath : dld_str_rx_unitdata; } else { rx = (dls_rx_t)dls_soft_ring_fanout; } @@ -1734,7 +1734,7 @@ */ if (!(dld_opt & DLD_OPT_NO_SOFTRING)) { subsize += sizeof (dl_capability_sub_t) + - sizeof (dl_capab_dls_t); + sizeof (dl_capab_dls_t); } /* @@ -1943,3 +1943,16 @@ qreply(q, mp); return (B_TRUE); } + +/* + * Disable any enabled capabilities. + */ +void +dld_capabilities_disable(dld_str_t *dsp) +{ + if (dsp->ds_polling) + proto_poll_disable(dsp); + + if (dsp->ds_soft_ring) + proto_soft_ring_disable(dsp); +}
--- a/usr/src/uts/common/io/dld/dld_str.c Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/io/dld/dld_str.c Fri Sep 21 07:56:36 2007 -0700 @@ -1098,10 +1098,11 @@ mac_notify_remove(dsp->ds_mh, dsp->ds_mnh); /* - * Clear the polling and promisc flags. + * Disable the capabilities and clear the promisc flag. */ - dsp->ds_polling = B_FALSE; - dsp->ds_soft_ring = B_FALSE; + ASSERT(!dsp->ds_polling); + ASSERT(!dsp->ds_soft_ring); + dld_capabilities_disable(dsp); dsp->ds_promisc = 0; /*
--- a/usr/src/uts/common/sys/dld_impl.h Fri Sep 21 05:48:44 2007 -0700 +++ b/usr/src/uts/common/sys/dld_impl.h Fri Sep 21 07:56:36 2007 -0700 @@ -243,6 +243,7 @@ */ extern void dld_proto(dld_str_t *, mblk_t *); extern void dld_finish_pending_ops(dld_str_t *); +extern void dld_capabilities_disable(dld_str_t *); /* * Options: there should be a separate bit defined here for each