util-solaris.c revision 5637
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <alloca.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <strings.h>
#include <stropts.h>
#include <fcntl.h>
#include <unistd.h>
#include <libdlpi.h>
#include <libdladm.h>
#include <libdllink.h>
#include <zone.h>
#include <net/if_types.h>
#include <netdb.h>
#include <rad/radclient.h>
#include "netlink-protocol.h"
#include "netlink.h"
#include "flow.h"
#include "packets.h"
#include "util-solaris.h"
#include "util.h"
#include "dpif-solaris.h"
typedef struct {
} ifspec_t;
static int
{
char *ep;
unsigned long ul;
errno = 0;
return (-1);
return (0);
}
/*
* Given a token with a logical unit spec, return the logical unit converted
* to a uint_t.
*
* Returns: 0 for success, nonzero if an error occurred. errno is set if
* necessary.
*/
static int
{
const char *tp;
/* Lun must be all digits */
/* Null body */;
return (-1);
}
return (0);
}
/*
* Given a single token ending with a ppa spec, return the ppa spec converted
* to a uint_t.
*
* Returns: 0 for success, nonzero if an error occurred. errno is set if
* necessary.
*/
static int
{
const char *tp;
/* Null body */;
/*
* If the device name does not end with a digit or the device
* name is a sequence of numbers or a PPA contains a leading
* zero, return error.
*/
goto fail;
goto fail;
/* max value of PPA is 4294967294, which is (UINT_MAX - 1) */
goto fail;
return (0);
fail:
return (-1);
}
/*
* Given a `linkname' of the form drv(ppa), parse it into `driver' and `ppa'.
* If the `dsize' for the `driver' is not atleast MAXLINKNAMELEN then part of
* the driver name will be copied to `driver'.
*
* This function also validates driver name and PPA and therefore callers can
* call this function with `driver' and `ppa' set to NULL, to just verify the
* linkname.
*/
{
char *tp;
char linkname[MAXLINKNAMELEN];
goto fail;
if (len >= MAXLINKNAMELEN)
goto fail;
/* Get PPA */
return (_B_FALSE);
/* strip the ppa off of the linkname, if present */
*tp = '\0';
/*
* Now check for the validity of the device name. The legal characters
* in a device name are: alphanumeric (a-z, A-Z, 0-9), underscore
* ('_'), hyphen ('-'), and period ('.'). The first character
* of the device name cannot be a digit and should be an alphabetic
* character.
*/
goto fail;
goto fail;
}
return (_B_TRUE);
fail:
return (_B_FALSE);
}
/*
* Given an IP interface name, which is either a
* - datalink name (which is driver name plus PPA), for e.g. bge0 or
* - datalink name plus a logical interface identifier (delimited by ':'),
* for e.g. bge0:34
* the following function validates its form and decomposes the contents into
* ifspec_t.
*
* Returns _B_TRUE for success, otherwise _B_FALSE is returned.
*/
static boolean_t
{
char *lp;
return (_B_FALSE);
}
/* Any logical units? */
return (_B_FALSE);
*lp = '\0';
}
}
/*
* Issues the ioctl SIOCSLIFNAME to kernel.
*/
static int
{
int status = 0;
/* We should have already validated the interface name. */
}
return (status);
}
/*
* Wrapper for sending a non-transparent I_STR ioctl().
* Returns: Result from ioctl().
*/
static int
{
}
/*
* Issues the ioctl SIOCSLIFNAME to kernel on the given ARP stream fd.
*/
static int
{
/*
* Tell ARP the name and unit number for this interface.
* Note that arp has no support for transparent ioctls.
*/
sizeof (lifr)) == -1) {
return (errno);
}
return (0);
}
/*
* the bottom of the stream for tunneling interfaces.
*/
static int
{
int err;
return (errno);
/*
* Pop off all undesired modules (note that the user may have
* configured autopush to add modules above udp), and push the
* arp module onto the resulting stream. This is used to make
* IP+ARP be able to atomically track the muxid for the I_PLINKed
* STREAMS, thus it isn't related to ARP running the ARP protocol.
*/
;
return (0);
return (err);
}
static char *
{
if (protocol == IPPROTO_TCP)
return ("tcp");
if (protocol == IPPROTO_UDP)
return ("udp");
if (protocol == IPPROTO_SCTP)
return ("sctp");
if (protocol == IPPROTO_ICMPV6)
return ("icmpv6");
if (protocol == IPPROTO_ICMP)
return ("icmp");
else
return ("");
}
static uint8_t
solaris_str2proto(const char *protostr)
{
return (IPPROTO_TCP);
return (IPPROTO_UDP);
return (IPPROTO_SCTP);
return (IPPROTO_ICMPV6);
return (IPPROTO_ICMP);
return (0);
}
/*
* Returns the flags value for the logical interface in `lifname'
* in the buffer pointed to by `flags'.
*/
static int
{
return (errno);
return (0);
}
/*
* For a given interface name, checks if IP interface exists.
*/
int
{
int error = 0;
return (error);
}
int
{
int ip_muxid;
int arp_muxid;
int mux_fd = -1;
int muxid_fd = -1;
char *udp_dev_name;
int ret = 0;
/*
* the same now for PUNLINK also.
*/
goto done;
}
if (ret != 0)
goto done;
goto done;
}
if (ret != 0)
goto done;
/*
* We don't have a good way of knowing whether the arp stream is
* plumbed. We can't rely on IFF_NOARP because someone could
* have turned it off later using "ifconfig xxx -arp".
*/
if (arp_muxid != 0) {
/*
* Some plumbing utilities set the muxid to
* -1 or some invalid value to signify that
* there is no arp stream. Set the muxid to 0
* before trying to unplumb the IP stream.
* IP does not allow the IP stream to be
* unplumbed if it sees a non-null arp muxid,
* for consistency of IP-ARP streams.
*/
lifr.lifr_arp_muxid = 0;
}
}
}
if (changed_arp_muxid) {
/*
* Some error occurred, and we need to restore
* everything back to what it was.
*/
}
}
done:
if (muxid_fd != -1)
if (mux_fd != -1)
return (ret);
}
/*
* Plumbs the interface `ifname'.
*/
int
{
int ip_muxid;
char *udp_dev_name;
int status = 0;
const char *linkname;
int ret;
goto done;
}
/*
* We use DLPI_NOATTACH because the ip module will do the attach
* itself for DLPI style-2 devices.
*/
if (ret != DLPI_SUCCESS) {
goto done;
}
goto done;
}
} else {
}
if (status != 0)
goto done;
/* Get the full set of existing flags for this stream */
if (status != 0)
goto done;
if (status != 0)
goto done;
/* Check if arp is not needed */
/*
* PLINK the interface stream so that the application can exit
* without tearing down the stream.
*/
goto done;
}
/*
* This interface does use ARP, so set up a separate stream
* from the interface to ARP.
*
* We use DLPI_NOATTACH because the arp module will do the attach
* itself for DLPI style-2 devices.
*/
if (ret != DLPI_SUCCESS) {
goto done;
}
goto done;
}
if (status != 0)
goto done;
/*
* PLINK the IP and ARP streams so that we can exit
* without tearing down the stream.
*/
goto done;
}
}
done:
if (mux_fd != -1)
return (status);
}
int
{
return (ENODEV); /* Not sure what to return */
return (ENODEV); /* Not sure what to return */
}
return (0);
}
static rc_err_t
{
return (RCE_OK);
}
static rc_err_t
{
}
return (RCE_OK);
}
static int
{
char propstr[DLADM_STRSIZE];
int error = 0;
"name", netdev_name);
goto out;
}
if (status == RCE_SERVER_OBJECT) {
"failed Datalink_getInfo(%s): %s",
}
goto out;
}
propstr[0] = '\0';
propstr);
goto out;
}
out:
return (error);
}
int
{
int error = 0;
"name", netdev_name);
goto out;
}
if (status == RCE_SERVER_OBJECT) {
"failed Physical_getInfo(%s): %s",
}
goto out;
}
&dlval);
goto out;
}
out:
return (error);
}
int
{
test_dlclass));
}
int
{
test_dllower));
}
int
{
const char *props[1];
const char *fields[1];
int ndlist = 0;
int error = 0, i = 0;
char buf[DLADM_STRSIZE];
"name", netdev_name);
goto out;
}
fields[0] = field_name;
if (status == RCE_SERVER_OBJECT) {
"failed Datalink_getProperties(%s, %s): %s",
}
goto out;
}
field_name, &dlval);
goto out;
}
case DDLVT_STRING:
goto out;
}
break;
case DDLVT_STRINGS:
if (dlval->ddlv_slist_count == 0) {
goto out;
}
for (i = 0; i < dlval->ddlv_slist_count; i++) {
}
break;
case DDLVT_ULONG:
goto out;
}
break;
case DDLVT_BOOLEAN:
case DDLVT_BOOLEANS:
case DDLVT_LONG:
case DDLVT_LONGS:
case DDLVT_ULONGS:
case DDLVT_DICTIONARY:
case DDLVT_DICTIONARYS:
default:
ovs_assert(0);
break;
}
out:
return (error);
}
static int
{
int error = 0;
"name", netdev_name);
goto out;
}
if (sprop_dict == NULL) {
goto out;
}
switch (vtype) {
case DDLVT_BOOLEAN:
goto out;
}
break;
case DDLVT_ULONG:
goto out;
}
break;
case DDLVT_STRING:
goto out;
}
break;
case DDLVT_LONG:
case DDLVT_LONGS:
case DDLVT_ULONGS:
case DDLVT_STRINGS:
case DDLVT_BOOLEANS:
case DDLVT_DICTIONARY:
case DDLVT_DICTIONARYS:
default:
ovs_assert(0);
break;
}
/* we need to add temporary flag */
goto out;
}
if (status == RCE_SERVER_OBJECT) {
"failed Datalink_setPropertiess(%s, %s): %s",
}
}
out:
return (error);
}
int
void *arg)
{
}
int
void *arg)
{
}
int
void *arg)
{
}
int
{
&linkmgr, 0);
goto out;
goto out;
/* linkname is 'const char *' and ddlv_sval is 'char *' */
goto out;
goto out;
if (macaddr_info == NULL)
goto out;
goto out;
&macaddr_info_val, &old_val);
goto out;
if (status == RCE_SERVER_OBJECT) {
"failed DatalinkManager_createVNIC(%s): %s",
}
out:
}
int
{
int error = 0;
"name", vnicname);
goto out;
}
if (sprop_dict == NULL) {
goto out;
}
goto out;
}
/* we need to add temporary flag */
goto out;
}
if (macaddr_info == NULL)
goto out;
goto out;
goto out;
if (status == RCE_SERVER_OBJECT) {
"failed Datalink_setPropertiess(%s, lower-link): "
}
}
out:
return (error);
}
int
solaris_delete_vnic(const char *vnicname)
{
int err = 0;
&linkmgr, 0);
goto out;
}
goto out;
}
goto out;
}
&derrp);
err = -1;
if (status == RCE_SERVER_OBJECT) {
"failed DatalinkManager_deleteVNIC(%s): %s",
}
}
out:
return (err);
}
int
solaris_create_etherstub(const char *name)
{
&linkmgr, 0);
goto out;
goto out;
goto out;
if (status == RCE_SERVER_OBJECT) {
"failed DatalinkManager_createEtherstub(%s): %s",
}
out:
}
int
solaris_delete_etherstub(const char *name)
{
&linkmgr, 0);
goto out;
goto out;
goto out;
&derrp);
if (status == RCE_SERVER_OBJECT) {
"failed DatalinkManager_deleteEtherstub(%s): %s",
}
out:
}
solaris_etherstub_exists(const char *name)
{
"name", name);
} else {
}
} else {
}
return (exists);
}
static int
{
goto done;
}
done:
return (err);
}
static int
{
int af;
} else {
return (EINVAL);
}
IN6_INADDR_TO_V4MAPPED(&v4addr, f);
} else {
*f = v6addr;
}
return (0);
}
static int
{
int err = 0;
&flist);
return (EINVAL);
"linkname", &dlval);
goto out;
}
out:
return (err);
}
static void
{
buf[0] = '\0';
rbuf[0] = '\0';
if (!eth_addr_is_zero(f) || !eth_addr_is_zero(m)) {
}
}
}
}
static void
{
buf[0] = '\0';
rbuf[0] = '\0';
}
}
static int
int *cnt)
{
char buf[DLADM_STRSIZE];
int i, error = 0;
char **strs;
*cnt = 0;
if (nofports != 0) {
/* Sort OF port list and convert it to a mac_propval_range */
if (dlstatus != DLADM_STATUS_OK) {
goto out;
}
goto out;
}
/*
* Write ranges and individual elements into their own
* buffer.
*/
/* single element */
} else {
/* range of elements */
}
while (i >= 0) {
i--;
}
goto out;
}
}
}
out:
return (error);
}
static int
{
return (EINVAL);
}
}
return (0);
}
static int
{
return (EINVAL);
}
return (EINVAL);
}
}
return (0);
}
/*
* Caller allocated "pvals" is freed here
*/
static int
{
int i, err = 0;
if (pvalcnt != 0) {
goto out;
}
for (i = 0; i < pvalcnt; i++)
pvals[i]);
out:
for (i = 0; i < pvalcnt; i++)
}
return (err);
}
static int
{
return (EINVAL);
}
return (0);
}
static int
{
return (EINVAL);
}
return (0);
}
static int
{
unsigned long long f_ulval = f;
unsigned long long m_ulval = m;
return (EINVAL);
}
return (EINVAL);
}
return (0);
}
static int
{
char dstr[DLADM_STRSIZE];
int err = 0;
dstr[0] = '\0';
if (err != 0)
goto out;
}
if (is_arp) {
if (err != 0)
goto out;
}
sizeof (rbuf));
if (err != 0)
goto out;
}
sizeof (rbuf));
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
} else {
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
sizeof (dstr));
if (err != 0)
goto out;
}
if (f->nw_proto != IPPROTO_ICMP &&
f->nw_proto != IPPROTO_ICMPV6) {
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
} else {
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
}
}
sizeof (rbuf));
if (err != 0)
goto out;
}
sizeof (rbuf));
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
if (err != 0)
goto out;
}
out:
return (err);
}
static int
{
goto outport;
goto outport;
}
/* min-rate and priority not currently used */
goto outport;
errno = 0;
goto outport;
if (err == 0) {
}
return (err);
}
static int
{
char buf[DLADM_STRSIZE];
int err;
}
goto out;
}
goto out;
}
goto out;
}
/* TODO(gmoodalb): this should be two entries. fix later */
dslen);
out:
return (err);
}
static int
{
char *cp;
char buf[DLADM_STRSIZE];
int err;
"%sdst:%s,protocol:%s,tos:0x%x,hoplimit:%d",
goto out;
}
goto out;
}
dstrlen);
out:
return (err);
}
static int
{
char abuf[INET6_ADDRSTRLEN];
char buf[DLADM_STRSIZE];
int err;
goto out;
}
goto out;
}
dstrlen);
out:
return (err);
}
static int
{
char buf[DLADM_STRSIZE];
int err;
goto out;
}
goto out;
}
out:
dstr);
return (err);
}
static int
{
char *cp;
char buf[DLADM_STRSIZE];
int err;
goto out;
}
goto out;
}
dstrlen);
out:
return (err);
}
static int
solaris_nlattr_to_DLVal(void *cookie,
{
const struct nlattr *a;
unsigned int left;
char buf[DLADM_STRSIZE];
char dstr[DLADM_STRSIZE];
char **pvals;
dstr[0] = '\0';
sizeof (dstr));
if (err != 0)
goto out;
/* if actions_len == 0, then the action is drop */
if (actions_len == 0) {
goto out;
}
goto out;
}
goto out;
}
type = nl_attr_type(a);
if ((type != OVS_ACTION_ATTR_OUTPUT) ||
(lasttype != OVS_ACTION_ATTR_OUTPUT)) {
if (lasttype == OVS_ACTION_ATTR_OUTPUT) {
dpif_log(0, "solaris_nlattr_to_DLVal outports "
"total %d ports", nofports);
if (err != 0)
goto out;
}
nofports = 0;
}
switch ((enum ovs_action_attr) type) {
/* These only make sense in the context of a datapath. */
case OVS_ACTION_ATTR_OUTPUT:
break;
}
dpif_log(0, "solaris_nlattr_to_DLVal %d ports: %u",
break;
case OVS_ACTION_ATTR_USERSPACE: {
union user_action_cookie cookie;
userdata_len > sizeof (cookie)) {
"unexpected action size %"PRIuSIZE,
break;
}
err = EOPNOTSUPP;
"type unsupported %d", userdata_len,
break;
}
break;
break;
}
break;
}
break;
}
case OVS_ACTION_ATTR_SET: {
switch (nl_attr_type(aset)) {
case OVS_KEY_ATTR_PRIORITY:
break;
case OVS_KEY_ATTR_ETHERNET: {
const struct ovs_key_ethernet *ek;
sizeof (struct ovs_key_ethernet));
break;
}
case OVS_KEY_ATTR_IPV4: {
const struct ovs_key_ipv4 *eip4;
sizeof (struct ovs_key_ipv4));
break;
}
case OVS_KEY_ATTR_IPV6: {
const struct ovs_key_ipv6 *eip6;
sizeof (struct ovs_key_ipv6));
break;
}
case OVS_KEY_ATTR_TCP: {
const struct ovs_key_tcp *etcp;
sizeof (struct ovs_key_tcp));
break;
}
case OVS_KEY_ATTR_UDP: {
const struct ovs_key_udp *eudp;
sizeof (struct ovs_key_udp));
break;
}
case OVS_KEY_ATTR_SCTP: {
const struct ovs_key_sctp *esctp;
sizeof (struct ovs_key_sctp));
break;
}
case OVS_KEY_ATTR_TUNNEL: {
enum odp_key_fitness fitness;
break;
}
default:
err = EOPNOTSUPP;
"%d not supported",
nl_attr_type(nl_attr_get(a)));
}
break;
}
case OVS_ACTION_ATTR_PUSH_VLAN: {
const struct ovs_action_push_vlan *vlan;
vlan = nl_attr_get_unspec(a,
sizeof (struct ovs_action_push_vlan));
break;
}
case OVS_ACTION_ATTR_POP_VLAN:
break;
case OVS_ACTION_ATTR_RECIRC:
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_POP_MPLS:
case OVS_ACTION_ATTR_SAMPLE:
/* TBD */
err = EOPNOTSUPP;
"not supported", type);
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
}
if (err != 0)
goto out;
}
if (type == OVS_ACTION_ATTR_OUTPUT) {
dpif_log(0, "solaris_nlattr_to_DLVal outports total %d ports",
nofports);
}
out:
return (err);
}
int
{
int err = 0;
"name", linkname);
goto out;
}
goto out;
}
goto out;
}
goto out;
}
if (err != 0)
goto out;
actions_len, &prop);
if (err != 0)
goto out;
err = -1;
if (status == RCE_SERVER_OBJECT) {
"failed Datalink_addFlow(%s, %s): %s",
}
}
out:
return (err);
}
int
{
int err;
"name", flowname);
goto out;
}
goto out;
}
actions_len, &prop);
if (err != 0)
goto out;
err = -1;
if (status == RCE_SERVER_OBJECT) {
"failed Flow_setProperties(%s): %s",
}
}
out:
return (err);
}
int
{
int error = 0;
"name", linkname);
goto out;
}
goto out;
}
goto out;
}
error = -1;
if (status == RCE_SERVER_OBJECT) {
}
}
out:
return (error);
}
static rc_err_t
{
if (err != 0)
goto out;
} else {
}
} else {
} else {
}
}
}
out:
}
static int
{
bzero(f, sizeof (*f));
bzero(m, sizeof (*m));
&flist);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (0);
}
int
{
int err = 0;
"name", flowname);
return (ENODEV);
}
err = -1;
if (status == RCE_SERVER_OBJECT) {
/*
* XXX For now, log DDLSTATUS_NOT_FOUND as debug until
* we can determine how to handle the RAD caching
* issue.
*/
"failed Flow_getInfo(%s): %s",
}
}
if (err == 0) {
}
return (err);
}
static int
{
return (0);
return (EINVAL);
}
static int
{
int err = 0;
&pv_range);
if (status != DLADM_STATUS_OK)
return (solaris_dladm_status2error(status));
/* Convert mac_propval_range to a single ofports list */
if (status != DLADM_STATUS_OK) {
goto out;
}
for (i = 0; i < nofports; i++)
out:
return (err);
}
static int
{
/* TBD */
return (0);
}
void
{
union user_action_cookie cookie;
}
static int
{
return (0);
}
static int
{
int64_t n;
struct ovs_action_push_vlan push;
int tpid = ETH_TYPE_VLAN;
errno = 0;
return (EINVAL);
return (0);
}
static int
{
return (0);
}
static int
{
char pval[DLADM_PROP_VAL_MAX];
struct ovs_key_ethernet eth_key;
int etheraddrlen;
char *sep;
uint_t i;
int err = 0;
/*
* The property value is in the format of "ether_src:xxx"
* "ether_dst:xxx"
*/
for (i = 0; i < nval; i++) {
goto out;
}
*sep = '\0';
sep++;
goto out;
}
/* Only ethernet address is supported */
if (etheraddrlen != ETHERADDRL) {
goto out;
}
if (src_set) {
} else {
}
if (dst_set) {
} else {
}
} else {
}
if (err != 0)
goto out;
}
goto out;
}
sizeof (eth_key));
out:
return (err);
}
static int
{
struct ovs_key_ipv4 ipv4;
char pval[DLADM_PROP_VAL_MAX];
/*
* The property value is in the format of "src:xxx" "dst:xxx"
* "protocol:xxx" "tos:xxx" "hoplimit:xxx"
*/
for (i = 0; i < nval; i++) {
goto out;
}
*sep = '\0';
sep++;
goto out;
goto out;
goto out;
goto out;
if (ipv4.ipv4_proto != 0)
goto out;
if (protocol == 0)
goto out;
if (tos_set)
goto out;
errno = 0;
goto out;
goto out;
errno = 0;
*endp != '\0')
goto out;
}
}
err = 0;
out:
return (err);
}
static int
{
struct ovs_key_ipv6 ipv6;
char pval[DLADM_PROP_VAL_MAX];
/*
* The property value is in the format of "src:xxx" "dst:xxx"
* "label:0xxxxx" "protocol:xxx" "tos:xxx" "hoplimit:xxx"
*/
for (i = 0; i < nval; i++) {
goto out;
*sep = '\0';
sep++;
sizeof (struct in6_addr));
if (!IN6_IS_ADDR_UNSPECIFIED(&in6))
goto out;
goto out;
sizeof (struct in6_addr));
if (!IN6_IS_ADDR_UNSPECIFIED(&in6))
goto out;
goto out;
if (ipv6.ipv6_proto != 0)
goto out;
if (protocol == 0)
goto out;
if (tos_set)
goto out;
errno = 0;
goto out;
if (ipv6.ipv6_hlimit != 0)
goto out;
errno = 0;
*endp != '\0') {
goto out;
}
if (ipv6.ipv6_label != 0)
goto out;
errno = 0;
*endp != '\0') {
goto out;
}
}
}
err = 0;
out:
return (err);
}
static int
{
char pval[DLADM_PROP_VAL_MAX];
/* The property value is in the format of "sport:xxx" "dport:xxx" */
for (i = 0; i < nval; i++) {
goto out;
*sep = '\0';
sep++;
if (sport != 0)
goto out;
errno = 0;
*endp != '\0') {
goto out;
}
if (dport != 0)
return (DLADM_STATUS_DUPLICATE_ARG);
errno = 0;
*endp != '\0') {
goto out;
}
}
}
err = 0;
out:
return (err);
}
static int
{
struct ovs_key_tcp tcp;
int err;
if (err != 0)
return (err);
return (0);
}
static int
{
struct ovs_key_udp udp;
int err;
if (err != 0)
return (err);
return (0);
}
static int
{
struct ovs_key_sctp sctp;
int err;
if (err != 0)
return (err);
return (0);
}
static int
{
void *ptr;
return (EINVAL);
/* Check if hostname resolves to multiple addresses */
ai->ai_addrlen) != 0) {
/* maps to more than one address */
return (EINVAL);
}
}
return (EINVAL);
}
return (0);
}
static int
{
char pval[DLADM_PROP_VAL_MAX];
int err = 0;
/*
* The property value is in the format of "src:xxx" "dst:xxx"
* "tun_id:0x%x" "tos:0x%x" "hoplimit:xxx"
*/
for (i = 0; i < nval; i++) {
return (EINVAL);
*sep = '\0';
sep++;
if (id_set)
return (EINVAL);
errno = 0;
return (EINVAL);
if (src_set)
return (EINVAL);
if (err != 0)
return (err);
if (dst_set)
return (EINVAL);
if (err != 0)
return (err);
if (tos_set)
return (EINVAL);
errno = 0;
return (EINVAL);
if (ttl_set)
return (EINVAL);
errno = 0;
*endp != '\0') {
return (EINVAL);
}
}
}
return (0);
}
static rc_err_t
void *arg)
{
for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
i * DLADM_PROP_VAL_MAX;
}
case DDLVT_STRING:
goto out;
goto out;
valcnt = 1;
break;
case DDLVT_STRINGS:
if (val->ddlv_slist_count == 0)
goto out;
goto out;
for (i = 0; i < val->ddlv_slist_count; i++) {
}
break;
case DDLVT_ULONG:
goto out;
valcnt = 1;
*val->ddlv_ulval);
break;
case DDLVT_BOOLEAN:
case DDLVT_BOOLEANS:
case DDLVT_LONG:
case DDLVT_LONGS:
case DDLVT_ULONGS:
case DDLVT_DICTIONARY:
case DDLVT_DICTIONARYS:
default:
goto out;
}
propvals[0]);
if (err == 0)
goto out;
}
out:
}
static int
{
int err = 0;
&flist);
return (EINVAL);
return (err);
}
int
{
int err = 0;
"name", flowname);
return (ENODEV);
}
err = -1;
if (status == RCE_SERVER_OBJECT) {
/*
* XXX For now, log DDLSTATUS_NOT_FOUND as debug until
* we can determine how to handle the RAD caching
* issue.
*/
"failed Flow_getInfo(%s): %s",
}
}
if (err == 0) {
}
return (err);
}
static int
{
int err = 0;
err = -1;
if (status == RCE_SERVER_OBJECT) {
derrp->dde_errmsg);
}
goto out;
}
#if _TBD_
#endif
&dlval);
goto out;
}
&dlval);
goto out;
}
&dlval);
goto out;
}
&dlval);
goto out;
}
&dlval);
goto out;
}
out:
return (err);
}
int
{
int err;
"name", flowname);
goto out;
}
out:
return (err);
}
{
}
{
}
void
{
}
{
if (stat != KSTAT2_S_OK) {
(void) printf("can't get value: %s\n",
return (0);
}
return (0);
}
return (val->kstat2_integer);
}
void
{
int anamecnt = 0, i;
&anamecnt, 0);
return;
if (anamecnt == 0) {
return;
}
for (i = 0; i < anamecnt; i++) {
const char *props[1];
const char *fields[1];
int ndlist = 0;
continue;
props[0] = "ofport";
fields[0] = "current";
if (rerr == RCE_SERVER_OBJECT) {
"failed Datalink_getProperties(%s, %s): %s",
}
continue;
}
"current", &dlval);
continue;
}
}
}
for (i = 0; i < anamecnt; i++)
adr_name_rele(anamearr[i]);
}
{
int anamecnt = 0, i;
int err = 0;
&anamecnt, 0);
return (0);
if (anamecnt == 0) {
return (0);
}
for (i = 0; i < anamecnt; i++) {
char linkname[MAXLINKNAMELEN];
const char *props[1];
const char *fields[1];
struct flow f, m;
int ndlist = 0;
NULL) {
if (no_default)
continue;
else
is_default = B_TRUE;
}
continue;
&lastused)) != 0) {
"name"), err);
goto done;
}
err = -1;
if (rerr == RCE_SERVER_OBJECT) {
/*
* XXX For now, log DDLSTATUS_NOT_FOUND as
* debug until we can determine how to handle
* the RAD caching issue.
*/
"failed Flow_getInfo(%s): %s",
derrp->dde_errmsg);
}
goto done;
}
/* See whether this flow is created over of enabled link */
if (err != 0) {
goto done;
}
goto done;
}
props[0] = "openvswitch";
fields[0] = "current";
err = -1;
if (rerr == RCE_SERVER_OBJECT) {
"failed Datalink_getProperties(%s, %s): %s",
}
goto done;
}
"current", &dlval);
goto done;
goto done;
if (err != 0) {
"name"), err);
goto done;
}
if (err != 0) {
"flowinfo2flow failed for %s: %d",
goto done;
}
}
}
n_flows++;
done:
}
for (i = 0; i < anamecnt; i++)
adr_name_rele(anamearr[i]);
return (n_flows);
}
int
{
int error;
if (status == DLADM_STATUS_NOMEM) {
} else if (status == DLADM_STATUS_DENIED) {
} else if (status == DLADM_STATUS_OK) {
error = 0;
} else if (status == DLADM_STATUS_IOERR) {
} else {
}
return (error);
}
solaris_is_uplink_class(const char *class)
{
}
/*
* This is a copy of dlparse_zonelinkname() function in libinetutil. libinetutil
* is not a public interface, therefore we make a copy here.
*
* Given a linkname that can be specified using a zonename prefix retrieve
* specified we set the optional linkname and set optional zone ID return
* value to ALL_ZONES.
*/
{
char buffer[MAXLINKNAMESPECIFIER];
char *search = "/";
char *zonetoken;
char *linktoken;
char *last;
link_name[0] = '\0';
sizeof (buffer))
return (_B_FALSE);
return (_B_FALSE);
/* If there are no other strings, return given name as linkname */
if (namelen >= MAXLINKNAMELEN)
return (_B_FALSE);
return (_B_TRUE);
}
/* First token is the zonename. Check zone and link lengths */
return (_B_FALSE);
/*
* If there are more '/' separated strings in the input
* name then we return failure. We only support a single
*/
return (_B_FALSE);
return (_B_FALSE);
}
return (_B_TRUE);
}