summaryrefslogtreecommitdiff
path: root/usr.sbin/altq/libaltq/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/altq/libaltq/parser.c')
-rw-r--r--usr.sbin/altq/libaltq/parser.c769
1 files changed, 306 insertions, 463 deletions
diff --git a/usr.sbin/altq/libaltq/parser.c b/usr.sbin/altq/libaltq/parser.c
index 2fb0a65351d..22d1e2cdeae 100644
--- a/usr.sbin/altq/libaltq/parser.c
+++ b/usr.sbin/altq/libaltq/parser.c
@@ -1,32 +1,36 @@
-/* $OpenBSD: parser.c,v 1.4 2001/08/16 12:59:43 kjc Exp $ */
-/* $KAME: parser.c,v 1.12 2001/08/16 10:39:13 kjc Exp $ */
-/*******************************************************************
-
- Copyright (c) 1996 by the University of Southern California
- All rights reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation in source and binary forms for any purpose and without
- fee is hereby granted, provided that both the above copyright notice
- and this permission notice appear in all copies. and that any
- documentation, advertising materials, and other materials related to
- such distribution and use acknowledge that the software was developed
- in part by the University of Southern California, Information
- Sciences Institute. The name of the University may not be used to
- endorse or promote products derived from this software without
- specific prior written permission.
-
- THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
- the suitability of this software for any purpose. THIS SOFTWARE IS
- PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
- Other copyrights might apply to parts of this software and are so
- noted when applicable.
-
-********************************************************************/
+/* $OpenBSD: parser.c,v 1.5 2002/02/13 08:21:45 kjc Exp $ */
+/* $KAME: parser.c,v 1.13 2002/02/12 10:14:01 kjc Exp $ */
+/*
+ * Copyright (C) 1999-2002
+ * Sony Computer Science Laboratories, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,11 +40,7 @@
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
-#include <sys/socket.h>
#include <netdb.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include <altq/altq.h>
#include <altq/altq_cdnr.h>
@@ -49,17 +49,10 @@
#include "altq_qop.h"
#include "qop_cdnr.h"
-#define show_help(op) printf(cmd_tab[op].cmd_help)
-
-/*
- * Forward & External Declarations
- */
static int is_qdisc_name(const char *);
static int qdisc_interface_parser(const char *, const char *, int, char **);
static int qdisc_class_parser(const char *, const char *, const char *,
- const char *, int, char **);
-
-static int pfxcmp(const char *, const char *);
+ const char *, int, char **);
static int next_word(char **, char *);
static int do_cmd(int, char *);
@@ -82,18 +75,10 @@ static int rio_parser(char *);
static int conditioner_parser(char *);
static int tc_action_parser(char *, char **, struct tc_action *);
-/*
- * Globals
- */
-#define MAX_NFLWDS 64
-#define MAX_T 64
-
-int TNO = 1; /* Current Thread number */
-int line_no = 0;
-int filter_dontwarn;
-
-static char if_names[MAX_T][IFNAMSIZ];
-static struct if_nameindex *if_namelist = NULL;
+#define MAX_LINE 1024
+#define MAX_WORD 64
+#define MAX_ARGS 64
+#define MAX_ACTIONS 16
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
@@ -101,70 +86,143 @@ static struct if_nameindex *if_namelist = NULL;
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
+#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
+
+int line_no = 0;
+int filter_dontwarn;
-enum op_codes {
- /* order must be same as entries cmd_tab[].cmd_op below!! */
- OP_HELP = 1, OP_QUIT,
- OP_IFACE, OP_CLASS, OP_FILTER,
- OP_ALTQ, OP_DEL,
+static char curifname[IFNAMSIZ];
+static struct if_nameindex *if_namelist = NULL;
+
+struct cmd_tab {
+ const char *cmd;
+ int (*parser)(char *);
+ const char *help;
+} cmd_tab[] = {
+ {"help", NULL, "help | ?"},
+ {"quit", NULL, "quit"},
+ {"interface", interface_parser, "interface if_name [bandwidth bps] [cbq|hfsc]"},
+ {"class", class_parser, "class discipline if_name class_name [parent]"},
+ {"filter", filter_parser, "filter if_name class_name [name filt_name] dst [netmask #] dport src [netmask #] sport proto [tos # [tosmask #] [gpi #] [dontwarn]"},
+ {"altq", ctl_parser, "altq if_name {enable|disable}"},
+ {"delete", delete_parser, "delete if_name class_name [filter_name]"},
#ifdef INET6
- OP_FILTER6,
+ {"filter6", filter6_parser, "filter6 if_name class_name [name filt_name] dst[/prefix] dport src[/prefix] sport proto [flowlabel #][tclass # [tclassmask #]][gpi #] [dontwarn]"},
#endif
- OP_RED, OP_RIO,
- OP_CDNR,
- OP_NULL, OP_BUG
+ {"red", red_parser, "red th_min th_max inv_pmax"},
+ {"rio", rio_parser, "rio low_th_min low_th_max low_inv_pmax med_th_min med_th_max med_inv_pmax high_th_min high_th_max high_inv_pmax"},
+ {"conditioner", conditioner_parser, "conditioner if_name cdnr_name <tc_action>"},
+ {"debug", NULL, "debug"},
+ {NULL, NULL, NULL} /* termination */
};
-/* Following table MUST match enum order of op_codes !
+/*
+ * read one line from the specified stream. if it's a command,
+ * execute the command.
+ * returns 1 if OK, 0 if error or EOF.
*/
-struct cmds {
- char *cmd_verb;
- int cmd_op;
- char *cmd_help;
-} cmd_tab[] = {
-
- { "?", OP_HELP, "Commands are:\n" },
- { "help", OP_HELP, " help | ?\n" },
- { "quit", OP_QUIT, " quit\n" },
- { "interface", OP_IFACE, " interface if_name [bandwidth bps] [cbq|hfsc]\n" },
- { "class", OP_CLASS, " class discipline if_name class_name [parent]\n" },
- { "filter", OP_FILTER, " filter if_name class_name [name filt_name] dst [netmask #] dport src [netmask #] sport proto [tos # [tosmask #] [gpi #] [dontwarn]\n" },
- { "altq", OP_ALTQ, " disc if_name {enable|disable}\n" },
- { "delete", OP_DEL, " delete if_name class_name\n" },
-#ifdef INET6
- { "filter6", OP_FILTER6, " filter6 if_name class_name [name filt_name] dst[/prefix] dport src[/prefix] sport proto [flowlabel #][tclass # [tclassmask #]][gpi #] [dontwarn]\n" },
-#endif
- { "red", OP_RED, " red th_min th_max inv_pmax\n" },
- { "rio", OP_RIO, " rio low_th_min low_th_max low_inv_pmax med_th_min med_th_max med_inv_pmax high_th_min high_th_max high_inv_pmax\n" },
- { "conditioner", OP_CDNR, " conditioner if_name cdnr_name <tc_action>\n" },
- { "bug", OP_BUG, " bug (On/Off)\n" },
- { "", OP_NULL, "" } /* MUST BE LAST IN CMD TABLE */
-};
+do_command(FILE *fp)
+{
+ char cmd_line[MAX_LINE], cmd[MAX_WORD], *cp;
+ struct cmd_tab *tp;
+ int len, rval;
-static int
+ /*
+ * read a line from the stream and make it a null-terminated string
+ */
+ cp = cmd_line;
+read_line:
+ if (fgets(cp, &cmd_line[MAX_LINE] - cp, fp) == NULL)
+ /* EOF or error */
+ return(0);
+ line_no++;
+
+ /* null-terminate the line */
+ if ((len = strlen(cmd_line)) > 0) {
+ cp = cmd_line + len - 1;
+ if (*cp == '\n') {
+ /* if escaped newline, read next line */
+ if (len > 1 && *(cp - 1) == '\\')
+ goto read_line;
+ *cp = '\0';
+ } else if (!feof(fp))
+ err(1, "LINE %d too long!", line_no);
+ }
+ /* trim comments */
+ if ((cp = strchr(cmd_line, '#')) != NULL)
+ *cp = '\0';
+
+ cp = cmd_line;
+ if ((len = next_word(&cp, cmd)) == 0)
+ /* no command in this line */
+ return (1);
+
+ /* fnind the corresponding parser */
+ rval = 0;
+ for (tp = cmd_tab; tp->cmd != NULL; tp++)
+ if (strncmp(cmd, tp->cmd, len) == 0)
+ break;
+
+ if (tp->cmd == NULL) {
+ if (fp == stdin) {
+ printf(" ?? %s\n", cmd);
+ rval = 1;
+ } else
+ LOG(LOG_ERR, 0, "unknown command: %s", cmd);
+ return (rval);
+ }
+
+ if (tp->parser != NULL)
+ rval = (*tp->parser)(cp);
+ else {
+ /* handle other commands */
+ if (strcmp(tp->cmd, "quit") == 0)
+ rval = 0;
+ else if (strcmp(tp->cmd, "help") == 0 ||
+ strcmp(tp->cmd, "?") == 0) {
+ for (tp = cmd_tab; tp->cmd != NULL; tp++)
+ printf("%s\n", tp->help);
+ rval = 1;
+ } else if (strcmp(tp->cmd, "debug") == 0) {
+ if (m_debug & DEBUG_ALTQ) {
+ /* turn off verbose */
+ l_debug = LOG_INFO;
+ m_debug &= ~DEBUG_ALTQ;
+ } else {
+ /* turn on verbose */
+ l_debug = LOG_DEBUG;
+ m_debug |= DEBUG_ALTQ;
+ }
+ rval = 1;
+ }
+ }
+ return (rval);
+}
+
+static int
is_qdisc_name(const char *qname)
{
struct qdisc_parser *qp;
-
+
for (qp = qdisc_parser; qp->qname != NULL; qp++)
if (strncmp(qp->qname, qname, strlen(qp->qname)) == 0)
return (1);
return (0);
}
-static int
+static int
qdisc_interface_parser(const char * qname, const char *ifname,
int argc, char **argv)
{
struct qdisc_parser *qp;
-
+
for (qp = qdisc_parser; qp->qname != NULL; qp++)
if (strncmp(qp->qname, qname, strlen(qp->qname)) == 0)
return (*qp->interface_parser)(ifname, argc, argv);
return (0);
}
-static int
+static int
qdisc_class_parser(const char *qname, const char *ifname,
const char *class_name, const char *parent_name,
int argc, char **argv)
@@ -180,15 +238,13 @@ qdisc_class_parser(const char *qname, const char *ifname,
return (0);
}
if ((ifinfo = ifname2ifinfo(ifname)) == NULL) {
- LOG(LOG_ERR, 0,
- "no such interface, line %d", line_no);
+ LOG(LOG_ERR, 0, "no such interface");
return (0);
}
if (strncmp(ifinfo->qdisc->qname, qname,
strlen(ifinfo->qdisc->qname)) != 0) {
LOG(LOG_ERR, 0,
- "qname doesn't match the interface, line %d",
- line_no);
+ "qname doesn't match the interface");
return (0);
}
return (*qp->class_parser)(ifname, class_name,
@@ -197,222 +253,67 @@ qdisc_class_parser(const char *qname, const char *ifname,
return (0);
}
-
/*
- * Read the config file to learn about tunnel vifs and non-default phyint
- * parameters.
+ * read the config file
*/
int
qcmd_config(void)
{
- FILE *f;
- int i, rc = 1;
+ FILE *fp;
+ int i, rval;
if (if_namelist != NULL)
if_freenameindex(if_namelist);
if_namelist = if_nameindex();
-
- for (i = 0; i < MAX_T; i++)
- if_names[i][0] = '\0';
+ curifname[0] = '\0';
LOG(LOG_INFO, 0, "ALTQ config file is %s", altqconfigfile);
- f = fopen(altqconfigfile, "r");
- if (f == NULL) {
+ fp = fopen(altqconfigfile, "r");
+ if (fp == NULL) {
LOG(LOG_ERR, errno, "can't open %s", altqconfigfile, 0);
return (QOPERR_INVAL);
}
line_no = 0;
- while (rc)
- rc = DoCommand(altqconfigfile, f);
-
- (void) fclose(f);
- line_no = 0;
- return (0);
-}
-
-/*
- * Do_Command(): Top-level routine to read the next line from a given
- * file and execute the command it contains.
- * returns 1 if OK, 0 if EOF.
- */
-int
-DoCommand(char *infile, FILE *infp)
-{
- char cmd_line[256], cmd_op[80];
- struct cmds *cmdp;
- char *cp;
- int rc;
-
- if (fgets(cmd_line, sizeof(cmd_line), infp) == NULL)
- /* EOF */
- return(0);
- line_no++;
-
- /* check escaped newline */
- while ((cp = strrchr(cmd_line, '\\')) != NULL && cp[1] == '\n') {
- if (fgets(cp, &cmd_line[256] - cp, infp) != NULL)
- line_no++;
- }
-
- /* remove trailing NL */
- cp = cmd_line + strlen(cmd_line) - 1;
- if (*cp == '\n')
- *cp = '\0';
- else if (!feof(infp)) {
- printf("LINE %d > 255 CHARS: %s.\n", line_no, cmd_line);
- exit(1);
- }
- /*** printf("DoCommand: %s\n", cmd_line); ***/
-
- if (cmd_line[0] == '#') { /* Comment, skip this line */
- return(1);
- }
- cp = cmd_line;
- if (!next_word(&cp, cmd_op))
- return(1);
- if (cmd_op[0] == 'T') {
- TNO = atoi(&cmd_op[1]);
- if (!next_word(&cp, cmd_op))
- return(1);
- }
- cmdp = cmd_tab;
- while ((cmdp->cmd_op != OP_NULL) && pfxcmp(cmd_op, cmdp->cmd_verb))
- cmdp++;
-
- if (cmdp->cmd_op == OP_NULL) {
- if (cmd_op[0])
- printf(" ?? %s\n", cmd_op);
- return(1);
- }
- rc = do_cmd(cmdp->cmd_op, cp);
- if (rc == 0) {
- if (infile) {
- /* error in the config file. cleanup and exit. */
- LOG(LOG_ERR, 0, "config failed. exiting...");
- (void) qcmd_destroyall();
- (void) fclose(infp);
- exit(1);
- } else {
- /* interactive mode */
- printf("error: usage :");
- show_help(cmdp->cmd_op);
- }
- }
- return(1);
-}
+ while (rval)
+ rval = do_command(fp);
+ if (!feof(fp)) {
+ LOG(LOG_ERR, 0, "Error in %s, line %d. config failed.",
+ altqconfigfile, line_no);
+ (void) qcmd_destroyall();
+ rval = QOPERR_INVAL;
+ } else
+ rval = 0;
-/*
- * Prefix string comparison: Return 0 if s1 string is prefix of s2 string, 1
- * otherwise.
- */
-static int
-pfxcmp(const char *s1, const char *s2)
-{
- while (*s1)
- if (*s1++ != *s2++)
- return (1);
- return (0);
+ (void)fclose(fp);
+ line_no = 0;
+ return (rval);
}
-/*
- * Skip leading blanks, then copy next word (delimited by blank or zero, but
- * no longer than 63 bytes) into buffer b, set scan pointer to following
- * non-blank (or end of string), and return 1. If there is no non-blank text,
- * set scan ptr to point to 0 byte and return 0.
- */
static int
next_word(char **cpp, char *b)
{
- char *tp;
- size_t L;
-
- *cpp += strspn(*cpp, " \t");
- if (**cpp == '\0' || **cpp == '\n' || **cpp == '#')
- return(0);
-
- tp = strpbrk(*cpp, " \t\n#");
- L = MIN((tp)?(tp-*cpp):strlen(*cpp), 63);
- strncpy(b, *cpp, L);
- *(b + L) = '\0';
- *cpp += L;
- *cpp += strspn(*cpp, " \t");
- return (1);
-}
+ char *cp;
+ int i;
-/*
- * do_cmd executes a command input.
- * returns 1 if OK, 0 if an error occurs.
- */
-static int
-do_cmd(int op, char *cmdbuf)
-{
- int i, rval = 0;
-
- switch (op) {
- case OP_HELP:
- for (i = 0; i < OP_NULL; i++)
- show_help(i);
- rval = 1;
- break;
- case OP_QUIT:
- qcmd_destroyall();
- exit(0);
- break;
- case OP_IFACE:
- rval = interface_parser(cmdbuf);
- break;
- case OP_CLASS:
- rval = class_parser(cmdbuf);
- break;
- case OP_FILTER:
- rval = filter_parser(cmdbuf);
- break;
- case OP_ALTQ:
- rval = ctl_parser(cmdbuf);
- break;
- case OP_DEL:
- rval = delete_parser(cmdbuf);
- break;
-#ifdef INET6
- case OP_FILTER6:
- rval = filter6_parser(cmdbuf);
- break;
-#endif
- case OP_RED:
- rval = red_parser(cmdbuf);
- break;
- case OP_RIO:
- rval = rio_parser(cmdbuf);
- break;
- case OP_CDNR:
- rval = conditioner_parser(cmdbuf);
- break;
- case OP_BUG:
- if (m_debug & DEBUG_ALTQ) {
- /* turn off verbose */
- l_debug = LOG_INFO;
- m_debug &= ~DEBUG_ALTQ;
- } else {
- /* turn on verbose */
- l_debug = LOG_DEBUG;
- m_debug |= DEBUG_ALTQ;
- }
- break;
- default:
- printf("command %d not supported\n", op);
- rval = 0;
- break;
+ cp = *cpp;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ for (i = 0; i < MAX_WORD - 1; i++) {
+ if (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\0')
+ break;
+ *b++ = *cp++;
}
- return(rval);
+ *b = '\0';
+ *cpp = cp;
+ return (i);
}
-#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
-
-char *cur_ifname(void)
+char *
+cur_ifname(void)
{
- return (if_names[TNO]);
+ return (curifname);
}
u_int
@@ -429,7 +330,7 @@ get_ifindex(const char *ifname)
static int
get_ifname(char **cpp, char **ifnamep)
{
- char w[128], *ocp;
+ char w[MAX_WORD], *ocp;
struct if_nameindex *ifnp;
ocp = *cpp;
@@ -437,16 +338,16 @@ get_ifname(char **cpp, char **ifnamep)
for (ifnp = if_namelist; ifnp->if_name != NULL; ifnp++)
if (strcmp(w, ifnp->if_name) == 0) {
/* if_name found. advance the word pointer */
- *cpp = ocp;
- strlcpy(if_names[TNO], w, sizeof(if_names[TNO]));
- *ifnamep = if_names[TNO];
+ *cpp = ocp;
+ strlcpy(curifname, w, sizeof(curifname));
+ *ifnamep = curifname;
return (1);
}
/* this is not interface name. use one in the context. */
- if (if_names[TNO][0] == 0)
+ if (curifname[0] == '\0')
return (0);
- *ifnamep = if_names[TNO];
+ *ifnamep = curifname;
return (1);
}
@@ -454,9 +355,9 @@ get_ifname(char **cpp, char **ifnamep)
static int
get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask)
{
- char w[128], *ocp;
+ char w[MAX_WORD], *ocp;
struct in_addr tmp;
-
+
addr->s_addr = 0;
mask->s_addr = 0xffffffff;
@@ -467,13 +368,11 @@ get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask)
/* try gethostbyname */
struct hostent *h;
- if ((h = gethostbyname(w)) == NULL
- || h->h_addrtype != AF_INET || h->h_length != 4)
+ if ((h = gethostbyname(w)) == NULL ||
+ h->h_addrtype != AF_INET || h->h_length != 4)
return (0);
-
bcopy(h->h_addr, &tmp, (size_t)h->h_length);
}
-
addr->s_addr = tmp.s_addr;
/* check if netmask option is present */
@@ -481,12 +380,11 @@ get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask)
if (next_word(&ocp, w) && EQUAL(w, "netmask")) {
if (!next_word(&ocp, w))
return (0);
-
if (inet_aton((char *)w, (struct in_addr *)&tmp) != 1)
return (0);
mask->s_addr = tmp.s_addr;
- *cpp = ocp;
+ *cpp = ocp;
return (1);
}
/* no netmask option */
@@ -499,7 +397,7 @@ get_port(const char *name, u_int16_t *port_no)
{
struct servent *s;
u_int16_t num;
-
+
if (isdigit(name[0])) {
num = (u_int16_t)strtol(name, NULL, 0);
*port_no = htons(num);
@@ -517,7 +415,7 @@ static int
get_proto(const char *name, int *proto_no)
{
struct protoent *p;
-
+
if (isdigit(name[0])) {
*proto_no = (int)strtol(name, NULL, 0);
return (1);
@@ -533,7 +431,7 @@ get_proto(const char *name, int *proto_no)
static int
get_fltr_opts(char **cpp, char *fltr_name, size_t len, int *ruleno)
{
- char w[128], *ocp;
+ char w[MAX_WORD], *ocp;
ocp = *cpp;
while (next_word(&ocp, w)) {
@@ -559,88 +457,78 @@ get_fltr_opts(char **cpp, char *fltr_name, size_t len, int *ruleno)
static int
interface_parser(char *cmdbuf)
{
- char w[256], *ap, *cp = cmdbuf;
- char *ifname, *argv[64], qdisc_name[64];
- int argc, rval;
+ char w[MAX_WORD], *ap, *cp = cmdbuf;
+ char *ifname, *argv[MAX_ARGS], qdisc_name[MAX_WORD];
+ int argc;
if (!get_ifname(&cp, &ifname)) {
- LOG(LOG_ERR, 0, "missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name");
return (0);
}
- /*
- * Create argment list & look for scheduling discipline options.
- */
- snprintf(qdisc_name, sizeof(qdisc_name), "null");
+ /* create argment list & look for scheduling discipline options. */
+ sprintf(qdisc_name, "null");
argc = 0;
ap = w;
while (next_word(&cp, ap)) {
if (is_qdisc_name(ap))
- strlcpy(qdisc_name, ap, sizeof(qdisc_name));
+ strcpy(qdisc_name, ap);
argv[argc] = ap;
ap += strlen(ap) + 1;
argc++;
+ if (argc >= MAX_ARGS) {
+ LOG(LOG_ERR, 0, "too many args");
+ return (0);
+ }
}
- rval = qdisc_interface_parser(qdisc_name, ifname, argc, argv);
- if (rval == 0) {
- LOG(LOG_ERR, 0, "Error in %s, line %d",
- altqconfigfile, line_no);
- return (0);
- }
- return (1);
+ return qdisc_interface_parser(qdisc_name, ifname, argc, argv);
}
+
static int
-class_parser(char *cmdbuf)
+class_parser(char *cmdbuf)
{
- char w[256], *cp = cmdbuf;
- char *ifname, qdisc_name[128], class_name[128], parent_name[128];
+ char w[MAX_WORD], *cp = cmdbuf;
+ char *ifname, qdisc_name[MAX_WORD];
+ char class_name[MAX_WORD], parent_name[MAX_WORD];
char *clname = class_name;
char *parent = NULL;
- char *argv[64], *ap;
+ char *argv[MAX_ARGS], *ap;
int argc, rval;
/* get scheduling class */
if (!next_word(&cp, qdisc_name)) {
- LOG(LOG_ERR, 0, "missing scheduling discipline in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing discipline");
return (0);
}
if (!is_qdisc_name(qdisc_name)) {
- LOG(LOG_ERR, 0,
- "unknown scheduling discipline '%s' in %s, line %d",
- qdisc_name, altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "unknown discipline '%s'", qdisc_name);
return (0);
}
/* get interface name */
if (!get_ifname(&cp, &ifname)) {
- LOG(LOG_ERR, 0, "missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name");
return (0);
}
/* get class name */
if (!next_word(&cp, class_name)) {
- LOG(LOG_ERR, 0, "missing class name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing class name");
return (0);
}
/* get parent name */
if (!next_word(&cp, parent_name)) {
- LOG(LOG_ERR, 0, "missing parent class in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing parent class");
return (0);
}
- if (!EQUAL(parent_name, "null") && !EQUAL(parent_name, "NULL")) {
+ if (!EQUAL(parent_name, "null") && !EQUAL(parent_name, "NULL"))
parent = parent_name;
- } else {
+ else
parent = NULL;
- }
ap = w;
argc = 0;
@@ -648,24 +536,22 @@ class_parser(char *cmdbuf)
argv[argc] = ap;
ap += strlen(ap) + 1;
argc++;
+ if (argc >= MAX_ARGS) {
+ LOG(LOG_ERR, 0, "too many args");
+ return (0);
+ }
}
- rval = qdisc_class_parser(qdisc_name, ifname, clname, parent,
- argc, argv);
- if (rval == 0) {
- LOG(LOG_ERR, 0, "can't add class '%s' on interface '%s'",
- clname, ifname);
- return (0);
- }
-
- return (1);
+ return qdisc_class_parser(qdisc_name, ifname, clname, parent,
+ argc, argv);
}
static int
-filter_parser(char *cmdbuf)
+filter_parser(char *cmdbuf)
{
- char w[128], *cp = cmdbuf;
- char *ifname, class_name[64], fltr_name[64], *flname = NULL;
+ char w[MAX_WORD], *cp = cmdbuf;
+ char *ifname, class_name[MAX_WORD], fltr_name[MAX_WORD];
+ char *flname = NULL;
struct flow_filter sfilt;
int protocol;
u_char tos, tosmask;
@@ -677,24 +563,19 @@ filter_parser(char *cmdbuf)
sfilt.ff_flow.fi_family = AF_INET;
if (!get_ifname(&cp, &ifname)) {
- LOG(LOG_ERR, 0, "missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name in filter command");
return (0);
}
if (!next_word(&cp, class_name)) {
- LOG(LOG_ERR, 0,
- "missing class name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing class name in filter command");
return (0);
}
fltr_name[0] = '\0';
ruleno = 0;
if (!get_fltr_opts(&cp, &fltr_name[0], sizeof(fltr_name), &ruleno)) {
- LOG(LOG_ERR, 0,
- "bad filter option in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter option");
return (0);
}
if (fltr_name[0] != '\0')
@@ -703,53 +584,43 @@ filter_parser(char *cmdbuf)
/* get filter destination Address */
if (!get_addr(&cp, &sfilt.ff_flow.fi_dst, &sfilt.ff_mask.mask_dst)) {
- LOG(LOG_ERR, 0,
- "bad filter destination address in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter destination address");
return (0);
}
/* get filter destination port */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0,
- "missing filter destination port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter destination port");
return (0);
}
if (!get_port(w, &sfilt.ff_flow.fi_dport)) {
- LOG(LOG_ERR, 0, "bad filter destination port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter destination port");
return (0);
}
-
+
/* get filter source address */
if (!get_addr(&cp, &sfilt.ff_flow.fi_src, &sfilt.ff_mask.mask_src)) {
- LOG(LOG_ERR, 0, "bad filter source address in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter source address");
return (0);
}
/* get filter source port */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing filter source port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter source port");
return (0);
}
if (!get_port(w, &sfilt.ff_flow.fi_sport)) {
- LOG(LOG_ERR, 0, "bad filter source port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter source port");
return (0);
}
/* get filter protocol id */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing filter protocol id in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter protocol");
return (0);
}
if (!get_proto(w, &protocol)) {
- LOG(LOG_ERR, 0, "bad protocol in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad protocol");
return (0);
}
sfilt.ff_flow.fi_proto = protocol;
@@ -758,7 +629,7 @@ filter_parser(char *cmdbuf)
if (EQUAL(w, "tos")) {
tos = 0;
tosmask = 0xff;
-
+
if (next_word(&cp, w)) {
tos = (u_char)strtol(w, NULL, 0);
if (next_word(&cp, w)) {
@@ -768,8 +639,8 @@ filter_parser(char *cmdbuf)
}
}
}
- sfilt.ff_flow.fi_tos = tos;
- sfilt.ff_mask.mask_tos = tosmask;
+ sfilt.ff_flow.fi_tos = tos;
+ sfilt.ff_mask.mask_tos = tosmask;
} else if (EQUAL(w, "gpi")) {
if (next_word(&cp, w)) {
sfilt.ff_flow.fi_gpi =
@@ -793,7 +664,6 @@ filter_parser(char *cmdbuf)
class_name, ifname);
return (0);
}
-
return (1);
}
@@ -801,8 +671,9 @@ filter_parser(char *cmdbuf)
static int
filter6_parser(char *cmdbuf)
{
- char w[128], *cp = cmdbuf;
- char *ifname, class_name[128], fltr_name[64], *flname = NULL;
+ char w[MAX_WORD], *cp = cmdbuf;
+ char *ifname, class_name[MAX_WORD], fltr_name[MAX_WORD];
+ char *flname = NULL;
struct flow_filter6 sfilt;
int protocol;
u_char tclass, tclassmask;
@@ -814,23 +685,19 @@ filter6_parser(char *cmdbuf)
sfilt.ff_flow6.fi6_family = AF_INET6;
if (!get_ifname(&cp, &ifname)) {
- LOG(LOG_ERR, 0, "missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name");
return (0);
}
if (!next_word(&cp, class_name)) {
- LOG(LOG_ERR, 0, "missing class name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing class name");
return (0);
}
fltr_name[0] = '\0';
ruleno = 0;
if (!get_fltr_opts(&cp, &fltr_name[0], sizeof(fltr_name), &ruleno)) {
- LOG(LOG_ERR, 0,
- "bad filter option in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter option");
return (0);
}
if (fltr_name[0] != '\0')
@@ -840,56 +707,47 @@ filter6_parser(char *cmdbuf)
/* get filter destination address */
if (!get_ip6addr(&cp, &sfilt.ff_flow6.fi6_dst,
&sfilt.ff_mask6.mask6_dst)) {
- LOG(LOG_ERR, 0, "bad destination address in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad destination address");
return (0);
}
/* get filter destination port */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0,
- "missing filter destination port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter destination port");
return (0);
}
if (!get_port(w, &sfilt.ff_flow6.fi6_dport)) {
- LOG(LOG_ERR, 0, "bad filter destination port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter destination port");
return (0);
}
/* get filter source address */
if (!get_ip6addr(&cp, &sfilt.ff_flow6.fi6_src,
&sfilt.ff_mask6.mask6_src)) {
- LOG(LOG_ERR, 0, "bad source address in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad source address");
return (0);
}
/* get filter source port */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing filter source port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter source port");
return (0);
}
if (!get_port(w, &sfilt.ff_flow6.fi6_sport)) {
- LOG(LOG_ERR, 0, "bad filter source port in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad filter source port");
return (0);
}
/* get filter protocol id */
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing filter protocol id in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing filter protocol");
return (0);
}
if (!get_proto(w, &protocol)) {
- LOG(LOG_ERR, 0, "bad protocol in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad protocol");
return (0);
}
- sfilt.ff_flow6.fi6_proto = protocol;
+ sfilt.ff_flow6.fi6_proto = protocol;
while (next_word(&cp, w)) {
if (EQUAL(w, "tclass")) {
@@ -946,7 +804,7 @@ filter6_parser(char *cmdbuf)
static int
get_ip6addr(char **cpp, struct in6_addr *addr, struct in6_addr *mask)
{
- char w[128], *prefix;
+ char w[MAX_WORD], *prefix;
u_char *cp;
int len;
@@ -998,11 +856,11 @@ get_ip6addr(char **cpp, struct in6_addr *addr, struct in6_addr *mask)
static int
ctl_parser(char *cmdbuf)
{
- char w[128], *cp = cmdbuf;
+ char w[MAX_WORD], *cp = cmdbuf;
char *ifname;
int state;
int rval;
-
+
if (!get_ifname(&cp, &ifname)) {
printf("missing interface name in %s, line %d",
altqconfigfile, line_no);
@@ -1033,27 +891,35 @@ ctl_parser(char *cmdbuf)
return (1);
}
-
static int
delete_parser(char *cmdbuf)
{
char *cp = cmdbuf;
- char *ifname, class_name[128];
+ char *ifname, class_name[MAX_WORD], filter_name[MAX_WORD];
int ret;
-
+
if (!get_ifname(&cp, &ifname)) {
- printf("missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name");
return (0);
}
if (!next_word(&cp, class_name)) {
- LOG(LOG_ERR, 0,
- "missing class name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing class name");
return (0);
}
+ /* check if filter is specified */
+ if (next_word(&cp, filter_name)) {
+ ret = qcmd_delete_filter(ifname, class_name, filter_name);
+ if (ret) {
+ LOG(LOG_ERR, 0,
+ "can't delete filter '%s' on interface '%s'",
+ filter_name, ifname);
+ return (0);
+ }
+ return (1);
+ }
+
ret = qcmd_delete_class(ifname, class_name);
if (ret) {
LOG(LOG_ERR, 0,
@@ -1068,7 +934,7 @@ delete_parser(char *cmdbuf)
static int
red_parser(char *cmdbuf)
{
- char w[128], *cp = cmdbuf;
+ char w[MAX_WORD], *cp = cmdbuf;
int th_min, th_max, inv_pmax;
if (!next_word(&cp, w))
@@ -1091,15 +957,14 @@ red_parser(char *cmdbuf)
return (1);
bad:
- LOG(LOG_ERR, 0, "bad red parameter in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad red parameter");
return (0);
}
static int
rio_parser(char *cmdbuf)
{
- char w[128], *cp = cmdbuf;
+ char w[MAX_WORD], *cp = cmdbuf;
int i;
struct redparams params[RIO_NDROPPREC];
@@ -1125,28 +990,25 @@ rio_parser(char *cmdbuf)
return (1);
bad:
- LOG(LOG_ERR, 0, "bad rio parameter in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "bad rio parameter");
return (0);
}
static int
conditioner_parser(char *cmdbuf)
{
- char cdnr_name[128], *cp = cmdbuf;
+ char cdnr_name[MAX_WORD], *cp = cmdbuf;
char *ifname;
- struct tc_action action[64];
-
+ struct tc_action action[MAX_ACTIONS];
+
if (!get_ifname(&cp, &ifname)) {
- LOG(LOG_ERR, 0, "missing interface name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing interface name");
return (0);
}
/* get conditioner name */
if (!next_word(&cp, cdnr_name)) {
- LOG(LOG_ERR, 0, "missing cdnr name in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing cdnr name");
return (0);
}
@@ -1166,7 +1028,7 @@ static int
tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
{
char *cp, *start, *end;
- char type[128], w[128];
+ char type[MAX_WORD], w[MAX_WORD];
int depth, i;
struct tb_profile profile[2];
@@ -1176,8 +1038,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
*/
start = strchr(*cpp, '<');
if (start == NULL) {
- LOG(LOG_ERR, 0, "conditioner action missing in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "conditioner action missing");
return (0);
}
depth = 1;
@@ -1186,8 +1047,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
end = strpbrk(cp, "<>");
if (end == NULL) {
LOG(LOG_ERR, 0,
- "conditioner action delimiter mismatch in %s, line %d",
- altqconfigfile, line_no);
+ "conditioner action delimiter mismatch");
return (0);
}
if (*end == '<')
@@ -1205,9 +1065,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
}
if (!next_word(&cp, type)) {
- LOG(LOG_ERR, 0,
- "missing conditioner action type in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing conditioner action type");
return (0);
}
@@ -1217,16 +1075,14 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
if (EQUAL(type, "conditioner")) {
if (!next_word(&cp, w)) {
LOG(LOG_ERR, 0,
- "missing conditioner name in %s, line %d",
- altqconfigfile, line_no);
+ "missing conditioner name");
return (0);
}
action->tca_code = TCACODE_HANDLE;
action->tca_handle = cdnr_name2handle(ifname, w);
if (action->tca_handle == CDNR_NULL_HANDLE) {
LOG(LOG_ERR, 0,
- "wrong conditioner name %s in %s, line %d",
- w, altqconfigfile, line_no);
+ "wrong conditioner name %s", w);
return (0);
}
} else if (EQUAL(type, "pass")) {
@@ -1235,22 +1091,19 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
action->tca_code = TCACODE_DROP;
} else if (EQUAL(type, "mark")) {
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing dscp in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing dscp");
return (0);
}
action->tca_code = TCACODE_MARK;
action->tca_dscp = (u_int8_t)strtol(w, NULL, 0);
} else if (EQUAL(type, "tbmeter")) {
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing tb profile in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing tb profile");
return (0);
}
profile[0].rate = atobps(w);
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing tb profile in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing tb profile");
return (0);
}
profile[0].depth = atobytes(w);
@@ -1267,16 +1120,12 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
for (i=0; i<2; i++) {
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0,
- "missing tb profile in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing tb profile");
return (0);
}
profile[i].rate = atobps(w);
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0,
- "missing tb profile in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing tb profile");
return (0);
}
profile[i].depth = atobytes(w);
@@ -1301,24 +1150,21 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
return (0);
} else if (EQUAL(type, "tswtcm")) {
u_int32_t cmtd_rate, peak_rate, avg_interval;
-
+
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing cmtd rate in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing cmtd rate");
return (0);
}
cmtd_rate = atobps(w);
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing peak rate in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing peak rate");
return (0);
}
peak_rate = atobps(w);
if (!next_word(&cp, w)) {
- LOG(LOG_ERR, 0, "missing avg interval in %s, line %d",
- altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "missing avg interval");
return (0);
}
avg_interval = (u_int32_t)strtoul(w, NULL, 0);
@@ -1336,9 +1182,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
!= 0)
return (0);
} else {
- LOG(LOG_ERR, 0,
- "Unkown action type %s in %s, line %d",
- type, altqconfigfile, line_no);
+ LOG(LOG_ERR, 0, "unkown action type %s");
return (0);
}
@@ -1346,4 +1190,3 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action)
return (1);
}
-