Print this page
OS-4018 lxbrand support TCP SO_REUSEPORT
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Cody Mello <cody.mello@joyent.com>


 389  * connection (or the listener) which decrements tlc_cnt to zero frees the
 390  * struct.
 391  *
 392  * tlc_max is the maximum number of concurrent TCP connections created from a
 393  * listner.  It is calculated when the tcp_listen_cnt_t is allocated.
 394  *
 395  * tlc_report_time stores the time when cmn_err() is called to report that the
 396  * max has been exceeeded.  Report is done at most once every
 397  * TCP_TLC_REPORT_INTERVAL mins for a listener.
 398  *
 399  * tlc_drop stores the number of connection attempt dropped because the
 400  * limit has reached.
 401  */
 402 typedef struct tcp_listen_cnt_s {
 403         uint32_t        tlc_max;
 404         uint32_t        tlc_cnt;
 405         int64_t         tlc_report_time;
 406         uint32_t        tlc_drop;
 407 } tcp_listen_cnt_t;
 408 
















 409 #define TCP_TLC_REPORT_INTERVAL (30 * MINUTES)
 410 
 411 #define TCP_DECR_LISTEN_CNT(tcp)                                        \
 412 {                                                                       \
 413         ASSERT((tcp)->tcp_listen_cnt->tlc_cnt > 0);                    \
 414         if (atomic_dec_32_nv(&(tcp)->tcp_listen_cnt->tlc_cnt) == 0) \
 415                 kmem_free((tcp)->tcp_listen_cnt, sizeof (tcp_listen_cnt_t)); \
 416         (tcp)->tcp_listen_cnt = NULL;                                        \
 417 }
 418 
 419 /* Increment and decrement the number of connections in tcp_stack_t. */
 420 #define TCPS_CONN_INC(tcps)                                             \
 421         atomic_inc_64(                                                  \
 422             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
 423 
 424 #define TCPS_CONN_DEC(tcps)                                             \
 425         atomic_dec_64(                                                  \
 426             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
 427 
 428 /*


 632 extern int      tcp_set_destination(tcp_t *);
 633 extern void     tcp_set_ws_value(tcp_t *);
 634 extern void     tcp_stop_lingering(tcp_t *);
 635 extern void     tcp_update_pmtu(tcp_t *, boolean_t);
 636 extern mblk_t   *tcp_zcopy_backoff(tcp_t *, mblk_t *, boolean_t);
 637 extern boolean_t        tcp_zcopy_check(tcp_t *);
 638 extern void     tcp_zcopy_notify(tcp_t *);
 639 extern void     tcp_get_proto_props(tcp_t *, struct sock_proto_props *);
 640 
 641 /*
 642  * Bind related functions in tcp_bind.c
 643  */
 644 extern int      tcp_bind_check(conn_t *, struct sockaddr *, socklen_t,
 645                     cred_t *, boolean_t);
 646 extern void     tcp_bind_hash_insert(tf_t *, tcp_t *, int);
 647 extern void     tcp_bind_hash_remove(tcp_t *);
 648 extern in_port_t        tcp_bindi(tcp_t *, in_port_t, const in6_addr_t *,
 649                             int, boolean_t, boolean_t, boolean_t);
 650 extern in_port_t        tcp_update_next_port(in_port_t, const tcp_t *,
 651                             boolean_t);




 652 
 653 /*
 654  * Fusion related functions in tcp_fusion.c.
 655  */
 656 extern void     tcp_fuse(tcp_t *, uchar_t *, tcpha_t *);
 657 extern void     tcp_unfuse(tcp_t *);
 658 extern boolean_t tcp_fuse_output(tcp_t *, mblk_t *, uint32_t);
 659 extern void     tcp_fuse_output_urg(tcp_t *, mblk_t *);
 660 extern boolean_t tcp_fuse_rcv_drain(queue_t *, tcp_t *, mblk_t **);
 661 extern size_t   tcp_fuse_set_rcv_hiwat(tcp_t *, size_t);
 662 extern int      tcp_fuse_maxpsz(tcp_t *);
 663 extern void     tcp_fuse_backenable(tcp_t *);
 664 extern void     tcp_iss_key_init(uint8_t *, int, tcp_stack_t *);
 665 
 666 /*
 667  * Output related functions in tcp_output.c.
 668  */
 669 extern void     tcp_close_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 670 extern void     tcp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 671 extern void     tcp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *);




 389  * connection (or the listener) which decrements tlc_cnt to zero frees the
 390  * struct.
 391  *
 392  * tlc_max is the maximum number of concurrent TCP connections created from a
 393  * listner.  It is calculated when the tcp_listen_cnt_t is allocated.
 394  *
 395  * tlc_report_time stores the time when cmn_err() is called to report that the
 396  * max has been exceeeded.  Report is done at most once every
 397  * TCP_TLC_REPORT_INTERVAL mins for a listener.
 398  *
 399  * tlc_drop stores the number of connection attempt dropped because the
 400  * limit has reached.
 401  */
 402 typedef struct tcp_listen_cnt_s {
 403         uint32_t        tlc_max;
 404         uint32_t        tlc_cnt;
 405         int64_t         tlc_report_time;
 406         uint32_t        tlc_drop;
 407 } tcp_listen_cnt_t;
 408 
 409 /*
 410  * Track tcp_t entities bound to the same port/address tuple via SO_REUSEPORT.
 411  * - tcprg_lock:        Protects the other fields
 412  * - tcprg_size:        Allocated size (in entries) of tcprg_members array
 413  * - tcprg_count:       Count of occupied tcprg_members slots
 414  * - tcprg_active:      Count of members which still have SO_REUSEPORT set
 415  * - tcprg_members:     Connections associated with address/port group
 416  */
 417 typedef struct tcp_rg_s {
 418         kmutex_t        tcprg_lock;
 419         unsigned int    tcprg_size;
 420         unsigned int    tcprg_count;
 421         unsigned int    tcprg_active;
 422         tcp_t           **tcprg_members;
 423 } tcp_rg_t;
 424 
 425 #define TCP_TLC_REPORT_INTERVAL (30 * MINUTES)
 426 
 427 #define TCP_DECR_LISTEN_CNT(tcp)                                        \
 428 {                                                                       \
 429         ASSERT((tcp)->tcp_listen_cnt->tlc_cnt > 0);                    \
 430         if (atomic_dec_32_nv(&(tcp)->tcp_listen_cnt->tlc_cnt) == 0) \
 431                 kmem_free((tcp)->tcp_listen_cnt, sizeof (tcp_listen_cnt_t)); \
 432         (tcp)->tcp_listen_cnt = NULL;                                        \
 433 }
 434 
 435 /* Increment and decrement the number of connections in tcp_stack_t. */
 436 #define TCPS_CONN_INC(tcps)                                             \
 437         atomic_inc_64(                                                  \
 438             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
 439 
 440 #define TCPS_CONN_DEC(tcps)                                             \
 441         atomic_dec_64(                                                  \
 442             (uint64_t *)&(tcps)->tcps_sc[CPU->cpu_seqid]->tcp_sc_conn_cnt)
 443 
 444 /*


 648 extern int      tcp_set_destination(tcp_t *);
 649 extern void     tcp_set_ws_value(tcp_t *);
 650 extern void     tcp_stop_lingering(tcp_t *);
 651 extern void     tcp_update_pmtu(tcp_t *, boolean_t);
 652 extern mblk_t   *tcp_zcopy_backoff(tcp_t *, mblk_t *, boolean_t);
 653 extern boolean_t        tcp_zcopy_check(tcp_t *);
 654 extern void     tcp_zcopy_notify(tcp_t *);
 655 extern void     tcp_get_proto_props(tcp_t *, struct sock_proto_props *);
 656 
 657 /*
 658  * Bind related functions in tcp_bind.c
 659  */
 660 extern int      tcp_bind_check(conn_t *, struct sockaddr *, socklen_t,
 661                     cred_t *, boolean_t);
 662 extern void     tcp_bind_hash_insert(tf_t *, tcp_t *, int);
 663 extern void     tcp_bind_hash_remove(tcp_t *);
 664 extern in_port_t        tcp_bindi(tcp_t *, in_port_t, const in6_addr_t *,
 665                             int, boolean_t, boolean_t, boolean_t);
 666 extern in_port_t        tcp_update_next_port(in_port_t, const tcp_t *,
 667                             boolean_t);
 668 extern tcp_rg_t *tcp_rg_init(tcp_t *);
 669 extern boolean_t tcp_rg_remove(tcp_rg_t *, tcp_t *);
 670 extern void tcp_rg_destroy(tcp_rg_t *);
 671 extern void tcp_rg_setactive(tcp_rg_t *, boolean_t);
 672 
 673 /*
 674  * Fusion related functions in tcp_fusion.c.
 675  */
 676 extern void     tcp_fuse(tcp_t *, uchar_t *, tcpha_t *);
 677 extern void     tcp_unfuse(tcp_t *);
 678 extern boolean_t tcp_fuse_output(tcp_t *, mblk_t *, uint32_t);
 679 extern void     tcp_fuse_output_urg(tcp_t *, mblk_t *);
 680 extern boolean_t tcp_fuse_rcv_drain(queue_t *, tcp_t *, mblk_t **);
 681 extern size_t   tcp_fuse_set_rcv_hiwat(tcp_t *, size_t);
 682 extern int      tcp_fuse_maxpsz(tcp_t *);
 683 extern void     tcp_fuse_backenable(tcp_t *);
 684 extern void     tcp_iss_key_init(uint8_t *, int, tcp_stack_t *);
 685 
 686 /*
 687  * Output related functions in tcp_output.c.
 688  */
 689 extern void     tcp_close_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 690 extern void     tcp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 691 extern void     tcp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *);