Print this page
Re-enable commented-out lxinit code, as a prelude to
enabling zonecfg(1M)-property networking configuration for LX.


 170                 lxi_err("internal libzonecfg.so.1 error", 0);
 171 
 172         if ((res = zonecfg_get_handle(zonename, handle)) != Z_OK) {
 173                 zonecfg_fini_handle(handle);
 174                 lxi_err("could not locate zone config %d", res);
 175         }
 176 
 177         /*
 178          * Only exclusive stack is supported.
 179          */
 180         if (zonecfg_get_iptype(handle, &iptype) != Z_OK ||
 181             iptype != ZS_EXCLUSIVE) {
 182                 zonecfg_fini_handle(handle);
 183                 lxi_err("lx zones do not support shared IP stacks");
 184         }
 185 
 186         return (handle);
 187 
 188 }
 189 
 190 #if 0 /* XXX KEBE SAYS NOT YET */
 191 static int
 192 zone_find_attr(struct zone_res_attrtab *attrs, const char *name,
 193     const char **result)
 194 {
 195         while (attrs != NULL) {
 196                 if (strncmp(attrs->zone_res_attr_name, name,
 197                     MAXNAMELEN) == 0) {
 198                         *result = attrs->zone_res_attr_value;
 199                         return (0);
 200                 }
 201                 attrs = attrs->zone_res_attr_next;
 202         }
 203         return (-1);
 204 }
 205 #endif /* XXX KEBE SAYS NOT YET */
 206 
 207 static void
 208 lxi_svc_start(char *name, char *path, char *fmri)
 209 {
 210         pid_t pid;
 211         int status;
 212         char *argv[] = {
 213                 NULL,
 214                 NULL
 215         };
 216         char *envp[] = {
 217                 NULL,
 218                 NULL
 219         };
 220         argv[0] = name;
 221         envp[0] = fmri;
 222 
 223         pid = fork();
 224         if (pid == -1) {
 225                 lxi_err("fork() failed: %s", strerror(errno));


 390                 goto done;
 391         }
 392 
 393         if ((status = ipadm_create_addr(iph, ipaddr,
 394             IPADM_OPT_ACTIVE | IPADM_OPT_UP)) != IPADM_SUCCESS) {
 395                 lxi_warn("ipadm_create_addr error for %s: %s\n", iface,
 396                     ipadm_status2str(status));
 397                 err = -4;
 398                 goto done;
 399         }
 400 
 401         if (af == AF_INET) {
 402                 *first_ipv4_configured = B_TRUE;
 403         }
 404 
 405 done:
 406         ipadm_destroy_addrobj(ipaddr);
 407         return (err);
 408 }
 409 
 410 #if 0 /* XXX KEBE SAYS NOT YET */
 411 static int
 412 lxi_iface_dhcp(const char *origiface, boolean_t *first_ipv4_configured)
 413 {
 414         dhcp_ipc_request_t *dhcpreq = NULL;
 415         dhcp_ipc_reply_t *dhcpreply = NULL;
 416         int err = 0, timeout = 5;
 417         char iface[LIFNAMSIZ];
 418 
 419         (void) strncpy(iface, origiface, sizeof (iface));
 420 
 421         if (lxi_getif(AF_INET, iface, sizeof (iface), *first_ipv4_configured)
 422             != 0) {
 423                 lxi_warn("failed to create new logical interface "
 424                     "on %s: %s", origiface, strerror(errno));
 425                 return (-1);
 426         }
 427 
 428         if (dhcp_start_agent(timeout) != 0) {
 429                 lxi_err("Failed to start dhcpagent\n");
 430                 /* NOTREACHED */


 442         if (err != 0) {
 443                 free(dhcpreq);
 444                 lxi_warn("Failed to start DHCP on %s: %s\n", iface,
 445                     dhcp_ipc_strerror(err));
 446                 return (-1);
 447         }
 448         err = dhcpreply->return_code;
 449         if (err != 0) {
 450                 lxi_warn("Failed to start DHCP on %s: %s\n", iface,
 451                     dhcp_ipc_strerror(err));
 452                 goto done;
 453         }
 454 
 455         *first_ipv4_configured = B_TRUE;
 456 
 457 done:
 458         free(dhcpreq);
 459         free(dhcpreply);
 460         return (err);
 461 }
 462 #endif /* XXX KEBE SAYS NOT YET */
 463 
 464 /*
 465  * Initialize an IPv6 link-local address on a given interface
 466  */
 467 static int
 468 lxi_iface_ipv6_link_local(const char *iface)
 469 {
 470         struct lifreq lifr;
 471         int s;
 472 
 473         s = socket(AF_INET6, SOCK_DGRAM, 0);
 474         if (s == -1) {
 475                 lxi_warn("socket error %d: bringing up %s: %s",
 476                     errno, iface, strerror(errno));
 477         }
 478 
 479         (void) strncpy(lifr.lifr_name, iface, sizeof (lifr.lifr_name));
 480         if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
 481                 lxi_warn("SIOCGLIFFLAGS error %d: bringing up %s: %s",
 482                     errno, iface, strerror(errno));


 560                 lxi_warn("write() rtmsg incomplete");
 561                 (void) close(sockfd);
 562                 return (-1);
 563         }
 564 
 565         (void) close(sockfd);
 566         return (0);
 567 }
 568 
 569 static void
 570 lxi_net_loopback()
 571 {
 572         const char *iface = "lo0";
 573         boolean_t first_ipv4_configured = B_FALSE;
 574 
 575         lxi_net_plumb(iface);
 576         (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
 577         (void) lxi_iface_ipv6_link_local(iface);
 578 }
 579 
 580 
 581 
 582 #if 0 /* XXX KEBE SAYS NOT YET */
 583 /*
 584  * This function is used when the "ips" property doesn't exist in a zone's
 585  * configuration. It may be an older configuration, so we should search for
 586  * "ip" and "netmask" and convert them into the new format.
 587  */
 588 static int
 589 lxi_get_old_ip(struct zone_res_attrtab *attrs, const char **ipaddrs,
 590     char *cidraddr, int len)
 591 {
 592 
 593         const char *netmask;
 594         int prefixlen;
 595         struct sockaddr_in mask_sin;
 596 
 597         lxi_warn("Could not find \"ips\" property for zone. Looking "
 598             "for older \"ip\" and \"netmask\" properties, instead.");
 599 
 600         if (zone_find_attr(attrs, "ip", ipaddrs) != 0) {
 601                 return (-1);
 602         }
 603 
 604         if (strcmp(*ipaddrs, "dhcp") == 0) {
 605                 return (0);
 606         }
 607 
 608         if (zone_find_attr(attrs, "netmask", &netmask) != 0) {
 609                 lxi_err("could not find netmask for interface");
 610                 /* NOTREACHED */
 611         }
 612 
 613         /* Convert the netmask to a number */
 614         mask_sin.sin_family = AF_INET;
 615         if (inet_pton(AF_INET, netmask, &mask_sin.sin_addr) != 1) {
 616                 lxi_err("invalid netmask address: %s\n",
 617                     strerror(errno));
 618                 /* NOTREACHED */
 619         }
 620         prefixlen = mask2plen((struct sockaddr *)&mask_sin);
 621 
 622         /*
 623          * Write out the IP address in the new format and use
 624          * that instead
 625          */
 626         (void) snprintf(cidraddr, len, "%s/%d", *ipaddrs, prefixlen);
 627 
 628         *ipaddrs = cidraddr;
 629         return (0);
 630 }
 631 #endif /* XXX KEBE SAYS NOT YET */
 632 
 633 static void
 634 lxi_net_setup(zone_dochandle_t handle)
 635 {
 636         struct zone_nwiftab lookup;
 637         boolean_t do_addrconf = B_FALSE;
 638 
 639         if (zonecfg_setnwifent(handle) != Z_OK)
 640                 return;
 641         while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
 642                 const char *iface = lookup.zone_nwif_physical;
 643 #if 0   /* XXX KEBE SAYS NOT YET */
 644                 struct zone_res_attrtab *attrs = lookup.zone_nwif_attrp;
 645                 const char *ipaddrs, *primary, *gateway;
 646                 char ipaddrs_copy[MAXNAMELEN], cidraddr[BUFSIZ],
 647                     *ipaddr, *tmp, *lasts;
 648                 boolean_t first_ipv4_configured = B_FALSE;
 649                 boolean_t *ficp = &first_ipv4_configured;
 650 #endif  /* XXX KEBE */
 651 





 652                 lxi_net_plumb(iface);
 653 
 654                 /* XXX KEBE SAYS this bit was shuffled around. */












 655                 if (lxi_iface_ipv6_link_local(iface) != 0) {
 656                         lxi_warn("unable to bring up link-local address on "
 657                             "interface %s", iface);
 658                 } else {
 659                         /* XXX KEBE SAYS this bit is new. */
 660                         do_addrconf = B_TRUE;
 661                 }
 662 
 663 #if 0   /* XXX KEBE SAYS NOT YET */
 664                 if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 &&
 665                     lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0) {
 666                         lxi_warn("Could not find a valid network configuration "
 667                             "for the %s interface", iface);
 668                         continue;
 669                 }
 670 
 671                 /*
 672                  * If we're going to be doing DHCP, we have to do it first since
 673                  * dhcpagent doesn't like to operate on non-zero logical
 674                  * interfaces.
 675                  */
 676                 if (strstr(ipaddrs, "dhcp") != NULL &&
 677                     lxi_iface_dhcp(iface, ficp) != 0) {
 678                         lxi_warn("Failed to start DHCP on %s\n", iface);
 679                 }
 680 
 681                 /*
 682                  * Copy the ipaddrs string, since strtok_r will write NUL
 683                  * characters into it.
 684                  */
 685                 (void) strlcpy(ipaddrs_copy, ipaddrs, MAXNAMELEN);
 686                 tmp = ipaddrs_copy;
 687 
 688                 /*
 689                  * Iterate over each IP and then set it up on the interface.
 690                  */
 691                 while ((ipaddr = strtok_r(tmp, ",", &lasts)) != NULL) {
 692                         tmp = NULL;
 693                         if (strcmp(ipaddr, "addrconf") == 0) {
 694                                 do_addrconf = B_TRUE;
 695                         } else if (strcmp(ipaddr, "dhcp") == 0) {
 696                                 continue;
 697                         } else if (lxi_iface_ip(iface, ipaddr, ficp) < 0) {
 698                                 lxi_warn("Unable to add new IP address (%s) "
 699                                     "to interface %s", ipaddr, iface);
 700                         }
 701                 }
 702 
 703                 if (zone_find_attr(attrs, "primary", &primary) == 0 &&
 704                     strncmp(primary, "true", MAXNAMELEN) == 0 &&
 705                     zone_find_attr(attrs, "gateway", &gateway) == 0) {
 706                         lxi_iface_gateway(iface, NULL, 0, gateway);
 707                 }
 708 #endif /* XXX KEBE */
 709         }
 710 
 711         if (do_addrconf) {
 712                 lxi_net_ndpd_start();
 713         }
 714 
 715         (void) zonecfg_endnwifent(handle);
 716 }
 717 
 718 static void
 719 lxi_net_static_route(const char *line)
 720 {
 721         /*
 722          * Each static route line is a string of the form:
 723          *
 724          *      "10.77.77.2|10.1.1.0/24|false"
 725          *
 726          * i.e. gateway address, destination network, and whether this is
 727          * a "link local" route or a next hop route.
 728          */




 170                 lxi_err("internal libzonecfg.so.1 error", 0);
 171 
 172         if ((res = zonecfg_get_handle(zonename, handle)) != Z_OK) {
 173                 zonecfg_fini_handle(handle);
 174                 lxi_err("could not locate zone config %d", res);
 175         }
 176 
 177         /*
 178          * Only exclusive stack is supported.
 179          */
 180         if (zonecfg_get_iptype(handle, &iptype) != Z_OK ||
 181             iptype != ZS_EXCLUSIVE) {
 182                 zonecfg_fini_handle(handle);
 183                 lxi_err("lx zones do not support shared IP stacks");
 184         }
 185 
 186         return (handle);
 187 
 188 }
 189 

 190 static int
 191 zone_find_attr(struct zone_res_attrtab *attrs, const char *name,
 192     const char **result)
 193 {
 194         while (attrs != NULL) {
 195                 if (strncmp(attrs->zone_res_attr_name, name,
 196                     MAXNAMELEN) == 0) {
 197                         *result = attrs->zone_res_attr_value;
 198                         return (0);
 199                 }
 200                 attrs = attrs->zone_res_attr_next;
 201         }
 202         return (-1);
 203 }

 204 
 205 static void
 206 lxi_svc_start(char *name, char *path, char *fmri)
 207 {
 208         pid_t pid;
 209         int status;
 210         char *argv[] = {
 211                 NULL,
 212                 NULL
 213         };
 214         char *envp[] = {
 215                 NULL,
 216                 NULL
 217         };
 218         argv[0] = name;
 219         envp[0] = fmri;
 220 
 221         pid = fork();
 222         if (pid == -1) {
 223                 lxi_err("fork() failed: %s", strerror(errno));


 388                 goto done;
 389         }
 390 
 391         if ((status = ipadm_create_addr(iph, ipaddr,
 392             IPADM_OPT_ACTIVE | IPADM_OPT_UP)) != IPADM_SUCCESS) {
 393                 lxi_warn("ipadm_create_addr error for %s: %s\n", iface,
 394                     ipadm_status2str(status));
 395                 err = -4;
 396                 goto done;
 397         }
 398 
 399         if (af == AF_INET) {
 400                 *first_ipv4_configured = B_TRUE;
 401         }
 402 
 403 done:
 404         ipadm_destroy_addrobj(ipaddr);
 405         return (err);
 406 }
 407 

 408 static int
 409 lxi_iface_dhcp(const char *origiface, boolean_t *first_ipv4_configured)
 410 {
 411         dhcp_ipc_request_t *dhcpreq = NULL;
 412         dhcp_ipc_reply_t *dhcpreply = NULL;
 413         int err = 0, timeout = 5;
 414         char iface[LIFNAMSIZ];
 415 
 416         (void) strncpy(iface, origiface, sizeof (iface));
 417 
 418         if (lxi_getif(AF_INET, iface, sizeof (iface), *first_ipv4_configured)
 419             != 0) {
 420                 lxi_warn("failed to create new logical interface "
 421                     "on %s: %s", origiface, strerror(errno));
 422                 return (-1);
 423         }
 424 
 425         if (dhcp_start_agent(timeout) != 0) {
 426                 lxi_err("Failed to start dhcpagent\n");
 427                 /* NOTREACHED */


 439         if (err != 0) {
 440                 free(dhcpreq);
 441                 lxi_warn("Failed to start DHCP on %s: %s\n", iface,
 442                     dhcp_ipc_strerror(err));
 443                 return (-1);
 444         }
 445         err = dhcpreply->return_code;
 446         if (err != 0) {
 447                 lxi_warn("Failed to start DHCP on %s: %s\n", iface,
 448                     dhcp_ipc_strerror(err));
 449                 goto done;
 450         }
 451 
 452         *first_ipv4_configured = B_TRUE;
 453 
 454 done:
 455         free(dhcpreq);
 456         free(dhcpreply);
 457         return (err);
 458 }

 459 
 460 /*
 461  * Initialize an IPv6 link-local address on a given interface
 462  */
 463 static int
 464 lxi_iface_ipv6_link_local(const char *iface)
 465 {
 466         struct lifreq lifr;
 467         int s;
 468 
 469         s = socket(AF_INET6, SOCK_DGRAM, 0);
 470         if (s == -1) {
 471                 lxi_warn("socket error %d: bringing up %s: %s",
 472                     errno, iface, strerror(errno));
 473         }
 474 
 475         (void) strncpy(lifr.lifr_name, iface, sizeof (lifr.lifr_name));
 476         if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
 477                 lxi_warn("SIOCGLIFFLAGS error %d: bringing up %s: %s",
 478                     errno, iface, strerror(errno));


 556                 lxi_warn("write() rtmsg incomplete");
 557                 (void) close(sockfd);
 558                 return (-1);
 559         }
 560 
 561         (void) close(sockfd);
 562         return (0);
 563 }
 564 
 565 static void
 566 lxi_net_loopback()
 567 {
 568         const char *iface = "lo0";
 569         boolean_t first_ipv4_configured = B_FALSE;
 570 
 571         lxi_net_plumb(iface);
 572         (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
 573         (void) lxi_iface_ipv6_link_local(iface);
 574 }
 575 





















































 576 static void
 577 lxi_net_setup(zone_dochandle_t handle)
 578 {
 579         struct zone_nwiftab lookup;
 580         boolean_t do_addrconf = B_FALSE;
 581 
 582         if (zonecfg_setnwifent(handle) != Z_OK)
 583                 return;
 584         while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
 585                 const char *iface = lookup.zone_nwif_physical;

 586                 struct zone_res_attrtab *attrs = lookup.zone_nwif_attrp;
 587                 const char *ipaddrs, *primary, *gateway;
 588                 char ipaddrs_copy[MAXNAMELEN], /* cidraddr[BUFSIZ], */
 589                     *ipaddr, *tmp, *lasts;
 590                 boolean_t first_ipv4_configured = B_FALSE;
 591                 boolean_t *ficp = &first_ipv4_configured;
 592                 boolean_t no_zonecfg;
 593 
 594                 /*
 595                  * Regardless of whether we're configured in zonecfg(1M), or
 596                  * configured by other means, make sure we plumb every
 597                  * physical=<foo> for IPv4 and IPv6.
 598                  */
 599                 lxi_net_plumb(iface);
 600 
 601                 if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 /* &&
 602                     lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0*/) {
 603                         /*
 604                          * Do not panic.  This interface has no in-zonecfg(1M)
 605                          * configuration.  We keep a warning around.
 606                          */
 607                         lxi_warn("Could not find zonecfg(1M) network "
 608                             "configuration for the %s interface", iface);
 609                         no_zonecfg = B_TRUE;
 610                 } else {
 611                         no_zonecfg = B_FALSE;
 612                 }
 613 
 614                 if (lxi_iface_ipv6_link_local(iface) != 0) {
 615                         lxi_warn("unable to bring up link-local address on "
 616                             "interface %s", iface);



 617                 }
 618 
 619                 /*
 620                  * Every thing else below only happens if we have zonecfg(1M)
 621                  * network configuration.
 622                  */
 623                 if (no_zonecfg)
 624                         continue;

 625 
 626                 /*
 627                  * If we're going to be doing DHCP, we have to do it first
 628                  * since dhcpagent doesn't like to operate on non-zero logical
 629                  * interfaces.
 630                  */
 631                 if (strstr(ipaddrs, "dhcp") != NULL &&
 632                     lxi_iface_dhcp(iface, ficp) != 0) {
 633                         lxi_warn("Failed to start DHCP on %s\n", iface);
 634                 }
 635 
 636                 /*
 637                  * Copy the ipaddrs string, since strtok_r will write NUL
 638                  * characters into it.
 639                  */
 640                 (void) strlcpy(ipaddrs_copy, ipaddrs, MAXNAMELEN);
 641                 tmp = ipaddrs_copy;
 642 
 643                 /*
 644                  * Iterate over each IP and then set it up on the interface.
 645                  */
 646                 while ((ipaddr = strtok_r(tmp, ",", &lasts)) != NULL) {
 647                         tmp = NULL;
 648                         if (strcmp(ipaddr, "addrconf") == 0) {
 649                                 do_addrconf = B_TRUE;
 650                         } else if (strcmp(ipaddr, "dhcp") == 0) {
 651                                 continue;
 652                         } else if (lxi_iface_ip(iface, ipaddr, ficp) < 0) {
 653                                 lxi_warn("Unable to add new IP address (%s) "
 654                                     "to interface %s", ipaddr, iface);
 655                         }
 656                 }
 657 
 658                 if (zone_find_attr(attrs, "primary", &primary) == 0 &&
 659                     strncmp(primary, "true", MAXNAMELEN) == 0 &&
 660                     zone_find_attr(attrs, "gateway", &gateway) == 0) {
 661                         lxi_iface_gateway(iface, NULL, 0, gateway);
 662                 }

 663         }
 664 
 665         if (do_addrconf) {
 666                 lxi_net_ndpd_start();
 667         }
 668 
 669         (void) zonecfg_endnwifent(handle);
 670 }
 671 
 672 static void
 673 lxi_net_static_route(const char *line)
 674 {
 675         /*
 676          * Each static route line is a string of the form:
 677          *
 678          *      "10.77.77.2|10.1.1.0/24|false"
 679          *
 680          * i.e. gateway address, destination network, and whether this is
 681          * a "link local" route or a next hop route.
 682          */