Print this page
Version bump SVP to 2


 262 void
 263 svp_remote_detach(svp_t *svp)
 264 {
 265         svp_t *lookup;
 266         svp_remote_t *srp = svp->svp_remote;
 267 
 268         if (srp == NULL)
 269                 libvarpd_panic("trying to detach remote when none exists");
 270 
 271         mutex_enter(&srp->sr_lock);
 272         lookup = avl_find(&srp->sr_tree, svp, NULL);
 273         if (lookup == NULL || lookup != svp)
 274                 libvarpd_panic("inconsitent remote avl tree...");
 275         avl_remove(&srp->sr_tree, svp);
 276         svp->svp_remote = NULL;
 277         mutex_exit(&srp->sr_lock);
 278         svp_remote_release(srp);
 279 }
 280 
 281 /*
 282  * Walk the list of connections and find the first one that's available, the
 283  * move it to the back of the list so it's less likely to be used again.



 284  */
 285 static boolean_t





























 286 svp_remote_conn_queue(svp_remote_t *srp, svp_query_t *sqp)
 287 {
 288         svp_conn_t *scp;
 289 
 290         assert(MUTEX_HELD(&srp->sr_lock));
 291         for (scp = list_head(&srp->sr_conns); scp != NULL;
 292             scp = list_next(&srp->sr_conns, scp)) {
 293                 mutex_enter(&scp->sc_lock);
 294                 if (scp->sc_cstate != SVP_CS_ACTIVE) {

 295                         mutex_exit(&scp->sc_lock);
 296                         continue;
 297                 }
 298                 svp_conn_queue(scp, sqp);
 299                 mutex_exit(&scp->sc_lock);
 300                 list_remove(&srp->sr_conns, scp);
 301                 list_insert_tail(&srp->sr_conns, scp);
 302                 return (B_TRUE);
 303         }
 304 
 305         return (B_FALSE);
 306 }
 307 
 308 static void
 309 svp_remote_vl2_lookup_cb(svp_query_t *sqp, void *arg)
 310 {
 311         svp_t *svp = sqp->sq_svp;
 312         svp_vl2_ack_t *vl2a = (svp_vl2_ack_t *)sqp->sq_wdata;
 313 
 314         if (sqp->sq_status == SVP_S_OK)
 315                 svp->svp_cb.scb_vl2_lookup(svp, sqp->sq_status,
 316                     (struct in6_addr *)vl2a->sl2a_addr, ntohs(vl2a->sl2a_port),
 317                     arg);
 318         else
 319                 svp->svp_cb.scb_vl2_lookup(svp, sqp->sq_status, NULL, 0, arg);
 320 }
 321 
 322 void
 323 svp_remote_vl2_lookup(svp_t *svp, svp_query_t *sqp, const uint8_t *mac,
 324     void *arg)
 325 {
 326         svp_remote_t *srp;
 327         svp_vl2_req_t *vl2r = &sqp->sq_rdun.sqd_vl2r;
 328 
 329         srp = svp->svp_remote;
 330         sqp->sq_func = svp_remote_vl2_lookup_cb;
 331         sqp->sq_arg = arg;
 332         sqp->sq_svp = svp;
 333         sqp->sq_state = SVP_QUERY_INIT;
 334         sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
 335         sqp->sq_header.svp_op = htons(SVP_R_VL2_REQ);
 336         sqp->sq_header.svp_size = htonl(sizeof (svp_vl2_req_t));
 337         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 338         if (sqp->sq_header.svp_id == (id_t)-1)
 339                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 340                     errno);
 341         sqp->sq_header.svp_crc32 = htonl(0);
 342         sqp->sq_rdata = vl2r;
 343         sqp->sq_rsize = sizeof (svp_vl2_req_t);
 344         sqp->sq_wdata = NULL;
 345         sqp->sq_wsize = 0;
 346 
 347         bcopy(mac, vl2r->sl2r_mac, ETHERADDRL);
 348         vl2r->sl2r_vnetid = ntohl(svp->svp_vid);
 349 
 350         mutex_enter(&srp->sr_lock);
 351         if (svp_remote_conn_queue(srp, sqp) == B_FALSE)
 352                 svp->svp_cb.scb_vl2_lookup(svp, SVP_S_FATAL, NULL, NULL, arg);
 353         mutex_exit(&srp->sr_lock);
 354 }


 366                     sra->sra_ip, sra->sra_src_pfx, sra->sra_dst_pfx, arg);
 367         } else {
 368                 svp->svp_cb.scb_route_lookup(svp, sqp->sq_status,
 369                     0, 0, 0, NULL, NULL, 0, NULL, 0, 0, arg);
 370         }
 371 }
 372 
 373 void
 374 svp_remote_route_lookup(svp_t *svp, svp_query_t *sqp,
 375     const struct in6_addr *src, const struct in6_addr *dst, uint32_t vnetid,
 376     uint16_t vlan, void *arg)
 377 {
 378         svp_remote_t *srp;
 379         svp_route_req_t *srr = &sqp->sq_rdun.sqd_rr;
 380 
 381         srp = svp->svp_remote;
 382         sqp->sq_func = svp_remote_route_lookup_cb;
 383         sqp->sq_arg = arg;
 384         sqp->sq_svp = svp;
 385         sqp->sq_state = SVP_QUERY_INIT;
 386         sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
 387         sqp->sq_header.svp_op = htons(SVP_R_ROUTE_REQ);
 388         sqp->sq_header.svp_size = htonl(sizeof (svp_route_req_t));
 389         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 390         if (sqp->sq_header.svp_id == (id_t)-1)
 391                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 392                     errno);
 393         sqp->sq_header.svp_crc32 = htonl(0);
 394         sqp->sq_rdata = srr;
 395 
 396         bcopy(src, srr->srr_srcip, sizeof (struct in6_addr));
 397         bcopy(dst, srr->srr_dstip, sizeof (struct in6_addr));
 398         /* Caller should've checked both are the same type... */
 399         srr->srr_vnetid = vnetid;
 400         srr->srr_vlan = vlan;
 401         srr->srr_pad = 0;
 402 
 403         mutex_enter(&srp->sr_lock);
 404         if (!svp_remote_conn_queue(srp, sqp)) {
 405                 sqp->sq_status = SVP_S_FATAL;
 406                 sqp->sq_func(sqp, arg);


 418                 svp->svp_cb.scb_vl3_lookup(svp, sqp->sq_status, vl3a->sl3a_mac,
 419                     (struct in6_addr *)vl3a->sl3a_uip, ntohs(vl3a->sl3a_uport),
 420                     arg);
 421         else
 422                 svp->svp_cb.scb_vl3_lookup(svp, sqp->sq_status, NULL, NULL, 0,
 423                     arg);
 424 }
 425 
 426 static void
 427 svp_remote_vl3_common(svp_remote_t *srp, svp_query_t *sqp,
 428     const struct sockaddr *addr,  svp_query_f func, void *arg, uint32_t vid)
 429 {
 430         svp_vl3_req_t *vl3r = &sqp->sq_rdun.sdq_vl3r;
 431 
 432         if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
 433                 libvarpd_panic("unexpected sa_family for the vl3 lookup");
 434 
 435         sqp->sq_func = func;
 436         sqp->sq_arg = arg;
 437         sqp->sq_state = SVP_QUERY_INIT;
 438         sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
 439         sqp->sq_header.svp_op = htons(SVP_R_VL3_REQ);
 440         sqp->sq_header.svp_size = htonl(sizeof (svp_vl3_req_t));
 441         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 442         if (sqp->sq_header.svp_id == (id_t)-1)
 443                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 444                     errno);
 445         sqp->sq_header.svp_crc32 = htonl(0);
 446         sqp->sq_rdata = vl3r;
 447         sqp->sq_rsize = sizeof (svp_vl3_req_t);
 448         sqp->sq_wdata = NULL;
 449         sqp->sq_wsize = 0;
 450 
 451         if (addr->sa_family == AF_INET6) {
 452                 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)addr;
 453                 vl3r->sl3r_type = htonl(SVP_VL3_IPV6);
 454                 bcopy(&s6->sin6_addr, vl3r->sl3r_ip,
 455                     sizeof (struct in6_addr));
 456         } else {
 457                 struct sockaddr_in *s4 = (struct sockaddr_in *)addr;
 458                 struct in6_addr v6;


 500         svp_remote_t *srp = sqp->sq_arg;
 501 
 502         assert(sqp->sq_wdata != NULL);
 503         if (sqp->sq_status == SVP_S_OK)
 504                 svp_shootdown_logr_cb(srp, sqp->sq_status, sqp->sq_wdata,
 505                     sqp->sq_size);
 506         else
 507                 svp_shootdown_logr_cb(srp, sqp->sq_status, NULL, 0);
 508 }
 509 
 510 void
 511 svp_remote_log_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 512     size_t buflen)
 513 {
 514         svp_log_req_t *logr = &sqp->sq_rdun.sdq_logr;
 515         boolean_t queued;
 516 
 517         sqp->sq_func = svp_remote_log_request_cb;
 518         sqp->sq_state = SVP_QUERY_INIT;
 519         sqp->sq_arg = srp;
 520         sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
 521         sqp->sq_header.svp_op = htons(SVP_R_LOG_REQ);
 522         sqp->sq_header.svp_size = htonl(sizeof (svp_log_req_t));
 523         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 524         if (sqp->sq_header.svp_id == (id_t)-1)
 525                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 526                     errno);
 527         sqp->sq_header.svp_crc32 = htonl(0);
 528         sqp->sq_rdata = logr;
 529         sqp->sq_rsize = sizeof (svp_log_req_t);
 530         sqp->sq_wdata = buf;
 531         sqp->sq_wsize = buflen;
 532 
 533         logr->svlr_count = htonl(buflen);
 534         bcopy(&srp->sr_uip, logr->svlr_ip, sizeof (struct in6_addr));
 535 
 536         /*
 537          * If this fails, there isn't much that we can't do. Give the callback
 538          * with a fatal status.
 539          */
 540         mutex_enter(&srp->sr_lock);


 546 }
 547 
 548 static void
 549 svp_remote_lrm_request_cb(svp_query_t *sqp, void *arg)
 550 {
 551         svp_remote_t *srp = arg;
 552 
 553         svp_shootdown_lrm_cb(srp, sqp->sq_status);
 554 }
 555 
 556 void
 557 svp_remote_lrm_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 558     size_t buflen)
 559 {
 560         boolean_t queued;
 561         svp_lrm_req_t *svrr = buf;
 562 
 563         sqp->sq_func = svp_remote_lrm_request_cb;
 564         sqp->sq_state = SVP_QUERY_INIT;
 565         sqp->sq_arg = srp;
 566         sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
 567         sqp->sq_header.svp_op = htons(SVP_R_LOG_RM);
 568         sqp->sq_header.svp_size = htonl(buflen);
 569         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 570         if (sqp->sq_header.svp_id == (id_t)-1)
 571                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 572                     errno);
 573         sqp->sq_header.svp_crc32 = htonl(0);
 574         sqp->sq_rdata = buf;
 575         sqp->sq_rsize = buflen;
 576         sqp->sq_wdata = NULL;
 577         sqp->sq_wsize = 0;
 578 
 579         /*
 580          * We need to fix up the count to be in proper network order.
 581          */
 582         svrr->svrr_count = htonl(svrr->svrr_count);
 583 
 584         /*
 585          * If this fails, there isn't much that we can't do. Give the callback
 586          * with a fatal status.




 262 void
 263 svp_remote_detach(svp_t *svp)
 264 {
 265         svp_t *lookup;
 266         svp_remote_t *srp = svp->svp_remote;
 267 
 268         if (srp == NULL)
 269                 libvarpd_panic("trying to detach remote when none exists");
 270 
 271         mutex_enter(&srp->sr_lock);
 272         lookup = avl_find(&srp->sr_tree, svp, NULL);
 273         if (lookup == NULL || lookup != svp)
 274                 libvarpd_panic("inconsitent remote avl tree...");
 275         avl_remove(&srp->sr_tree, svp);
 276         svp->svp_remote = NULL;
 277         mutex_exit(&srp->sr_lock);
 278         svp_remote_release(srp);
 279 }
 280 
 281 /*
 282  * See if the request can be sent over the connection's supported version.
 283  * Scribble the version in the request itself.  NOTE that we do not check the
 284  * version that already exists in sqp->sq_header.svp_ver, as we may be called
 285  * from svp_remote_reassign() (and change versions when arriving at a new
 286  * connection).
 287  */
 288 static boolean_t
 289 svp_outbound_version_check(int version, svp_query_t *sqp)
 290 {
 291         uint16_t op = htons(sqp->sq_header.svp_op);
 292 
 293         /*
 294          * As of v1 -> v2, we really only need to restrict SVP_R_ROUTE_REQ
 295          * as v2-only.  Reflect that here.
 296          *
 297          * NOTE that if any message semantics change between future versions,
 298          * (e.g. "in v3 SVP_R_VL2_REQ takes on additional work"), we'll
 299          * need to more-deeply inspect the query.  It's possible that the
 300          * svp_op space is big enough to just continue op-only inspections.
 301          */
 302 
 303         assert(version > 0 && version <= SVP_CURRENT_VERSION);
 304 
 305         if (op != SVP_R_ROUTE_REQ || version >= SVP_VERSION_TWO) {
 306                 sqp->sq_header.svp_ver = htons(version);
 307                 return (B_TRUE);
 308         }
 309         return (B_FALSE);
 310 }
 311 
 312 /*
 313  * Walk the list of connections and find the first one that's available AND
 314  * version-appropriate for the message, then move the matched connection to
 315  * the back of the list so it's less likely to be used again.
 316  */
 317 static boolean_t
 318 svp_remote_conn_queue(svp_remote_t *srp, svp_query_t *sqp)
 319 {
 320         svp_conn_t *scp;
 321 
 322         assert(MUTEX_HELD(&srp->sr_lock));
 323         for (scp = list_head(&srp->sr_conns); scp != NULL;
 324             scp = list_next(&srp->sr_conns, scp)) {
 325                 mutex_enter(&scp->sc_lock);
 326                 if (scp->sc_cstate != SVP_CS_ACTIVE ||
 327                     !svp_outbound_version_check(scp->sc_version, sqp)) {
 328                         mutex_exit(&scp->sc_lock);
 329                         continue;
 330                 }
 331                 svp_conn_queue(scp, sqp);
 332                 mutex_exit(&scp->sc_lock);
 333                 list_remove(&srp->sr_conns, scp);
 334                 list_insert_tail(&srp->sr_conns, scp);
 335                 return (B_TRUE);
 336         }
 337 
 338         return (B_FALSE);
 339 }
 340 
 341 static void
 342 svp_remote_vl2_lookup_cb(svp_query_t *sqp, void *arg)
 343 {
 344         svp_t *svp = sqp->sq_svp;
 345         svp_vl2_ack_t *vl2a = (svp_vl2_ack_t *)sqp->sq_wdata;
 346 
 347         if (sqp->sq_status == SVP_S_OK)
 348                 svp->svp_cb.scb_vl2_lookup(svp, sqp->sq_status,
 349                     (struct in6_addr *)vl2a->sl2a_addr, ntohs(vl2a->sl2a_port),
 350                     arg);
 351         else
 352                 svp->svp_cb.scb_vl2_lookup(svp, sqp->sq_status, NULL, 0, arg);
 353 }
 354 
 355 void
 356 svp_remote_vl2_lookup(svp_t *svp, svp_query_t *sqp, const uint8_t *mac,
 357     void *arg)
 358 {
 359         svp_remote_t *srp;
 360         svp_vl2_req_t *vl2r = &sqp->sq_rdun.sqd_vl2r;
 361 
 362         srp = svp->svp_remote;
 363         sqp->sq_func = svp_remote_vl2_lookup_cb;
 364         sqp->sq_arg = arg;
 365         sqp->sq_svp = svp;
 366         sqp->sq_state = SVP_QUERY_INIT;

 367         sqp->sq_header.svp_op = htons(SVP_R_VL2_REQ);
 368         sqp->sq_header.svp_size = htonl(sizeof (svp_vl2_req_t));
 369         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 370         if (sqp->sq_header.svp_id == (id_t)-1)
 371                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 372                     errno);
 373         sqp->sq_header.svp_crc32 = htonl(0);
 374         sqp->sq_rdata = vl2r;
 375         sqp->sq_rsize = sizeof (svp_vl2_req_t);
 376         sqp->sq_wdata = NULL;
 377         sqp->sq_wsize = 0;
 378 
 379         bcopy(mac, vl2r->sl2r_mac, ETHERADDRL);
 380         vl2r->sl2r_vnetid = ntohl(svp->svp_vid);
 381 
 382         mutex_enter(&srp->sr_lock);
 383         if (svp_remote_conn_queue(srp, sqp) == B_FALSE)
 384                 svp->svp_cb.scb_vl2_lookup(svp, SVP_S_FATAL, NULL, NULL, arg);
 385         mutex_exit(&srp->sr_lock);
 386 }


 398                     sra->sra_ip, sra->sra_src_pfx, sra->sra_dst_pfx, arg);
 399         } else {
 400                 svp->svp_cb.scb_route_lookup(svp, sqp->sq_status,
 401                     0, 0, 0, NULL, NULL, 0, NULL, 0, 0, arg);
 402         }
 403 }
 404 
 405 void
 406 svp_remote_route_lookup(svp_t *svp, svp_query_t *sqp,
 407     const struct in6_addr *src, const struct in6_addr *dst, uint32_t vnetid,
 408     uint16_t vlan, void *arg)
 409 {
 410         svp_remote_t *srp;
 411         svp_route_req_t *srr = &sqp->sq_rdun.sqd_rr;
 412 
 413         srp = svp->svp_remote;
 414         sqp->sq_func = svp_remote_route_lookup_cb;
 415         sqp->sq_arg = arg;
 416         sqp->sq_svp = svp;
 417         sqp->sq_state = SVP_QUERY_INIT;

 418         sqp->sq_header.svp_op = htons(SVP_R_ROUTE_REQ);
 419         sqp->sq_header.svp_size = htonl(sizeof (svp_route_req_t));
 420         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 421         if (sqp->sq_header.svp_id == (id_t)-1)
 422                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 423                     errno);
 424         sqp->sq_header.svp_crc32 = htonl(0);
 425         sqp->sq_rdata = srr;
 426 
 427         bcopy(src, srr->srr_srcip, sizeof (struct in6_addr));
 428         bcopy(dst, srr->srr_dstip, sizeof (struct in6_addr));
 429         /* Caller should've checked both are the same type... */
 430         srr->srr_vnetid = vnetid;
 431         srr->srr_vlan = vlan;
 432         srr->srr_pad = 0;
 433 
 434         mutex_enter(&srp->sr_lock);
 435         if (!svp_remote_conn_queue(srp, sqp)) {
 436                 sqp->sq_status = SVP_S_FATAL;
 437                 sqp->sq_func(sqp, arg);


 449                 svp->svp_cb.scb_vl3_lookup(svp, sqp->sq_status, vl3a->sl3a_mac,
 450                     (struct in6_addr *)vl3a->sl3a_uip, ntohs(vl3a->sl3a_uport),
 451                     arg);
 452         else
 453                 svp->svp_cb.scb_vl3_lookup(svp, sqp->sq_status, NULL, NULL, 0,
 454                     arg);
 455 }
 456 
 457 static void
 458 svp_remote_vl3_common(svp_remote_t *srp, svp_query_t *sqp,
 459     const struct sockaddr *addr,  svp_query_f func, void *arg, uint32_t vid)
 460 {
 461         svp_vl3_req_t *vl3r = &sqp->sq_rdun.sdq_vl3r;
 462 
 463         if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
 464                 libvarpd_panic("unexpected sa_family for the vl3 lookup");
 465 
 466         sqp->sq_func = func;
 467         sqp->sq_arg = arg;
 468         sqp->sq_state = SVP_QUERY_INIT;

 469         sqp->sq_header.svp_op = htons(SVP_R_VL3_REQ);
 470         sqp->sq_header.svp_size = htonl(sizeof (svp_vl3_req_t));
 471         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 472         if (sqp->sq_header.svp_id == (id_t)-1)
 473                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 474                     errno);
 475         sqp->sq_header.svp_crc32 = htonl(0);
 476         sqp->sq_rdata = vl3r;
 477         sqp->sq_rsize = sizeof (svp_vl3_req_t);
 478         sqp->sq_wdata = NULL;
 479         sqp->sq_wsize = 0;
 480 
 481         if (addr->sa_family == AF_INET6) {
 482                 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)addr;
 483                 vl3r->sl3r_type = htonl(SVP_VL3_IPV6);
 484                 bcopy(&s6->sin6_addr, vl3r->sl3r_ip,
 485                     sizeof (struct in6_addr));
 486         } else {
 487                 struct sockaddr_in *s4 = (struct sockaddr_in *)addr;
 488                 struct in6_addr v6;


 530         svp_remote_t *srp = sqp->sq_arg;
 531 
 532         assert(sqp->sq_wdata != NULL);
 533         if (sqp->sq_status == SVP_S_OK)
 534                 svp_shootdown_logr_cb(srp, sqp->sq_status, sqp->sq_wdata,
 535                     sqp->sq_size);
 536         else
 537                 svp_shootdown_logr_cb(srp, sqp->sq_status, NULL, 0);
 538 }
 539 
 540 void
 541 svp_remote_log_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 542     size_t buflen)
 543 {
 544         svp_log_req_t *logr = &sqp->sq_rdun.sdq_logr;
 545         boolean_t queued;
 546 
 547         sqp->sq_func = svp_remote_log_request_cb;
 548         sqp->sq_state = SVP_QUERY_INIT;
 549         sqp->sq_arg = srp;

 550         sqp->sq_header.svp_op = htons(SVP_R_LOG_REQ);
 551         sqp->sq_header.svp_size = htonl(sizeof (svp_log_req_t));
 552         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 553         if (sqp->sq_header.svp_id == (id_t)-1)
 554                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 555                     errno);
 556         sqp->sq_header.svp_crc32 = htonl(0);
 557         sqp->sq_rdata = logr;
 558         sqp->sq_rsize = sizeof (svp_log_req_t);
 559         sqp->sq_wdata = buf;
 560         sqp->sq_wsize = buflen;
 561 
 562         logr->svlr_count = htonl(buflen);
 563         bcopy(&srp->sr_uip, logr->svlr_ip, sizeof (struct in6_addr));
 564 
 565         /*
 566          * If this fails, there isn't much that we can't do. Give the callback
 567          * with a fatal status.
 568          */
 569         mutex_enter(&srp->sr_lock);


 575 }
 576 
 577 static void
 578 svp_remote_lrm_request_cb(svp_query_t *sqp, void *arg)
 579 {
 580         svp_remote_t *srp = arg;
 581 
 582         svp_shootdown_lrm_cb(srp, sqp->sq_status);
 583 }
 584 
 585 void
 586 svp_remote_lrm_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 587     size_t buflen)
 588 {
 589         boolean_t queued;
 590         svp_lrm_req_t *svrr = buf;
 591 
 592         sqp->sq_func = svp_remote_lrm_request_cb;
 593         sqp->sq_state = SVP_QUERY_INIT;
 594         sqp->sq_arg = srp;

 595         sqp->sq_header.svp_op = htons(SVP_R_LOG_RM);
 596         sqp->sq_header.svp_size = htonl(buflen);
 597         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 598         if (sqp->sq_header.svp_id == (id_t)-1)
 599                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 600                     errno);
 601         sqp->sq_header.svp_crc32 = htonl(0);
 602         sqp->sq_rdata = buf;
 603         sqp->sq_rsize = buflen;
 604         sqp->sq_wdata = NULL;
 605         sqp->sq_wsize = 0;
 606 
 607         /*
 608          * We need to fix up the count to be in proper network order.
 609          */
 610         svrr->svrr_count = htonl(svrr->svrr_count);
 611 
 612         /*
 613          * If this fails, there isn't much that we can't do. Give the callback
 614          * with a fatal status.