/*
* 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 <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/mac_flow.h>
#include <netdb.h>
#include <net/if_types.h>
#include <libdladm.h>
#include <libdlflow.h>
#include <libdlflow_impl.h>
/* max port number for UDP, TCP & SCTP */
{ "local_ip", do_check_local_ip },
{ "remote_ip", do_check_remote_ip },
{ "transport", do_check_protocol },
{ "local_port", do_check_local_port },
{ "remote_port", do_check_remote_port },
{ "dsfield", do_check_dsfield },
};
static dladm_status_t
{
}
static dladm_status_t
{
}
{
int family;
*prefix_str++ = '\0';
errno = 0;
return (DLADM_STATUS_INVALID_PREFIXLEN);
}
} else {
return (DLADM_STATUS_INVALID_IP);
}
if (local) {
mask |= FLOW_IP_LOCAL;
} else {
mask |= FLOW_IP_REMOTE;
}
} else {
}
if (prefix_len == 0)
if (status != DLADM_STATUS_OK) {
return (DLADM_STATUS_INVALID_PREFIXLEN);
}
return (DLADM_STATUS_OK);
}
{
if (protocol != 0) {
return (DLADM_STATUS_OK);
} else {
return (DLADM_STATUS_INVALID_PROTOCOL);
}
}
{
}
{
}
{
long val;
return (DLADM_STATUS_INVALID_PORT);
if (local) {
} else {
}
return (DLADM_STATUS_OK);
}
/*
*/
static dladm_status_t
{
int i, j;
for (j = 0; j < DLADM_MAX_FLOWATTRS; j++)
for (j = 0; j < DLADM_MAX_FLOWATTRS; j++) {
attr_table[j].ad_name) == 0) {
if (isset[j])
return (DLADM_STATUS_FLOW_INCOMPATIBLE);
else
}
}
/*
* if the attribute did not match any of the attribute in
* attr_table, then it's an invalid attribute.
*/
if (!matched)
return (DLADM_STATUS_BADARG);
}
return (DLADM_STATUS_OK);
}
/*
* Convert an attribute list to a flow_desc_t using the attribute ad_check()
* functions.
*/
{
int i;
int j;
for (j = 0; j < DLADM_MAX_FLOWATTRS; j++) {
continue;
return (DLADM_STATUS_BADARG);
else
if (status != DLADM_STATUS_OK)
return (status);
}
}
/*
* Make sure protocol is specified if either local or
* remote port is specified.
*/
(FLOW_ULP_PORT_LOCAL | FLOW_ULP_PORT_REMOTE)) != 0 &&
return (DLADM_STATUS_PORT_NOPROTO);
return (status);
}
void
{
}
{
!= DLADM_STATUS_OK)
return (DLADM_STATUS_ATTR_PARSE_ERR);
!= DLADM_STATUS_OK) {
return (DLADM_STATUS_ATTR_PARSE_ERR);
}
return (DLADM_STATUS_OK);
}
{
*mask_str++ = '\0';
errno = 0;
*endp != '\0')
return (DLADM_STATUS_INVALID_DSFMASK);
}
errno = 0;
return (DLADM_STATUS_INVALID_DSF);
return (DLADM_STATUS_OK);
}
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 ("");
}
{
return (IPPROTO_TCP);
return (IPPROTO_UDP);
return (IPPROTO_SCTP);
return (IPPROTO_ICMPV6);
return (IPPROTO_ICMP);
return (0);
}
void
{
} else {
}
prefix_max, &prefix_len);
} else {
}
prefix_max, &prefix_len);
} else {
buf[0] = '\0';
}
}
void
{
}
void
{
} else {
buf[0] = '\0';
}
}
void
{
} else {
buf[0] = '\0';
}
}