1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2012 David Hoeppner. All rights reserved.
  14  */
  15 
  16 #ifndef _INET_DCCP_IMPL_H
  17 #define _INET_DCCP_IMPL_H
  18 
  19 #include <sys/int_types.h>
  20 #include <sys/netstack.h>
  21 #include <sys/socket.h>
  22 #include <sys/socket_proto.h>
  23 
  24 #include <netinet/in.h>
  25 #include <netinet/ip6.h>
  26 #include <netinet/dccp.h>
  27 
  28 #include <inet/common.h>
  29 #include <inet/ip.h>
  30 #include <inet/ip6.h>
  31 #include <inet/optcom.h>
  32 #include <inet/tunables.h>
  33 
  34 #include "dccp_stack.h"
  35 
  36 #ifdef  __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 #ifdef  _KERNEL
  41 
  42 #define DCCP_MOD_ID             5999 /* XXX */
  43 
  44 extern struct qinit     dccp_sock_winit;
  45 extern struct qinit     dccp_winit;
  46 
  47 extern sock_downcalls_t sock_dccp_downcalls;
  48 
  49 #define DCCP_XMIT_LOWATER       (4 * 1024)
  50 #define DCCP_XMIT_HIWATER       49152
  51 #define DCCP_RECV_LOWATER       (2 * 1024)
  52 #define DCCP_RECV_HIWATER       128000
  53 
  54 #define TIDUSZ  4096    /* transport interface data unit size */
  55 
  56 /*
  57  * Bind hash array size and hash function.
  58  */
  59 #define DCCP_BIND_FANOUT_SIZE           128
  60 #define DCCP_BIND_HASH(lport, size)     ((ntohs((uint16_t)lport)) & (size - 1))
  61 
  62 /*
  63  * Was this tcp created via socket() interface?
  64  */
  65 #define DCCP_IS_SOCKET(dccp)    ((dccp)->dccp_issocket)
  66 
  67 #define DCCP_HDR_LENGTH(dccph)          (((dccph_t *)dccph)->dh_offset * 4) /* XXX >> 2 */
  68 #define DCCP_MAX_HDR_LENGTH             1020
  69 #define DCCP_MIN_HEADER_LENGTH          12
  70 
  71 /* Packet types (RFC 4340, Section 5.1.) */
  72 #define DCCP_PKT_REQUEST        0
  73 #define DCCP_PKT_RESPONSE       1
  74 #define DCCP_PKT_DATA           2
  75 #define DCCP_PKT_ACK            3
  76 #define DCCP_PKT_DATAACK        4
  77 #define DCCP_PKT_CLOSEREQ       5
  78 #define DCCP_PKT_CLOSE          6
  79 #define DCCP_PKT_RESET          7
  80 #define DCCP_PKT_SYNC           8
  81 #define DCCP_PKT_SYNCACK        9
  82 
  83 /*
  84  * DCCP options and features.
  85  */
  86 
  87 /* Options types (RFC 4340, Section 5.8.) */
  88 #define DCCP_OPTION_PADDING             0
  89 #define DCCP_OPTION_MANDATORY           1
  90 #define DCCP_OPTION_SLOW_RECEIVER       2
  91 #define DCCP_OPTION_CHANGE_L            32
  92 #define DCCP_OPTION_CONFIRM_L           33
  93 #define DCCP_OPTION_CHANGE_R            34
  94 #define DCCP_OPTION_CONFIRM_R           35
  95 #define DCCP_OPTION_INIT_COOKIE         36
  96 #define DCCP_OPTION_NDP_COUNT           37
  97 #define DCCP_OPTION_ACK_VECTOR_1        38
  98 #define DCCP_OPTION_ACK_VECTOR_2        39
  99 #define DCCP_OPTION_DATA_DROPPED        40
 100 #define DCCP_OPTION_TIMESTAMP           41
 101 #define DCCP_OPTION_TIMESTAMP_ECHO      42
 102 #define DCCP_OPTION_ELAPSED_TIME        43
 103 #define DCCP_OPTION_DATA_CHECKSUM       44
 104 
 105 /* Feature types (RFC 4340, Section 6.4.) */
 106 #define DCCP_FEATURE_CCID                       1
 107 #define DCCP_FEATURE_ALLOW_SHORT_SEQNOS         2
 108 #define DCCP_FEATURE_SEQUENCE_WINDOW            3
 109 #define DCCP_FEATURE_ECN_INCAPABLE              4
 110 #define DCCP_FEATURE_ACK_RATIO                  5
 111 #define DCCP_FEATURE_SEND_ACK_VECTOR            6
 112 #define DCCP_FEATURE_SEND_NDP_COUNT             7
 113 #define DCCP_FEATURE_MIN_CHECKSUM_COVERAGE      8
 114 #define DCCP_FEATURE_CHECK_DATA_CHECKSUM        9
 115 
 116 /* Feature negotation states (RFC 4340, Section 6.6.2.) */
 117 #define DCCP_FEATURE_STATE_CHANGING             0
 118 #define DCCP_FEATURE_STATE_UNSTABLE             1
 119 #define DCCP_FEATURE_STATE_STABLE               2
 120 
 121 typedef struct dccp_feature_s {
 122         list_node_t     df_next;
 123         uint8_t         df_option;
 124         uint8_t         df_type;
 125         uint8_t         df_state;
 126         uint64_t        df_value;
 127         boolean_t       df_mandatory;
 128 } dccp_feature_t;
 129 
 130 /* Options in DCCP header */
 131 typedef struct dccp_opt_s {
 132         int             type;
 133         boolean_t       mandatory;
 134 } dccp_opt_t;
 135 
 136 /*
 137  * DCCP header structures.
 138  */
 139 
 140 /* Generic protocol header (RFC 4340, Section 5.1.) */
 141 typedef struct dccphdr_s {
 142         uint8_t         dh_lport[2];
 143         uint8_t         dh_fport[2];
 144         uint8_t         dh_offset;
 145         uint8_t         dh_ccval:4,
 146                         dh_cscov:4;
 147         uint8_t         db_sum[2];
 148         uint8_t         dh_reserved:3,
 149                         dh_type:4,
 150                         dh_x:1;
 151         uint8_t         dh_res_seq;
 152         uint8_t         dh_seq[2];
 153 } dccph_t;
 154 
 155 
 156 /* Generic protocol header aligned (RFC 4340, Section 5.1.) */
 157 typedef struct dccphdra_s {
 158         in_port_t       dha_lport;              /* Source port */
 159         in_port_t       dha_fport;              /* Destination port */
 160         uint8_t         dha_offset;             /* Data offset */
 161         uint8_t         dha_ccval:4,            /* */
 162                         dha_cscov:4;            /* */
 163         uint16_t        dha_sum;                /* Checksum */
 164         uint8_t         dha_x:1,                /* Reserved */
 165                         dha_type:4,             /* Packet type */
 166                         dha_reserved:3;         /* Header type */
 167         uint8_t         dha_res_seq;
 168         uint16_t        dha_seq;                /* Partial sequence number */
 169 } dccpha_t;
 170 
 171 typedef struct dccphdra_ext_s {
 172         uint32_t        dha_ext_seq;
 173 } dccpha_ext_t;
 174 
 175 /* Acknowledgement number */
 176 typedef struct dccphdra_ack {
 177         uint16_t        dha_ack_reserved;
 178         uint16_t        dha_ack_high;
 179         uint32_t        dha_ack_low;
 180 } dccpha_ack_t;
 181 
 182 /* Service number */
 183 typedef struct dccphdra_srv {
 184         uint32_t        dha_srv_code;
 185 } dccpha_srv_t;
 186 
 187 /* Reset data */
 188 typedef struct dccphdra_reset {
 189         uint8_t         dha_reset_code;
 190         uint8_t         dha_reset_data[3];
 191 } dccpha_reset_t;
 192 
 193 /* Internal DCCP structure */
 194 typedef struct dccp_s {
 195 
 196         conn_t          *dccp_connp;            /* Backpointer to conn_t */
 197         dccp_stack_t    *dccp_dccps;            /* Backpointer to dccp_stack_t */
 198 
 199         int32_t         dccp_state;
 200 
 201         uint32_t
 202                 dccp_loopback: 1,       /* Src and dst are the same machine */
 203                 dccp_localnet: 1,       /* Src and dst are on the same subnet */
 204                 dccp_active_open: 1,    /* This is a active open */
 205                 dccp_dummy: 1;
 206 
 207         /* Bind related */
 208         struct dccp_s   *dccp_bind_hash;        /* Bind hash chain */
 209         struct dccp_s   *dccp_bind_hash_port;   /* Bound to the same port */
 210         struct dccp_s   **dccp_ptpbhn;
 211 
 212         struct dccphdra_s *dccp_dccpha;         /* Template header */
 213 
 214         mblk_t          *dccp_xmit_head;
 215 
 216         /*
 217          * Pointers into the header template.
 218          */
 219         ipha_t          *dccp_ipha;
 220         ip6_t           *dccp_ip6h;
 221 
 222         t_uscalar_t     dccp_acceptor_id;       /* ACCEPTOR_id */
 223 
 224         sock_connid_t   dccp_connid;
 225 
 226         /* Incrementing pending conn req ID */
 227         t_scalar_t      dccp_conn_req_seqnum;
 228 
 229         boolean_t       dccp_issocket;          /* This is a socket dccp */
 230 
 231         /* List of features being negotiated */
 232         list_t          dccp_features;
 233 
 234         /*
 235          *Sequence numbers (Section 7.1.)
 236          */
 237         uint64_t        dccp_iss;       /* Initial sequence number sent */
 238         uint64_t        dccp_isr;       /* Initial sequence number received */
 239         uint64_t        dccp_gss;       /* Greatest sequence number sent */
 240         uint64_t        dccp_gsr;       /* Greatest sequence */
 241                                         /* number received */
 242         uint64_t        dccp_gar;       /* Greatest acknowledgement */
 243                                         /* number received */
 244 } dccp_t;
 245 
 246 #define dccps_smallest_nonpriv_port     dccps_propinfo_tbl[0].prop_cur_uval
 247 #define dccps_smallest_anon_port        dccps_propinfo_tbl[1].prop_cur_uval
 248 #define dccps_largest_anon_port         dccps_propinfo_tbl[2].prop_cur_uval
 249 
 250 #define dccps_dbg                       dccps_propinfo_tbl[4].prop_cur_uval
 251 #define dccps_rst_sent_rate_enabled     dccps_propinfo_tbl[5].prop_cur_uval
 252 #define dccps_rst_sent_rate             dccps_propinfo_tbl[6].prop_cur_uval
 253 
 254 typedef struct dccp_df_s {
 255         struct dccp_s   *df_dccp;
 256         kmutex_t        df_lock;
 257         uchar_t         df_pad[TF_CACHEL_PAD - (sizeof (dccp_t *) +
 258                             sizeof (kmutex_t))];
 259 } dccp_df_t;
 260 
 261 extern struct qinit dccp_rinitv4, dccp_rinitv6;
 262 
 263 extern optdb_obj_t      dccp_opt_obj;
 264 extern uint_t           dccp_max_optsize;
 265 
 266 extern int              dccp_squeue_flag;
 267 
 268 /*
 269  * Functions in dccp.c
 270  */
 271 extern int      dccp_build_hdrs(dccp_t *);
 272 extern conn_t   *dccp_create_common(cred_t *, boolean_t, boolean_t, int *);
 273 extern void     dccp_close_common(conn_t *, int);
 274 extern int      dccp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
 275                     boolean_t);
 276 extern int      dccp_do_unbind(conn_t *);
 277 extern int      dccp_do_listen(conn_t *, struct sockaddr *, socklen_t, int,
 278                     cred_t *, boolean_t);
 279 extern int      dccp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
 280                     cred_t *, pid_t);
 281 extern void     dccp_init_values(dccp_t *, dccp_t *);
 282 extern void     *dccp_get_conn(void *, dccp_stack_t *);
 283 extern int      dccp_set_destination(dccp_t *dccp);
 284 
 285 /*
 286  * Functions in dccp_bind.c
 287  */
 288 extern void     dccp_bind_hash_insert(dccp_df_t *, dccp_t *, int);
 289 extern void     dccp_bind_hash_remove(dccp_t *);
 290 extern int      dccp_bind_check(conn_t *, struct sockaddr *, socklen_t, cred_t *cr,
 291                     boolean_t);
 292 extern in_port_t dccp_bindi(dccp_t *, in_port_t, const in6_addr_t *, int,
 293                     boolean_t, boolean_t, boolean_t);
 294 extern in_port_t dccp_update_next_port(in_port_t, const dccp_t *, boolean_t);
 295 
 296 /*
 297  * Functions in dccp_features.c
 298  */
 299 extern void     dccp_process_options(dccp_t *, dccpha_t *);
 300 extern int      dccp_generate_options(dccp_t *, void **, size_t *);
 301 
 302 /*
 303  * Functions in dccp_stats.c
 304  */
 305 extern mblk_t   *dccp_snmp_get(queue_t *, mblk_t *, boolean_t);
 306 extern void     *dccp_kstat_init(netstackid_t);
 307 extern void     dccp_kstat_fini(netstackid_t, kstat_t *);
 308 
 309 /*
 310  * Functions in dccp_socket.c
 311  */
 312 extern sock_lower_handle_t      dccp_create(int, int, int, sock_downcalls_t **,
 313                                     uint_t *, int *, int, cred_t *);
 314 extern int      dccp_fallback(sock_lower_handle_t, queue_t *, boolean_t,
 315                     so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
 316 
 317 /*
 318  * Functions in dccp_input.c
 319  */
 320 extern void     dccp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
 321 extern void     dccp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *);
 322 extern void     dccp_rsrv(queue_t *);
 323 extern void     dccp_input_listener_unbound(void *, mblk_t *, void *,
 324                     ip_recv_attr_t *);
 325 extern boolean_t dccp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *,
 326                     ip_recv_attr_t *);
 327 
 328 /*
 329  * Functions in dccp_misc.c
 330  */
 331 extern void     dccp_stack_cpu_add(dccp_stack_t *, processorid_t);
 332 
 333 /*
 334  * Functions in dccp_output.c
 335  */
 336 extern void     dccp_wput(queue_t *, mblk_t *);
 337 extern void     dccp_wput_sock(queue_t *, mblk_t *);
 338 extern void     dccp_wput_fallback(queue_t *, mblk_t *);
 339 extern void     dccp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *);
 340 extern void     dccp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 341 extern void     dccp_send_data(dccp_t *, mblk_t *);
 342 extern void     dccp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *,
 343                     ip_stack_t *, conn_t *);
 344 extern void     dccp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *);
 345 extern mblk_t   *dccp_xmit_mp(dccp_t *, mblk_t *, int32_t, int32_t *,
 346                     mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t);
 347 /* XXX following functions should be redone */
 348 extern mblk_t   *dccp_generate_packet(conn_t *, mblk_t *);
 349 extern mblk_t   *dccp_generate_request(conn_t *);
 350 
 351 /*
 352  * Functions in dccp_opt_data.c
 353  */
 354 extern int      dccp_opt_get(conn_t *, int, int, uchar_t *);
 355 extern int      dccp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
 356                     uint_t *, uchar_t *, void *, cred_t *);
 357 
 358 /*
 359  * Functions in dccp_tpi.c
 360  */
 361 extern void     dccp_do_capability_ack(dccp_t *, struct T_capability_ack *,
 362                     t_uscalar_t);
 363 extern void     dccp_capability_req(dccp_t *, mblk_t *);
 364 extern void     dccp_err_ack(dccp_t *, mblk_t *, int, int);
 365 extern void     dccp_tpi_connect(dccp_t *, mblk_t *);
 366 extern int      dccp_tpi_close(queue_t *, int);
 367 extern int      dccp_tpi_close_accept(queue_t *);
 368 extern int      dccp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
 369 extern int      dccp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
 370                     uint_t *, uchar_t *, void *, cred_t *);
 371 extern void     dccp_tpi_accept(queue_t *, mblk_t *);
 372 
 373 #endif  /* _KERNEL */
 374 
 375 #ifdef  __cplusplus
 376 }
 377 #endif
 378 
 379 #endif  /* _INET_DCCP_IMPL_H */