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_nat.c
          +++ new/usr/src/uts/common/inet/vxlnat/vxlnat_nat.c
↓ open down ↓ 341 lines elided ↑ open up ↑
 342  342  
 343  343          /* We're done with the remote entry now. */
 344  344          VXNREM_REFRELE(remote);
 345  345  
 346  346          /* Advance rptr to the inner IP header and proceed. */
 347  347          mp->b_rptr = (uint8_t *)ipha;
 348  348          return (mp);
 349  349  }
 350  350  
 351  351  /*
      352 + * See if the inbound VXLAN packet hits a 1-1/fixed mapping, and process if it
      353 + * does.  B_TRUE means the packet was handled, and we shouldn't continue
      354 + * processing (even if "was handled" means droppage).
      355 + */
      356 +static boolean_t
      357 +vxlnat_one_vxlan_fixed(vxlnat_vnet_t *vnet, mblk_t *mp, ipha_t *ipha,
      358 +    ip6_t *ip6h)
      359 +{
      360 +        vxlnat_fixed_t *fixed, fsearch;
      361 +        mblk_t *newmp;
      362 +        ire_t *outbound_ire;
      363 +        /* Use C99's initializers for fun & profit. */
      364 +        ip_recv_attr_t iras = { IRAF_IS_IPV4 | IRAF_VERIFIED_SRC };
      365 +
      366 +        if (ipha != NULL) {
      367 +                IN6_INADDR_TO_V4MAPPED((struct in_addr *)(&ipha->ipha_src),
      368 +                    &fsearch.vxnf_addr);
      369 +        } else {
      370 +                /* vxlnat_cache_remote() did reality checks... */
      371 +                ASSERT(ipha == NULL && ip6h != NULL);
      372 +                fsearch.vxnf_addr = ip6h->ip6_src;
      373 +        }
      374 +
      375 +        rw_enter(&vnet->vxnv_fixed_lock, RW_READER);
      376 +        fixed = avl_find(&vnet->vxnv_fixed_ips, &fsearch, NULL);
      377 +        if (fixed != NULL)
      378 +                VXNF_REFHOLD(fixed);
      379 +        rw_exit(&vnet->vxnv_fixed_lock);
      380 +        if (fixed == NULL)
      381 +                return (B_FALSE);       /* Try another method of processing. */
      382 +
      383 +        newmp = NULL;
      384 +        /*
      385 +         * XXX KEBE ASKS --> Do an MTU check NOW?!  That way, we have
      386 +         * pre-natted data.  One gotcha, external dests may have
      387 +         * different PathMTUs so see below about EMSGSIZE...
      388 +         *
      389 +         * For now, let the post-NAT crunch through
      390 +         * ire_recv_forward_v4() take care of all of that.
      391 +         */
      392 +
      393 +        if (ipha != NULL)
      394 +                newmp = vxlnat_fixed_fixv4(mp, fixed, B_FALSE);
      395 +        else {
      396 +                freemsg(mp); /* XXX handle ip6h */
      397 +                return (B_TRUE);
      398 +        }
      399 +
      400 +        if (newmp == NULL)
      401 +                return (B_TRUE);        /* mp eaten by vxlnat_fixed_fixv4() */
      402 +
      403 +
      404 +        ASSERT3P(ipha, ==, newmp->b_rptr);
      405 +        /* XXX KEBE ASKS, IRR_ALLOCATE okay?!? */
      406 +        /* XXX KEBE SAYS XMIT HINT! */
      407 +        outbound_ire = ire_route_recursive_dstonly_v4(ipha->ipha_dst,
      408 +            IRR_ALLOCATE, 0, vxlnat_netstack->netstack_ip);
      409 +        VERIFY3P(outbound_ire, !=, NULL);
      410 +        if (outbound_ire->ire_type == IRE_NOROUTE) {
      411 +                /* Bail! */
      412 +                DTRACE_PROBE2(vxlnat__in__drop__fixedire, ipaddr_t,
      413 +                    ipha->ipha_dst, mblk_t *, mp);
      414 +                VXNF_REFRELE(fixed);
      415 +                freemsg(mp);
      416 +                return (B_TRUE);
      417 +        }
      418 +
      419 +        iras.ira_ip_hdr_length = IPH_HDR_LENGTH(ipha);
      420 +        if (iras.ira_ip_hdr_length > sizeof (ipha_t))
      421 +                iras.ira_flags |= IRAF_IPV4_OPTIONS;
      422 +        iras.ira_xmit_hint = 0; /* XXX KEBE SAYS FIX ME! */
      423 +        iras.ira_zoneid = outbound_ire->ire_zoneid;
      424 +        iras.ira_pktlen = ntohs(ipha->ipha_length);
      425 +        iras.ira_protocol = ipha->ipha_protocol;
      426 +        /* XXX KEBE ASKS rifindex & ruifindex ?!? */
      427 +        /*
      428 +         * NOTE: AT LEAST ira_ill needs ILLF_ROUTER set, as
      429 +         * well as the ill for the external NIC (where
      430 +         * off-link destinations live).  For fixed, ira_ill
      431 +         * should be the ill of the external source.
      432 +         */
      433 +        iras.ira_rill = vxlnat_underlay_ire->ire_ill;
      434 +        iras.ira_ill = fixed->vxnf_ire->ire_ill;
      435 +        /* XXX KEBE ASKS cred & cpid ? */
      436 +        iras.ira_verified_src = ipha->ipha_src;
      437 +        /* XXX KEBE SAYS don't sweat IPsec stuff. */
      438 +        /* XXX KEBE SAYS ALSO don't sweat l2src & mhip */
      439 +
      440 +        /* Okay, we're good! Let's pretend we're forwarding. */
      441 +        ire_recv_forward_v4(outbound_ire, mp, ipha, &iras);
      442 +        ire_refrele(outbound_ire);
      443 +
      444 +        return (B_TRUE);
      445 +}
      446 +
      447 +/*
 352  448   * Process exactly one VXLAN packet.
 353  449   */
 354  450  static void
 355  451  vxlnat_one_vxlan(mblk_t *mp, struct sockaddr_in6 *underlay_src)
 356  452  {
 357  453          vxlan_hdr_t *vxh;
 358  454          vxlnat_vnet_t *vnet;
 359  455          ipha_t *ipha;
 360  456          ip6_t *ip6h;
 361      -        vxlnat_fixed_t *fixed, fsearch;
 362  457  
 363  458          if (MBLKL(mp) < sizeof (*vxh)) {
 364  459                  /* XXX KEBE ASKS -- should we be more forgiving? */
 365  460                  DTRACE_PROBE1(vxlnat__in__drop__vxlsize, mblk_t *, mp);
 366  461                  freemsg(mp);
 367  462                  return;
 368  463          }
 369  464          vxh = (vxlan_hdr_t *)mp->b_rptr;
 370  465  
 371  466          /* If we start using more than just the one flag, fix it. */
↓ open down ↓ 27 lines elided ↑ open up ↑
 399  494  
 400  495          /* 1.) Locate the ethernet header and check/update/add-into remotes. */
 401  496          mp->b_rptr += sizeof (*vxh);
 402  497          while (MBLKL(mp) == 0) {
 403  498                  mblk_t *oldmp = mp;
 404  499  
 405  500                  mp = mp->b_cont;
 406  501                  freeb(oldmp);
 407  502          }
 408  503          mp = vxlnat_cache_remote(mp, underlay_src, vnet);
 409      -        if (mp == NULL) {
 410      -                VXNV_REFRELE(vnet);
 411      -                return;
 412      -        }
      504 +        if (mp == NULL)
      505 +                goto bail_no_free;
 413  506  
 414      -        /* 2.) Search 1-1s, process if hit. */
      507 +        /* Let's cache the IP header here... */
 415  508          ipha = (ipha_t *)mp->b_rptr;
 416      -        if (IPH_HDR_VERSION(ipha) == IPV4_VERSION) {
      509 +        switch (IPH_HDR_VERSION(ipha)) {
      510 +        case IPV4_VERSION:
 417  511                  ip6h = NULL;
 418      -                IN6_INADDR_TO_V4MAPPED((struct in_addr *)(&ipha->ipha_src),
 419      -                    &fsearch.vxnf_addr);
 420      -        } else {
 421      -                /* vxlnat_cache_remote() did reality checks... */
 422      -                ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
      512 +                break;
      513 +        case IPV6_VERSION:
 423  514                  ip6h = (ip6_t *)ipha;
 424  515                  ipha = NULL;
 425      -                fsearch.vxnf_addr = ip6h->ip6_src;
      516 +                break;
      517 +        default:
      518 +                DTRACE_PROBE2(vxlnat__in__drop__ipvers, int,
      519 +                    IPH_HDR_VERSION(ipha), mblk_t *, mp);
      520 +                goto bail_and_free;
 426  521          }
 427      -        rw_enter(&vnet->vxnv_fixed_lock, RW_READER);
 428      -        fixed = avl_find(&vnet->vxnv_fixed_ips, &fsearch, NULL);
 429      -        if (fixed != NULL)
 430      -                VXNF_REFHOLD(fixed);
 431      -        rw_exit(&vnet->vxnv_fixed_lock);
 432      -        if (fixed != NULL) {
 433      -                mblk_t *newmp = NULL;
 434  522  
 435      -                /*
 436      -                 * XXX KEBE ASKS --> Do MTU check NOW?!  That way, we have
 437      -                 * pre-natted data.  One gotcha, external dests may have
 438      -                 * different PathMTUs so see below about EMSGSIZE...
 439      -                 */
      523 +        /* 2.) Search 1-1s, process if hit. */
      524 +        if (vxlnat_one_vxlan_fixed(vnet, mp, ipha, ip6h))
      525 +                goto bail_no_free;      /* Success means mp was consumed. */
 440  526  
 441      -                /* XXX KEBE SAYS -- FILL ME IN... but for now: */
 442      -                if (ipha != NULL)
 443      -                        newmp = vxlnat_fixed_fixv4(mp, fixed, B_FALSE);
 444      -                else
 445      -                        freemsg(mp); /* XXX handle ip6h */
      527 +#ifdef notyet
      528 +        /* 3.) Search flows, process if hit. */
      529 +        if (vxlnat_one_vxlan_flow(vnet, mp, ipha, ip6h))
      530 +                goto bail_no_free;      /* Success means mp was consumed. */
 446  531  
 447      -                if (newmp != NULL) {
 448      -                        ire_t *outbound_ire;
 449      -                        /* Use C99's initializers for fun & profit. */
 450      -                        ip_recv_attr_t iras =
 451      -                            { IRAF_IS_IPV4 | IRAF_VERIFIED_SRC };
      532 +        /* 4.) Search rules, create new flow (or not) if hit. */
      533 +        if (vxlnat_one_vxlan_rule(vnet, mp, ipha, ip6h))
      534 +                goto bail_no_free;      /* Success means mp was consumed. */
      535 +#endif
 452  536  
 453      -                        ASSERT3P(ipha, !=, NULL);
 454      -                        ASSERT3P(ipha, ==, newmp->b_rptr);
 455      -                        /* XXX KEBE ASKS, IRR_ALLOCATE okay?!? */
 456      -                        outbound_ire = ire_route_recursive_dstonly_v4(
 457      -                            ipha->ipha_dst, IRR_ALLOCATE,
 458      -                            0 /* XXX KEBE SAYS XMIT HINT! */,
 459      -                            vxlnat_netstack->netstack_ip);
 460      -                        VERIFY3P(outbound_ire, !=, NULL);
 461      -                        if (outbound_ire->ire_type == IRE_NOROUTE) {
 462      -                                /* Bail! */
 463      -                                VXNF_REFRELE(fixed);
 464      -                                VXNV_REFRELE(vnet);
 465      -                                return;
 466      -                        }
      537 +        /* 5.) Nothing, drop the packet. */
 467  538  
 468      -                        iras.ira_ip_hdr_length = IPH_HDR_LENGTH(ipha);
 469      -                        if (iras.ira_ip_hdr_length > sizeof (ipha_t))
 470      -                                iras.ira_flags |= IRAF_IPV4_OPTIONS;
 471      -                        iras.ira_xmit_hint = 0; /* XXX KEBE SAYS FIX ME! */
 472      -                        iras.ira_zoneid = outbound_ire->ire_zoneid;
 473      -                        iras.ira_pktlen = ntohs(ipha->ipha_length);
 474      -                        iras.ira_protocol = ipha->ipha_protocol;
 475      -                        /* XXX KEBE ASKS rifindex & ruifindex ?!? */
 476      -                        /*
 477      -                         * NOTE: AT LEAST ira_ill needs ILLF_ROUTER set, as
 478      -                         * well as the ill for the external NIC (where
 479      -                         * off-link destinations live).  For fixed, ira_ill
 480      -                         * should be the ill of the external source.
 481      -                         */
 482      -                        iras.ira_rill = vxlnat_underlay_ire->ire_ill;
 483      -                        iras.ira_ill = fixed->vxnf_ire->ire_ill;
 484      -                        /* XXX KEBE ASKS cred & cpid ? */
 485      -                        iras.ira_verified_src = ipha->ipha_src;
 486      -                        /* XXX KEBE SAYS don't sweat IPsec stuff. */
 487      -                        /* XXX KEBE SAYS ALSO don't sweat l2src & mhip */
      539 +        DTRACE_PROBE2(vxlnat__in___drop__nohits, vxlnat_vnet_t *, vnet,
      540 +            mblk_t *, mp);
 488  541  
 489      -                        /* Okay, we're good! Let's pretend we're forwarding. */
 490      -                        ire_recv_forward_v4(outbound_ire, mp, ipha, &iras);
 491      -                        ire_refrele(outbound_ire);
 492      -                }
 493      -
 494      -                /* All done... */
 495      -                VXNF_REFRELE(fixed);
 496      -                VXNV_REFRELE(vnet);
 497      -                return;
 498      -        }
 499      -
 500      -        /* XXX KEBE SAYS BUILD STEPS 3-4. */
 501      -
 502      -        /* 5.) Nothing, drop the packet. */
 503      -        /* XXX KEBE ASKS DIAGNOSTIC? */
 504      -        VXNV_REFRELE(vnet);
      542 +bail_and_free:
 505  543          freemsg(mp);
      544 +bail_no_free:
      545 +        VXNV_REFRELE(vnet);
 506  546  }
 507  547  /*
 508  548   * ONLY return B_FALSE if we get a packet-clogging event.
 509  549   */
 510  550  /* ARGSUSED */
 511  551  static boolean_t
 512  552  vxlnat_vxlan_input(ksocket_t insock, mblk_t *chain, size_t msgsize, int oob,
 513  553      void *ignored)
 514  554  {
 515  555          mblk_t *mp, *nextmp;
↓ open down ↓ 115 lines elided ↑ open up ↑
 631  671          /*
 632  672           * XXX KEBE ASKS, recompute *inner-packet* checksums?  Let's not for
 633  673           * now, but consider this Fair Warning (or some other VH album...).
 634  674           */
 635  675          return (mp);
 636  676  }
 637  677  
 638  678  /*
 639  679   * Take a 1-1/fixed IPv4 packet and convert it for transmission out the
 640  680   * appropriate end. "to_private" is what it says on the tin.
      681 + * ALWAYS consumes "mp", regardless of return value.
 641  682   */
 642  683  static mblk_t *
 643  684  vxlnat_fixed_fixv4(mblk_t *mp, vxlnat_fixed_t *fixed, boolean_t to_private)
 644  685  {
 645  686          ipaddr_t new_one, old_one;
 646  687          ipaddr_t *new_ones_place;
 647  688          ipha_t *ipha = (ipha_t *)mp->b_rptr;
 648  689          uint8_t *nexthdr, *end_wptr;
 649  690  
 650  691          if (to_private) {
↓ open down ↓ 377 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX