Print this page
Factor out fixed/1-1 processing from vxlnat_vxlan_one(), paving way for
future processing types.
Initial definitions of NAT flows.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/vxlnat/vxlnat_rules.c
          +++ new/usr/src/uts/common/inet/vxlnat/vxlnat_rules.c
↓ open down ↓ 88 lines elided ↑ open up ↑
  89   89  
  90   90          ret = memcmp(firstaddr, secondaddr, sizeof (in6_addr_t));
  91   91          if (ret > 0)
  92   92                  return (1);
  93   93          if (ret < 0)
  94   94                  return (-1);
  95   95          return (0);
  96   96  }
  97   97  
  98   98  /*
       99 + * Comparison function for NAT flow.
      100 + */
      101 +static int
      102 +vxlnat_flow_cmp_v4(const void *first, const void *second)
      103 +{
      104 +        vxlnat_flow_t *first_flow = (vxlnat_flow_t *)first;
      105 +        vxlnat_flow_t *second_flow = (vxlnat_flow_t *)second;
      106 +        uint64_t firstaddrs, secondaddrs, firstportproto, secondportproto;
      107 +
      108 +        firstaddrs = first_flow->vxnfl_src._S6_un._S6_u32[3] |
      109 +            (((uint64_t)first_flow->vxnfl_dst._S6_un._S6_u32[3]) << 32ULL);
      110 +        secondaddrs = second_flow->vxnfl_src._S6_un._S6_u32[3] |
      111 +            (((uint64_t)second_flow->vxnfl_dst._S6_un._S6_u32[3]) << 32ULL);
      112 +        firstportproto = first_flow->vxnfl_ports |
      113 +            (((uint64_t)first_flow->vxnfl_protocol) << 32ULL);
      114 +        secondportproto = second_flow->vxnfl_ports |
      115 +            (((uint64_t)second_flow->vxnfl_protocol) << 32ULL);
      116 +
      117 +        if (firstaddrs > secondaddrs)
      118 +                return (1);
      119 +        else if (firstaddrs < secondaddrs)
      120 +                return (-1);
      121 +        else if (firstportproto > secondportproto)
      122 +                return (1);
      123 +        else if (firstportproto < secondportproto)
      124 +                return (-1);
      125 +
      126 +        return (0);
      127 +}
      128 +
      129 +/*
  99  130   * Find-and-reference-hold a vnet.  If none present, create one.
 100  131   * "vnetid" MUST be in wire-order and its one byte cleared.
 101  132   */
 102  133  vxlnat_vnet_t *
 103  134  vxlnat_get_vnet(uint32_t vnetid, boolean_t create_on_miss)
 104  135  {
 105  136          vxlnat_vnet_t *vnet, searcher;
 106  137          avl_index_t where;
 107  138  
 108  139          /* Cheesy, but we KNOW vxnv_vnetid is the only thing checked. */
↓ open down ↓ 5 lines elided ↑ open up ↑
 114  145                  vnet = kmem_zalloc(sizeof (*vnet), KM_SLEEP);
 115  146                  /* KM_SLEEP means non-NULL guaranteed. */
 116  147                  vnet->vxnv_refcount = 1; /* Internment reference. */
 117  148                  vnet->vxnv_vnetid = vnetid;
 118  149                  /* Initialize 1-1 mappings... */
 119  150                  rw_init(&vnet->vxnv_fixed_lock, NULL, RW_DRIVER, NULL);
 120  151                  avl_create(&vnet->vxnv_fixed_ips, vxlnat_tree_plus_in6_cmp,
 121  152                      sizeof (vxlnat_fixed_t), 0);
 122  153                  /* Initialize NAT rules.  (NAT mutex is zeroed-out.) */
 123  154                  list_create(&vnet->vxnv_rules, sizeof (vxlnat_rule_t), 0);
 124      -#ifdef notyet
 125      -                /* XXX KEBE SAYS INITIALIZE NAT flows... */
 126      -#endif /* notyet */
      155 +
      156 +                /* Initialize NAT flows... */
      157 +                rw_init(&vnet->vxnv_flowv4_lock, NULL, RW_DRIVER, NULL);
      158 +                avl_create(&vnet->vxnv_flows_v4, vxlnat_flow_cmp_v4,
      159 +                    sizeof (vxlnat_flow_t), 0);
      160 +
 127  161                  /*
 128  162                   * Initialize remote VXLAN destination cache.
 129  163                   * (remotes mutex is zeroed-out.)
 130  164                   */
 131  165                  avl_create(&vnet->vxnv_remotes, vxlnat_tree_plus_in6_cmp,
 132  166                      sizeof (vxlnat_remote_t), 0);
 133  167  
 134  168                  avl_insert(&vxlnat_vnets, vnet, where);
 135  169          }
 136  170          if (vnet != NULL)
↓ open down ↓ 290 lines elided ↑ open up ↑
 427  461          rw_enter(&vnet->vxnv_fixed_lock, RW_WRITER);
 428  462          if (avl_find(&vnet->vxnv_fixed_ips, fixed, &where) != NULL) {
 429  463                  /* Oh crap, we have an internal IP mapped already. */
 430  464                  ire_refrele(ire);
 431  465                  kmem_free(fixed, sizeof (*fixed));
 432  466                  rc = EEXIST;
 433  467          } else {
 434  468                  avl_insert(&vnet->vxnv_fixed_ips, fixed, where);
 435  469                  rc = 0;
 436  470                  /*
 437      -                 * CHEESY USE OF POINTERS WARNING: I'm going to use
 438      -                 * ire_dep_children for this IRE_LOCAL as a backpointer to
      471 +                 * ODD USE OF POINTERS WARNING: I'm going to use
      472 +                 * ire_dep_sib_next for this IRE_LOCAL as a backpointer to
 439  473                   * this 'fixed'.  This'll allow rapid packet processing.
 440  474                   * Inspection seems to indicate that IRE_LOCAL ires NEVER use
 441  475                   * the ire_dep* pointers, so we'll use one (and independent of
 442  476                   * ip_stack_t's ips_ire_dep_lock as well).  If I'm wrong,
 443  477                   * fix it here and add a new pointer in ip.h for ire_t.
 444  478                   */
 445  479                  ire->ire_dep_sib_next = (ire_t *)fixed;
      480 +                VXNF_REFHOLD(fixed);    /* ire holds us too... */
      481 +                fixed->vxnf_ire = ire;
 446  482                  /* and then rewire the ire receive and send functions. */
 447  483                  if (ire->ire_ipversion == IPV4_VERSION) {
 448  484                          ire->ire_recvfn = vxlnat_fixed_ire_recv_v4;
 449  485                          ire->ire_sendfn = vxlnat_fixed_ire_send_v4;
 450  486                  } else {
 451  487                          ASSERT(ire->ire_ipversion == IPV6_VERSION);
 452  488                          ire->ire_recvfn = vxlnat_fixed_ire_recv_v6;
 453  489                          ire->ire_sendfn = vxlnat_fixed_ire_send_v6;
 454  490                  }
 455      -                VXNF_REFHOLD(fixed);    /* ire holds us too... */
 456      -                fixed->vxnf_ire = ire;
      491 +#if 1   /* Cheesy hack */
 457  492                  /*
 458  493                   * XXX KEBE SAYS CHEESY HACK:
 459  494                   */
 460  495                  if (!(ire->ire_ill->ill_flags & ILLF_ROUTER)) {
 461  496                          fixed->vxnf_clear_router = B_TRUE;
 462  497                          ire->ire_ill->ill_flags |= ILLF_ROUTER;
 463  498                  } else {
 464  499                          /* Just so we're clear... */
 465  500                          fixed->vxnf_clear_router = B_FALSE;
 466  501                  }
      502 +#endif  /* Cheesy hack */
 467  503          }
 468  504          rw_exit(&vnet->vxnv_fixed_lock);
 469  505  
 470  506  fail:
 471  507          if (rc != 0)
 472  508                  vxlnat_public_rele(&vxnm->vxnm_public);
 473  509  
 474  510          return (rc);
 475  511  }
 476  512  
↓ open down ↓ 214 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX