Print this page
Commit IPMP changes


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.

  24  */
  25 
  26 /*
  27  * This file contains routines that are used to modify/retrieve protocol or
  28  * interface property values. It also holds all the supported properties for
  29  * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
  30  * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
  31  *
  32  * This file also contains walkers, which walks through the property table and
  33  * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
  34  * property in the table.
  35  */
  36 
  37 #include <unistd.h>
  38 #include <errno.h>
  39 #include <ctype.h>
  40 #include <fcntl.h>
  41 #include <strings.h>
  42 #include <stdlib.h>
  43 #include <netinet/in.h>


 128 
 129         { "nud", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 130             i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
 131             i_ipadm_get_ifprop_flags },
 132 
 133         { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 134             i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
 135             i_ipadm_get_ifprop_flags },
 136 
 137         { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 138             i_ipadm_set_usesrc, NULL, i_ipadm_get_usesrc },
 139 
 140         { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0,
 141             i_ipadm_set_hostmodel, i_ipadm_get_hostmodel,
 142             i_ipadm_get_hostmodel },
 143 
 144         { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0,
 145             i_ipadm_set_hostmodel, i_ipadm_get_hostmodel,
 146             i_ipadm_get_hostmodel },
 147 





 148         { NULL, NULL, 0, 0, 0, NULL, NULL, NULL }
 149 };
 150 
 151 /* possible values for TCP properties `ecn' and `sack' */
 152 static const char *ecn_sack_vals[] = {"never", "passive", "active", NULL};
 153 
 154 /* Supported TCP protocol properties */
 155 static ipadm_prop_desc_t ipadm_tcp_prop_table[] = {
 156         { "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 157             i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
 158 
 159         { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
 160             IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
 161             i_ipadm_get_prop },
 162 
 163         { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 164             i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
 165 
 166         { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 167             i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },


 578         return (IPADM_SUCCESS);
 579 }
 580 
 581 /* ARGSUSED */
 582 static ipadm_status_t
 583 i_ipadm_set_ifprop_flags(ipadm_handle_t iph, const void *arg,
 584     ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
 585 {
 586         ipadm_status_t  status = IPADM_SUCCESS;
 587         const char      *ifname = arg;
 588         uint64_t        on_flags = 0, off_flags = 0;
 589         boolean_t       on = B_FALSE;
 590         sa_family_t     af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);
 591 
 592         /* if we are resetting, set the value to its default value */
 593         if (flags & IPADM_OPT_DEFAULT) {
 594                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0 ||
 595                     strcmp(pdp->ipd_name, "arp") == 0 ||
 596                     strcmp(pdp->ipd_name, "nud") == 0) {
 597                         pval = IPADM_ONSTR;
 598                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {

 599                         pval = IPADM_OFFSTR;
 600                 } else {
 601                         return (IPADM_PROP_UNKNOWN);
 602                 }
 603         }
 604 
 605         if (strcmp(pval, IPADM_ONSTR) == 0)
 606                 on = B_TRUE;
 607         else if (strcmp(pval, IPADM_OFFSTR) == 0)
 608                 on = B_FALSE;
 609         else
 610                 return (IPADM_INVALID_ARG);
 611 
 612         if (strcmp(pdp->ipd_name, "exchange_routes") == 0) {
 613                 if (on)
 614                         off_flags = IFF_NORTEXCH;
 615                 else
 616                         on_flags = IFF_NORTEXCH;
 617         } else if (strcmp(pdp->ipd_name, "arp") == 0) {
 618                 if (on)
 619                         off_flags = IFF_NOARP;
 620                 else
 621                         on_flags = IFF_NOARP;
 622         } else if (strcmp(pdp->ipd_name, "nud") == 0) {
 623                 if (on)
 624                         off_flags = IFF_NONUD;
 625                 else
 626                         on_flags = IFF_NONUD;
 627         } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {
 628                 if (on)
 629                         on_flags = IFF_ROUTER;
 630                 else
 631                         off_flags = IFF_ROUTER;





 632         }
 633 
 634         if (on_flags || off_flags)  {
 635                 status = i_ipadm_set_flags(iph, ifname, af, on_flags,
 636                     off_flags);
 637         }
 638         return (status);
 639 }
 640 
 641 /* ARGSUSED */
 642 static ipadm_status_t
 643 i_ipadm_set_eprivport(ipadm_handle_t iph, const void *arg,
 644     ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
 645 {
 646         nvlist_t        *portsnvl = NULL;
 647         nvpair_t        *nvp;
 648         ipadm_status_t  status = IPADM_SUCCESS;
 649         int             err;
 650         uint_t          count = 0;
 651 


 980 i_ipadm_get_ifprop_flags(ipadm_handle_t iph, const void *arg,
 981     ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto,
 982     uint_t valtype)
 983 {
 984         uint64_t        intf_flags;
 985         char            *val;
 986         size_t          nbytes;
 987         const char      *ifname = arg;
 988         sa_family_t     af;
 989         ipadm_status_t  status = IPADM_SUCCESS;
 990 
 991         switch (valtype) {
 992         case MOD_PROP_PERM:
 993                 nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW);
 994                 break;
 995         case MOD_PROP_DEFAULT:
 996                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0 ||
 997                     strcmp(pdp->ipd_name, "arp") == 0 ||
 998                     strcmp(pdp->ipd_name, "nud") == 0) {
 999                         val = IPADM_ONSTR;
1000                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {

1001                         val = IPADM_OFFSTR;
1002                 } else {
1003                         return (IPADM_PROP_UNKNOWN);
1004                 }
1005                 nbytes = snprintf(buf, *bufsize, "%s", val);
1006                 break;
1007         case MOD_PROP_ACTIVE:
1008                 af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);
1009                 status = i_ipadm_get_flags(iph, ifname, af, &intf_flags);
1010                 if (status != IPADM_SUCCESS)
1011                         return (status);
1012 
1013                 val = IPADM_OFFSTR;
1014                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0) {
1015                         if (!(intf_flags & IFF_NORTEXCH))
1016                                 val = IPADM_ONSTR;
1017                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {
1018                         if (intf_flags & IFF_ROUTER)
1019                                 val = IPADM_ONSTR;
1020                 } else if (strcmp(pdp->ipd_name, "arp") == 0) {
1021                         if (!(intf_flags & IFF_NOARP))
1022                                 val = IPADM_ONSTR;
1023                 } else if (strcmp(pdp->ipd_name, "nud") == 0) {
1024                         if (!(intf_flags & IFF_NONUD))
1025                                 val = IPADM_ONSTR;



1026                 }
1027                 nbytes = snprintf(buf, *bufsize, "%s", val);
1028                 break;
1029         default:
1030                 return (IPADM_INVALID_ARG);
1031         }
1032         if (nbytes >= *bufsize) {
1033                 /* insufficient buffer space */
1034                 *bufsize = nbytes + 1;
1035                 status = IPADM_NO_BUFS;
1036         }
1037 
1038         return (status);
1039 }
1040 
1041 static void
1042 i_ipadm_perm2str(char *buf, uint_t *bufsize)
1043 {
1044         uint_t perm = atoi(buf);
1045 


1681                 parg.ia_cmd = IPMGMT_CMD_RESETPROP;
1682         else
1683                 parg.ia_cmd = IPMGMT_CMD_SETPROP;
1684 
1685         err = ipadm_door_call(iph, &parg, sizeof (parg), NULL, 0, B_FALSE);
1686 
1687         /*
1688          * its fine if there were no entry in the DB to delete. The user
1689          * might be changing property value, which was not changed
1690          * persistently.
1691          */
1692         if (err == ENOENT)
1693                 err = 0;
1694         return (ipadm_errno2status(err));
1695 }
1696 
1697 /*
1698  * This is called from ipadm_set_ifprop() to validate the set operation.
1699  * It does the following steps:
1700  * 1. Validates the interface name.
1701  * 2. Fails if it is an IPMP meta-interface or an underlying interface.
1702  * 3. In case of a persistent operation, verifies that the
1703  *      interface is persistent.
1704  */
1705 static ipadm_status_t
1706 i_ipadm_validate_if(ipadm_handle_t iph, const char *ifname,
1707     uint_t proto, uint_t flags)
1708 {
1709         sa_family_t     af, other_af;
1710         ipadm_status_t  status;
1711         boolean_t       p_exists;
1712         boolean_t       af_exists, other_af_exists, a_exists;
1713 
1714         /* Check if the interface name is valid. */
1715         if (!i_ipadm_validate_ifname(iph, ifname))
1716                 return (IPADM_INVALID_ARG);
1717 
1718         af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);
1719         /*
1720          * Setting properties on an IPMP meta-interface or underlying
1721          * interface is not supported.
1722          */
1723         if (i_ipadm_is_ipmp(iph, ifname) || i_ipadm_is_under_ipmp(iph, ifname))
1724                 return (IPADM_NOTSUP);
1725 
1726         /* Check if interface exists in the persistent configuration. */
1727         status = i_ipadm_if_pexists(iph, ifname, af, &p_exists);
1728         if (status != IPADM_SUCCESS)
1729                 return (status);
1730 
1731         /* Check if interface exists in the active configuration. */
1732         af_exists = ipadm_if_enabled(iph, ifname, af);
1733         other_af = (af == AF_INET ? AF_INET6 : AF_INET);
1734         other_af_exists = ipadm_if_enabled(iph, ifname, other_af);
1735         a_exists = (af_exists || other_af_exists);
1736         if (!a_exists && p_exists)
1737                 return (IPADM_OP_DISABLE_OBJ);
1738         if (!af_exists)
1739                 return (IPADM_ENXIO);
1740 
1741         /*
1742          * If a persistent operation is requested, check if the underlying
1743          * IP interface is persistent.
1744          */




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.
  24  * Copyright (c) 2014 Nexenta Systems, Inc. All rights reserved
  25  */
  26 
  27 /*
  28  * This file contains routines that are used to modify/retrieve protocol or
  29  * interface property values. It also holds all the supported properties for
  30  * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
  31  * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
  32  *
  33  * This file also contains walkers, which walks through the property table and
  34  * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
  35  * property in the table.
  36  */
  37 
  38 #include <unistd.h>
  39 #include <errno.h>
  40 #include <ctype.h>
  41 #include <fcntl.h>
  42 #include <strings.h>
  43 #include <stdlib.h>
  44 #include <netinet/in.h>


 129 
 130         { "nud", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 131             i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
 132             i_ipadm_get_ifprop_flags },
 133 
 134         { "exchange_routes", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 135             i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
 136             i_ipadm_get_ifprop_flags },
 137 
 138         { "usesrc", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IPV6, 0,
 139             i_ipadm_set_usesrc, NULL, i_ipadm_get_usesrc },
 140 
 141         { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV6, 0,
 142             i_ipadm_set_hostmodel, i_ipadm_get_hostmodel,
 143             i_ipadm_get_hostmodel },
 144 
 145         { "hostmodel", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_IPV4, 0,
 146             i_ipadm_set_hostmodel, i_ipadm_get_hostmodel,
 147             i_ipadm_get_hostmodel },
 148 
 149         { "standby", NULL, IPADMPROP_CLASS_IF, MOD_PROTO_IP, 0,
 150             i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
 151             i_ipadm_get_ifprop_flags },
 152 
 153 
 154         { NULL, NULL, 0, 0, 0, NULL, NULL, NULL }
 155 };
 156 
 157 /* possible values for TCP properties `ecn' and `sack' */
 158 static const char *ecn_sack_vals[] = {"never", "passive", "active", NULL};
 159 
 160 /* Supported TCP protocol properties */
 161 static ipadm_prop_desc_t ipadm_tcp_prop_table[] = {
 162         { "ecn", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 163             i_ipadm_set_ecnsack, i_ipadm_get_ecnsack, i_ipadm_get_ecnsack },
 164 
 165         { "extra_priv_ports", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP,
 166             IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
 167             i_ipadm_get_prop },
 168 
 169         { "largest_anon_port", NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 170             i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
 171 
 172         { "max_buf", "_max_buf", IPADMPROP_CLASS_MODULE, MOD_PROTO_TCP, 0,
 173             i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },


 584         return (IPADM_SUCCESS);
 585 }
 586 
 587 /* ARGSUSED */
 588 static ipadm_status_t
 589 i_ipadm_set_ifprop_flags(ipadm_handle_t iph, const void *arg,
 590     ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
 591 {
 592         ipadm_status_t  status = IPADM_SUCCESS;
 593         const char      *ifname = arg;
 594         uint64_t        on_flags = 0, off_flags = 0;
 595         boolean_t       on = B_FALSE;
 596         sa_family_t     af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);
 597 
 598         /* if we are resetting, set the value to its default value */
 599         if (flags & IPADM_OPT_DEFAULT) {
 600                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0 ||
 601                     strcmp(pdp->ipd_name, "arp") == 0 ||
 602                     strcmp(pdp->ipd_name, "nud") == 0) {
 603                         pval = IPADM_ONSTR;
 604                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0 ||
 605                     strcmp(pdp->ipd_name, "standby") == 0) {
 606                         pval = IPADM_OFFSTR;
 607                 } else {
 608                         return (IPADM_PROP_UNKNOWN);
 609                 }
 610         }
 611 
 612         if (strcmp(pval, IPADM_ONSTR) == 0)
 613                 on = B_TRUE;
 614         else if (strcmp(pval, IPADM_OFFSTR) == 0)
 615                 on = B_FALSE;
 616         else
 617                 return (IPADM_INVALID_ARG);
 618 
 619         if (strcmp(pdp->ipd_name, "exchange_routes") == 0) {
 620                 if (on)
 621                         off_flags = IFF_NORTEXCH;
 622                 else
 623                         on_flags = IFF_NORTEXCH;
 624         } else if (strcmp(pdp->ipd_name, "arp") == 0) {
 625                 if (on)
 626                         off_flags = IFF_NOARP;
 627                 else
 628                         on_flags = IFF_NOARP;
 629         } else if (strcmp(pdp->ipd_name, "nud") == 0) {
 630                 if (on)
 631                         off_flags = IFF_NONUD;
 632                 else
 633                         on_flags = IFF_NONUD;
 634         } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {
 635                 if (on)
 636                         on_flags = IFF_ROUTER;
 637                 else
 638                         off_flags = IFF_ROUTER;
 639         } else if (strcmp(pdp->ipd_name, "standby") == 0) {
 640                 if (on)
 641                         on_flags = IFF_STANDBY;
 642                 else
 643                         off_flags = IFF_STANDBY;
 644         }
 645 
 646         if (on_flags || off_flags)  {
 647                 status = i_ipadm_set_flags(iph, ifname, af, on_flags,
 648                     off_flags);
 649         }
 650         return (status);
 651 }
 652 
 653 /* ARGSUSED */
 654 static ipadm_status_t
 655 i_ipadm_set_eprivport(ipadm_handle_t iph, const void *arg,
 656     ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
 657 {
 658         nvlist_t        *portsnvl = NULL;
 659         nvpair_t        *nvp;
 660         ipadm_status_t  status = IPADM_SUCCESS;
 661         int             err;
 662         uint_t          count = 0;
 663 


 992 i_ipadm_get_ifprop_flags(ipadm_handle_t iph, const void *arg,
 993     ipadm_prop_desc_t *pdp, char *buf, uint_t *bufsize, uint_t proto,
 994     uint_t valtype)
 995 {
 996         uint64_t        intf_flags;
 997         char            *val;
 998         size_t          nbytes;
 999         const char      *ifname = arg;
1000         sa_family_t     af;
1001         ipadm_status_t  status = IPADM_SUCCESS;
1002 
1003         switch (valtype) {
1004         case MOD_PROP_PERM:
1005                 nbytes = snprintf(buf, *bufsize, "%d", MOD_PROP_PERM_RW);
1006                 break;
1007         case MOD_PROP_DEFAULT:
1008                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0 ||
1009                     strcmp(pdp->ipd_name, "arp") == 0 ||
1010                     strcmp(pdp->ipd_name, "nud") == 0) {
1011                         val = IPADM_ONSTR;
1012                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0 ||
1013                     strcmp(pdp->ipd_name, "standby") == 0) {
1014                         val = IPADM_OFFSTR;
1015                 } else {
1016                         return (IPADM_PROP_UNKNOWN);
1017                 }
1018                 nbytes = snprintf(buf, *bufsize, "%s", val);
1019                 break;
1020         case MOD_PROP_ACTIVE:
1021                 af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);
1022                 status = i_ipadm_get_flags(iph, ifname, af, &intf_flags);
1023                 if (status != IPADM_SUCCESS)
1024                         return (status);
1025 
1026                 val = IPADM_OFFSTR;
1027                 if (strcmp(pdp->ipd_name, "exchange_routes") == 0) {
1028                         if (!(intf_flags & IFF_NORTEXCH))
1029                                 val = IPADM_ONSTR;
1030                 } else if (strcmp(pdp->ipd_name, "forwarding") == 0) {
1031                         if (intf_flags & IFF_ROUTER)
1032                                 val = IPADM_ONSTR;
1033                 } else if (strcmp(pdp->ipd_name, "arp") == 0) {
1034                         if (!(intf_flags & IFF_NOARP))
1035                                 val = IPADM_ONSTR;
1036                 } else if (strcmp(pdp->ipd_name, "nud") == 0) {
1037                         if (!(intf_flags & IFF_NONUD))
1038                                 val = IPADM_ONSTR;
1039                 } else if (strcmp(pdp->ipd_name, "standby") == 0) {
1040                         if (!(intf_flags & IFF_STANDBY))
1041                                 val = IPADM_ONSTR;
1042                 }
1043                 nbytes = snprintf(buf, *bufsize, "%s", val);
1044                 break;
1045         default:
1046                 return (IPADM_INVALID_ARG);
1047         }
1048         if (nbytes >= *bufsize) {
1049                 /* insufficient buffer space */
1050                 *bufsize = nbytes + 1;
1051                 status = IPADM_NO_BUFS;
1052         }
1053 
1054         return (status);
1055 }
1056 
1057 static void
1058 i_ipadm_perm2str(char *buf, uint_t *bufsize)
1059 {
1060         uint_t perm = atoi(buf);
1061 


1697                 parg.ia_cmd = IPMGMT_CMD_RESETPROP;
1698         else
1699                 parg.ia_cmd = IPMGMT_CMD_SETPROP;
1700 
1701         err = ipadm_door_call(iph, &parg, sizeof (parg), NULL, 0, B_FALSE);
1702 
1703         /*
1704          * its fine if there were no entry in the DB to delete. The user
1705          * might be changing property value, which was not changed
1706          * persistently.
1707          */
1708         if (err == ENOENT)
1709                 err = 0;
1710         return (ipadm_errno2status(err));
1711 }
1712 
1713 /*
1714  * This is called from ipadm_set_ifprop() to validate the set operation.
1715  * It does the following steps:
1716  * 1. Validates the interface name.
1717  * 2. In case of a persistent operation, verifies that the

1718  *      interface is persistent.
1719  */
1720 static ipadm_status_t
1721 i_ipadm_validate_if(ipadm_handle_t iph, const char *ifname,
1722     uint_t proto, uint_t flags)
1723 {
1724         sa_family_t     af, other_af;
1725         ipadm_status_t  status;
1726         boolean_t       p_exists;
1727         boolean_t       af_exists, other_af_exists, a_exists;
1728 
1729         /* Check if the interface name is valid. */
1730         if (!i_ipadm_validate_ifname(iph, ifname))
1731                 return (IPADM_INVALID_ARG);
1732 
1733         af = (proto == MOD_PROTO_IPV6 ? AF_INET6 : AF_INET);






1734 
1735         /* Check if interface exists in the persistent configuration. */
1736         status = i_ipadm_if_pexists(iph, ifname, af, &p_exists);
1737         if (status != IPADM_SUCCESS)
1738                 return (status);
1739 
1740         /* Check if interface exists in the active configuration. */
1741         af_exists = ipadm_if_enabled(iph, ifname, af);
1742         other_af = (af == AF_INET ? AF_INET6 : AF_INET);
1743         other_af_exists = ipadm_if_enabled(iph, ifname, other_af);
1744         a_exists = (af_exists || other_af_exists);
1745         if (!a_exists && p_exists)
1746                 return (IPADM_OP_DISABLE_OBJ);
1747         if (!af_exists)
1748                 return (IPADM_ENXIO);
1749 
1750         /*
1751          * If a persistent operation is requested, check if the underlying
1752          * IP interface is persistent.
1753          */