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

@@ -94,10 +94,41 @@
                 return (-1);
         return (0);
 }
 
 /*
+ * Comparison function for NAT flow.
+ */
+static int
+vxlnat_flow_cmp_v4(const void *first, const void *second)
+{
+        vxlnat_flow_t *first_flow = (vxlnat_flow_t *)first;
+        vxlnat_flow_t *second_flow = (vxlnat_flow_t *)second;
+        uint64_t firstaddrs, secondaddrs, firstportproto, secondportproto;
+
+        firstaddrs = first_flow->vxnfl_src._S6_un._S6_u32[3] |
+            (((uint64_t)first_flow->vxnfl_dst._S6_un._S6_u32[3]) << 32ULL);
+        secondaddrs = second_flow->vxnfl_src._S6_un._S6_u32[3] |
+            (((uint64_t)second_flow->vxnfl_dst._S6_un._S6_u32[3]) << 32ULL);
+        firstportproto = first_flow->vxnfl_ports |
+            (((uint64_t)first_flow->vxnfl_protocol) << 32ULL);
+        secondportproto = second_flow->vxnfl_ports |
+            (((uint64_t)second_flow->vxnfl_protocol) << 32ULL);
+
+        if (firstaddrs > secondaddrs)
+                return (1);
+        else if (firstaddrs < secondaddrs)
+                return (-1);
+        else if (firstportproto > secondportproto)
+                return (1);
+        else if (firstportproto < secondportproto)
+                return (-1);
+
+        return (0);
+}
+
+/*
  * Find-and-reference-hold a vnet.  If none present, create one.
  * "vnetid" MUST be in wire-order and its one byte cleared.
  */
 vxlnat_vnet_t *
 vxlnat_get_vnet(uint32_t vnetid, boolean_t create_on_miss)

@@ -119,13 +150,16 @@
                 rw_init(&vnet->vxnv_fixed_lock, NULL, RW_DRIVER, NULL);
                 avl_create(&vnet->vxnv_fixed_ips, vxlnat_tree_plus_in6_cmp,
                     sizeof (vxlnat_fixed_t), 0);
                 /* Initialize NAT rules.  (NAT mutex is zeroed-out.) */
                 list_create(&vnet->vxnv_rules, sizeof (vxlnat_rule_t), 0);
-#ifdef notyet
-                /* XXX KEBE SAYS INITIALIZE NAT flows... */
-#endif /* notyet */
+
+                /* Initialize NAT flows... */
+                rw_init(&vnet->vxnv_flowv4_lock, NULL, RW_DRIVER, NULL);
+                avl_create(&vnet->vxnv_flows_v4, vxlnat_flow_cmp_v4,
+                    sizeof (vxlnat_flow_t), 0);
+
                 /*
                  * Initialize remote VXLAN destination cache.
                  * (remotes mutex is zeroed-out.)
                  */
                 avl_create(&vnet->vxnv_remotes, vxlnat_tree_plus_in6_cmp,

@@ -432,30 +466,31 @@
                 rc = EEXIST;
         } else {
                 avl_insert(&vnet->vxnv_fixed_ips, fixed, where);
                 rc = 0;
                 /*
-                 * CHEESY USE OF POINTERS WARNING: I'm going to use
-                 * ire_dep_children for this IRE_LOCAL as a backpointer to
+                 * ODD USE OF POINTERS WARNING: I'm going to use
+                 * ire_dep_sib_next for this IRE_LOCAL as a backpointer to
                  * this 'fixed'.  This'll allow rapid packet processing.
                  * Inspection seems to indicate that IRE_LOCAL ires NEVER use
                  * the ire_dep* pointers, so we'll use one (and independent of
                  * ip_stack_t's ips_ire_dep_lock as well).  If I'm wrong,
                  * fix it here and add a new pointer in ip.h for ire_t.
                  */
                 ire->ire_dep_sib_next = (ire_t *)fixed;
+                VXNF_REFHOLD(fixed);    /* ire holds us too... */
+                fixed->vxnf_ire = ire;
                 /* and then rewire the ire receive and send functions. */
                 if (ire->ire_ipversion == IPV4_VERSION) {
                         ire->ire_recvfn = vxlnat_fixed_ire_recv_v4;
                         ire->ire_sendfn = vxlnat_fixed_ire_send_v4;
                 } else {
                         ASSERT(ire->ire_ipversion == IPV6_VERSION);
                         ire->ire_recvfn = vxlnat_fixed_ire_recv_v6;
                         ire->ire_sendfn = vxlnat_fixed_ire_send_v6;
                 }
-                VXNF_REFHOLD(fixed);    /* ire holds us too... */
-                fixed->vxnf_ire = ire;
+#if 1   /* Cheesy hack */
                 /*
                  * XXX KEBE SAYS CHEESY HACK:
                  */
                 if (!(ire->ire_ill->ill_flags & ILLF_ROUTER)) {
                         fixed->vxnf_clear_router = B_TRUE;

@@ -462,10 +497,11 @@
                         ire->ire_ill->ill_flags |= ILLF_ROUTER;
                 } else {
                         /* Just so we're clear... */
                         fixed->vxnf_clear_router = B_FALSE;
                 }
+#endif  /* Cheesy hack */
         }
         rw_exit(&vnet->vxnv_fixed_lock);
 
 fail:
         if (rc != 0)