/*
* 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
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Milan Jurik. All rights reserved.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <netdb.h>
#include <ofmt.h>
#include <assert.h>
#include <libilb.h>
#include "ilbadm.h"
};
};
};
};
};
};
/* field ids for of_* functions */
#define OF_IP_VIP 0
#define OF_STR_RNAME 0
#define OF_PORT 0
#define OF_T_CONN 0
#define OF_SRV_ID 0
/* some field sizes of ofmt_field_t arrays */
typedef struct arg_struct {
int flags;
char *o_str;
typedef struct ilbadm_rl_exp_arg {
typedef struct ilbadm_rl_list_arg {
ilb_handle_t h;
typedef struct ilbadm_rl_srvlist_arg {
char *sgname;
int flags;
char *o_str;
};
};
};
};
extern char *optarg;
extern ilbadm_val_type_t algo_types[];
extern ilbadm_val_type_t topo_types[];
static char *
{
int i;
for (i = 0; n[i].k_key != ILB_KEY_BAD; i++)
if (n[i].k_key == k)
break;
return (n[i].k_name);
}
char *
{
char *name;
int i;
if (*name != '\0')
return (name);
}
return (NULL);
}
/*
* ports are in HOST byte order
*/
static void
{
else
}
static void
{
else
}
static void
{
}
static int
{
}
static void
{
}
static int
{
}
static boolean_t
{
case OF_STR_RNAME:
break;
case OF_STR_SGNAME:
break;
case OF_STR_HCNAME:
break;
}
return (B_TRUE);
}
/* ARGSUSED */
static boolean_t
{
else
return (B_FALSE);
return (B_TRUE);
}
static boolean_t
{
case OF_IP_VIP:
break;
case OF_IP_PROXYSRC:
break;
case OF_IP_STICKYMASK:
break;
}
/* only print something valid */
buf[0] != '\0') {
}
return (B_TRUE);
}
static boolean_t
{
return (B_TRUE);
return (B_TRUE);
}
static void
{
else
buf[0] = '\0';
}
static boolean_t
{
bufsize));
/* only print a hcport if there's a hc name as well */
return (B_TRUE);
}
/* ARGSUSED */
static boolean_t
{
buf[0] = 'E';
else
buf[0] = 'D';
return (B_TRUE);
}
static boolean_t
{
return (B_FALSE);
return (B_TRUE);
}
static boolean_t
{
return (B_FALSE);
return (B_TRUE);
}
static boolean_t
{
case OF_T_CONN:
break;
case OF_T_NAT:
break;
case OF_T_STICKY:
break;
}
return (B_TRUE);
}
typedef struct rl_showlist_arg {
char *buf;
/* ARGSUSED */
/* called by ilb_walk_servers(), cannot get rid of unused args */
static ilb_status_t
{
int len;
return (ILB_STATUS_OK);
}
static boolean_t
{
(void *)&sla);
/* we're trailing a ',' which we need to remove */
return (B_TRUE);
}
static boolean_t
{
int len;
if (h_min == 0)
return (B_FALSE); /* print "unspec" == "all ports" */
return (B_TRUE);
}
static ilbadm_status_t
{
int ret;
case AF_INET:
break;
case AF_INET6:
break;
default: return (ILBADM_INVAL_AF);
}
/* if we can't resolve this, just return an empty name */
buf[0] = '\0';
else
return (ILBADM_OK);
}
/* ARGSUSED */
/*
* Since this function is used by libilb routine ilb_walk_rules()
* it must return libilb errors
*/
static ilb_status_t
{
int oflags = 0;
return (ILB_STATUS_GENERIC);
}
/*
* note: both LIST_**ABLED flags can be set at the same time,
* whereas a rule has one state only. therefore the complicated
* statement.
*/
return (ILB_STATUS_OK);
oflags |= OFMT_PARSABLE;
oflags |= OFMT_MULTILINE;
ra.h = h;
fields = rfields_v4;
else
fields = rfields_v6;
if (oerr != OFMT_SUCCESS) {
char e[80];
return (ILB_STATUS_GENERIC);
}
}
return (ILB_STATUS_OK);
}
static char *full_list_rule_hdrs =
"RULENAME,STATUS,PORT,PROTOCOL,LBALG,TYPE,PROXY-SRC,PMASK,"
"HC-NAME,HC-PORT,CONN-DRAIN,NAT-TIMEOUT,"
"PERSIST-TIMEOUT,SERVERGROUP,VIP,SERVERS";
static char *def_list_rule_hdrs =
"RULENAME,STATUS,LBALG,TYPE,PROTOCOL,VIP,PORT";
/* ARGSUSED */
{
int c;
switch ((char)c) {
break;
break;
break;
/* -e and -d may be repeated - make sure the last one wins */
break;
break;
(char)optopt);
rc = ILBADM_LIBERR;
goto out;
case '?':
default:
/* not reached */
break;
}
}
" exclusive"));
exit(1);
}
exit(1);
}
" names for -o"));
exit(1);
}
/* no -o option, so we use std. fields */
if (rclib != ILB_STATUS_OK)
goto out;
(void*)&larg);
} else {
if (rclib != ILB_STATUS_OK)
break;
}
}
out:
if (h != ILB_INVALID_HANDLE)
(void) ilb_close(h);
if (rclib != ILB_STATUS_OK) {
/*
* The show function returns ILB_STATUS_GENERIC after printing
* out an error message. So we don't need to print it again.
*/
if (rclib != ILB_STATUS_GENERIC)
rc = ILBADM_LIBERR;
}
return (rc);
}
static boolean_t
{
return (B_FALSE);
switch (op) {
case OF_SRV_ID:
break;
case OF_SRV_STATUS:
buf[0] = 'E';
else
buf[0] = 'D';
break;
case OF_SRV_RNAME:
break;
case OF_SRV_SGNAME:
break;
case OF_SRV_HOSTNAME:
buf[0] = '\0';
}
break;
case OF_SRV_PORT:
break;
case OF_SRV_ADDR:
break;
}
return (ret);
}
/* ARGSUSED */
static ilb_status_t
void *arg)
{
return (ILB_STATUS_OK);
}
/* ARGSUSED */
/*
* Since this function is used by libilb routine ilb_walk_rules()
* it must return libilb errors
*/
{
int oflags = 0;
/*
* in full mode, we currently re-open ofmt() for every rule; we use
* a variable number of lines, as we print one for every server
* attached to a rule.
*/
return (ILB_STATUS_GENERIC);
}
oflags |= OFMT_PARSABLE;
else
if (oerr != OFMT_SUCCESS) {
char e[80];
return (ILB_STATUS_GENERIC);
}
}
}
static char *def_show_srv_hdrs =
"SERVERID,ADDRESS,PORT,RULENAME,STATUS,SERVERGROUP";
/* ARGSUSED */
{
int c;
switch ((char)c) {
break;
break;
(char)optopt);
rc = ILBADM_LIBERR;
goto out;
case '?':
default:
/* not reached */
break;
}
}
exit(1);
}
" field names for -o"));
exit(1);
}
/* no -o option, so we use default fields */
if (!o_opt)
if (rclib != ILB_STATUS_OK)
goto out;
(void*)&larg);
} else {
if (rclib != ILB_STATUS_OK)
break;
}
}
out:
if (h != ILB_INVALID_HANDLE)
(void) ilb_close(h);
if (rclib != ILB_STATUS_OK) {
/*
* The show function returns ILB_STATUS_GENERIC after printing
* out an error message. So we don't need to print it again.
*/
if (rclib != ILB_STATUS_GENERIC)
rc = ILBADM_LIBERR;
}
return (rc);
}
static ilbadm_status_t
{
return (rc);
}
static void
{
return;
}
static void
{
}
/* ARGSUSED */
{
int c, i;
switch ((char)c) {
case 'a':
break;
case '?':
default:
/* not reached */
break;
}
}
return (ILBADM_LIBERR);
}
/* either "-a" or rulename, not both */
goto out;
}
if (rclib != ILB_STATUS_OK)
goto out;
if (all_rules) {
goto out;
}
out:
if (h != ILB_INVALID_HANDLE)
(void) ilb_close(h);
/* This prints the specific errors */
if (rclib != ILB_STATUS_OK) {
rc = ILBADM_LIBERR;
}
/* This prints the generic errors */
return (rc);
}
/* ARGSUSED */
static ilbadm_status_t
{
int i;
if (rclib != ILB_STATUS_OK)
goto out;
/*
* by default, en/disable-rule mean "all", and not using
* a rule name will cause this behaviour to kick in
*/
if (argc < 2) {
if (cmd == cmd_enable_rule)
else
} else {
if (cmd == cmd_enable_rule)
else
}
}
out:
if (h != ILB_INVALID_HANDLE)
(void) ilb_close(h);
if (rclib != ILB_STATUS_OK) {
rc = ILBADM_LIBERR;
}
return (rc);
}
{
}
{
}
/*
* parse and create a rule
*/
{
int c;
switch ((char)c) {
case 'e':
break;
case 'h':
/*
* Default value of of r_hcpflag means that if there
* is a port range, probe any port. If there is only
* one port, probe that port.
*/
break;
case 'o':
break;
case 'm':
break;
case 't':
break;
case 'i':
break;
case 'p':
break;
case ':':
" for %c"), (char)optopt);
rc = ILBADM_LIBERR;
break;
case '?':
default:
/* not reached */
break;
}
goto out;
}
" to 'ilbadm create-rule' subcommand description in"
" ilbadm(1M)"));
rc = ILBADM_LIBERR;
goto out;
}
if (p_opt) {
/*
* if user hasn't specified a mask, apply default
*/
char *maskstr;
case AF_INET:
maskstr = "32";
break;
case AF_INET6:
maskstr = "128";
break;
}
" persistence mask"));
rc = ILBADM_LIBERR;
goto out;
}
}
} else {
/* use of sticky mask currently mandates "-p" */
" -p option"));
rc = ILBADM_LIBERR;
goto out;
}
}
ILBD_NAMESZ - 1);
rc = ILBADM_LIBERR;
goto out;
}
goto out;
if (rclib != ILB_STATUS_OK)
goto out;
out:
if (h != ILB_INVALID_HANDLE)
(void) ilb_close(h);
if (rclib != ILB_STATUS_OK) {
rc = ILBADM_LIBERR;
}
return (rc);
}
/* ARGSUSED */
/*
* Since this function is used by libilb function, ilb_walk_rules()
* it must return libilb errors
*/
static ilb_status_t
{
/* if the address is unspecified, skip it */
if (linebuf[0] != '\0') {
}
}
}
if (linebuf[0] != '\0')
}
int cnt = 0;
if (conndrain != 0) {
cnt++;
}
if (nat_timeout != 0) {
if (cnt > 0)
cnt++;
}
if (sticky_timeout != 0) {
if (cnt > 0)
}
}
return (ILB_STATUS_WRITE);
return (ILB_STATUS_OK);
}
{
if (rclib != ILB_STATUS_OK)
rc = ILBADM_LIBERR;
return (rc);
}