Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/inet/ipclassifier.h
          +++ new/usr/src/uts/common/inet/ipclassifier.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   * Copyright 2015 Joyent, Inc.
  25   25   */
  26   26  
  27   27  #ifndef _INET_IPCLASSIFIER_H
  28   28  #define _INET_IPCLASSIFIER_H
  29   29  
  30   30  #ifdef  __cplusplus
  31   31  extern "C" {
  32   32  #endif
  33   33  
  34   34  #include <inet/common.h>
  35   35  #include <inet/ip.h>
  36   36  #include <inet/mi.h>
  37   37  #include <inet/tcp.h>
  38   38  #include <inet/ip6.h>
  39   39  #include <netinet/in.h>         /* for IPPROTO_* constants */
  40   40  #include <sys/sdt.h>
  41   41  #include <sys/socket_proto.h>
  42   42  #include <sys/sunddi.h>
  43   43  #include <sys/sunldi.h>
  44   44  
  45   45  typedef void (*edesc_rpf)(void *, mblk_t *, void *, ip_recv_attr_t *);
  46   46  struct icmph_s;
  47   47  struct icmp6_hdr;
  48   48  typedef boolean_t (*edesc_vpf)(conn_t *, void *, struct icmph_s *,
  49   49      struct icmp6_hdr *, ip_recv_attr_t *);
  50   50  
  51   51  /*
  52   52   * ==============================
  53   53   * =    The CONNECTION          =
  54   54   * ==============================
  55   55   */
  56   56  
  57   57  /*
  58   58   * The connection structure contains the common information/flags/ref needed.
  59   59   * Implementation will keep the connection struct, the layers (with their
  60   60   * respective data for event i.e. tcp_t if event was tcp_input_data) all in one
  61   61   * contiguous memory location.
  62   62   */
  63   63  
  64   64  /* Conn Flags */
  65   65  /* Unused                       0x00020000 */
  66   66  /* Unused                       0x00040000 */
  67   67  #define IPCL_FULLY_BOUND        0x00080000      /* Bound to correct squeue */
  68   68  /* Unused                       0x00100000 */
  69   69  /* Unused                       0x00200000 */
  70   70  /* Unused                       0x00400000 */
  71   71  #define IPCL_CL_LISTENER        0x00800000      /* Cluster listener */
  72   72  /* Unused                       0x01000000 */
  73   73  /* Unused                       0x02000000 */
  74   74  /* Unused                       0x04000000 */
  75   75  /* Unused                       0x08000000 */
  76   76  /* Unused                       0x10000000 */
  77   77  /* Unused                       0x20000000 */
  78   78  #define IPCL_CONNECTED          0x40000000      /* Conn in connected table */
  79   79  #define IPCL_BOUND              0x80000000      /* Conn in bind table */
  80   80  
  81   81  /* Flags identifying the type of conn */
  82   82  #define IPCL_TCPCONN            0x00000001      /* From tcp_conn_cache */
  83   83  #define IPCL_SCTPCONN           0x00000002      /* From sctp_conn_cache */
  84   84  #define IPCL_IPCCONN            0x00000004      /* From ip_conn_cache */
  85   85  #define IPCL_UDPCONN            0x00000008      /* From udp_conn_cache */
  86   86  #define IPCL_RAWIPCONN          0x00000010      /* From rawip_conn_cache */
  87   87  #define IPCL_RTSCONN            0x00000020      /* From rts_conn_cache */
  88   88  /* Unused                       0x00000040 */
  89   89  #define IPCL_IPTUN              0x00000080      /* iptun module above us */
  90   90  
  91   91  #define IPCL_NONSTR             0x00001000      /* A non-STREAMS socket */
  92   92  /* Unused                       0x10000000 */
  93   93  
  94   94  #define IPCL_REMOVED            0x00000100
  95   95  #define IPCL_REUSED             0x00000200
  96   96  
  97   97  #define IPCL_IS_CONNECTED(connp)                                        \
  98   98          ((connp)->conn_flags & IPCL_CONNECTED)
  99   99  
 100  100  #define IPCL_IS_BOUND(connp)                                            \
 101  101          ((connp)->conn_flags & IPCL_BOUND)
 102  102  
 103  103  /*
 104  104   * Can't use conn_proto since we need to tell difference
 105  105   * between a real TCP socket and a SOCK_RAW, IPPROTO_TCP.
 106  106   */
 107  107  #define IPCL_IS_TCP(connp)                                              \
 108  108          ((connp)->conn_flags & IPCL_TCPCONN)
 109  109  
 110  110  #define IPCL_IS_SCTP(connp)                                             \
 111  111          ((connp)->conn_flags & IPCL_SCTPCONN)
 112  112  
 113  113  #define IPCL_IS_UDP(connp)                                              \
 114  114          ((connp)->conn_flags & IPCL_UDPCONN)
 115  115  
 116  116  #define IPCL_IS_RAWIP(connp)                                            \
 117  117          ((connp)->conn_flags & IPCL_RAWIPCONN)
 118  118  
 119  119  #define IPCL_IS_RTS(connp)                                              \
 120  120          ((connp)->conn_flags & IPCL_RTSCONN)
 121  121  
 122  122  #define IPCL_IS_IPTUN(connp)                                            \
 123  123          ((connp)->conn_flags & IPCL_IPTUN)
 124  124  
 125  125  #define IPCL_IS_NONSTR(connp)   ((connp)->conn_flags & IPCL_NONSTR)
 126  126  
 127  127  typedef struct connf_s connf_t;
 128  128  
 129  129  typedef struct
 130  130  {
 131  131          int     ctb_depth;
 132  132  #define CONN_STACK_DEPTH        15
 133  133          pc_t    ctb_stack[CONN_STACK_DEPTH];
 134  134  } conn_trace_t;
 135  135  
 136  136  typedef struct ip_helper_minor_info_s {
 137  137          dev_t   ip_minfo_dev;           /* Device */
 138  138          vmem_t  *ip_minfo_arena;        /* Arena */
 139  139  } ip_helper_minfo_t;
 140  140  
 141  141  /*
 142  142   * ip helper stream info
 143  143   */
 144  144  typedef struct ip_helper_stream_info_s {
 145  145          ldi_handle_t            iphs_handle;
 146  146          queue_t                 *iphs_rq;
 147  147          queue_t                 *iphs_wq;
 148  148          ip_helper_minfo_t       *iphs_minfo;
 149  149  } ip_helper_stream_info_t;
 150  150  
 151  151  /*
 152  152   * Mandatory Access Control mode, in conn_t's conn_mac_mode field.
 153  153   *      CONN_MAC_DEFAULT: strict enforcement of MAC.
 154  154   *      CONN_MAC_AWARE:   allows communications between unlabeled systems
 155  155   *                        and privileged daemons
 156  156   *      CONN_MAC_IMPLICIT: allows communications without explicit labels
 157  157   *                         on the wire with privileged daemons.
 158  158   *
 159  159   * CONN_MAC_IMPLICIT is intended specifically for labeled IPsec key management
 160  160   * in networks which don't pass CIPSO-labeled packets.
 161  161   */
 162  162  #define CONN_MAC_DEFAULT 0
 163  163  #define CONN_MAC_AWARE 1
 164  164  #define CONN_MAC_IMPLICIT 2
 165  165  
 166  166  /*
 167  167   * conn receive ancillary definition.
 168  168   *
 169  169   * These are the set of socket options that make the receive side
 170  170   * potentially pass up ancillary data items.
 171  171   * We have a union with an integer so that we can quickly check whether
 172  172   * any ancillary data items need to be added.
 173  173   */
 174  174  typedef struct crb_s {
 175  175          union {
 176  176                  uint32_t        crbu_all;
 177  177                  struct {
 178  178                          uint32_t
 179  179          crbb_recvdstaddr : 1,           /* IP_RECVDSTADDR option */
 180  180          crbb_recvopts : 1,              /* IP_RECVOPTS option */
 181  181          crbb_recvif : 1,                /* IP_RECVIF option */
 182  182          crbb_recvslla : 1,              /* IP_RECVSLLA option */
 183  183  
 184  184          crbb_recvttl : 1,               /* IP_RECVTTL option */
 185  185          crbb_ip_recvpktinfo : 1,        /* IP*_RECVPKTINFO option  */
 186  186          crbb_ipv6_recvhoplimit : 1,     /* IPV6_RECVHOPLIMIT option */
 187  187          crbb_ipv6_recvhopopts : 1,      /* IPV6_RECVHOPOPTS option */
 188  188  
 189  189          crbb_ipv6_recvdstopts : 1,      /* IPV6_RECVDSTOPTS option */
 190  190          crbb_ipv6_recvrthdr : 1,        /* IPV6_RECVRTHDR option */
 191  191          crbb_old_ipv6_recvdstopts : 1,  /* old form of IPV6_DSTOPTS */
 192  192          crbb_ipv6_recvrthdrdstopts : 1, /* IPV6_RECVRTHDRDSTOPTS */
 193  193  
 194  194          crbb_ipv6_recvtclass : 1,       /* IPV6_RECVTCLASS */
 195  195          crbb_recvucred : 1,             /* IP_RECVUCRED option */
 196  196          crbb_timestamp : 1;             /* SO_TIMESTAMP "socket" option */
 197  197  
 198  198                  } crbb;
 199  199          } crbu;
 200  200  } crb_t;
 201  201  
 202  202  #define crb_all                         crbu.crbu_all
 203  203  #define crb_recvdstaddr                 crbu.crbb.crbb_recvdstaddr
 204  204  #define crb_recvopts                    crbu.crbb.crbb_recvopts
 205  205  #define crb_recvif                      crbu.crbb.crbb_recvif
 206  206  #define crb_recvslla                    crbu.crbb.crbb_recvslla
 207  207  #define crb_recvttl                     crbu.crbb.crbb_recvttl
 208  208  #define crb_ip_recvpktinfo              crbu.crbb.crbb_ip_recvpktinfo
 209  209  #define crb_ipv6_recvhoplimit           crbu.crbb.crbb_ipv6_recvhoplimit
 210  210  #define crb_ipv6_recvhopopts            crbu.crbb.crbb_ipv6_recvhopopts
 211  211  #define crb_ipv6_recvdstopts            crbu.crbb.crbb_ipv6_recvdstopts
 212  212  #define crb_ipv6_recvrthdr              crbu.crbb.crbb_ipv6_recvrthdr
 213  213  #define crb_old_ipv6_recvdstopts        crbu.crbb.crbb_old_ipv6_recvdstopts
 214  214  #define crb_ipv6_recvrthdrdstopts       crbu.crbb.crbb_ipv6_recvrthdrdstopts
 215  215  #define crb_ipv6_recvtclass             crbu.crbb.crbb_ipv6_recvtclass
 216  216  #define crb_recvucred                   crbu.crbb.crbb_recvucred
 217  217  #define crb_timestamp                   crbu.crbb.crbb_timestamp
 218  218  
 219  219  /*
 220  220   * The initial fields in the conn_t are setup by the kmem_cache constructor,
 221  221   * and are preserved when it is freed. Fields after that are bzero'ed when
 222  222   * the conn_t is freed.
 223  223   *
 224  224   * Much of the conn_t is protected by conn_lock.
 225  225   *
 226  226   * conn_lock is also used by some ULPs (like UDP and RAWIP) to protect
 227  227   * their state.
 228  228   */
 229  229  struct conn_s {
 230  230          kmutex_t        conn_lock;
 231  231          uint32_t        conn_ref;               /* Reference counter */
 232  232          uint32_t        conn_flags;             /* Conn Flags */
 233  233  
 234  234          union {
 235  235                  tcp_t           *cp_tcp;        /* Pointer to the tcp struct */
 236  236                  struct udp_s    *cp_udp;        /* Pointer to the udp struct */
 237  237                  struct icmp_s   *cp_icmp;       /* Pointer to rawip struct */
 238  238                  struct rts_s    *cp_rts;        /* Pointer to rts struct */
 239  239                  struct iptun_s  *cp_iptun;      /* Pointer to iptun_t */
 240  240                  struct sctp_s   *cp_sctp;       /* For IPCL_SCTPCONN */
 241  241                  void            *cp_priv;
 242  242          } conn_proto_priv;
 243  243  #define conn_tcp        conn_proto_priv.cp_tcp
 244  244  #define conn_udp        conn_proto_priv.cp_udp
 245  245  #define conn_icmp       conn_proto_priv.cp_icmp
 246  246  #define conn_rts        conn_proto_priv.cp_rts
 247  247  #define conn_iptun      conn_proto_priv.cp_iptun
 248  248  #define conn_sctp       conn_proto_priv.cp_sctp
 249  249  #define conn_priv       conn_proto_priv.cp_priv
 250  250  
 251  251          kcondvar_t      conn_cv;
 252  252          uint8_t         conn_proto;             /* protocol type */
 253  253  
 254  254          edesc_rpf       conn_recv;              /* Pointer to recv routine */
 255  255          edesc_rpf       conn_recvicmp;          /* For ICMP error */
 256  256          edesc_vpf       conn_verifyicmp;        /* Verify ICMP error */
 257  257  
 258  258          ip_xmit_attr_t  *conn_ixa;              /* Options if no ancil data */
 259  259  
 260  260          /* Fields after this are bzero'ed when the conn_t is freed. */
 261  261  #define conn_start_clr  conn_recv_ancillary
 262  262  
 263  263          /* Options for receive-side ancillary data */
 264  264          crb_t           conn_recv_ancillary;
 265  265  
 266  266          squeue_t        *conn_sqp;              /* Squeue for processing */
 267  267          uint_t          conn_state_flags;       /* IP state flags */
 268  268  
 269  269          int             conn_lingertime;        /* linger time (in seconds) */
 270  270  
 271  271          unsigned int
 272  272                  conn_on_sqp : 1,                /* Conn is being processed */
 273  273                  conn_linger : 1,                /* SO_LINGER state */
 274  274                  conn_useloopback : 1,           /* SO_USELOOPBACK state */
 275  275                  conn_broadcast : 1,             /* SO_BROADCAST state */
 276  276  
 277  277                  conn_reuseaddr : 1,             /* SO_REUSEADDR state */
 278  278                  conn_keepalive : 1,             /* SO_KEEPALIVE state */
 279  279                  conn_multi_router : 1,          /* Wants all multicast pkts */
 280  280                  conn_unspec_src : 1,            /* IP_UNSPEC_SRC */
 281  281  
 282  282                  conn_policy_cached : 1,         /* Is policy cached/latched ? */
 283  283                  conn_in_enforce_policy : 1,     /* Enforce Policy on inbound */
 284  284                  conn_out_enforce_policy : 1,    /* Enforce Policy on outbound */
 285  285                  conn_debug : 1,                 /* SO_DEBUG */
 286  286  
 287  287                  conn_ipv6_v6only : 1,           /* IPV6_V6ONLY */
 288  288                  conn_oobinline : 1,             /* SO_OOBINLINE state */
 289  289                  conn_dgram_errind : 1,          /* SO_DGRAM_ERRIND state */
 290  290                  conn_exclbind : 1,              /* SO_EXCLBIND state */
 291  291  
 292  292                  conn_mdt_ok : 1,                /* MDT is permitted */
 293  293                  conn_allzones : 1,              /* SO_ALLZONES */
 294  294                  conn_ipv6_recvpathmtu : 1,      /* IPV6_RECVPATHMTU */
 295  295                  conn_mcbc_bind : 1,             /* Bound to multi/broadcast */
 296  296  
 297  297                  conn_reuseport : 1,             /* SO_REUSEPORT state */
 298  298                  conn_pad_to_bit_31 : 11;
 299  299  
 300  300          boolean_t       conn_blocked;           /* conn is flow-controlled */
 301  301  
 302  302          squeue_t        *conn_initial_sqp;      /* Squeue at open time */
 303  303          squeue_t        *conn_final_sqp;        /* Squeue after connect */
 304  304          ill_t           *conn_dhcpinit_ill;     /* IP_DHCPINIT_IF */
 305  305          ipsec_latch_t   *conn_latch;            /* latched IDS */
 306  306          struct ipsec_policy_s   *conn_latch_in_policy; /* latched policy (in) */
 307  307          struct ipsec_action_s   *conn_latch_in_action; /* latched action (in) */
 308  308          uint_t          conn_bound_if;          /* IP*_BOUND_IF */
 309  309          queue_t         *conn_rq;               /* Read queue */
 310  310          queue_t         *conn_wq;               /* Write queue */
 311  311          dev_t           conn_dev;               /* Minor number */
 312  312          vmem_t          *conn_minor_arena;      /* Minor arena */
 313  313          ip_helper_stream_info_t *conn_helper_info;
 314  314  
 315  315          cred_t          *conn_cred;             /* Credentials */
 316  316          pid_t           conn_cpid;              /* pid from open/connect */
 317  317          uint64_t        conn_open_time;         /* time when this was opened */
 318  318  
 319  319          connf_t         *conn_g_fanout;         /* Global Hash bucket head */
 320  320          struct conn_s   *conn_g_next;           /* Global Hash chain next */
 321  321          struct conn_s   *conn_g_prev;           /* Global Hash chain prev */
 322  322          struct ipsec_policy_head_s *conn_policy; /* Configured policy */
 323  323          in6_addr_t      conn_bound_addr_v6;     /* Address in bind() */
 324  324  #define conn_bound_addr_v4      V4_PART_OF_V6(conn_bound_addr_v6)
 325  325          connf_t         *conn_fanout;           /* Hash bucket we're part of */
 326  326          struct conn_s   *conn_next;             /* Hash chain next */
 327  327          struct conn_s   *conn_prev;             /* Hash chain prev */
 328  328  
 329  329          struct {
 330  330                  in6_addr_t connua_laddr;        /* Local address - match */
 331  331                  in6_addr_t connua_faddr;        /* Remote address */
 332  332          } connua_v6addr;
 333  333  #define conn_laddr_v4   V4_PART_OF_V6(connua_v6addr.connua_laddr)
 334  334  #define conn_faddr_v4   V4_PART_OF_V6(connua_v6addr.connua_faddr)
 335  335  #define conn_laddr_v6   connua_v6addr.connua_laddr
 336  336  #define conn_faddr_v6   connua_v6addr.connua_faddr
 337  337          in6_addr_t      conn_saddr_v6;          /* Local address - source */
 338  338  #define conn_saddr_v4   V4_PART_OF_V6(conn_saddr_v6)
 339  339  
 340  340          union {
 341  341                  /* Used for classifier match performance */
 342  342                  uint32_t                connu_ports2;
 343  343                  struct {
 344  344                          in_port_t       connu_fport;    /* Remote port */
 345  345                          in_port_t       connu_lport;    /* Local port */
 346  346                  } connu_ports;
 347  347          } u_port;
 348  348  #define conn_fport      u_port.connu_ports.connu_fport
 349  349  #define conn_lport      u_port.connu_ports.connu_lport
 350  350  #define conn_ports      u_port.connu_ports2
 351  351  
 352  352          uint_t          conn_incoming_ifindex;  /* IP{,V6}_BOUND_IF, scopeid */
 353  353          ill_t           *conn_oper_pending_ill; /* pending shared ioctl */
 354  354  
 355  355          krwlock_t       conn_ilg_lock;          /* Protects conn_ilg_* */
 356  356          ilg_t           *conn_ilg;              /* Group memberships */
 357  357  
 358  358          kcondvar_t      conn_refcv;             /* For conn_oper_pending_ill */
 359  359  
 360  360          struct conn_s   *conn_drain_next;       /* Next conn in drain list */
 361  361          struct conn_s   *conn_drain_prev;       /* Prev conn in drain list */
 362  362          idl_t           *conn_idl;              /* Ptr to the drain list head */
 363  363          mblk_t          *conn_ipsec_opt_mp;     /* ipsec option mblk */
 364  364          zoneid_t        conn_zoneid;            /* zone connection is in */
 365  365          int             conn_rtaware;           /* RT_AWARE sockopt value */
 366  366          kcondvar_t      conn_sq_cv;             /* For non-STREAMS socket IO */
 367  367          sock_upcalls_t  *conn_upcalls;          /* Upcalls to sockfs */
 368  368          sock_upper_handle_t conn_upper_handle;  /* Upper handle: sonode * */
 369  369  
 370  370          unsigned int
 371  371                  conn_mlp_type : 2,              /* mlp_type_t; tsol/tndb.h */
 372  372                  conn_anon_mlp : 1,              /* user wants anon MLP */
 373  373                  conn_anon_port : 1,             /* user bound anonymously */
 374  374  
 375  375                  conn_mac_mode : 2,              /* normal/loose/implicit MAC */
 376  376                  conn_anon_priv_bind : 1,        /* *_ANON_PRIV_BIND state */
 377  377                  conn_zone_is_global : 1,        /* GLOBAL_ZONEID */
 378  378                  conn_isvrrp : 1,                /* VRRP control socket */
 379  379                  conn_spare : 23;
 380  380  
 381  381          boolean_t       conn_flow_cntrld;
 382  382          netstack_t      *conn_netstack; /* Corresponds to a netstack_hold */
 383  383  
 384  384          /*
 385  385           * IP format that packets received for this struct should use.
 386  386           * Value can be IP4_VERSION or IPV6_VERSION.
 387  387           * The sending version is encoded using IXAF_IS_IPV4.
 388  388           */
 389  389          ushort_t        conn_ipversion;
 390  390  
 391  391          /* Written to only once at the time of opening the endpoint */
 392  392          sa_family_t     conn_family;            /* Family from socket() call */
 393  393          uint_t          conn_so_type;           /* Type from socket() call */
 394  394  
 395  395          uint_t          conn_sndbuf;            /* SO_SNDBUF state */
 396  396          uint_t          conn_rcvbuf;            /* SO_RCVBUF state */
 397  397          uint_t          conn_wroff;             /* Current write offset */
 398  398  
 399  399          uint_t          conn_sndlowat;          /* Send buffer low water mark */
 400  400          uint_t          conn_rcvlowat;          /* Recv buffer low water mark */
 401  401  
 402  402          uint8_t         conn_default_ttl;       /* Default TTL/hoplimit */
 403  403  
 404  404          uint32_t        conn_flowinfo;  /* Connected flow id and tclass */
 405  405  
 406  406          /*
 407  407           * The most recent address for sendto. Initially set to zero
 408  408           * which is always different than then the destination address
 409  409           * since the send interprets zero as the loopback address.
 410  410           */
 411  411          in6_addr_t      conn_v6lastdst;
 412  412  #define conn_v4lastdst  V4_PART_OF_V6(conn_v6lastdst)
 413  413          ushort_t        conn_lastipversion;
 414  414          in_port_t       conn_lastdstport;
 415  415          uint32_t        conn_lastflowinfo;      /* IPv6-only */
 416  416          uint_t          conn_lastscopeid;       /* IPv6-only */
 417  417          uint_t          conn_lastsrcid;         /* Only for AF_INET6 */
 418  418          /*
 419  419           * When we are not connected conn_saddr might be unspecified.
 420  420           * We track the source that was used with conn_v6lastdst here.
 421  421           */
 422  422          in6_addr_t      conn_v6lastsrc;
 423  423  #define conn_v4lastsrc  V4_PART_OF_V6(conn_v6lastsrc)
 424  424  
 425  425          /* Templates for transmitting packets */
 426  426          ip_pkt_t        conn_xmit_ipp;          /* Options if no ancil data */
 427  427  
 428  428          /*
 429  429           * Header template - conn_ht_ulp is a pointer into conn_ht_iphc.
 430  430           * Note that ixa_ip_hdr_length indicates the offset of ht_ulp in
 431  431           * ht_iphc
 432  432           *
 433  433           * The header template is maintained for connected endpoints (and
 434  434           * updated when sticky options are changed) and also for the lastdst.
 435  435           * There is no conflict between those usages since SOCK_DGRAM and
 436  436           * SOCK_RAW can not be used to specify a destination address (with
 437  437           * sendto/sendmsg) if the socket has been connected.
 438  438           */
 439  439          uint8_t         *conn_ht_iphc;          /* Start of IP header */
 440  440          uint_t          conn_ht_iphc_allocated; /* Allocated buffer size */
 441  441          uint_t          conn_ht_iphc_len;       /* IP+ULP size */
 442  442          uint8_t         *conn_ht_ulp;           /* Upper-layer header */
 443  443          uint_t          conn_ht_ulp_len;        /* ULP header len */
 444  444  
 445  445          /* Checksum to compensate for source routed packets. Host byte order */
 446  446          uint32_t        conn_sum;
 447  447  
 448  448          uint32_t        conn_ioctlref;          /* ioctl ref count */
 449  449  #ifdef CONN_DEBUG
 450  450  #define CONN_TRACE_MAX  10
 451  451          int             conn_trace_last;        /* ndx of last used tracebuf */
 452  452          conn_trace_t    conn_trace_buf[CONN_TRACE_MAX];
 453  453  #endif
 454  454  };
 455  455  
 456  456  /*
 457  457   * connf_t - connection fanout data.
 458  458   *
 459  459   * The hash tables and their linkage (conn_t.{hashnextp, hashprevp} are
 460  460   * protected by the per-bucket lock. Each conn_t inserted in the list
 461  461   * points back at the connf_t that heads the bucket.
 462  462   */
 463  463  struct connf_s {
 464  464          struct conn_s   *connf_head;
 465  465          kmutex_t        connf_lock;
 466  466  };
 467  467  
 468  468  #define CONN_INC_REF(connp)     {                               \
 469  469          mutex_enter(&(connp)->conn_lock);                       \
 470  470          DTRACE_PROBE1(conn__inc__ref, conn_t *, connp);         \
 471  471          ASSERT(conn_trace_ref(connp));                          \
 472  472          (connp)->conn_ref++;                                    \
 473  473          ASSERT((connp)->conn_ref != 0);                         \
 474  474          mutex_exit(&(connp)->conn_lock);                        \
 475  475  }
 476  476  
 477  477  #define CONN_INC_REF_LOCKED(connp)      {                       \
 478  478          DTRACE_PROBE1(conn__inc__ref, conn_t *, connp);         \
 479  479          ASSERT(MUTEX_HELD(&(connp)->conn_lock));                \
 480  480          ASSERT(conn_trace_ref(connp));                          \
 481  481          (connp)->conn_ref++;                                    \
 482  482          ASSERT((connp)->conn_ref != 0);                         \
 483  483  }
 484  484  
 485  485  #define CONN_DEC_REF(connp)     {                                       \
 486  486          mutex_enter(&(connp)->conn_lock);                               \
 487  487          DTRACE_PROBE1(conn__dec__ref, conn_t *, connp);                 \
 488  488          /*                                                              \
 489  489           * The squeue framework always does a CONN_DEC_REF after return \
 490  490           * from TCP. Hence the refcnt must be at least 2 if conn_on_sqp \
 491  491           * is B_TRUE and conn_ref is being decremented. This is to      \
 492  492           * account for the mblk being currently processed.              \
 493  493           */                                                             \
 494  494          if ((connp)->conn_ref == 0 ||                                   \
 495  495              ((connp)->conn_ref == 1 && (connp)->conn_on_sqp))           \
 496  496                  cmn_err(CE_PANIC, "CONN_DEC_REF: connp(%p) has ref "    \
 497  497                          "= %d\n", (void *)(connp), (connp)->conn_ref);  \
 498  498          ASSERT(conn_untrace_ref(connp));                                \
 499  499          (connp)->conn_ref--;                                            \
 500  500          if ((connp)->conn_ref == 0) {                                   \
 501  501                  /* Refcnt can't increase again, safe to drop lock */    \
 502  502                  mutex_exit(&(connp)->conn_lock);                        \
 503  503                  ipcl_conn_destroy(connp);                               \
 504  504          } else {                                                        \
 505  505                  cv_broadcast(&(connp)->conn_cv);                        \
 506  506                  mutex_exit(&(connp)->conn_lock);                        \
 507  507          }                                                               \
 508  508  }
 509  509  
 510  510  /*
 511  511   * For use with subsystems within ip which use ALL_ZONES as a wildcard
 512  512   */
 513  513  #define IPCL_ZONEID(connp)                                              \
 514  514          ((connp)->conn_allzones ? ALL_ZONES : (connp)->conn_zoneid)
 515  515  
 516  516  /*
 517  517   * For matching between a conn_t and a zoneid.
 518  518   */
 519  519  #define IPCL_ZONE_MATCH(connp, zoneid)                                  \
 520  520          (((connp)->conn_allzones) ||                                    \
 521  521              ((zoneid) == ALL_ZONES) ||                                  \
 522  522              (connp)->conn_zoneid == (zoneid))
 523  523  
 524  524  /*
 525  525   * On a labeled system, we must treat bindings to ports
 526  526   * on shared IP addresses by sockets with MAC exemption
 527  527   * privilege as being in all zones, as there's
 528  528   * otherwise no way to identify the right receiver.
 529  529   */
 530  530  
 531  531  #define IPCL_CONNS_MAC(conn1, conn2)                                    \
 532  532          (((conn1)->conn_mac_mode != CONN_MAC_DEFAULT) ||                \
 533  533          ((conn2)->conn_mac_mode != CONN_MAC_DEFAULT))
 534  534  
 535  535  #define IPCL_BIND_ZONE_MATCH(conn1, conn2)                              \
 536  536          (IPCL_CONNS_MAC(conn1, conn2) ||                                \
 537  537          IPCL_ZONE_MATCH(conn1, conn2->conn_zoneid) ||                   \
 538  538          IPCL_ZONE_MATCH(conn2, conn1->conn_zoneid))
 539  539  
 540  540  
 541  541  #define _IPCL_V4_MATCH(v6addr, v4addr)  \
 542  542          (V4_PART_OF_V6((v6addr)) == (v4addr) && IN6_IS_ADDR_V4MAPPED(&(v6addr)))
 543  543  
 544  544  #define _IPCL_V4_MATCH_ANY(addr)        \
 545  545          (IN6_IS_ADDR_V4MAPPED_ANY(&(addr)) || IN6_IS_ADDR_UNSPECIFIED(&(addr)))
 546  546  
 547  547  
 548  548  /*
 549  549   * IPCL_PROTO_MATCH() and IPCL_PROTO_MATCH_V6() only matches conns with
 550  550   * the specified ira_zoneid or conn_allzones by calling conn_wantpacket.
 551  551   */
 552  552  #define IPCL_PROTO_MATCH(connp, ira, ipha)                              \
 553  553          ((((connp)->conn_laddr_v4 == INADDR_ANY) ||                     \
 554  554          (((connp)->conn_laddr_v4 == ((ipha)->ipha_dst)) &&              \
 555  555              (((connp)->conn_faddr_v4 == INADDR_ANY) ||                  \
 556  556          ((connp)->conn_faddr_v4 == ((ipha)->ipha_src))))) &&            \
 557  557          conn_wantpacket((connp), (ira), (ipha)))
 558  558  
 559  559  #define IPCL_PROTO_MATCH_V6(connp, ira, ip6h)                           \
 560  560          ((IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_laddr_v6) ||           \
 561  561          (IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, &((ip6h)->ip6_dst)) &&   \
 562  562          (IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_faddr_v6) ||                  \
 563  563          IN6_ARE_ADDR_EQUAL(&(connp)->conn_faddr_v6, &((ip6h)->ip6_src))))) && \
 564  564          (conn_wantpacket_v6((connp), (ira), (ip6h))))
 565  565  
 566  566  #define IPCL_CONN_HASH(src, ports, ipst)                                \
 567  567          ((unsigned)(ntohl((src)) ^ ((ports) >> 24) ^ ((ports) >> 16) ^  \
 568  568          ((ports) >> 8) ^ (ports)) % (ipst)->ips_ipcl_conn_fanout_size)
 569  569  
 570  570  #define IPCL_CONN_HASH_V6(src, ports, ipst)                             \
 571  571          IPCL_CONN_HASH(V4_PART_OF_V6((src)), (ports), (ipst))
 572  572  
 573  573  #define IPCL_CONN_MATCH(connp, proto, src, dst, ports)                  \
 574  574          ((connp)->conn_proto == (proto) &&                              \
 575  575                  (connp)->conn_ports == (ports) &&                       \
 576  576                  _IPCL_V4_MATCH((connp)->conn_faddr_v6, (src)) &&        \
 577  577                  _IPCL_V4_MATCH((connp)->conn_laddr_v6, (dst)) &&        \
 578  578                  !(connp)->conn_ipv6_v6only)
 579  579  
 580  580  #define IPCL_CONN_MATCH_V6(connp, proto, src, dst, ports)               \
 581  581          ((connp)->conn_proto == (proto) &&                              \
 582  582                  (connp)->conn_ports == (ports) &&                       \
 583  583                  IN6_ARE_ADDR_EQUAL(&(connp)->conn_faddr_v6, &(src)) &&  \
 584  584                  IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, &(dst)))
 585  585  
 586  586  #define IPCL_PORT_HASH(port, size) \
 587  587          ((((port) >> 8) ^ (port)) & ((size) - 1))
 588  588  
 589  589  #define IPCL_BIND_HASH(lport, ipst)                                     \
 590  590          ((unsigned)(((lport) >> 8) ^ (lport)) % \
 591  591              (ipst)->ips_ipcl_bind_fanout_size)
 592  592  
 593  593  #define IPCL_BIND_MATCH(connp, proto, laddr, lport)                     \
 594  594          ((connp)->conn_proto == (proto) &&                              \
 595  595                  (connp)->conn_lport == (lport) &&                       \
 596  596                  (_IPCL_V4_MATCH_ANY((connp)->conn_laddr_v6) ||          \
 597  597                  _IPCL_V4_MATCH((connp)->conn_laddr_v6, (laddr))) &&     \
 598  598                  !(connp)->conn_ipv6_v6only)
 599  599  
 600  600  #define IPCL_BIND_MATCH_V6(connp, proto, laddr, lport)                  \
 601  601          ((connp)->conn_proto == (proto) &&                              \
 602  602                  (connp)->conn_lport == (lport) &&                       \
 603  603                  (IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, &(laddr)) || \
 604  604                  IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_laddr_v6)))
 605  605  
 606  606  /*
 607  607   * We compare conn_laddr since it captures both connected and a bind to
 608  608   * a multicast or broadcast address.
 609  609   * The caller needs to match the zoneid and also call conn_wantpacket
 610  610   * for multicast, broadcast, or when conn_incoming_ifindex is set.
 611  611   */
 612  612  #define IPCL_UDP_MATCH(connp, lport, laddr, fport, faddr)               \
 613  613          (((connp)->conn_lport == (lport)) &&                            \
 614  614          ((_IPCL_V4_MATCH_ANY((connp)->conn_laddr_v6) ||                 \
 615  615          (_IPCL_V4_MATCH((connp)->conn_laddr_v6, (laddr)) &&             \
 616  616          (_IPCL_V4_MATCH_ANY((connp)->conn_faddr_v6) ||                  \
 617  617          (_IPCL_V4_MATCH((connp)->conn_faddr_v6, (faddr)) &&             \
 618  618          (connp)->conn_fport == (fport)))))) &&                          \
 619  619          !(connp)->conn_ipv6_v6only)
 620  620  
 621  621  /*
 622  622   * We compare conn_laddr since it captures both connected and a bind to
 623  623   * a multicast or broadcast address.
 624  624   * The caller needs to match the zoneid and also call conn_wantpacket_v6
 625  625   * for multicast or when conn_incoming_ifindex is set.
 626  626   */
 627  627  #define IPCL_UDP_MATCH_V6(connp, lport, laddr, fport, faddr)    \
 628  628          (((connp)->conn_lport == (lport)) &&                    \
 629  629          (IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_laddr_v6) ||    \
 630  630          (IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, &(laddr)) &&       \
 631  631          (IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_faddr_v6) ||    \
 632  632          (IN6_ARE_ADDR_EQUAL(&(connp)->conn_faddr_v6, &(faddr)) &&       \
 633  633          (connp)->conn_fport == (fport))))))
 634  634  
 635  635  #define IPCL_IPTUN_HASH(laddr, faddr)                                   \
 636  636          ((ntohl(laddr) ^ ((ntohl(faddr) << 24) | (ntohl(faddr) >> 8))) % \
 637  637          ipcl_iptun_fanout_size)
 638  638  
 639  639  #define IPCL_IPTUN_HASH_V6(laddr, faddr)                                \
 640  640          IPCL_IPTUN_HASH((laddr)->s6_addr32[0] ^ (laddr)->s6_addr32[1] ^ \
 641  641              (faddr)->s6_addr32[2] ^ (faddr)->s6_addr32[3],              \
 642  642              (faddr)->s6_addr32[0] ^ (faddr)->s6_addr32[1] ^             \
 643  643              (laddr)->s6_addr32[2] ^ (laddr)->s6_addr32[3])
 644  644  
 645  645  #define IPCL_IPTUN_MATCH(connp, laddr, faddr)                   \
 646  646          (_IPCL_V4_MATCH((connp)->conn_laddr_v6, (laddr)) &&     \
 647  647          _IPCL_V4_MATCH((connp)->conn_faddr_v6, (faddr)))
 648  648  
 649  649  #define IPCL_IPTUN_MATCH_V6(connp, laddr, faddr)                \
 650  650          (IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, (laddr)) &&        \
 651  651          IN6_ARE_ADDR_EQUAL(&(connp)->conn_faddr_v6, (faddr)))
 652  652  
 653  653  #define IPCL_UDP_HASH(lport, ipst)      \
 654  654          IPCL_PORT_HASH(lport, (ipst)->ips_ipcl_udp_fanout_size)
 655  655  
 656  656  #define CONN_G_HASH_SIZE        1024
 657  657  
 658  658  /* Raw socket hash function. */
 659  659  #define IPCL_RAW_HASH(lport, ipst)      \
 660  660          IPCL_PORT_HASH(lport, (ipst)->ips_ipcl_raw_fanout_size)
 661  661  
 662  662  /*
 663  663   * This is similar to IPCL_BIND_MATCH except that the local port check
 664  664   * is changed to a wildcard port check.
 665  665   * We compare conn_laddr since it captures both connected and a bind to
 666  666   * a multicast or broadcast address.
 667  667   */
 668  668  #define IPCL_RAW_MATCH(connp, proto, laddr)                     \
 669  669          ((connp)->conn_proto == (proto) &&                      \
 670  670          (connp)->conn_lport == 0 &&                             \
 671  671          (_IPCL_V4_MATCH_ANY((connp)->conn_laddr_v6) ||          \
 672  672          _IPCL_V4_MATCH((connp)->conn_laddr_v6, (laddr))))
 673  673  
 674  674  #define IPCL_RAW_MATCH_V6(connp, proto, laddr)                  \
 675  675          ((connp)->conn_proto == (proto) &&                      \
 676  676          (connp)->conn_lport == 0 &&                             \
 677  677          (IN6_IS_ADDR_UNSPECIFIED(&(connp)->conn_laddr_v6) ||    \
 678  678          IN6_ARE_ADDR_EQUAL(&(connp)->conn_laddr_v6, &(laddr))))
 679  679  
 680  680  /* Function prototypes */
 681  681  extern void ipcl_g_init(void);
 682  682  extern void ipcl_init(ip_stack_t *);
 683  683  extern void ipcl_g_destroy(void);
 684  684  extern void ipcl_destroy(ip_stack_t *);
 685  685  extern conn_t *ipcl_conn_create(uint32_t, int, netstack_t *);
 686  686  extern void ipcl_conn_destroy(conn_t *);
 687  687  
 688  688  void ipcl_hash_insert_wildcard(connf_t *, conn_t *);
 689  689  void ipcl_hash_remove(conn_t *);
 690  690  void ipcl_hash_remove_locked(conn_t *connp, connf_t *connfp);
 691  691  
 692  692  extern int      ipcl_bind_insert(conn_t *);
 693  693  extern int      ipcl_bind_insert_v4(conn_t *);
 694  694  extern int      ipcl_bind_insert_v6(conn_t *);
 695  695  extern int      ipcl_conn_insert(conn_t *);
 696  696  extern int      ipcl_conn_insert_v4(conn_t *);
 697  697  extern int      ipcl_conn_insert_v6(conn_t *);
 698  698  extern conn_t   *ipcl_get_next_conn(connf_t *, conn_t *, uint32_t);
 699  699  
 700  700  conn_t *ipcl_classify_v4(mblk_t *, uint8_t, uint_t, ip_recv_attr_t *,
 701  701              ip_stack_t *);
 702  702  conn_t *ipcl_classify_v6(mblk_t *, uint8_t, uint_t, ip_recv_attr_t *,
 703  703              ip_stack_t *);
 704  704  conn_t *ipcl_classify(mblk_t *, ip_recv_attr_t *, ip_stack_t *);
 705  705  conn_t *ipcl_classify_raw(mblk_t *, uint8_t, uint32_t, ipha_t *,
 706  706      ip6_t *, ip_recv_attr_t *, ip_stack_t *);
 707  707  conn_t *ipcl_iptun_classify_v4(ipaddr_t *, ipaddr_t *, ip_stack_t *);
 708  708  conn_t *ipcl_iptun_classify_v6(in6_addr_t *, in6_addr_t *, ip_stack_t *);
 709  709  void    ipcl_globalhash_insert(conn_t *);
 710  710  void    ipcl_globalhash_remove(conn_t *);
 711  711  void    ipcl_walk(pfv_t, void *, ip_stack_t *);
 712  712  conn_t  *ipcl_tcp_lookup_reversed_ipv4(ipha_t *, tcpha_t *, int, ip_stack_t *);
 713  713  conn_t  *ipcl_tcp_lookup_reversed_ipv6(ip6_t *, tcpha_t *, int, uint_t,
 714  714              ip_stack_t *);
 715  715  conn_t  *ipcl_lookup_listener_v4(uint16_t, ipaddr_t, zoneid_t, ip_stack_t *);
 716  716  conn_t  *ipcl_lookup_listener_v6(uint16_t, in6_addr_t *, uint_t, zoneid_t,
 717  717              ip_stack_t *);
 718  718  int     conn_trace_ref(conn_t *);
 719  719  int     conn_untrace_ref(conn_t *);
 720  720  void    ipcl_conn_cleanup(conn_t *);
 721  721  extern uint_t   conn_recvancillary_size(conn_t *, crb_t, ip_recv_attr_t *,
 722  722      mblk_t *, ip_pkt_t *);
 723  723  extern void     conn_recvancillary_add(conn_t *, crb_t, ip_recv_attr_t *,
 724  724      ip_pkt_t *, uchar_t *, uint_t);
 725  725  conn_t *ipcl_conn_tcp_lookup_reversed_ipv4(conn_t *, ipha_t *, tcpha_t *,
 726  726              ip_stack_t *);
 727  727  conn_t *ipcl_conn_tcp_lookup_reversed_ipv6(conn_t *, ip6_t *, tcpha_t *,
 728  728              ip_stack_t *);
 729  729  
 730  730  extern int ip_create_helper_stream(conn_t *, ldi_ident_t);
 731  731  extern void ip_free_helper_stream(conn_t *);
 732  732  extern int      ip_helper_stream_setup(queue_t *, dev_t *, int, int,
 733  733      cred_t *, boolean_t);
 734  734  
 735  735  #ifdef  __cplusplus
 736  736  }
 737  737  #endif
 738  738  
 739  739  #endif  /* _INET_IPCLASSIFIER_H */
  
    | 
      ↓ open down ↓ | 
    739 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX