Print this page
    
Interpret sl3a_uport == 0 in SVP_R_VL3_ACK to indicate the VL3 IP is a
next-hop router.
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/varpd/svp/common/libvarpd_svp.h
          +++ new/usr/src/lib/varpd/svp/common/libvarpd_svp.h
   1    1  /*
   2    2   * This file and its contents are supplied under the terms of the
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2018 Joyent, Inc.
  14   14   */
  15   15  
  16   16  #ifndef _LIBVARPD_SVP_H
  17   17  #define _LIBVARPD_SVP_H
  18   18  
  19   19  /*
  20   20   * Implementation details of the SVP plugin and the SVP protocol.
  21   21   */
  22   22  
  23   23  #include <netinet/in.h>
  24   24  #include <sys/ethernet.h>
  25   25  #include <thread.h>
  26   26  #include <synch.h>
  27   27  #include <libvarpd_provider.h>
  28   28  #include <sys/avl.h>
  29   29  #include <port.h>
  30   30  #include <sys/list.h>
  31   31  #include <bunyan.h>
  32   32  
  33   33  #include <libvarpd_svp_prot.h>
  34   34  
  35   35  #ifdef __cplusplus
  36   36  extern "C" {
  37   37  #endif
  38   38  
  39   39  typedef struct svp svp_t;
  40   40  typedef struct svp_remote svp_remote_t;
  41   41  typedef struct svp_conn svp_conn_t;
  42   42  typedef struct svp_query svp_query_t;
  43   43  
  44   44  typedef void (*svp_event_f)(port_event_t *, void *);
  45   45  
  46   46  typedef struct svp_event {
  47   47          svp_event_f     se_func;
  48   48          void            *se_arg;
  49   49          int             se_events;
  50   50  } svp_event_t;
  51   51  
  52   52  typedef void (*svp_timer_f)(void *);
  53   53  
  54   54  typedef struct svp_timer {
  55   55          svp_timer_f     st_func;        /* Timer callback function */
  56   56          void            *st_arg;        /* Timer callback arg */
  57   57          boolean_t       st_oneshot;     /* Is timer a one shot? */
  58   58          uint32_t        st_value;       /* periodic or one-shot time */
  59   59          /* Fields below here are private to the svp_timer implementaiton */
  60   60          uint64_t        st_expire;      /* Next expiration */
  61   61          boolean_t       st_delivering;  /* Are we currently delivering this */
  62   62          avl_node_t      st_link;
  63   63  } svp_timer_t;
  64   64  
  65   65  /*
  66   66   * Note, both the svp_log_ack_t and svp_lrm_req_t are not part of this structure
  67   67   * as they are rather variable sized data and we don't want to constrain their
  68   68   * size. Instead, the rdata and wdata members must be set appropriately.
  69   69   */
  70   70  typedef union svp_query_data {
  71   71          svp_vl2_req_t   sqd_vl2r;
  72   72          svp_vl2_ack_t   sqd_vl2a;
  73   73          svp_vl3_req_t   sdq_vl3r;
  74   74          svp_vl3_ack_t   sdq_vl3a;
  75   75          svp_log_req_t   sdq_logr;
  76   76          svp_lrm_ack_t   sdq_lrma;
  77   77          svp_route_req_t sqd_rr;
  78   78          svp_route_ack_t sqd_ra;
  79   79  } svp_query_data_t;
  80   80  
  81   81  typedef void (*svp_query_f)(svp_query_t *, void *);
  82   82  
  83   83  typedef enum svp_query_state {
  84   84          SVP_QUERY_INIT          = 0x00,
  85   85          SVP_QUERY_WRITING       = 0x01,
  86   86          SVP_QUERY_READING       = 0x02,
  87   87          SVP_QUERY_FINISHED      = 0x03
  88   88  } svp_query_state_t;
  89   89  
  90   90  /*
  91   91   * The query structure is usable for all forms of svp queries that end up
  92   92   * getting passed across. Right now it's optimized for the fixed size data
  93   93   * requests as opposed to requests whose responses will always be streaming in
  94   94   * nature. Though, the streaming requests are the less common ones we have. We
  95   95   * may need to make additional changes for those.
  96   96   */
  97   97  struct svp_query {
  98   98          list_node_t             sq_lnode;       /* List entry */
  99   99          svp_query_f             sq_func;        /* Callback function */
 100  100          svp_query_state_t       sq_state;       /* Query state */
 101  101          void                    *sq_arg;        /* Callback function arg */
 102  102          svp_t                   *sq_svp;        /* Pointer back to svp_t */
 103  103          svp_req_t               sq_header;      /* Header for the query */
 104  104          svp_query_data_t        sq_rdun;        /* Union for read data */
 105  105          svp_query_data_t        sq_wdun;        /* Union for write data */
 106  106          svp_status_t            sq_status;      /* Query response status */
 107  107          size_t                  sq_size;        /* Query response size */
 108  108          void                    *sq_rdata;      /* Read data pointer */
 109  109          size_t                  sq_rsize;       /* Read data size */
 110  110          void                    *sq_wdata;      /* Write data pointer */
 111  111          size_t                  sq_wsize;       /* Write data size */
 112  112          hrtime_t                sq_acttime;     /* Last I/O activity time */
 113  113  };
 114  114  
 115  115  typedef enum svp_conn_state {
 116  116          SVP_CS_ERROR            = 0x00,
 117  117          SVP_CS_INITIAL          = 0x01,
 118  118          SVP_CS_CONNECTING       = 0x02,
 119  119          SVP_CS_BACKOFF          = 0x03,
 120  120          SVP_CS_ACTIVE           = 0x04,
 121  121          SVP_CS_WINDDOWN         = 0x05
 122  122  } svp_conn_state_t;
 123  123  
 124  124  typedef enum svp_conn_error {
 125  125          SVP_CE_NONE             = 0x00,
 126  126          SVP_CE_ASSOCIATE        = 0x01,
 127  127          SVP_CE_NOPOLLOUT        = 0x02,
 128  128          SVP_CE_SOCKET           = 0x03
 129  129  } svp_conn_error_t;
 130  130  
 131  131  typedef enum svp_conn_flags {
 132  132          SVP_CF_ADDED            = 0x01,
 133  133          SVP_CF_DEGRADED         = 0x02,
 134  134          SVP_CF_REAP             = 0x04,
 135  135          SVP_CF_TEARDOWN         = 0x08,
 136  136          SVP_CF_UFLAG            = 0x0c,
 137  137          SVP_CF_USER             = 0x10
 138  138  } svp_conn_flags_t;
 139  139  
 140  140  typedef struct svp_conn_out {
 141  141          svp_query_t             *sco_query;
 142  142          size_t                  sco_offset;
 143  143  } svp_conn_out_t;
 144  144  
 145  145  typedef struct svp_conn_in {
 146  146          svp_query_t             *sci_query;
 147  147          svp_req_t               sci_req;
 148  148          size_t                  sci_offset;
 149  149  } svp_conn_in_t;
 150  150  
 151  151  struct svp_conn {
 152  152          svp_remote_t            *sc_remote;     /* RO */
 153  153          struct in6_addr         sc_addr;        /* RO */
 154  154          list_node_t             sc_rlist;       /* svp_remote_t`sr_lock */
 155  155          mutex_t                 sc_lock;
 156  156          svp_event_t             sc_event;
 157  157          svp_timer_t             sc_btimer;
 158  158          svp_timer_t             sc_qtimer;
 159  159          int                     sc_socket;
 160  160          uint_t                  sc_gen;
 161  161          uint_t                  sc_nbackoff;
 162  162          svp_conn_flags_t        sc_flags;
 163  163          svp_conn_state_t        sc_cstate;
 164  164          svp_conn_error_t        sc_error;
 165  165          int                     sc_errno;
 166  166          list_t                  sc_queries;
 167  167          svp_conn_out_t          sc_output;
 168  168          svp_conn_in_t           sc_input;
 169  169  };
 170  170  
 171  171  typedef enum svp_remote_state {
 172  172          SVP_RS_LOOKUP_SCHEDULED         = 0x01, /* On the DNS Queue */
 173  173          SVP_RS_LOOKUP_INPROGRESS        = 0x02, /* Doing a DNS lookup */
 174  174          SVP_RS_LOOKUP_VALID             = 0x04  /* addrinfo valid */
 175  175  } svp_remote_state_t;
 176  176  
 177  177  /*
 178  178   * These series of bit-based flags should be ordered such that the most severe
 179  179   * is first. We only can set one message that user land can see, so if more than
 180  180   * one is set we want to make sure that one is there.
 181  181   */
 182  182  typedef enum svp_degrade_state {
 183  183          SVP_RD_DNS_FAIL         = 0x01, /* DNS Resolution Failure */
 184  184          SVP_RD_REMOTE_FAIL      = 0x02, /* cannot reach any remote peers */
 185  185          SVP_RD_ALL              = 0x03  /* Only suitable for restore */
 186  186  } svp_degrade_state_t;
 187  187  
 188  188  typedef enum svp_shootdown_flags {
 189  189          SVP_SD_RUNNING          = 0x01,
 190  190          SVP_SD_QUIESCE          = 0x02,
 191  191          SVP_SD_DORM             = 0x04
 192  192  } svp_shootdown_flags_t;
 193  193  
 194  194  /*
 195  195   * There is a single svp_sdlog_t per svp_remote_t. It maintains its own lock and
 196  196   * condition variables. See the big theory statement for more information on how
 197  197   * it's used.
 198  198   */
 199  199  typedef struct svp_sdlog {
 200  200          mutex_t                 sdl_lock;
 201  201          cond_t                  sdl_cond;
 202  202          uint_t                  sdl_ref;
 203  203          svp_timer_t             sdl_timer;
 204  204          svp_shootdown_flags_t   sdl_flags;
 205  205          svp_query_t             sdl_query;
 206  206          void                    *sdl_logack;
 207  207          void                    *sdl_logrm;
 208  208          void                    *sdl_remote;
 209  209  } svp_sdlog_t;
 210  210  
 211  211  struct svp_remote {
 212  212          char                    *sr_hostname;   /* RO */
 213  213          uint16_t                sr_rport;       /* RO */
 214  214          struct in6_addr         sr_uip;         /* RO */
 215  215          avl_node_t              sr_gnode;       /* svp_remote_lock */
 216  216          svp_remote_t            *sr_nexthost;   /* svp_host_lock */
 217  217          mutex_t                 sr_lock;
 218  218          cond_t                  sr_cond;
 219  219          svp_remote_state_t      sr_state;
 220  220          svp_degrade_state_t     sr_degrade;
 221  221          struct addrinfo         *sr_addrinfo;
 222  222          avl_tree_t              sr_tree;
 223  223          uint_t                  sr_count;       /* active count */
 224  224          uint_t                  sr_gen;
 225  225          uint_t                  sr_tconns;      /* total conns + dconns */
 226  226          uint_t                  sr_ndconns;     /* number of degraded conns */
 227  227          list_t                  sr_conns;       /* all conns */
 228  228          svp_sdlog_t             sr_shoot;
 229  229  };
 230  230  
 231  231  /*
 232  232   * We have a bunch of different things that we get back from the API at the
 233  233   * plug-in layer. These include:
 234  234   *
 235  235   *   o OOB Shootdowns
 236  236   *   o VL3->VL2 Lookups
 237  237   *   o VL2->UL3 Lookups
 238  238   *   o VL2 Log invalidations
 239  239   *   o VL3 Log injections
 240  240   */
 241  241  typedef void (*svp_vl2_lookup_f)(svp_t *, svp_status_t, const struct in6_addr *,
 242  242      const uint16_t, void *);
 243  243  typedef void (*svp_vl3_lookup_f)(svp_t *, svp_status_t, const uint8_t *,
 244  244      const struct in6_addr *, const uint16_t, void *);
 245  245  typedef void (*svp_vl2_invalidation_f)(svp_t *, const uint8_t *);
 246  246  typedef void (*svp_vl3_inject_f)(svp_t *, const uint16_t,
 247  247      const struct in6_addr *, const uint8_t *, const uint8_t *);
 248  248  typedef void (*svp_shootdown_f)(svp_t *, const uint8_t *,
 249  249      const struct in6_addr *, const uint16_t uport);
 250  250  typedef void (*svp_route_lookup_f)(svp_t *, svp_status_t, uint32_t, uint32_t,
 251  251      uint16_t, uint8_t *, uint8_t *, uint16_t, uint8_t *, uint8_t, uint8_t,
 252  252      void *);
 253  253  
 254  254  typedef struct svp_cb {
 255  255          svp_vl2_lookup_f        scb_vl2_lookup;
 256  256          svp_vl3_lookup_f        scb_vl3_lookup;
 257  257          svp_vl2_invalidation_f  scb_vl2_invalidate;
 258  258          svp_vl3_inject_f        scb_vl3_inject;
 259  259          svp_shootdown_f         scb_shootdown;
 260  260          svp_route_lookup_f      scb_route_lookup;
 261  261  } svp_cb_t;
 262  262  
 263  263  /*
 264  264   * Core implementation structure.
 265  265   */
 266  266  struct svp {
 267  267          overlay_plugin_dest_t   svp_dest;       /* RO */
 268  268          varpd_provider_handle_t *svp_hdl;       /* RO */
 269  269          svp_cb_t                svp_cb;         /* RO */
  
    | 
      ↓ open down ↓ | 
    269 lines elided | 
    
      ↑ open up ↑ | 
  
 270  270          uint64_t                svp_vid;        /* RO */
 271  271          avl_node_t              svp_rlink;      /* Owned by svp_remote */
 272  272          svp_remote_t            *svp_remote;    /* RO iff started */
 273  273          mutex_t                 svp_lock;
 274  274          char                    *svp_host;      /* svp_lock */
 275  275          uint16_t                svp_port;       /* svp_lock */
 276  276          uint16_t                svp_uport;      /* svp_lock */
 277  277          uint32_t                svp_dcid;       /* svp_lock (but write-once?) */
 278  278          boolean_t               svp_huip;       /* svp_lock */
 279  279          struct in6_addr         svp_uip;        /* svp_lock */
 280      -        struct ether_addr       svp_router_mac; /* svp_lock (but write-once?) */
      280 +        /* NOTE: lower-3 bytes are 0s. */
      281 +        uint8_t         svp_router_oui[6];      /* svp_lock (but write-once?) */
 281  282  };
 282  283  
 283  284  extern bunyan_logger_t *svp_bunyan;
 284  285  
 285  286  extern int svp_remote_find(char *, uint16_t, struct in6_addr *,
 286  287      svp_remote_t **);
 287  288  extern int svp_remote_attach(svp_remote_t *, svp_t *);
 288  289  extern void svp_remote_detach(svp_t *);
 289  290  extern void svp_remote_release(svp_remote_t *);
 290  291  extern void svp_remote_vl3_lookup(svp_t *, svp_query_t *,
 291  292      const struct sockaddr *, void *);
 292  293  extern void svp_remote_vl2_lookup(svp_t *, svp_query_t *, const uint8_t *,
 293  294      void *);
 294  295  extern void svp_remote_route_lookup(svp_t *, svp_query_t *,
 295  296      const struct in6_addr *, const struct in6_addr *, uint32_t,
 296  297      uint16_t, void *);
 297  298  
 298  299  
 299  300  /*
 300  301   * Init functions
 301  302   */
 302  303  extern int svp_remote_init(void);
 303  304  extern void svp_remote_fini(void);
 304  305  extern int svp_event_init(void);
 305  306  extern int svp_event_timer_init(svp_event_t *);
 306  307  extern void svp_event_fini(void);
 307  308  extern int svp_host_init(void);
 308  309  extern int svp_timer_init(void);
 309  310  
 310  311  /*
 311  312   * Timers
 312  313   */
 313  314  extern int svp_tickrate;
 314  315  extern void svp_timer_add(svp_timer_t *);
 315  316  extern void svp_timer_remove(svp_timer_t *);
 316  317  
 317  318  /*
 318  319   * Event loop management
 319  320   */
 320  321  extern int svp_event_associate(svp_event_t *, int);
 321  322  extern int svp_event_dissociate(svp_event_t *, int);
 322  323  extern int svp_event_inject(svp_event_t *);
 323  324  
 324  325  /*
 325  326   * Connection manager
 326  327   */
 327  328  extern int svp_conn_create(svp_remote_t *, const struct in6_addr *);
 328  329  extern void svp_conn_destroy(svp_conn_t *);
 329  330  extern void svp_conn_fallout(svp_conn_t *);
 330  331  extern void svp_conn_queue(svp_conn_t *, svp_query_t *);
 331  332  
 332  333  /*
 333  334   * FMA related
 334  335   */
 335  336  extern void svp_remote_degrade(svp_remote_t *, svp_degrade_state_t);
 336  337  extern void svp_remote_restore(svp_remote_t *, svp_degrade_state_t);
 337  338  
 338  339  /*
 339  340   * Misc.
 340  341   */
 341  342  extern int svp_comparator(const void *, const void *);
 342  343  extern void svp_remote_reassign(svp_remote_t *, svp_conn_t *);
 343  344  extern void svp_remote_resolved(svp_remote_t *, struct addrinfo *);
 344  345  extern void svp_host_queue(svp_remote_t *);
 345  346  extern void svp_query_release(svp_query_t *);
 346  347  extern void svp_query_crc32(svp_req_t *, void *, size_t);
 347  348  
 348  349  /*
 349  350   * Shootdown related
 350  351   */
 351  352  extern void svp_remote_shootdown_vl3(svp_remote_t *, svp_log_vl3_t *,
 352  353      svp_sdlog_t *);
 353  354  extern void svp_remote_shootdown_vl2(svp_remote_t *, svp_log_vl2_t *);
 354  355  extern void svp_remote_log_request(svp_remote_t *, svp_query_t *, void *,
 355  356      size_t);
 356  357  extern void svp_remote_lrm_request(svp_remote_t *, svp_query_t *, void *,
 357  358      size_t);
 358  359  extern void svp_shootdown_logr_cb(svp_remote_t *, svp_status_t, void *, size_t);
 359  360  extern void svp_shootdown_lrm_cb(svp_remote_t *, svp_status_t);
 360  361  extern void svp_shootdown_vl3_cb(svp_status_t, svp_log_vl3_t *, svp_sdlog_t *);
 361  362  extern int svp_shootdown_init(svp_remote_t *);
 362  363  extern void svp_shootdown_fini(svp_remote_t *);
 363  364  extern void svp_shootdown_start(svp_remote_t *);
 364  365  
 365  366  #ifdef __cplusplus
 366  367  }
 367  368  #endif
 368  369  
 369  370  #endif /* _LIBVARPD_SVP_H */
  
    | 
      ↓ open down ↓ | 
    79 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX