117 (void) net_protocol_release(info);
118
119 return (0);
120 }
121
122 net_handle_t
123 net_protocol_lookup(netid_t netid, const char *protocol)
124 {
125 neti_stack_t *nts;
126 net_handle_t nd;
127
128 ASSERT(protocol != NULL);
129
130 nts = net_getnetistackbyid(netid);
131 if (nts == NULL)
132 return (NULL);
133
134 mutex_enter(&nts->nts_lock);
135 nd = net_find(protocol, nts);
136 if (nd != NULL)
137 atomic_add_32((uint_t *)&nd->netd_refcnt, 1);
138 mutex_exit(&nts->nts_lock);
139 return (nd);
140 }
141
142 /*
143 * Note: the man page specifies "returns -1 if the value passed in is unknown
144 * to this framework". We are not doing a lookup in this function, just a
145 * simply add to the netd_refcnt of the net_handle_t passed in, so -1 is never a
146 * return value.
147 */
148 int
149 net_protocol_release(net_handle_t info)
150 {
151
152 ASSERT(info->netd_refcnt > 0);
153 /*
154 * Is this safe? No hold on nts_lock? Consider that if the caller
155 * of net_protocol_release() is going to free this structure then
156 * it is now the only owner (refcnt==1) and it will have been
157 * removed from the nts_netd_head list on the neti_stack_t from a
158 * call to net_protocol_unregister already, so it is thus an orphan.
159 */
160 if (atomic_add_32_nv((uint_t *)&info->netd_refcnt, -1) == 0) {
161 ASSERT(info->netd_hooks == NULL);
162 ASSERT(info->netd_stack == NULL);
163 kmem_free(info, sizeof (struct net_data));
164 }
165
166 return (0);
167 }
168
169 net_handle_t
170 net_protocol_walk(netid_t netid, net_handle_t info)
171 {
172 struct net_data *n = NULL;
173 boolean_t found = B_FALSE;
174 neti_stack_t *nts;
175
176 nts = net_getnetistackbyid(netid);
177 ASSERT(nts != NULL);
178
179 if (info == NULL)
180 found = B_TRUE;
184 if (found) {
185 /*
186 * We are only interested in finding protocols that
187 * are not in some sort of shutdown state. There is
188 * no need to check for netd_stack==NULL because
189 * that implies it is no longer on this list.
190 */
191 if (n->netd_condemned == 0)
192 continue;
193 break;
194 }
195
196 if (n == info)
197 found = B_TRUE;
198 }
199
200 if (info != NULL)
201 (void) net_protocol_release(info);
202
203 if (n != NULL)
204 atomic_add_32((uint_t *)&n->netd_refcnt, 1);
205
206 mutex_exit(&nts->nts_lock);
207
208 return (n);
209 }
210
211 /*
212 * Public accessor functions
213 */
214 int
215 net_getifname(net_handle_t info, phy_if_t nic, char *buffer,
216 const size_t buflen)
217 {
218
219 ASSERT(info != NULL);
220
221 if (info->netd_condemned != 0 || info->netd_stack == NULL)
222 return (-1);
223
224 return (info->netd_info.netp_getifname(info, nic, buffer, buflen));
|
117 (void) net_protocol_release(info);
118
119 return (0);
120 }
121
122 net_handle_t
123 net_protocol_lookup(netid_t netid, const char *protocol)
124 {
125 neti_stack_t *nts;
126 net_handle_t nd;
127
128 ASSERT(protocol != NULL);
129
130 nts = net_getnetistackbyid(netid);
131 if (nts == NULL)
132 return (NULL);
133
134 mutex_enter(&nts->nts_lock);
135 nd = net_find(protocol, nts);
136 if (nd != NULL)
137 atomic_inc_32((uint_t *)&nd->netd_refcnt);
138 mutex_exit(&nts->nts_lock);
139 return (nd);
140 }
141
142 /*
143 * Note: the man page specifies "returns -1 if the value passed in is unknown
144 * to this framework". We are not doing a lookup in this function, just a
145 * simply add to the netd_refcnt of the net_handle_t passed in, so -1 is never a
146 * return value.
147 */
148 int
149 net_protocol_release(net_handle_t info)
150 {
151
152 ASSERT(info->netd_refcnt > 0);
153 /*
154 * Is this safe? No hold on nts_lock? Consider that if the caller
155 * of net_protocol_release() is going to free this structure then
156 * it is now the only owner (refcnt==1) and it will have been
157 * removed from the nts_netd_head list on the neti_stack_t from a
158 * call to net_protocol_unregister already, so it is thus an orphan.
159 */
160 if (atomic_dec_32_nv((uint_t *)&info->netd_refcnt) == 0) {
161 ASSERT(info->netd_hooks == NULL);
162 ASSERT(info->netd_stack == NULL);
163 kmem_free(info, sizeof (struct net_data));
164 }
165
166 return (0);
167 }
168
169 net_handle_t
170 net_protocol_walk(netid_t netid, net_handle_t info)
171 {
172 struct net_data *n = NULL;
173 boolean_t found = B_FALSE;
174 neti_stack_t *nts;
175
176 nts = net_getnetistackbyid(netid);
177 ASSERT(nts != NULL);
178
179 if (info == NULL)
180 found = B_TRUE;
184 if (found) {
185 /*
186 * We are only interested in finding protocols that
187 * are not in some sort of shutdown state. There is
188 * no need to check for netd_stack==NULL because
189 * that implies it is no longer on this list.
190 */
191 if (n->netd_condemned == 0)
192 continue;
193 break;
194 }
195
196 if (n == info)
197 found = B_TRUE;
198 }
199
200 if (info != NULL)
201 (void) net_protocol_release(info);
202
203 if (n != NULL)
204 atomic_inc_32((uint_t *)&n->netd_refcnt);
205
206 mutex_exit(&nts->nts_lock);
207
208 return (n);
209 }
210
211 /*
212 * Public accessor functions
213 */
214 int
215 net_getifname(net_handle_t info, phy_if_t nic, char *buffer,
216 const size_t buflen)
217 {
218
219 ASSERT(info != NULL);
220
221 if (info->netd_condemned != 0 || info->netd_stack == NULL)
222 return (-1);
223
224 return (info->netd_info.netp_getifname(info, nic, buffer, buflen));
|