1 /* 2 * sppp_dlpi.c - Solaris STREAMS PPP multiplexing pseudo-driver DLPI handlers 3 * 4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 5 * Use is subject to license terms. 6 * 7 * Permission to use, copy, modify, and distribute this software and its 8 * documentation is hereby granted, provided that the above copyright 9 * notice appears in all copies. 10 * 11 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF 12 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 13 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 15 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 16 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES 17 * 18 * Copyright (c) 1994 The Australian National University. 19 * All rights reserved. 20 * 21 * Permission to use, copy, modify, and distribute this software and its 22 * documentation is hereby granted, provided that the above copyright 23 * notice appears in all copies. This software is provided without any 24 * warranty, express or implied. The Australian National University 25 * makes no representations about the suitability of this software for 26 * any purpose. 27 * 28 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY 29 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 30 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 31 * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY 32 * OF SUCH DAMAGE. 33 * 34 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, 35 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 36 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 37 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO 38 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 39 * OR MODIFICATIONS. 40 * 41 * This driver is derived from the original SVR4 STREAMS PPP driver 42 * originally written by Paul Mackerras <paul.mackerras@cs.anu.edu.au>. 43 * 44 * Adi Masputra <adi.masputra@sun.com> rewrote and restructured the code 45 * for improved performance and scalability. 46 */ 47 48 #define RCSID "$Id: sppp_dlpi.c,v 1.0 2000/05/08 01:10:12 masputra Exp $" 49 50 #include <sys/types.h> 51 #include <sys/param.h> 52 #include <sys/stat.h> 53 #include <sys/stream.h> 54 #include <sys/stropts.h> 55 #include <sys/errno.h> 56 #include <sys/time.h> 57 #include <sys/cmn_err.h> 58 #include <sys/conf.h> 59 #include <sys/dlpi.h> 60 #include <sys/ddi.h> 61 #include <sys/kstat.h> 62 #include <sys/strsubr.h> 63 #include <sys/strsun.h> 64 #include <sys/ethernet.h> 65 #include <net/ppp_defs.h> 66 #include <netinet/in.h> 67 #include <net/pppio.h> 68 #include "s_common.h" 69 #include "sppp.h" 70 71 static int sppp_dlattachreq(queue_t *, mblk_t *, spppstr_t *); 72 static int sppp_dldetachreq(queue_t *, mblk_t *, spppstr_t *); 73 static int sppp_dlbindreq(queue_t *, mblk_t *, spppstr_t *); 74 static int sppp_dlunbindreq(queue_t *, mblk_t *, spppstr_t *); 75 static int sppp_dlinforeq(queue_t *, mblk_t *, spppstr_t *); 76 static int sppp_dlunitdatareq(queue_t *, mblk_t *, spppstr_t *); 77 static int sppp_dlpromisconreq(queue_t *, mblk_t *, spppstr_t *); 78 static int sppp_dlpromiscoffreq(queue_t *, mblk_t *, spppstr_t *); 79 static int sppp_dlphyreq(queue_t *, mblk_t *, spppstr_t *); 80 static void sppp_dl_attach_upper(queue_t *, mblk_t *); 81 static void sppp_dl_detach_upper(queue_t *, mblk_t *); 82 static void sppp_dl_bind(queue_t *, mblk_t *); 83 static void sppp_dl_unbind(queue_t *, mblk_t *); 84 static void sppp_dl_promiscon(queue_t *, mblk_t *); 85 static void sppp_dl_promiscoff(queue_t *, mblk_t *); 86 static mblk_t *sppp_dladdether(spppstr_t *, mblk_t *, t_scalar_t); 87 88 static struct sppp_dlpi_pinfo_t dl_pinfo[DL_MAXPRIM + 1]; 89 90 #if 0 91 #define DBGERROR(x) cmn_err x 92 #else 93 #define DBGERROR(x) ((void)0) 94 #endif 95 96 /* #define DBG_DLPI 1 */ 97 98 #ifdef DBG_DLPI 99 struct sppp_dlpi_entry { 100 uint32_t sde_val; 101 const char *sde_name; 102 }; 103 104 static const struct sppp_dlpi_entry sppp_dlpi_list[] = { 105 { DL_INFO_REQ, "DL_INFO_REQ" }, 106 { DL_INFO_ACK, "DL_INFO_ACK" }, 107 { DL_ATTACH_REQ, "DL_ATTACH_REQ" }, 108 { DL_DETACH_REQ, "DL_DETACH_REQ" }, 109 { DL_BIND_REQ, "DL_BIND_REQ" }, 110 { DL_BIND_ACK, "DL_BIND_ACK" }, 111 { DL_UNBIND_REQ, "DL_UNBIND_REQ" }, 112 { DL_OK_ACK, "DL_OK_ACK" }, 113 { DL_ERROR_ACK, "DL_ERROR_ACK" }, 114 { DL_SUBS_BIND_REQ, "DL_SUBS_BIND_REQ" }, 115 { DL_SUBS_BIND_ACK, "DL_SUBS_BIND_ACK" }, 116 { DL_SUBS_UNBIND_REQ, "DL_SUBS_UNBIND_REQ" }, 117 { DL_ENABMULTI_REQ, "DL_ENABMULTI_REQ" }, 118 { DL_DISABMULTI_REQ, "DL_DISABMULTI_REQ" }, 119 { DL_PROMISCON_REQ, "DL_PROMISCON_REQ" }, 120 { DL_PROMISCOFF_REQ, "DL_PROMISCOFF_REQ" }, 121 { DL_UNITDATA_REQ, "DL_UNITDATA_REQ" }, 122 { DL_UNITDATA_IND, "DL_UNITDATA_IND" }, 123 { DL_UDERROR_IND, "DL_UDERROR_IND" }, 124 { DL_UDQOS_REQ, "DL_UDQOS_REQ" }, 125 { DL_CONNECT_REQ, "DL_CONNECT_REQ" }, 126 { DL_CONNECT_IND, "DL_CONNECT_IND" }, 127 { DL_CONNECT_RES, "DL_CONNECT_RES" }, 128 { DL_CONNECT_CON, "DL_CONNECT_CON" }, 129 { DL_TOKEN_REQ, "DL_TOKEN_REQ" }, 130 { DL_TOKEN_ACK, "DL_TOKEN_ACK" }, 131 { DL_DISCONNECT_REQ, "DL_DISCONNECT_REQ" }, 132 { DL_DISCONNECT_IND, "DL_DISCONNECT_IND" }, 133 { DL_RESET_REQ, "DL_RESET_REQ" }, 134 { DL_RESET_IND, "DL_RESET_IND" }, 135 { DL_RESET_RES, "DL_RESET_RES" }, 136 { DL_RESET_CON, "DL_RESET_CON" }, 137 { DL_DATA_ACK_REQ, "DL_DATA_ACK_REQ" }, 138 { DL_DATA_ACK_IND, "DL_DATA_ACK_IND" }, 139 { DL_DATA_ACK_STATUS_IND, "DL_DATA_ACK_STATUS_IND" }, 140 { DL_REPLY_REQ, "DL_REPLY_REQ" }, 141 { DL_REPLY_IND, "DL_REPLY_IND" }, 142 { DL_REPLY_STATUS_IND, "DL_REPLY_STATUS_IND" }, 143 { DL_REPLY_UPDATE_REQ, "DL_REPLY_UPDATE_REQ" }, 144 { DL_REPLY_UPDATE_STATUS_IND, "DL_REPLY_UPDATE_STATUS_IND" }, 145 { DL_XID_REQ, "DL_XID_REQ" }, 146 { DL_XID_IND, "DL_XID_IND" }, 147 { DL_XID_RES, "DL_XID_RES" }, 148 { DL_XID_CON, "DL_XID_CON" }, 149 { DL_TEST_REQ, "DL_TEST_REQ" }, 150 { DL_TEST_IND, "DL_TEST_IND" }, 151 { DL_TEST_RES, "DL_TEST_RES" }, 152 { DL_TEST_CON, "DL_TEST_CON" }, 153 { DL_PHYS_ADDR_REQ, "DL_PHYS_ADDR_REQ" }, 154 { DL_PHYS_ADDR_ACK, "DL_PHYS_ADDR_ACK" }, 155 { DL_SET_PHYS_ADDR_REQ, "DL_SET_PHYS_ADDR_REQ" }, 156 { DL_GET_STATISTICS_REQ, "DL_GET_STATISTICS_REQ" }, 157 { DL_GET_STATISTICS_ACK, "DL_GET_STATISTICS_ACK" }, 158 { 0, NULL } 159 }; 160 161 static const struct sppp_dlpi_entry sppp_state_list[] = { 162 { DL_UNBOUND, "DL_UNBOUND" }, 163 { DL_BIND_PENDING, "DL_BIND_PENDING" }, 164 { DL_UNBIND_PENDING, "DL_UNBIND_PENDING" }, 165 { DL_IDLE, "DL_IDLE" }, 166 { DL_UNATTACHED, "DL_UNATTACHED" }, 167 { DL_ATTACH_PENDING, "DL_ATTACH_PENDING" }, 168 { DL_DETACH_PENDING, "DL_DETACH_PENDING" }, 169 { DL_UDQOS_PENDING, "DL_UDQOS_PENDING" }, 170 { DL_OUTCON_PENDING, "DL_OUTCON_PENDING" }, 171 { DL_INCON_PENDING, "DL_INCON_PENDING" }, 172 { DL_CONN_RES_PENDING, "DL_CONN_RES_PENDING" }, 173 { DL_DATAXFER, "DL_DATAXFER" }, 174 { DL_USER_RESET_PENDING, "DL_USER_RESET_PENDING" }, 175 { DL_PROV_RESET_PENDING, "DL_PROV_RESET_PENDING" }, 176 { DL_RESET_RES_PENDING, "DL_RESET_RES_PENDING" }, 177 { DL_DISCON8_PENDING, "DL_DISCON8_PENDING" }, 178 { DL_DISCON9_PENDING, "DL_DISCON9_PENDING" }, 179 { DL_DISCON11_PENDING, "DL_DISCON11_PENDING" }, 180 { DL_DISCON12_PENDING, "DL_DISCON12_PENDING" }, 181 { DL_DISCON13_PENDING, "DL_DISCON13_PENDING" }, 182 { DL_SUBS_BIND_PND, "DL_SUBS_BIND_PND" }, 183 { DL_SUBS_UNBIND_PND, "DL_SUBS_UNBIND_PND" }, 184 { 0, NULL } 185 }; 186 187 static const char * 188 prim2name(uint32_t prim) 189 { 190 const struct sppp_dlpi_entry *sde; 191 192 for (sde = sppp_dlpi_list; sde->sde_name != NULL; sde++) 193 if (sde->sde_val == prim) 194 break; 195 return (sde->sde_name); 196 } 197 198 static const char * 199 state2name(uint32_t state) 200 { 201 const struct sppp_dlpi_entry *sde; 202 203 for (sde = sppp_state_list; sde->sde_name != NULL; sde++) 204 if (sde->sde_val == state) 205 break; 206 return (sde->sde_name); 207 } 208 209 #define DBGDLPI(x) cmn_err x 210 #else 211 #define DBGDLPI(x) ((void)0) 212 #endif /* DBG_DLPI */ 213 214 /* 215 * DL_INFO_ACK template for point-to-point interface. 216 */ 217 static dl_info_ack_t sppp_infoack = { 218 DL_INFO_ACK, /* dl_primitive */ 219 PPP_MAXMTU, /* dl_max_sdu */ 220 0, /* dl_min_sdu */ 221 SPPP_ADDRL, /* dl_addr_length */ 222 /* 223 * snoop et. al. don't know about DL_OTHER so this entry 224 * was changed to DL_ETHER so ethernet tracing/snooping 225 * facilities will work with PPP interfaces. 226 */ 227 DL_ETHER, /* dl_mac_type */ 228 0, /* dl_reserved */ 229 0, /* dl_current_state */ 230 SPPP_SAPL, /* dl_sap_length */ 231 DL_CLDLS, /* dl_service_mode */ 232 0, /* dl_qos_length */ 233 0, /* dl_qos_offset */ 234 0, /* dl_range_length */ 235 0, /* dl_range_offset */ 236 DL_STYLE2, /* dl_provider_style */ 237 sizeof (dl_info_ack_t), /* dl_addr_offset */ 238 DL_VERSION_2, /* dl_version */ 239 0, /* dl_brdcst_addr_length */ 240 0, /* dl_brdcst_addr_offset */ 241 0 /* dl_growth */ 242 }; 243 244 /* 245 * sppp_dlpi_pinfoinit() 246 * 247 * Description: 248 * Initialize dl_pinfo[], called from sppp_attach. 249 */ 250 void 251 sppp_dlpi_pinfoinit(void) 252 { 253 bzero(dl_pinfo, sizeof (dl_pinfo)); /* Just to be safe */ 254 255 dl_pinfo[DL_ATTACH_REQ].pi_minlen = sizeof (dl_attach_req_t); 256 dl_pinfo[DL_ATTACH_REQ].pi_state = DL_UNATTACHED; 257 dl_pinfo[DL_ATTACH_REQ].pi_funcp = sppp_dlattachreq; 258 259 dl_pinfo[DL_DETACH_REQ].pi_minlen = sizeof (dl_detach_req_t); 260 dl_pinfo[DL_DETACH_REQ].pi_state = DL_UNBOUND; 261 dl_pinfo[DL_DETACH_REQ].pi_funcp = sppp_dldetachreq; 262 263 dl_pinfo[DL_BIND_REQ].pi_minlen = sizeof (dl_bind_req_t); 264 dl_pinfo[DL_BIND_REQ].pi_state = DL_UNBOUND; 265 dl_pinfo[DL_BIND_REQ].pi_funcp = sppp_dlbindreq; 266 267 dl_pinfo[DL_UNBIND_REQ].pi_minlen = sizeof (dl_unbind_req_t); 268 dl_pinfo[DL_UNBIND_REQ].pi_state = DL_IDLE; 269 dl_pinfo[DL_UNBIND_REQ].pi_funcp = sppp_dlunbindreq; 270 271 dl_pinfo[DL_INFO_REQ].pi_minlen = sizeof (dl_info_req_t); 272 dl_pinfo[DL_INFO_REQ].pi_state = -1; /* special handling */ 273 dl_pinfo[DL_INFO_REQ].pi_funcp = sppp_dlinforeq; 274 275 dl_pinfo[DL_UNITDATA_REQ].pi_minlen = sizeof (dl_unitdata_req_t); 276 dl_pinfo[DL_UNITDATA_REQ].pi_state = DL_IDLE; 277 dl_pinfo[DL_UNITDATA_REQ].pi_funcp = sppp_dlunitdatareq; 278 279 dl_pinfo[DL_PROMISCON_REQ].pi_minlen = sizeof (dl_promiscon_req_t); 280 dl_pinfo[DL_PROMISCON_REQ].pi_state = -1; /* special handling */ 281 dl_pinfo[DL_PROMISCON_REQ].pi_funcp = sppp_dlpromisconreq; 282 283 dl_pinfo[DL_PROMISCOFF_REQ].pi_minlen = sizeof (dl_promiscoff_req_t); 284 dl_pinfo[DL_PROMISCOFF_REQ].pi_state = -1; /* special handling */ 285 dl_pinfo[DL_PROMISCOFF_REQ].pi_funcp = sppp_dlpromiscoffreq; 286 287 dl_pinfo[DL_PHYS_ADDR_REQ].pi_minlen = sizeof (dl_phys_addr_req_t); 288 dl_pinfo[DL_PHYS_ADDR_REQ].pi_state = -1; /* special handling */ 289 dl_pinfo[DL_PHYS_ADDR_REQ].pi_funcp = sppp_dlphyreq; 290 } 291 292 /* 293 * sppp_mproto() 294 * 295 * MT-Perimeters: 296 * shared inner, shared outer. 297 * 298 * Description: 299 * Handle M_PCPROTO/M_PROTO messages, called by sppp_uwput. 300 */ 301 int 302 sppp_mproto(queue_t *q, mblk_t *mp, spppstr_t *sps) 303 { 304 union DL_primitives *dlp; 305 struct sppp_dlpi_pinfo_t *dpi; 306 t_uscalar_t prim; 307 int len; 308 int error = 0; 309 310 ASSERT(!IS_SPS_CONTROL(sps)); 311 if ((len = MBLKL(mp)) < sizeof (t_uscalar_t)) { 312 DBGERROR((CE_CONT, "bad mproto: block length %d\n", len)); 313 merror(q, mp, EPROTO); 314 return (0); 315 } 316 dlp = (union DL_primitives *)mp->b_rptr; 317 prim = dlp->dl_primitive; 318 if (prim > DL_MAXPRIM) { 319 DBGERROR((CE_CONT, "bad mproto: primitive %d > %d\n", prim, 320 DL_MAXPRIM)); 321 error = DL_BADPRIM; 322 } else { 323 dpi = &dl_pinfo[prim]; 324 if (dpi->pi_funcp == NULL) { 325 DBGERROR((CE_CONT, 326 "bad mproto: primitive %d not supported\n", prim)); 327 error = DL_NOTSUPPORTED; 328 } else if (len < dpi->pi_minlen) { 329 DBGERROR((CE_CONT, 330 "bad mproto: primitive len %d < %d\n", len, 331 dpi->pi_minlen)); 332 error = DL_BADPRIM; 333 } else if (dpi->pi_state != -1 && 334 sps->sps_dlstate != dpi->pi_state) { 335 DBGERROR((CE_CONT, 336 "bad state %d != %d for primitive %d\n", 337 sps->sps_dlstate, dpi->pi_state, prim)); 338 error = DL_OUTSTATE; 339 } 340 } 341 if (error != 0) { 342 dlerrorack(q, mp, dlp->dl_primitive, error, 0); 343 return (0); 344 } 345 #ifdef DBG_DLPI 346 { 347 const char *cp = prim2name(prim); 348 if (cp != NULL) 349 cmn_err(CE_CONT, "/%d: Dispatching %s\n", 350 sps->sps_mn_id, cp); 351 else 352 cmn_err(CE_CONT, 353 "/%d: Dispatching unknown primitive %d\n", 354 sps->sps_mn_id, prim); 355 } 356 #endif 357 return ((*dpi->pi_funcp)(q, mp, sps)); 358 } 359 360 /* 361 * sppp_dlattachreq() 362 * 363 * MT-Perimeters: 364 * shared inner, shared outer. 365 * 366 * Description: 367 * Perform DL_ATTACH_REQ request, called by sppp_mproto. 368 */ 369 static int 370 sppp_dlattachreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 371 { 372 int error = 0; 373 union DL_primitives *dlp; 374 375 ASSERT(q != NULL && q->q_ptr != NULL); 376 ASSERT(mp != NULL && mp->b_rptr != NULL); 377 dlp = (union DL_primitives *)mp->b_rptr; 378 ASSERT(sps != NULL); 379 ASSERT(sps->sps_dlstate == DL_UNATTACHED); 380 381 if (IS_SPS_PIOATTACH(sps)) { 382 DBGERROR((CE_CONT, "DLPI attach: already attached\n")); 383 error = EINVAL; 384 } 385 if (error != 0) { 386 dlerrorack(q, mp, dlp->dl_primitive, DL_OUTSTATE, error); 387 } else { 388 qwriter(q, mp, sppp_dl_attach_upper, PERIM_OUTER); 389 } 390 return (0); 391 } 392 393 /* 394 * sppp_dl_attach_upper() 395 * 396 * MT-Perimeters: 397 * exclusive inner, exclusive outer. 398 * 399 * Description: 400 * Called by qwriter (INNER) from sppp_dlattachreq as the result of 401 * receiving a DL_ATTACH_REQ message. 402 */ 403 static void 404 sppp_dl_attach_upper(queue_t *q, mblk_t *mp) 405 { 406 sppa_t *ppa; 407 spppstr_t *sps = q->q_ptr; 408 union DL_primitives *dlp; 409 int err = ENOMEM; 410 cred_t *cr; 411 zoneid_t zoneid; 412 413 ASSERT(!IS_SPS_PIOATTACH(sps)); 414 dlp = (union DL_primitives *)mp->b_rptr; 415 416 /* If there's something here, it's detached. */ 417 if (sps->sps_ppa != NULL) { 418 sppp_remove_ppa(sps); 419 } 420 421 if ((cr = msg_getcred(mp, NULL)) == NULL) 422 zoneid = sps->sps_zoneid; 423 else 424 zoneid = crgetzoneid(cr); 425 426 ppa = sppp_find_ppa(dlp->attach_req.dl_ppa); 427 if (ppa == NULL) { 428 ppa = sppp_create_ppa(dlp->attach_req.dl_ppa, zoneid); 429 } else if (ppa->ppa_zoneid != zoneid) { 430 ppa = NULL; 431 err = EPERM; 432 } 433 434 /* 435 * If we can't find or create it, then it's either because we're out of 436 * memory or because the requested PPA is owned by a different zone. 437 */ 438 if (ppa == NULL) { 439 DBGERROR((CE_CONT, "DLPI attach: cannot create ppa %u\n", 440 dlp->attach_req.dl_ppa)); 441 dlerrorack(q, mp, dlp->dl_primitive, DL_SYSERR, err); 442 return; 443 } 444 /* 445 * Preallocate the hangup message so that we're always able to 446 * send this upstream in the event of a catastrophic failure. 447 */ 448 if ((sps->sps_hangup = allocb(1, BPRI_MED)) == NULL) { 449 DBGERROR((CE_CONT, "DLPI attach: cannot allocate hangup\n")); 450 dlerrorack(q, mp, dlp->dl_primitive, DL_SYSERR, ENOSR); 451 return; 452 } 453 sps->sps_dlstate = DL_UNBOUND; 454 sps->sps_ppa = ppa; 455 /* 456 * Add this stream to the head of the list of sibling streams 457 * which belong to the specified ppa. 458 */ 459 rw_enter(&ppa->ppa_sib_lock, RW_WRITER); 460 ppa->ppa_refcnt++; 461 sps->sps_nextsib = ppa->ppa_streams; 462 ppa->ppa_streams = sps; 463 /* 464 * And if this stream was marked as promiscuous (SPS_PROMISC), then we 465 * need to update the promiscuous streams count. This should only 466 * happen when DL_PROMISCON_REQ was issued prior to attachment. 467 */ 468 if (IS_SPS_PROMISC(sps)) { 469 ppa->ppa_promicnt++; 470 } 471 rw_exit(&ppa->ppa_sib_lock); 472 DBGDLPI((CE_CONT, "/%d: attached to ppa %d\n", sps->sps_mn_id, 473 ppa->ppa_ppa_id)); 474 dlokack(q, mp, DL_ATTACH_REQ); 475 } 476 477 /* 478 * sppp_dldetachreq() 479 * 480 * MT-Perimeters: 481 * shared inner, shared outer. 482 * 483 * Description: 484 * Perform DL_DETACH_REQ request, called by sppp_mproto. 485 */ 486 /* ARGSUSED */ 487 static int 488 sppp_dldetachreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 489 { 490 ASSERT(q != NULL && q->q_ptr != NULL); 491 ASSERT(mp != NULL && mp->b_rptr != NULL); 492 ASSERT(sps != NULL); 493 ASSERT(sps->sps_dlstate == DL_UNBOUND); 494 ASSERT(!IS_SPS_PIOATTACH(sps)); 495 496 qwriter(q, mp, sppp_dl_detach_upper, PERIM_INNER); 497 return (0); 498 } 499 500 /* 501 * sppp_dl_detach_upper() 502 * 503 * MT-Perimeters: 504 * exclusive inner, shared outer. 505 * 506 * Description: 507 * Called by qwriter (INNER) from sppp_dldetachreq as the result of 508 * receiving a DL_DETACH_REQ message. 509 */ 510 /* ARGSUSED */ 511 static void 512 sppp_dl_detach_upper(queue_t *q, mblk_t *mp) 513 { 514 spppstr_t *sps; 515 516 ASSERT(q != NULL && q->q_ptr != NULL); 517 ASSERT(mp != NULL && mp->b_rptr != NULL); 518 sps = (spppstr_t *)q->q_ptr; 519 /* 520 * We don't actually detach from the PPA until closed or 521 * reattached. 522 */ 523 sps->sps_flags &= ~SPS_PROMISC; /* clear flag anyway */ 524 sps->sps_dlstate = DL_UNATTACHED; 525 dlokack(q, mp, DL_DETACH_REQ); 526 } 527 528 /* 529 * sppp_dlbindreq() 530 * 531 * MT-Perimeters: 532 * shared inner, shared outer. 533 * 534 * Description: 535 * Perform DL_BIND_REQ request, called by sppp_mproto. 536 */ 537 static int 538 sppp_dlbindreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 539 { 540 sppa_t *ppa; 541 union DL_primitives *dlp; 542 spppreqsap_t req_sap; 543 int error = 0; 544 545 ASSERT(q != NULL && q->q_ptr != NULL); 546 ASSERT(mp != NULL && mp->b_rptr != NULL); 547 dlp = (union DL_primitives *)mp->b_rptr; 548 req_sap = dlp->bind_req.dl_sap; 549 ASSERT(sps != NULL); 550 ASSERT(!IS_SPS_PIOATTACH(sps)); 551 ASSERT(sps->sps_dlstate == DL_UNBOUND); 552 553 ppa = sps->sps_ppa; 554 if (ppa == NULL) { 555 DBGERROR((CE_CONT, "DLPI bind: no attached ppa\n")); 556 error = DL_OUTSTATE; 557 } else if ((req_sap != ETHERTYPE_IP) && (req_sap != ETHERTYPE_IPV6) && 558 (req_sap != ETHERTYPE_ALLSAP)) { 559 DBGERROR((CE_CONT, "DLPI bind: unknown SAP %x\n", req_sap)); 560 error = DL_BADADDR; 561 } 562 if (error != 0) { 563 dlerrorack(q, mp, dlp->dl_primitive, error, 0); 564 } else { 565 qwriter(q, mp, sppp_dl_bind, PERIM_INNER); 566 } 567 return (0); 568 } 569 570 /* 571 * sppp_dl_bind() 572 * 573 * MT-Perimeters: 574 * exclusive inner, shared outer. 575 * 576 * Description: 577 * Called by qwriter (INNER) from sppp_dlbindreq as the result of 578 * receiving a DL_BIND_REQ message. 579 */ 580 static void 581 sppp_dl_bind(queue_t *q, mblk_t *mp) 582 { 583 spppstr_t *sps; 584 sppa_t *ppa; 585 union DL_primitives *dlp; 586 t_scalar_t sap; 587 spppreqsap_t req_sap; 588 mblk_t *lsmp; 589 590 ASSERT(q != NULL && q->q_ptr != NULL); 591 sps = (spppstr_t *)q->q_ptr; 592 ASSERT(mp != NULL && mp->b_rptr != NULL); 593 dlp = (union DL_primitives *)mp->b_rptr; 594 ppa = sps->sps_ppa; 595 ASSERT(ppa != NULL); 596 req_sap = dlp->bind_req.dl_sap; 597 ASSERT((req_sap == ETHERTYPE_IP) || (req_sap == ETHERTYPE_IPV6) || 598 (req_sap == ETHERTYPE_ALLSAP)); 599 600 if (req_sap == ETHERTYPE_IP) { 601 sap = PPP_IP; 602 } else if (req_sap == ETHERTYPE_IPV6) { 603 sap = PPP_IPV6; 604 } else if (req_sap == ETHERTYPE_ALLSAP) { 605 sap = PPP_ALLSAP; 606 } 607 /* 608 * If there's another stream with the same sap has already been bound 609 * to the same ppa, then return with DL_NOADDR. However, we do make an 610 * exception for snoop (req_sap=0x00, sap=0xff) since multiple 611 * instances of snoop may execute an a given device. 612 */ 613 lsmp = NULL; 614 if (sap != PPP_ALLSAP) { 615 if ((sap == PPP_IP) && (ppa->ppa_ip_cache == NULL)) { 616 ppa->ppa_ip_cache = sps; 617 if (ppa->ppa_ctl != NULL) { 618 lsmp = create_lsmsg(PPP_LINKSTAT_IPV4_BOUND); 619 } 620 } else if ((sap == PPP_IPV6) && (ppa->ppa_ip6_cache == NULL)) { 621 ppa->ppa_ip6_cache = sps; 622 if (ppa->ppa_ctl != NULL) { 623 lsmp = create_lsmsg(PPP_LINKSTAT_IPV6_BOUND); 624 } 625 } else { 626 DBGERROR((CE_CONT, "DLPI bind: bad SAP %x\n", sap)); 627 dlerrorack(q, mp, dlp->dl_primitive, DL_NOADDR, 628 EEXIST); 629 return; 630 } 631 sps->sps_flags |= SPS_CACHED; 632 } 633 /* 634 * Tell the daemon that a DLPI bind has happened on this stream, 635 * and we'll only do this for PPP_IP or PPP_IPV6 sap (not snoop). 636 */ 637 if (lsmp != NULL && ppa->ppa_ctl != NULL) { 638 #ifdef DBG_DLPI 639 cmn_err(CE_CONT, "sending up %s\n", 640 ((sap == PPP_IP) ? "PPP_LINKSTAT_IPV4_BOUND" : 641 "PPP_LINKSTAT_IPV6_BOUND")); 642 #endif 643 putnext(ppa->ppa_ctl->sps_rq, lsmp); 644 } 645 DBGDLPI((CE_CONT, "/%d: bound to sap %X (req %X)\n", sps->sps_mn_id, 646 sap, req_sap)); 647 sps->sps_req_sap = req_sap; 648 sps->sps_sap = sap; 649 sps->sps_dlstate = DL_IDLE; 650 dlbindack(q, mp, req_sap, &sap, sizeof (int32_t), 0, 0); 651 } 652 653 /* 654 * sppp_dlunbindreq() 655 * 656 * MT-Perimeters: 657 * shared inner, shared outer. 658 * 659 * Description: 660 * Perform DL_UNBIND_REQ request, called by sppp_mproto. 661 */ 662 /* ARGSUSED */ 663 static int 664 sppp_dlunbindreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 665 { 666 ASSERT(q != NULL && q->q_ptr != NULL); 667 ASSERT(mp != NULL && mp->b_rptr != NULL); 668 ASSERT(sps != NULL); 669 ASSERT(!IS_SPS_PIOATTACH(sps)); 670 ASSERT(sps->sps_dlstate == DL_IDLE); 671 672 qwriter(q, mp, sppp_dl_unbind, PERIM_INNER); 673 return (0); 674 } 675 676 /* 677 * sppp_dl_unbind() 678 * 679 * MT-Perimeters: 680 * exclusive inner, shared outer. 681 * 682 * Description: 683 * Called by qwriter (INNER) from sppp_dlunbindreq as the result of 684 * receiving a DL_UNBIND_REQ message. 685 */ 686 static void 687 sppp_dl_unbind(queue_t *q, mblk_t *mp) 688 { 689 spppstr_t *sps; 690 sppa_t *ppa; 691 t_scalar_t sap; 692 mblk_t *msg; 693 boolean_t saydown; 694 695 ASSERT(q != NULL && q->q_ptr != NULL); 696 sps = (spppstr_t *)q->q_ptr; 697 ppa = sps->sps_ppa; 698 ASSERT(mp != NULL && mp->b_rptr != NULL); 699 sap = sps->sps_sap; 700 ASSERT((sap == PPP_IP) || (sap == PPP_IPV6) || (sap == PPP_ALLSAP)); 701 702 /* Flush messages on unbind, per DLPI specification. */ 703 flushq(WR(q), FLUSHALL); 704 flushq(RD(q), FLUSHALL); 705 706 if ((ppa != NULL) && IS_SPS_CACHED(sps)) { 707 sps->sps_flags &= ~SPS_CACHED; 708 msg = NULL; 709 saydown = (ppa->ppa_ctl != NULL && 710 (sps->sps_npmode == NPMODE_PASS || 711 sps->sps_npmode == NPMODE_QUEUE)); 712 if (sap == PPP_IP) { 713 ppa->ppa_ip_cache = NULL; 714 if (saydown) 715 msg = create_lsmsg(PPP_LINKSTAT_IPV4_UNBOUND); 716 } else if (sap == PPP_IPV6) { 717 ppa->ppa_ip6_cache = NULL; 718 if (saydown) 719 msg = create_lsmsg(PPP_LINKSTAT_IPV6_UNBOUND); 720 } 721 if (msg != NULL) { 722 #ifdef DBG_DLPI 723 cmn_err(CE_CONT, "sending up %s\n", 724 ((sap == PPP_IP) ? "PPP_LINKSTAT_IPV4_UNBOUND" : 725 "PPP_LINKSTAT_IPV6_UNBOUND")); 726 #endif 727 putnext(ppa->ppa_ctl->sps_rq, msg); 728 } 729 } 730 DBGDLPI((CE_CONT, "/%d: unbound from sap %X (req %X)\n", sps->sps_mn_id, 731 sps->sps_sap, sps->sps_req_sap)); 732 sps->sps_req_sap = 0; 733 sps->sps_sap = -1; 734 sps->sps_dlstate = DL_UNBOUND; 735 736 dlokack(q, mp, DL_UNBIND_REQ); 737 } 738 739 /* 740 * sppp_dlinforeq() 741 * 742 * MT-Perimeters: 743 * shared inner, shared outer. 744 * 745 * Description: 746 * Perform DL_INFO_REQ request, called by sppp_mproto. 747 */ 748 static int 749 sppp_dlinforeq(queue_t *q, mblk_t *mp, spppstr_t *sps) 750 { 751 dl_info_ack_t *dlip; 752 uint32_t size; 753 uint32_t addr_size; 754 sppa_t *ppa; 755 756 ASSERT(q != NULL && q->q_ptr != NULL); 757 ASSERT(mp != NULL && mp->b_rptr != NULL); 758 ASSERT(sps != NULL); 759 ppa = sps->sps_ppa; 760 761 /* Exchange current msg for a DL_INFO_ACK. */ 762 addr_size = SPPP_ADDRL; 763 size = sizeof (dl_info_ack_t) + addr_size; 764 if ((mp = mexchange(q, mp, size, M_PCPROTO, DL_INFO_ACK)) == NULL) { 765 DBGERROR((CE_CONT, "DLPI info: mexchange failed\n")); 766 /* mexchange already sent up an merror ENOSR */ 767 return (0); 768 } 769 /* Fill in DL_INFO_ACK fields and reply */ 770 dlip = (dl_info_ack_t *)mp->b_rptr; 771 *dlip = sppp_infoack; 772 dlip->dl_current_state = sps->sps_dlstate; 773 dlip->dl_max_sdu = ppa != NULL ? ppa->ppa_mtu : PPP_MAXMTU; 774 #ifdef DBG_DLPI 775 { 776 const char *cp = state2name(dlip->dl_current_state); 777 if (cp != NULL) 778 cmn_err(CE_CONT, "info returns state %s, max sdu %d\n", 779 cp, dlip->dl_max_sdu); 780 else 781 cmn_err(CE_CONT, "info returns state %d, max sdu %d\n", 782 dlip->dl_current_state, dlip->dl_max_sdu); 783 } 784 #endif 785 qreply(q, mp); 786 return (0); 787 } 788 789 /* 790 * sppp_dlunitdatareq() 791 * 792 * MT-Perimeters: 793 * shared inner, shared outer. 794 * 795 * Description: 796 * Handle DL_UNITDATA_REQ request, called by sppp_mproto. This procedure 797 * gets called for M_PROTO (DLPI) style of transmission. The fact that we 798 * have acknowledged IP's fastpath probing (DL_IOC_HDR_INFO) does not 799 * guarantee that IP will always transmit via M_DATA, and it merely implies 800 * that such situation _may_ happen. In other words, IP may decide to use 801 * M_PROTO (DLPI) for data transmission should it decide to do so. 802 * Therefore, we should never place any restrictions or checks against 803 * streams marked with SPS_FASTPATH, since it is legal for this procedure 804 * to be entered with or without the bit set. 805 */ 806 static int 807 sppp_dlunitdatareq(queue_t *q, mblk_t *mp, spppstr_t *sps) 808 { 809 sppa_t *ppa; 810 mblk_t *hdrmp; 811 mblk_t *pktmp; 812 dl_unitdata_req_t *dludp; 813 int dladdroff; 814 int dladdrlen; 815 int msize; 816 int error = 0; 817 boolean_t is_promisc; 818 819 ASSERT(q != NULL && q->q_ptr != NULL); 820 ASSERT(mp != NULL && mp->b_rptr != NULL); 821 ASSERT((MTYPE(mp) == M_PCPROTO) || (MTYPE(mp) == M_PROTO)); 822 dludp = (dl_unitdata_req_t *)mp->b_rptr; 823 dladdroff = dludp->dl_dest_addr_offset; 824 dladdrlen = dludp->dl_dest_addr_length; 825 ASSERT(sps != NULL); 826 ASSERT(!IS_SPS_PIOATTACH(sps)); 827 ASSERT(sps->sps_dlstate == DL_IDLE); 828 ASSERT(q->q_ptr == sps); 829 /* 830 * If this stream is not attached to any ppas, then discard data 831 * coming down through this stream. 832 */ 833 ppa = sps->sps_ppa; 834 if (ppa == NULL) { 835 DBGERROR((CE_CONT, "DLPI unitdata: no attached ppa\n")); 836 error = ENOLINK; 837 } else if (mp->b_cont == NULL) { 838 DBGERROR((CE_CONT, "DLPI unitdata: missing data\n")); 839 error = EPROTO; 840 } 841 if (error != 0) { 842 dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen, 843 DL_BADDATA, error); 844 return (0); 845 } 846 ASSERT(mp->b_cont->b_rptr != NULL); 847 /* 848 * Check if outgoing packet size is larger than allowed. We use 849 * msgdsize to count all of M_DATA blocks in the message. 850 */ 851 msize = msgdsize(mp); 852 if (msize > ppa->ppa_mtu) { 853 /* Log, and send it anyway */ 854 mutex_enter(&ppa->ppa_sta_lock); 855 ppa->ppa_otoolongs++; 856 mutex_exit(&ppa->ppa_sta_lock); 857 } 858 if (IS_SPS_KDEBUG(sps)) { 859 SPDEBUG(PPP_DRV_NAME 860 "/%d: DL_UNITDATA_REQ (%d bytes) sps=0x%p flags=0x%b " 861 "ppa=0x%p flags=0x%b\n", sps->sps_mn_id, msize, 862 (void *)sps, sps->sps_flags, SPS_FLAGS_STR, 863 (void *)ppa, ppa->ppa_flags, PPA_FLAGS_STR); 864 } 865 /* Allocate a message (M_DATA) to contain PPP header bytes. */ 866 if ((hdrmp = allocb(PPP_HDRLEN, BPRI_MED)) == NULL) { 867 mutex_enter(&ppa->ppa_sta_lock); 868 ppa->ppa_allocbfail++; 869 mutex_exit(&ppa->ppa_sta_lock); 870 DBGERROR((CE_CONT, 871 "DLPI unitdata: can't allocate header buffer\n")); 872 dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen, 873 DL_SYSERR, ENOSR); 874 return (0); 875 } 876 /* 877 * Should there be any promiscuous stream(s), send the data up 878 * for each promiscuous stream that we recognize. 879 */ 880 rw_enter(&ppa->ppa_sib_lock, RW_READER); 881 is_promisc = ppa->ppa_promicnt; 882 if (is_promisc) { 883 ASSERT(ppa->ppa_streams != NULL); 884 sppp_dlprsendup(ppa->ppa_streams, mp->b_cont, sps->sps_sap, 885 B_FALSE); 886 } 887 rw_exit(&ppa->ppa_sib_lock); 888 /* Discard DLPI header and keep only IP payload (mp->b_cont). */ 889 pktmp = mp->b_cont; 890 mp->b_cont = NULL; 891 freemsg(mp); 892 mp = hdrmp; 893 894 *(uchar_t *)mp->b_wptr++ = PPP_ALLSTATIONS; 895 *(uchar_t *)mp->b_wptr++ = PPP_UI; 896 *(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap >> 8) & 0xff; 897 *(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap) & 0xff; 898 ASSERT(MBLKL(mp) == PPP_HDRLEN); 899 900 linkb(mp, pktmp); 901 /* 902 * Only time-stamp the packet with hrtime if the upper stream 903 * is configured to do so. 904 */ 905 if (IS_PPA_TIMESTAMP(ppa)) { 906 ppa->ppa_lasttx = gethrtime(); 907 } 908 /* 909 * Just put this back on the queue and allow the write service 910 * routine to handle it. We're nested too deeply here to 911 * rewind the stack sufficiently to prevent overflow. This is 912 * the slow path anyway. 913 */ 914 if (putq(q, mp) == 0) { 915 mutex_enter(&ppa->ppa_sta_lock); 916 ppa->ppa_oqdropped++; 917 mutex_exit(&ppa->ppa_sta_lock); 918 freemsg(mp); 919 } else { 920 qenable(q); 921 } 922 return (0); 923 } 924 925 /* 926 * sppp_dlpromisconreq() 927 * 928 * MT-Perimeters: 929 * shared inner, shared outer. 930 * 931 * Description: 932 * Perform DL_PROMISCON_REQ request, called by sppp_mproto. 933 */ 934 static int 935 sppp_dlpromisconreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 936 { 937 t_uscalar_t level; 938 939 ASSERT(q != NULL && q->q_ptr != NULL); 940 ASSERT(mp != NULL && mp->b_rptr != NULL); 941 level = ((dl_promiscon_req_t *)mp->b_rptr)->dl_level; 942 ASSERT(sps != NULL); 943 944 /* snoop issues DL_PROMISCON_REQ more than once. */ 945 if (IS_SPS_PROMISC(sps)) { 946 dlokack(q, mp, DL_PROMISCON_REQ); 947 } else if ((level != DL_PROMISC_PHYS) && (level != DL_PROMISC_SAP) && 948 (level != DL_PROMISC_MULTI)) { 949 DBGERROR((CE_CONT, "DLPI promiscon: bad level %d\n", level)); 950 dlerrorack(q, mp, DL_PROMISCON_REQ, DL_NOTSUPPORTED, 0); 951 } else { 952 qwriter(q, mp, sppp_dl_promiscon, PERIM_INNER); 953 } 954 return (0); 955 } 956 957 /* 958 * sppp_dl_promiscon() 959 * 960 * MT-Perimeters: 961 * exclusive inner, shared outer. 962 * 963 * Description: 964 * Called by qwriter (INNER) from sppp_dlpromisconreq as the result of 965 * receiving a DL_PROMISCON_REQ message. 966 */ 967 static void 968 sppp_dl_promiscon(queue_t *q, mblk_t *mp) 969 { 970 spppstr_t *sps; 971 sppa_t *ppa; 972 973 ASSERT(q != NULL && q->q_ptr != NULL); 974 sps = (spppstr_t *)q->q_ptr; 975 ASSERT(!IS_SPS_PROMISC(sps)); 976 ASSERT(mp != NULL && mp->b_rptr != NULL); 977 ppa = sps->sps_ppa; 978 979 sps->sps_flags |= SPS_PROMISC; 980 /* 981 * We can't be sure that the sps_ppa field is valid, since the DLPI 982 * spec says that DL_PROMISCON_REQ can be issued at any state, i.e., 983 * the request can be issued even before DL_ATTACH_REQ or PPPIO_ATTACH 984 * be issued to associate this stream with a ppa. 985 */ 986 if (ppa != NULL) { 987 rw_enter(&ppa->ppa_sib_lock, RW_WRITER); 988 ppa->ppa_promicnt++; 989 rw_exit(&ppa->ppa_sib_lock); 990 } 991 DBGDLPI((CE_CONT, "/%d: promiscuous mode on\n", sps->sps_mn_id)); 992 dlokack(q, mp, DL_PROMISCON_REQ); 993 } 994 995 /* 996 * sppp_dlpromiscoffreq() 997 * 998 * MT-Perimeters: 999 * shared inner, shared outer. 1000 * 1001 * Description: 1002 * Perform DL_PROMISCOFF_REQ request, called by sppp_mproto. 1003 */ 1004 static int 1005 sppp_dlpromiscoffreq(queue_t *q, mblk_t *mp, spppstr_t *sps) 1006 { 1007 t_uscalar_t level; 1008 1009 ASSERT(q != NULL && q->q_ptr != NULL); 1010 ASSERT(mp != NULL && mp->b_rptr != NULL); 1011 level = ((dl_promiscoff_req_t *)mp->b_rptr)->dl_level; 1012 ASSERT(sps != NULL); 1013 1014 if (!IS_SPS_PROMISC(sps)) { 1015 DBGERROR((CE_CONT, "DLPI promiscoff: not promiscuous\n")); 1016 dlerrorack(q, mp, DL_PROMISCOFF_REQ, DL_NOTENAB, 0); 1017 } else if ((level != DL_PROMISC_PHYS) && (level != DL_PROMISC_SAP) && 1018 (level != DL_PROMISC_MULTI)) { 1019 dlerrorack(q, mp, DL_PROMISCOFF_REQ, DL_NOTSUPPORTED, 0); 1020 DBGERROR((CE_CONT, "DLPI promiscoff: bad level %d\n", level)); 1021 } else { 1022 qwriter(q, mp, sppp_dl_promiscoff, PERIM_INNER); 1023 } 1024 return (0); 1025 1026 } 1027 1028 /* 1029 * sppp_dl_promiscoff() 1030 * 1031 * MT-Perimeters: 1032 * exclusive inner, shared outer. 1033 * 1034 * Description: 1035 * Called by qwriter (INNER) from sppp_dlpromiscoffreq as the result of 1036 * receiving a DL_PROMISCOFF_REQ message. 1037 */ 1038 static void 1039 sppp_dl_promiscoff(queue_t *q, mblk_t *mp) 1040 { 1041 spppstr_t *sps; 1042 sppa_t *ppa; 1043 1044 ASSERT(q != NULL && q->q_ptr != NULL); 1045 sps = (spppstr_t *)q->q_ptr; 1046 ASSERT(IS_SPS_PROMISC(sps)); 1047 ASSERT(mp != NULL && mp->b_rptr != NULL); 1048 ppa = sps->sps_ppa; 1049 1050 sps->sps_flags &= ~SPS_PROMISC; 1051 /* 1052 * We can't be guaranteed that the sps_ppa field is still valid, since 1053 * the control stream might have been closed earlier, in which case 1054 * the close procedure would have NULL'd out the sps_ppa. 1055 */ 1056 if (ppa != NULL) { 1057 rw_enter(&ppa->ppa_sib_lock, RW_WRITER); 1058 ASSERT(ppa->ppa_promicnt > 0); 1059 ppa->ppa_promicnt--; 1060 rw_exit(&ppa->ppa_sib_lock); 1061 } 1062 DBGDLPI((CE_CONT, "/%d: promiscuous mode off\n", sps->sps_mn_id)); 1063 dlokack(q, mp, DL_PROMISCOFF_REQ); 1064 } 1065 1066 /* 1067 * sppp_dlphyreq() 1068 * 1069 * MT-Perimeters: 1070 * shared inner, shared outer. 1071 * 1072 * Description: 1073 * Perform DL_PHYS_ADDR_REQ request, called by sppp_mproto. This doesn't 1074 * return anything useful, but it keeps ifconfig happy. 1075 */ 1076 /* ARGSUSED */ 1077 static int 1078 sppp_dlphyreq(queue_t *q, mblk_t *mp, spppstr_t *us) 1079 { 1080 static struct ether_addr addr = { 0 }; 1081 1082 dlphysaddrack(q, mp, (char *)&addr, ETHERADDRL); 1083 return (0); 1084 } 1085 1086 /* 1087 * sppp_dladdether() 1088 * 1089 * Description: 1090 * Prepend an empty Ethernet header to msg for snoop, et al. Free 1091 * the original mblk if alloc fails. Only called for the purpose of sending 1092 * packets up the promiscous stream. 1093 */ 1094 /* ARGSUSED */ 1095 static mblk_t * 1096 sppp_dladdether(spppstr_t *sps, mblk_t *mp, t_scalar_t proto) 1097 { 1098 mblk_t *eh; 1099 t_scalar_t type; 1100 1101 if ((eh = allocb(sizeof (struct ether_header), BPRI_MED)) == NULL) { 1102 freemsg(mp); 1103 return (NULL); 1104 } 1105 if (proto == PPP_IP) { 1106 type = ETHERTYPE_IP; 1107 } else if (proto == PPP_IPV6) { 1108 type = ETHERTYPE_IPV6; 1109 } else { 1110 /* 1111 * For all other protocols, end this up as an ETHERTYPE_PPP 1112 * type of packet. Since we've skipped the PPP headers in the 1113 * caller, make sure that we restore it. We know for sure that 1114 * the PPP header still exists in the message (only skipped), 1115 * since the sender of this message is pppd and it must have 1116 * included the PPP header in front. 1117 */ 1118 type = ETHERTYPE_PPP; 1119 mp->b_rptr -= PPP_HDRLEN; 1120 ASSERT(mp->b_rptr >= mp->b_datap->db_base); 1121 } 1122 eh->b_wptr += sizeof (struct ether_header); 1123 bzero((caddr_t)eh->b_rptr, sizeof (struct ether_header)); 1124 ((struct ether_header *)eh->b_rptr)->ether_type = htons((int16_t)type); 1125 1126 linkb(eh, mp); 1127 return (eh); 1128 } 1129 1130 /* 1131 * sppp_dladdud() 1132 * 1133 * Description: 1134 * Prepend DL_UNITDATA_IND mblk to msg, free original alloc fails. 1135 */ 1136 /* ARGSUSED */ 1137 mblk_t * 1138 sppp_dladdud(spppstr_t *sps, mblk_t *mp, t_scalar_t proto, boolean_t promisc) 1139 { 1140 dl_unitdata_ind_t *dlu; 1141 mblk_t *dh; 1142 size_t size; 1143 t_scalar_t type; 1144 1145 size = sizeof (dl_unitdata_ind_t) + (2 * SPPP_ADDRL); 1146 if ((dh = allocb(size, BPRI_MED)) == NULL) { 1147 freemsg(mp); 1148 return (NULL); 1149 } 1150 1151 dh->b_datap->db_type = M_PROTO; 1152 dh->b_wptr = dh->b_datap->db_lim; 1153 dh->b_rptr = dh->b_wptr - size; 1154 1155 dlu = (dl_unitdata_ind_t *)dh->b_rptr; 1156 dlu->dl_primitive = DL_UNITDATA_IND; 1157 dlu->dl_dest_addr_length = SPPP_ADDRL; 1158 dlu->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t); 1159 dlu->dl_src_addr_length = SPPP_ADDRL; 1160 dlu->dl_src_addr_offset = sizeof (dl_unitdata_ind_t) + SPPP_ADDRL; 1161 dlu->dl_group_address = 0; 1162 1163 if (promisc) { 1164 if (proto == PPP_IP) { 1165 type = ETHERTYPE_IP; 1166 } else if (proto == PPP_IPV6) { 1167 type = ETHERTYPE_IPV6; 1168 } else { 1169 /* 1170 * For all other protocols, send this up as an 1171 * ETHERTYPE_PPP type of packet. Since we've skipped 1172 * the PPP headers in the caller, make sure that we 1173 * restore it. We know for sure that the PPP header 1174 * still exists in the message (only skipped), since 1175 * the sender of this message is pppd and it must 1176 * have included the PPP header in front. 1177 */ 1178 type = ETHERTYPE_PPP; 1179 mp->b_rptr -= PPP_HDRLEN; 1180 ASSERT(mp->b_rptr >= mp->b_datap->db_base); 1181 } 1182 } else { 1183 type = sps->sps_req_sap; 1184 } 1185 /* 1186 * Send the DLPI client the data with the SAP they requested, 1187 * (e.g. ETHERTYPE_IP) rather than the PPP protocol (e.g. PPP_IP). 1188 */ 1189 ((spppreqsap_t *)(dlu + 1))[0] = type; 1190 ((spppreqsap_t *)(dlu + 1))[1] = type; 1191 1192 linkb(dh, mp); 1193 return (dh); 1194 } 1195 1196 /* 1197 * sppp_dlprsendup() 1198 * 1199 * Description: 1200 * For any valid promiscuous streams (marked with SPS_PROMISC and its 1201 * sps_dlstate is DL_IDLE), send data upstream. The caller is expected 1202 * to hold ppa_sib_lock when calling this procedure. 1203 */ 1204 void 1205 sppp_dlprsendup(spppstr_t *sps, mblk_t *mp, t_scalar_t proto, boolean_t header) 1206 { 1207 sppa_t *ppa; 1208 mblk_t *dmp; 1209 1210 ASSERT(sps != NULL); 1211 ASSERT(mp != NULL && mp->b_rptr != NULL); 1212 ppa = sps->sps_ppa; 1213 ASSERT(ppa != NULL); 1214 1215 /* NOTE: caller must hold ppa_sib_lock in RW_READER mode */ 1216 ASSERT(RW_READ_HELD(&ppa->ppa_sib_lock)); 1217 1218 for (; sps != NULL; sps = sps->sps_nextsib) { 1219 /* 1220 * We specifically test to ensure that the DLPI state for the 1221 * promiscous stream is IDLE (DL_IDLE), since such state tells 1222 * us that the promiscous stream has been bound to PPP_ALLSAP. 1223 */ 1224 if (IS_SPS_PROMISC(sps) && (sps->sps_dlstate == DL_IDLE) && 1225 canputnext(sps->sps_rq)) { 1226 if ((dmp = dupmsg(mp)) == NULL) { 1227 mutex_enter(&ppa->ppa_sta_lock); 1228 ppa->ppa_allocbfail++; 1229 mutex_exit(&ppa->ppa_sta_lock); 1230 continue; 1231 } 1232 if (header) { 1233 dmp->b_rptr += PPP_HDRLEN; 1234 } 1235 if (IS_SPS_RAWDATA(sps)) { 1236 /* function frees original message if fails */ 1237 dmp = sppp_dladdether(sps, dmp, proto); 1238 } else { 1239 /* function frees original message if fails */ 1240 dmp = sppp_dladdud(sps, dmp, proto, B_TRUE); 1241 } 1242 if (dmp != NULL) { 1243 putnext(sps->sps_rq, dmp); 1244 } else { 1245 mutex_enter(&ppa->ppa_sta_lock); 1246 ppa->ppa_allocbfail++; 1247 mutex_exit(&ppa->ppa_sta_lock); 1248 } 1249 } 1250 } 1251 }