Print this page
Support route deletion entries in SVP_R_LOG_ACK.


 283         mutex_exit(&srp->sr_lock);
 284         svp_remote_release(srp);
 285 }
 286 
 287 /*
 288  * See if the request can be sent over the connection's supported version.
 289  * Scribble the version in the request itself.  NOTE that we do not check the
 290  * version that already exists in sqp->sq_header.svp_ver, as we may be called
 291  * from svp_remote_reassign() (and change versions when arriving at a new
 292  * connection).
 293  */
 294 static boolean_t
 295 svp_outbound_version_check(int version, svp_query_t *sqp)
 296 {
 297         uint16_t op = htons(sqp->sq_header.svp_op);
 298 
 299         /*
 300          * As of v1 -> v2, we really only need to restrict SVP_R_ROUTE_REQ
 301          * as v2-only.  Reflect that here.
 302          *
 303          * NOTE that if any message semantics change between future versions,
 304          * (e.g. "in v3 SVP_R_VL2_REQ takes on additional work"), we'll
 305          * need to more-deeply inspect the query.  It's possible that the
 306          * svp_op space is big enough to just continue op-only inspections.
 307          */
 308 
 309         assert(version > 0 && version <= SVP_CURRENT_VERSION);
 310 
 311         if (op != SVP_R_ROUTE_REQ || version >= SVP_VERSION_TWO) {
 312                 sqp->sq_header.svp_ver = htons(version);
 313                 return (B_TRUE);
 314         }

 315         return (B_FALSE);
 316 }
 317 
 318 /*
 319  * Walk the list of connections and find the first one that's available AND
 320  * version-appropriate for the message, then move the matched connection to
 321  * the back of the list so it's less likely to be used again.
 322  */
 323 static boolean_t
 324 svp_remote_conn_queue(svp_remote_t *srp, svp_query_t *sqp)
 325 {
 326         svp_conn_t *scp;
 327 
 328         assert(MUTEX_HELD(&srp->sr_lock));
 329         for (scp = list_head(&srp->sr_conns); scp != NULL;
 330             scp = list_next(&srp->sr_conns, scp)) {
 331                 mutex_enter(&scp->sc_lock);
 332                 if (scp->sc_cstate != SVP_CS_ACTIVE ||
 333                     !svp_outbound_version_check(scp->sc_version, sqp)) {
 334                         mutex_exit(&scp->sc_lock);


 524     const struct sockaddr *addr, svp_query_f func, void *arg)
 525 {
 526         svp_remote_vl3_common(srp, sqp, addr, func, arg, vid);
 527 }
 528 
 529 void
 530 svp_remote_vl3_lookup(svp_t *svp, svp_query_t *sqp,
 531     const struct sockaddr *addr, void *arg)
 532 {
 533         svp_remote_t *srp = svp->svp_remote;
 534 
 535         sqp->sq_svp = svp;
 536         svp_remote_vl3_common(srp, sqp, addr, svp_remote_vl3_lookup_cb,
 537             arg, svp->svp_vid);
 538 }
 539 
 540 static void
 541 svp_remote_log_request_cb(svp_query_t *sqp, void *arg)
 542 {
 543         svp_remote_t *srp = sqp->sq_arg;

 544 








 545         assert(sqp->sq_wdata != NULL);
 546         if (sqp->sq_status == SVP_S_OK)
 547                 svp_shootdown_logr_cb(srp, sqp->sq_status, sqp->sq_wdata,
 548                     sqp->sq_size);
 549         else
 550                 svp_shootdown_logr_cb(srp, sqp->sq_status, NULL, 0);
 551 }
 552 
 553 void
 554 svp_remote_log_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 555     size_t buflen)
 556 {
 557         svp_log_req_t *logr = &sqp->sq_rdun.sdq_logr;
 558         boolean_t queued;
 559 
 560         sqp->sq_func = svp_remote_log_request_cb;
 561         sqp->sq_state = SVP_QUERY_INIT;
 562         sqp->sq_arg = srp;
 563         sqp->sq_header.svp_op = htons(SVP_R_LOG_REQ);
 564         sqp->sq_header.svp_size = htonl(sizeof (svp_log_req_t));
 565         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 566         if (sqp->sq_header.svp_id == (id_t)-1)
 567                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 568                     errno);
 569         sqp->sq_header.svp_crc32 = 0;
 570         sqp->sq_rdata = logr;
 571         sqp->sq_rsize = sizeof (svp_log_req_t);
 572         sqp->sq_wdata = buf;
 573         sqp->sq_wsize = buflen;
 574 
 575         logr->svlr_count = htonl(buflen);
 576         bcopy(&srp->sr_uip, logr->svlr_ip, sizeof (struct in6_addr));
 577 
 578         /*
 579          * If this fails, there isn't much that we can't do. Give the callback
 580          * with a fatal status.
 581          */
 582         mutex_enter(&srp->sr_lock);
 583         queued = svp_remote_conn_queue(srp, sqp);
 584         mutex_exit(&srp->sr_lock);
 585 
 586         if (queued == B_FALSE)
 587                 svp_shootdown_logr_cb(srp, SVP_S_FATAL, NULL, 0);
 588 }
 589 
 590 static void
 591 svp_remote_lrm_request_cb(svp_query_t *sqp, void *arg)
 592 {
 593         svp_remote_t *srp = arg;
 594 
 595         svp_shootdown_lrm_cb(srp, sqp->sq_status);
 596 }
 597 
 598 void
 599 svp_remote_lrm_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 600     size_t buflen)
 601 {
 602         boolean_t queued;
 603         svp_lrm_req_t *svrr = buf;
 604 
 605         sqp->sq_func = svp_remote_lrm_request_cb;
 606         sqp->sq_state = SVP_QUERY_INIT;
 607         sqp->sq_arg = srp;


 614         sqp->sq_header.svp_crc32 = 0;
 615         sqp->sq_rdata = buf;
 616         sqp->sq_rsize = buflen;
 617         sqp->sq_wdata = NULL;
 618         sqp->sq_wsize = 0;
 619 
 620         /*
 621          * We need to fix up the count to be in proper network order.
 622          */
 623         svrr->svrr_count = htonl(svrr->svrr_count);
 624 
 625         /*
 626          * If this fails, there isn't much that we can't do. Give the callback
 627          * with a fatal status.
 628          */
 629         mutex_enter(&srp->sr_lock);
 630         queued = svp_remote_conn_queue(srp, sqp);
 631         mutex_exit(&srp->sr_lock);
 632 
 633         if (queued == B_FALSE)
 634                 svp_shootdown_logr_cb(srp, SVP_S_FATAL, NULL, 0);
 635 }
 636 
 637 /* ARGSUSED */
 638 void
 639 svp_remote_dns_timer(void *unused)
 640 {
 641         svp_remote_t *s;
 642         mutex_enter(&svp_remote_lock);
 643         for (s = avl_first(&svp_remote_tree); s != NULL;
 644             s = AVL_NEXT(&svp_remote_tree, s)) {
 645                 svp_host_queue(s);
 646         }
 647         mutex_exit(&svp_remote_lock);
 648 }
 649 
 650 void
 651 svp_remote_resolved(svp_remote_t *srp, struct addrinfo *newaddrs)
 652 {
 653         struct addrinfo *a;
 654         svp_conn_t *scp;


 874         squery->ssv_log = sdl;
 875         squery->ssv_sock.sin6_family = AF_INET6;
 876         bcopy(svl3->svl3_ip, &squery->ssv_sock.sin6_addr,
 877             sizeof (svl3->svl3_ip));
 878         svp_remote_vl3_logreq(srp, &squery->ssv_query, ntohl(svl3->svl3_vnetid),
 879             (struct sockaddr *)&squery->ssv_sock, svp_remote_shootdown_vl3_cb,
 880             squery);
 881 }
 882 
 883 void
 884 svp_remote_shootdown_vl2(svp_remote_t *srp, svp_log_vl2_t *svl2)
 885 {
 886         svp_t *svp, lookup;
 887 
 888         lookup.svp_vid = ntohl(svl2->svl2_vnetid);
 889         mutex_enter(&srp->sr_lock);
 890         if ((svp = avl_find(&srp->sr_tree, &lookup, NULL)) != NULL) {
 891                 svp->svp_cb.scb_vl2_invalidate(svp, svl2->svl2_mac);
 892         }
 893         mutex_exit(&srp->sr_lock);















 894 }
 895 
 896 int
 897 svp_remote_init(void)
 898 {
 899         svp_idspace = id_space_create("svp_req_ids", 1, INT32_MAX);
 900         if (svp_idspace == NULL)
 901                 return (errno);
 902         avl_create(&svp_remote_tree, svp_remote_comparator,
 903             sizeof (svp_remote_t), offsetof(svp_remote_t, sr_gnode));
 904         svp_dns_timer.st_func = svp_remote_dns_timer;
 905         svp_dns_timer.st_arg = NULL;
 906         svp_dns_timer.st_oneshot = B_FALSE;
 907         svp_dns_timer.st_value = svp_dns_timer_rate;
 908         svp_timer_add(&svp_dns_timer);
 909         return (0);
 910 }
 911 
 912 void
 913 svp_remote_fini(void)


 283         mutex_exit(&srp->sr_lock);
 284         svp_remote_release(srp);
 285 }
 286 
 287 /*
 288  * See if the request can be sent over the connection's supported version.
 289  * Scribble the version in the request itself.  NOTE that we do not check the
 290  * version that already exists in sqp->sq_header.svp_ver, as we may be called
 291  * from svp_remote_reassign() (and change versions when arriving at a new
 292  * connection).
 293  */
 294 static boolean_t
 295 svp_outbound_version_check(int version, svp_query_t *sqp)
 296 {
 297         uint16_t op = htons(sqp->sq_header.svp_op);
 298 
 299         /*
 300          * As of v1 -> v2, we really only need to restrict SVP_R_ROUTE_REQ
 301          * as v2-only.  Reflect that here.
 302          *
 303          * NOTE that if any message semantics change between versions,
 304          * (e.g. "in v3 SVP_R_VL2_REQ takes on additional work"), we'll
 305          * need to more-deeply inspect the query.  It's possible that the
 306          * svp_op space is big enough to just continue op-only inspections.
 307          */
 308 
 309         assert(version > 0 && version <= SVP_CURRENT_VERSION);
 310 
 311         if (op != SVP_R_ROUTE_REQ || version >= SVP_VERSION_TWO) {
 312                 sqp->sq_header.svp_ver = htons(version);
 313                 return (B_TRUE);
 314         }
 315 
 316         return (B_FALSE);
 317 }
 318 
 319 /*
 320  * Walk the list of connections and find the first one that's available AND
 321  * version-appropriate for the message, then move the matched connection to
 322  * the back of the list so it's less likely to be used again.
 323  */
 324 static boolean_t
 325 svp_remote_conn_queue(svp_remote_t *srp, svp_query_t *sqp)
 326 {
 327         svp_conn_t *scp;
 328 
 329         assert(MUTEX_HELD(&srp->sr_lock));
 330         for (scp = list_head(&srp->sr_conns); scp != NULL;
 331             scp = list_next(&srp->sr_conns, scp)) {
 332                 mutex_enter(&scp->sc_lock);
 333                 if (scp->sc_cstate != SVP_CS_ACTIVE ||
 334                     !svp_outbound_version_check(scp->sc_version, sqp)) {
 335                         mutex_exit(&scp->sc_lock);


 525     const struct sockaddr *addr, svp_query_f func, void *arg)
 526 {
 527         svp_remote_vl3_common(srp, sqp, addr, func, arg, vid);
 528 }
 529 
 530 void
 531 svp_remote_vl3_lookup(svp_t *svp, svp_query_t *sqp,
 532     const struct sockaddr *addr, void *arg)
 533 {
 534         svp_remote_t *srp = svp->svp_remote;
 535 
 536         sqp->sq_svp = svp;
 537         svp_remote_vl3_common(srp, sqp, addr, svp_remote_vl3_lookup_cb,
 538             arg, svp->svp_vid);
 539 }
 540 
 541 static void
 542 svp_remote_log_request_cb(svp_query_t *sqp, void *arg)
 543 {
 544         svp_remote_t *srp = sqp->sq_arg;
 545         uint16_t version;
 546 
 547         /*
 548          * Version in request is set in this sqp's read-data/sq_header by
 549          * now.
 550          */
 551         assert(sqp->sq_header.svp_op == htons(SVP_R_LOG_REQ));
 552         assert(sqp->sq_header.svp_ver != 0);
 553         version = htons(sqp->sq_header.svp_ver);
 554 
 555         assert(sqp->sq_wdata != NULL);
 556         if (sqp->sq_status == SVP_S_OK)
 557                 svp_shootdown_logr_cb(srp, sqp->sq_status, sqp->sq_wdata,
 558                     sqp->sq_size, version);
 559         else
 560                 svp_shootdown_logr_cb(srp, sqp->sq_status, NULL, 0, 0);
 561 }
 562 
 563 void
 564 svp_remote_log_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 565     size_t buflen)
 566 {
 567         svp_log_req_t *logr = &sqp->sq_rdun.sdq_logr;
 568         boolean_t queued;
 569 
 570         sqp->sq_func = svp_remote_log_request_cb;
 571         sqp->sq_state = SVP_QUERY_INIT;
 572         sqp->sq_arg = srp;
 573         sqp->sq_header.svp_op = htons(SVP_R_LOG_REQ);
 574         sqp->sq_header.svp_size = htonl(sizeof (svp_log_req_t));
 575         sqp->sq_header.svp_id = id_alloc(svp_idspace);
 576         if (sqp->sq_header.svp_id == (id_t)-1)
 577                 libvarpd_panic("failed to allcoate from svp_idspace: %d",
 578                     errno);
 579         sqp->sq_header.svp_crc32 = 0;
 580         sqp->sq_rdata = logr;
 581         sqp->sq_rsize = sizeof (svp_log_req_t);
 582         sqp->sq_wdata = buf;
 583         sqp->sq_wsize = buflen;
 584 
 585         logr->svlr_count = htonl(buflen);
 586         bcopy(&srp->sr_uip, logr->svlr_ip, sizeof (struct in6_addr));
 587 
 588         /*
 589          * If this fails, there isn't much that we can't do. Give the callback
 590          * with a fatal status.
 591          */
 592         mutex_enter(&srp->sr_lock);
 593         queued = svp_remote_conn_queue(srp, sqp);
 594         mutex_exit(&srp->sr_lock);
 595 
 596         if (queued == B_FALSE)
 597                 svp_shootdown_logr_cb(srp, SVP_S_FATAL, NULL, 0, 0);
 598 }
 599 
 600 static void
 601 svp_remote_lrm_request_cb(svp_query_t *sqp, void *arg)
 602 {
 603         svp_remote_t *srp = arg;
 604 
 605         svp_shootdown_lrm_cb(srp, sqp->sq_status);
 606 }
 607 
 608 void
 609 svp_remote_lrm_request(svp_remote_t *srp, svp_query_t *sqp, void *buf,
 610     size_t buflen)
 611 {
 612         boolean_t queued;
 613         svp_lrm_req_t *svrr = buf;
 614 
 615         sqp->sq_func = svp_remote_lrm_request_cb;
 616         sqp->sq_state = SVP_QUERY_INIT;
 617         sqp->sq_arg = srp;


 624         sqp->sq_header.svp_crc32 = 0;
 625         sqp->sq_rdata = buf;
 626         sqp->sq_rsize = buflen;
 627         sqp->sq_wdata = NULL;
 628         sqp->sq_wsize = 0;
 629 
 630         /*
 631          * We need to fix up the count to be in proper network order.
 632          */
 633         svrr->svrr_count = htonl(svrr->svrr_count);
 634 
 635         /*
 636          * If this fails, there isn't much that we can't do. Give the callback
 637          * with a fatal status.
 638          */
 639         mutex_enter(&srp->sr_lock);
 640         queued = svp_remote_conn_queue(srp, sqp);
 641         mutex_exit(&srp->sr_lock);
 642 
 643         if (queued == B_FALSE)
 644                 svp_shootdown_logr_cb(srp, SVP_S_FATAL, NULL, 0, 0);
 645 }
 646 
 647 /* ARGSUSED */
 648 void
 649 svp_remote_dns_timer(void *unused)
 650 {
 651         svp_remote_t *s;
 652         mutex_enter(&svp_remote_lock);
 653         for (s = avl_first(&svp_remote_tree); s != NULL;
 654             s = AVL_NEXT(&svp_remote_tree, s)) {
 655                 svp_host_queue(s);
 656         }
 657         mutex_exit(&svp_remote_lock);
 658 }
 659 
 660 void
 661 svp_remote_resolved(svp_remote_t *srp, struct addrinfo *newaddrs)
 662 {
 663         struct addrinfo *a;
 664         svp_conn_t *scp;


 884         squery->ssv_log = sdl;
 885         squery->ssv_sock.sin6_family = AF_INET6;
 886         bcopy(svl3->svl3_ip, &squery->ssv_sock.sin6_addr,
 887             sizeof (svl3->svl3_ip));
 888         svp_remote_vl3_logreq(srp, &squery->ssv_query, ntohl(svl3->svl3_vnetid),
 889             (struct sockaddr *)&squery->ssv_sock, svp_remote_shootdown_vl3_cb,
 890             squery);
 891 }
 892 
 893 void
 894 svp_remote_shootdown_vl2(svp_remote_t *srp, svp_log_vl2_t *svl2)
 895 {
 896         svp_t *svp, lookup;
 897 
 898         lookup.svp_vid = ntohl(svl2->svl2_vnetid);
 899         mutex_enter(&srp->sr_lock);
 900         if ((svp = avl_find(&srp->sr_tree, &lookup, NULL)) != NULL) {
 901                 svp->svp_cb.scb_vl2_invalidate(svp, svl2->svl2_mac);
 902         }
 903         mutex_exit(&srp->sr_lock);
 904 }
 905 
 906 void
 907 svp_remote_shootdown_route(svp_remote_t *srp, svp_log_route_t *svlr)
 908 {
 909         svp_t *svp, lookup;
 910 
 911         lookup.svp_vid = ntohl(svlr->svlr_src_vnetid);
 912         mutex_enter(&srp->sr_lock);
 913         if ((svp = avl_find(&srp->sr_tree, &lookup, NULL)) != NULL) {
 914                 svp->svp_cb.scb_route_shootdown(svp, svlr->svlr_srcip,
 915                     svlr->svlr_dstip, svlr->svlr_src_prefixlen,
 916                     svlr->svlr_dst_prefixlen, htons(svlr->svlr_src_vlan));
 917         }
 918         mutex_exit(&srp->sr_lock);
 919 }
 920 
 921 int
 922 svp_remote_init(void)
 923 {
 924         svp_idspace = id_space_create("svp_req_ids", 1, INT32_MAX);
 925         if (svp_idspace == NULL)
 926                 return (errno);
 927         avl_create(&svp_remote_tree, svp_remote_comparator,
 928             sizeof (svp_remote_t), offsetof(svp_remote_t, sr_gnode));
 929         svp_dns_timer.st_func = svp_remote_dns_timer;
 930         svp_dns_timer.st_arg = NULL;
 931         svp_dns_timer.st_oneshot = B_FALSE;
 932         svp_dns_timer.st_value = svp_dns_timer_rate;
 933         svp_timer_add(&svp_dns_timer);
 934         return (0);
 935 }
 936 
 937 void
 938 svp_remote_fini(void)