1069 lines
38 KiB
C
1069 lines
38 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_cmd_qos.c,v $ $Revision: 1.24.10.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_cmd_qos.c,v $
|
|
* $Author: svc-cmnet $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPCOM_KERNEL
|
|
#undef IPCOM_KERNEL
|
|
#endif
|
|
#include "ipnet_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_cmd.h>
|
|
#include <ipcom_getopt.h>
|
|
|
|
#include "ipnet.h"
|
|
#include "ipnet_policy_routing.h"
|
|
#ifdef IPCOM_USE_INET6
|
|
#include "ipnet_ip6.h"
|
|
#endif
|
|
#include "ipnet_qos.h"
|
|
#include "ipnet_diffserv.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/* Operations */
|
|
#define IPNET_CMD_QOS_OP_ADD 1 /* Add something */
|
|
#define IPNET_CMD_QOS_OP_DEL 2 /* Delete somthing */
|
|
#define IPNET_CMD_QOS_OP_GET 3 /* Get something */
|
|
#define IPNET_CMD_QOS_OP_LIST 4 /* List something */
|
|
|
|
/* Operation types */
|
|
#define IPNET_CMD_QOS_T_POLICY_RT 1 /* Policy routing */
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
#define IPNET_CMD_QOS_T_DS_FILTER 2 /* Differ Server */
|
|
#endif
|
|
|
|
/* Errors */
|
|
#define IPNET_CMD_ERR -1
|
|
#define IPNET_CMD_ERR_UNSUPPORTED_OP -2
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_cmd_qos
|
|
*===========================================================================
|
|
*/
|
|
typedef struct Ipnet_cmd_qos_struct
|
|
{
|
|
int sock;
|
|
int op; /* Operation IPNET_CMD_QOS_OP_xxx */
|
|
int op_type; /* Operation type IPNET_CMD_QOS_T_xxx */
|
|
int domain; /* Domain the rule applies to (IP_AF_INET | IP_AF_INET6) */
|
|
union
|
|
{
|
|
struct Ipnet_policy_routing_rule rule;
|
|
struct
|
|
{
|
|
struct Ipnet_ds_filter filter;
|
|
struct Ipnet_ds_map map;
|
|
struct Ipnet_ds handler;
|
|
} ds;
|
|
} d;
|
|
}
|
|
Ipnet_cmd_qos;
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_ops[] =
|
|
{
|
|
{ IPNET_CMD_QOS_OP_ADD, "add" },
|
|
{ IPNET_CMD_QOS_OP_DEL, "del" },
|
|
{ IPNET_CMD_QOS_OP_DEL, "delete" },
|
|
{ IPNET_CMD_QOS_OP_GET, "get" },
|
|
{ IPNET_CMD_QOS_OP_LIST,"list" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_scope[] =
|
|
{
|
|
{ IPNET_IP6_SCOPE_GLOBAL, "global" },
|
|
{ IPNET_IP6_SCOPE_NODE_LOCAL, "node" },
|
|
{ IPNET_IP6_SCOPE_LINK_LOCAL, "link" },
|
|
{ IPNET_IP6_SCOPE_SITE_LOCAL, "site" },
|
|
{ IPNET_IP6_SCOPE_ORG_LOCAL, "org" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
#endif /* IPCOM_USE_INET6 */
|
|
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_types[] =
|
|
{
|
|
{ IPNET_CMD_QOS_T_POLICY_RT, "policy" },
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
{ IPNET_CMD_QOS_T_DS_FILTER, "filter" },
|
|
#endif
|
|
{ -1, IP_NULL }
|
|
};
|
|
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_sm_drop_precedence[] =
|
|
{
|
|
{ IPCOM_PKT_DROP_PRECEDENCE_LOW, "low" },
|
|
{ IPCOM_PKT_DROP_PRECEDENCE_MEDIUM, "medium" },
|
|
{ IPCOM_PKT_DROP_PRECEDENCE_HIGH, "high" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_srtcm_mode[] =
|
|
{
|
|
{ IPNET_DS_SRTCM_MODE_COLOR_BLIND, "blind" },
|
|
{ IPNET_DS_SRTCM_MODE_COLOR_AWARE, "aware" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_cmd_qos_print_policy_rule
|
|
*===========================================================================
|
|
* Description: Prints a policy rule to the standard output.
|
|
* Parameters: rule - Rule to print.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipcom_cmd_qos_print_policy_rule(struct Ipnet_policy_routing_rule *rule)
|
|
{
|
|
char str[48];
|
|
|
|
ipcom_printf("Policy routing rule id %u prio %d:"IP_LF, (unsigned)rule->id, (int)rule->prio);
|
|
ipcom_printf(" %-10s: %-10s"IP_LF, "domain", rule->af == IP_AF_INET ? "INET" : "INET6");
|
|
ipcom_printf(" %-10s: %-10u"IP_LF, "table", (unsigned) rule->table);
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_RTKEYSADDR))
|
|
ipcom_printf(" %-10s: %-10s"IP_LF, "lookup", "reverse");
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_DS))
|
|
ipcom_printf(" %-10s: %-10u"IP_LF, rule->af == IP_AF_INET ? "tos" : "tclass", rule->ds);
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_IFINDEX))
|
|
ipcom_printf(" %-10s: %-10u"IP_LF, "ifindex", (unsigned)rule->ifindex);
|
|
#ifdef IPCOM_USE_INET6
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_SCOPE))
|
|
ipcom_printf(" %-10s: %-10s"IP_LF, "scope",
|
|
ipcom_cmd_key_to_str(ipnet_cmd_qos_scope, (int)rule->scope, str, sizeof(str)));
|
|
#endif /* IPCOM_USE_INET6 */
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_SADDR))
|
|
ipcom_printf(" %-10s: %-10s/%d"IP_LF,
|
|
"from",
|
|
ipcom_inet_ntop(rule->af, &rule->saddr, str, sizeof(str)),
|
|
rule->saddr_prefixlen);
|
|
if (IP_BIT_ISSET(rule->mask, IPNET_PR_RULE_DADDR))
|
|
ipcom_printf(" %-10s: %-10s/%d"IP_LF,
|
|
"to",
|
|
ipcom_inet_ntop(rule->af, &rule->daddr, str, sizeof(str)),
|
|
rule->daddr_prefixlen);
|
|
|
|
ipcom_printf(" %-10s: %-10s"IP_LF, "last", rule->last ? "TRUE" : "FALSE");
|
|
|
|
/* Line break */
|
|
ipcom_printf(IP_LF);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_qos_policy_routing
|
|
*===========================================================================
|
|
* Description: Handles the policy subcommand.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_cmd_qos_policy_routing(Ipnet_cmd_qos *cmd, char **argv)
|
|
{
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_args[] =
|
|
{
|
|
/* Indexes <10 has must have one integer argument
|
|
>=10 to <100 has one argument that needs custom argument parsing
|
|
>=100 have no argument */
|
|
{ 2, "tos" },
|
|
{ 2, "tclass" },
|
|
{ 4, "table" },
|
|
{ 5, "prio" },
|
|
{ 7, "ifindex" },
|
|
{ 8, "id" },
|
|
{ 8, "index" }, /* Let 'index' be and alias for 'id' since
|
|
the documentation said index instead of id */
|
|
{ 10, "from" },
|
|
#ifdef IPCOM_USE_INET6
|
|
{ 11, "scope" },
|
|
#endif
|
|
{ 12, "to" },
|
|
{ 100, "last" },
|
|
{ 101, "reverse" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
int c;
|
|
int i = 0;
|
|
char *p = IP_NULL;
|
|
char *str_prefixlen;
|
|
Ip_u8 prefix_len;
|
|
|
|
cmd->d.rule.af = (Ip_u8) cmd->domain;
|
|
cmd->d.rule.id = IPNET_PR_ID_NONE;
|
|
cmd->d.rule.table = IPCOM_ROUTE_TABLE_DEFAULT;
|
|
|
|
while (*argv != IP_NULL)
|
|
{
|
|
c = ipcom_cmd_str_to_key(ipnet_cmd_qos_args, *argv);
|
|
if (c == -1)
|
|
{
|
|
ipcom_printf("'%s' is an unknown argument"IP_LF, *argv);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
if (c < 100)
|
|
{
|
|
if (argv[1] == IP_NULL)
|
|
{
|
|
ipcom_printf("Parameter needed for argument %s"IP_LF, argv[0]);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
argv++;
|
|
if (c < 10)
|
|
i = ipcom_atoi(*argv);
|
|
else
|
|
p = *argv;
|
|
}
|
|
|
|
switch (c)
|
|
{
|
|
case 2:
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_DS);
|
|
cmd->d.rule.ds = (Ip_u8) i;
|
|
break;
|
|
case 4:
|
|
cmd->d.rule.table = (Ip_u32) i;
|
|
break;
|
|
case 5:
|
|
cmd->d.rule.prio = (Ip_s16) i;
|
|
break;
|
|
case 7:
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_IFINDEX);
|
|
cmd->d.rule.ifindex = (Ip_u32) i;
|
|
break;
|
|
case 8:
|
|
cmd->d.rule.id = (Ip_u32) i;
|
|
break;
|
|
case 10:
|
|
case 12:
|
|
str_prefixlen = ipcom_strstr(p, "/");
|
|
if (str_prefixlen == IP_NULL || ipcom_strlen(p) <= 1)
|
|
prefix_len = 0;
|
|
else
|
|
{
|
|
*str_prefixlen = '\0';
|
|
prefix_len = (Ip_u8) ipcom_atoi(str_prefixlen + 1);
|
|
}
|
|
if (c == 10)
|
|
{
|
|
if (ipcom_inet_pton(cmd->domain, p, &cmd->d.rule.saddr) != 1)
|
|
{
|
|
ipcom_printf("'%s' is not a valid IP address" IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_SADDR);
|
|
cmd->d.rule.saddr_prefixlen = prefix_len;
|
|
}
|
|
else
|
|
{
|
|
if (ipcom_inet_pton(cmd->domain, p, &cmd->d.rule.daddr) != 1)
|
|
{
|
|
ipcom_printf("'%s' is not a valid IP address" IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_DADDR);
|
|
cmd->d.rule.daddr_prefixlen = prefix_len;
|
|
}
|
|
break;
|
|
#ifdef IPCOM_USE_INET6
|
|
case 11:
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_SCOPE);
|
|
if (ipcom_cmd_str_to_key(ipnet_cmd_qos_scope, p) < 0)
|
|
{
|
|
ipcom_printf("'%s' is not one of global,link,site,node or org"IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
cmd->d.rule.scope = (Ip_u32) ipcom_cmd_str_to_key(ipnet_cmd_qos_scope, p);
|
|
break;
|
|
#endif /* IPCOM_USE_INET6 */
|
|
case 100:
|
|
cmd->d.rule.last = IP_TRUE;
|
|
break;
|
|
case 101:
|
|
IP_BIT_SET(cmd->d.rule.mask, IPNET_PR_RULE_RTKEYSADDR);
|
|
break;
|
|
default:
|
|
IP_PANIC();
|
|
break;
|
|
}
|
|
|
|
argv++;
|
|
}
|
|
|
|
switch (cmd->op)
|
|
{
|
|
case IPNET_CMD_QOS_OP_ADD:
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCSPRRULE, &cmd->d.rule) < 0)
|
|
ipcom_perror("Failed to add policy routing rule");
|
|
return 0;
|
|
case IPNET_CMD_QOS_OP_DEL:
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCDPRRULE, &cmd->d.rule) < 0)
|
|
ipcom_perror("Failed to delete policy routing rule");
|
|
return 0;
|
|
case IPNET_CMD_QOS_OP_GET:
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCGPRRULE, &cmd->d.rule) < 0)
|
|
ipcom_perror("Failed to get policy routing rule");
|
|
else
|
|
ipcom_cmd_qos_print_policy_rule(&cmd->d.rule);
|
|
return 0;
|
|
case IPNET_CMD_QOS_OP_LIST:
|
|
while (ipcom_socketioctl(cmd->sock, IPNET_SIOCEPRRULE, &cmd->d.rule) == 0)
|
|
ipcom_cmd_qos_print_policy_rule(&cmd->d.rule);
|
|
return 0;
|
|
|
|
default:
|
|
return IPNET_CMD_ERR_UNSUPPORTED_OP;
|
|
}
|
|
}
|
|
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_cmd_qos_print_ds_infor
|
|
*===========================================================================
|
|
* Description: Prints a filter to the standard output.
|
|
* Parameters: ds_infor - filter information to print.
|
|
* Returns: void
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipcom_cmd_qos_print_ds_infor(struct Ipnet_ds_get_infor *ds_infor)
|
|
{
|
|
struct Ipnet_classifier_rule *cr = &ds_infor->f.rule;
|
|
struct Ipnet_ds *ds = &ds_infor->ds;
|
|
char str[48];
|
|
|
|
ipcom_printf(" %-20s: %s/%s"IP_LF,
|
|
"domain",
|
|
cr->af == IP_AF_INET ? "INET" : "INET6",
|
|
IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_LOCAL) ? "local" : "forward");
|
|
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_PROTO))
|
|
ipcom_printf(" %-20s: %-10u"IP_LF, "proto", cr->proto);
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_DS))
|
|
ipcom_printf(" %-20s: %-10u"IP_LF, cr->af == IP_AF_INET ? "tos" : "tclass", cr->ds);
|
|
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_SADDR))
|
|
ipcom_printf(" %-20s: %s/%d"IP_LF,
|
|
"src",
|
|
ipcom_inet_ntop(cr->af, &cr->saddr, str, sizeof(str)),
|
|
cr->saddr_prefixlen);
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_DADDR))
|
|
ipcom_printf(" %-20s: %s/%d"IP_LF,
|
|
"dst",
|
|
ipcom_inet_ntop(cr->af, &cr->daddr, str, sizeof(str)),
|
|
cr->daddr_prefixlen);
|
|
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_SPORT))
|
|
{
|
|
if (cr->sport_low == cr->sport_high)
|
|
ipcom_printf(" %-20s: %d"IP_LF,
|
|
"srcport",
|
|
cr->sport_low);
|
|
else
|
|
ipcom_printf(" %-20s: %-5d -> %-5d"IP_LF,
|
|
"srcport",
|
|
cr->sport_low,
|
|
cr->sport_high);
|
|
}
|
|
if (IP_BIT_ISSET(cr->mask, IPNET_CLS_RULE_DPORT))
|
|
{
|
|
if (cr->dport_low == cr->dport_high)
|
|
ipcom_printf(" %-20s: %d"IP_LF,
|
|
"dstport",
|
|
cr->dport_low);
|
|
else
|
|
ipcom_printf(" %-20s: %-5d -> %-5d"IP_LF,
|
|
"dstport",
|
|
cr->dport_low,
|
|
cr->dport_high);
|
|
}
|
|
|
|
ipcom_printf(" %-20s: %-10s"IP_LF, "handler", ds->name);
|
|
|
|
if (0 == ipcom_strcmp(ds->name, IPNET_DS_SM_NAME))
|
|
{
|
|
if (IP_BIT_ISSET(ds->d.sm.mask, IPNET_DS_SM_DS_VAL))
|
|
ipcom_printf(" %-20s: 0x%-10x"IP_LF,
|
|
"ds-val",
|
|
ds->d.sm.ds_value);
|
|
if (IP_BIT_ISSET(ds->d.sm.mask, IPNET_DS_SM_DROP_P))
|
|
ipcom_printf(" %-20s: %s"IP_LF,
|
|
"drop-precedence",
|
|
ipcom_cmd_key_to_str(ipnet_cmd_qos_sm_drop_precedence,
|
|
ds->d.sm.drop_precedence,
|
|
IP_NULL,
|
|
0));
|
|
}
|
|
else if (0 == ipcom_strcmp(ds->name, IPNET_DS_SRTCM_NAME))
|
|
{
|
|
ipcom_printf(" %-20s: %s"IP_LF,
|
|
"mode",
|
|
ipcom_cmd_key_to_str(ipnet_cmd_qos_srtcm_mode,
|
|
ds->d.srtcm.mode,
|
|
IP_NULL,
|
|
0));
|
|
ipcom_printf(" %-20s: %-10u"IP_LF,
|
|
"CIR",
|
|
ds->d.srtcm.CIR);
|
|
ipcom_printf(" %-20s: %-10u"IP_LF,
|
|
"CBS",
|
|
ds->d.srtcm.CBS);
|
|
ipcom_printf(" %-20s: %-10u"IP_LF,
|
|
"EBS",
|
|
ds->d.srtcm.EBS);
|
|
ipcom_printf(" %-20s: 0x%-10x"IP_LF,
|
|
"ds-green",
|
|
ds->d.srtcm.ds_green);
|
|
ipcom_printf(" %-20s: 0x%-10x"IP_LF,
|
|
"ds-yellow",
|
|
ds->d.srtcm.ds_yellow);
|
|
ipcom_printf(" %-20s: 0x%-10x"IP_LF,
|
|
"ds-red",
|
|
ds->d.srtcm.ds_red);
|
|
}
|
|
|
|
/* Line break */
|
|
ipcom_printf(IP_LF);
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_qos_ds_filter
|
|
*===========================================================================
|
|
* Description: Handles the differ server subcommand.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_cmd_qos_ds_filter(Ipnet_cmd_qos *cmd, char **argv)
|
|
{
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_cmd_qos_args[] =
|
|
{
|
|
/* Indexes <10 has must have one integer argument
|
|
>=10 to <100 has one argument that needs custom argument parsing
|
|
>=100 have no argument */
|
|
{ 2, "tos" },
|
|
{ 2, "tclass" },
|
|
{ 4, "srcport" },
|
|
{ 5, "srcportmax" },
|
|
{ 6, "dstport" },
|
|
{ 7, "dstportmax" },
|
|
{ 8, "proto" },
|
|
|
|
{ 10, "src" },
|
|
{ 11, "dst" },
|
|
{ 12, "handler" },
|
|
|
|
{ 20, "ds-val" },
|
|
{ 21, "drop-precedence" },
|
|
|
|
{ 30, "mode" },
|
|
{ 31, "CIR" },
|
|
{ 32, "CBS" },
|
|
{ 33, "EBS" },
|
|
{ 34, "ds-green" },
|
|
{ 35, "ds-yellow" },
|
|
{ 36, "ds-red" },
|
|
|
|
{100, "local" },
|
|
|
|
{ -1, IP_NULL }
|
|
};
|
|
|
|
struct Ipnet_ds_get_infor gi;
|
|
int c;
|
|
int i = 0;
|
|
char *p = IP_NULL;
|
|
char *endptr = IP_NULL;
|
|
char *str_prefixlen;
|
|
Ip_u8 prefix_len;
|
|
long l = 0;
|
|
|
|
cmd->d.ds.filter.rule.af = (Ip_u8) cmd->domain;
|
|
|
|
while (*argv != IP_NULL)
|
|
{
|
|
c = ipcom_cmd_str_to_key(ipnet_cmd_qos_args, *argv);
|
|
if (c == -1)
|
|
{
|
|
ipcom_printf("'%s' is an unknown argument."IP_LF, *argv);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
if (c < 100)
|
|
{
|
|
if (argv[1] == IP_NULL)
|
|
{
|
|
ipcom_printf("Parameter needed for argument %s."IP_LF, argv[0]);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
argv++;
|
|
if (c < 10)
|
|
i = ipcom_atoi(*argv);
|
|
else
|
|
p = *argv;
|
|
}
|
|
|
|
switch (c)
|
|
{
|
|
case 2:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_DS);
|
|
cmd->d.ds.filter.rule.ds = (Ip_u8) i;
|
|
break;
|
|
case 4:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_SPORT);
|
|
cmd->d.ds.filter.rule.sport_low = (Ip_u16) i;
|
|
if (0 == cmd->d.ds.filter.rule.sport_high)
|
|
cmd->d.ds.filter.rule.sport_high = cmd->d.ds.filter.rule.sport_low;
|
|
break;
|
|
case 5:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_SPORT);
|
|
cmd->d.ds.filter.rule.sport_high = (Ip_u16) i;
|
|
if (0 == cmd->d.ds.filter.rule.sport_low)
|
|
cmd->d.ds.filter.rule.sport_low = cmd->d.ds.filter.rule.sport_high;
|
|
break;
|
|
case 6:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_DPORT);
|
|
cmd->d.ds.filter.rule.dport_low = (Ip_u16) i;
|
|
if (0 == cmd->d.ds.filter.rule.dport_high)
|
|
cmd->d.ds.filter.rule.dport_high = cmd->d.ds.filter.rule.dport_low;
|
|
break;
|
|
case 7:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_DPORT);
|
|
cmd->d.ds.filter.rule.dport_high = (Ip_u16) i;
|
|
if (0 == cmd->d.ds.filter.rule.dport_low)
|
|
cmd->d.ds.filter.rule.dport_low = cmd->d.ds.filter.rule.dport_high;
|
|
break;
|
|
case 8:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_PROTO);
|
|
cmd->d.ds.filter.rule.proto = (Ip_u8) i;
|
|
break;
|
|
case 10:
|
|
case 11:
|
|
str_prefixlen = ipcom_strstr(p, "/");
|
|
if (str_prefixlen == IP_NULL || ipcom_strlen(p) <= 1)
|
|
prefix_len = 0;
|
|
else
|
|
{
|
|
*str_prefixlen = '\0';
|
|
prefix_len = (Ip_u8) ipcom_atoi(str_prefixlen + 1);
|
|
}
|
|
|
|
if (c == 10)
|
|
{
|
|
if (ipcom_inet_pton(cmd->d.ds.filter.rule.af, p, &cmd->d.ds.filter.rule.saddr) != 1)
|
|
{
|
|
ipcom_printf("'%s' is not a valid IP address." IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_SADDR);
|
|
cmd->d.ds.filter.rule.saddr_prefixlen = prefix_len;
|
|
}
|
|
else
|
|
{
|
|
if (ipcom_inet_pton(cmd->d.ds.filter.rule.af, p, &cmd->d.ds.filter.rule.daddr) != 1)
|
|
{
|
|
ipcom_printf("'%s' is not a valid IP address." IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_DADDR);
|
|
cmd->d.ds.filter.rule.daddr_prefixlen = prefix_len;
|
|
}
|
|
break;
|
|
case 12:
|
|
ipcom_strncpy(cmd->d.ds.handler.name, p, (Ip_size_t)IPNET_DS_NAME_SIZE);
|
|
if ((0 != ipcom_strcmp(cmd->d.ds.handler.name, IPNET_DS_SM_NAME))
|
|
&& (0 != ipcom_strcmp(cmd->d.ds.handler.name, IPNET_DS_SRTCM_NAME)))
|
|
{
|
|
ipcom_printf("'%s' is not a supported handler name."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
|
|
case 20:
|
|
IP_BIT_SET(cmd->d.ds.handler.d.sm.mask, IPNET_DS_SM_DS_VAL);
|
|
cmd->d.ds.handler.d.sm.ds_value = ipcom_strtol(p, &endptr, 16);
|
|
if (*endptr != '\0')
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
case 21:
|
|
c = ipcom_cmd_str_to_key(ipnet_cmd_qos_sm_drop_precedence, p);
|
|
if (c < 0 || c > 255)
|
|
{
|
|
ipcom_printf("'%s' is an unknown argument."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
IP_BIT_SET(cmd->d.ds.handler.d.sm.mask, IPNET_DS_SM_DROP_P);
|
|
cmd->d.ds.handler.d.sm.drop_precedence = (Ip_u8)c;
|
|
break;
|
|
|
|
case 30:
|
|
c = ipcom_cmd_str_to_key(ipnet_cmd_qos_srtcm_mode, p);
|
|
if (c < 0 || c > 255)
|
|
{
|
|
ipcom_printf("'%s' is an unknown argument."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
cmd->d.ds.handler.d.srtcm.mode = (Ip_u8)c;
|
|
break;
|
|
case 31:
|
|
cmd->d.ds.handler.d.srtcm.CIR = (Ip_u32)ipcom_strtol(p, &endptr, 10);
|
|
if (*endptr != '\0')
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
case 32:
|
|
cmd->d.ds.handler.d.srtcm.CBS = (Ip_u32)ipcom_strtol(p, &endptr, 10);
|
|
if (*endptr != '\0')
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
case 33:
|
|
cmd->d.ds.handler.d.srtcm.EBS = (Ip_u32)ipcom_strtol(p, &endptr, 10);
|
|
if (*endptr != '\0')
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
case 34:
|
|
l = ipcom_strtol(p, &endptr, 16);
|
|
if (*endptr != '\0' || l > 255)
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
cmd->d.ds.handler.d.srtcm.ds_green = (Ip_u8)l;
|
|
break;
|
|
case 35:
|
|
l = ipcom_strtol(p, &endptr, 16);
|
|
if (*endptr != '\0' || l > 255)
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
cmd->d.ds.handler.d.srtcm.ds_yellow = (Ip_u8)l;
|
|
break;
|
|
case 36:
|
|
l = ipcom_strtol(p, &endptr, 16);
|
|
if (*endptr != '\0' || l > 255)
|
|
{
|
|
ipcom_printf("'%s' is not a invalid ds-val, need hex format."IP_LF, p);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
cmd->d.ds.handler.d.srtcm.ds_red = (Ip_u8)l;
|
|
break;
|
|
|
|
case 100:
|
|
IP_BIT_SET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_LOCAL);
|
|
break;
|
|
default:
|
|
IP_PANIC();
|
|
break;
|
|
}
|
|
|
|
argv++;
|
|
}
|
|
|
|
/* port rang check */
|
|
if (IP_BIT_ISSET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_SPORT))
|
|
{
|
|
if ((0 == cmd->d.ds.filter.rule.sport_low)
|
|
|| (0 == cmd->d.ds.filter.rule.sport_high)
|
|
|| (cmd->d.ds.filter.rule.sport_low > cmd->d.ds.filter.rule.sport_high))
|
|
{
|
|
ipcom_printf("src port rang is not valid." IP_LF);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
}
|
|
if (IP_BIT_ISSET(cmd->d.ds.filter.rule.mask, IPNET_CLS_RULE_DPORT))
|
|
{
|
|
if ((0 == cmd->d.ds.filter.rule.dport_low)
|
|
|| (0 == cmd->d.ds.filter.rule.dport_high)
|
|
|| (cmd->d.ds.filter.rule.dport_low > cmd->d.ds.filter.rule.dport_high))
|
|
{
|
|
ipcom_printf("dst port rang is not valid." IP_LF);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
}
|
|
|
|
ipcom_memset(&gi, 0, sizeof(gi));
|
|
gi.f.id = -1;
|
|
|
|
switch (cmd->op)
|
|
{
|
|
case IPNET_CMD_QOS_OP_ADD:
|
|
ipcom_memcpy(&gi.f.rule, &cmd->d.ds.filter.rule, sizeof(gi.f.rule));
|
|
|
|
if (0 == ipcom_socketioctl(cmd->sock, IPNET_SIOCXGDSFILTER, (void *)&gi))
|
|
{
|
|
ipcom_printf("this filter already exist." IP_LF);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCXADSFILTER, &cmd->d.ds.filter) < 0)
|
|
{
|
|
ipcom_perror("Failed to add differ server filter");
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCXDSCREATE, &cmd->d.ds.handler) < 0)
|
|
{
|
|
ipcom_perror("Failed to create differ server");
|
|
(void)ipcom_socketioctl(cmd->sock, IPNET_SIOCXDDSFILTER, &cmd->d.ds.filter);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
|
|
cmd->d.ds.map.filter_id = cmd->d.ds.filter.id;
|
|
cmd->d.ds.map.ds_id = cmd->d.ds.handler.id;
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCXADSMAP, &cmd->d.ds.map) < 0)
|
|
{
|
|
ipcom_perror("Failed to map filter to ds");
|
|
(void)ipcom_socketioctl(cmd->sock, IPNET_SIOCXDDSFILTER, &cmd->d.ds.filter);
|
|
(void)ipcom_socketioctl(cmd->sock, IPNET_SIOCXDSDESTROY, &cmd->d.ds.handler);
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
break;
|
|
|
|
case IPNET_CMD_QOS_OP_DEL:
|
|
ipcom_memcpy(&gi.f.rule, &cmd->d.ds.filter.rule, sizeof(gi.f.rule));
|
|
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCXGDSFILTER, (void *)&gi) < 0)
|
|
{
|
|
ipcom_perror("this filter does not exist.");
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
|
|
cmd->d.ds.filter.id = gi.f.id;
|
|
cmd->d.ds.handler.id = gi.ds.id;
|
|
(void)ipcom_socketioctl(cmd->sock, IPNET_SIOCXDDSFILTER, &cmd->d.ds.filter);
|
|
(void)ipcom_socketioctl(cmd->sock, IPNET_SIOCXDSDESTROY, &cmd->d.ds.handler);
|
|
break;
|
|
|
|
case IPNET_CMD_QOS_OP_LIST:
|
|
case IPNET_CMD_QOS_OP_GET:
|
|
do
|
|
{
|
|
if (ipcom_socketioctl(cmd->sock, IPNET_SIOCXGDSNEXTFILTER, (void *)&gi) < 0)
|
|
{
|
|
ipcom_perror("Failed to get next filter");
|
|
return IPNET_CMD_ERR;
|
|
}
|
|
|
|
if (-1 == gi.f.id)
|
|
break;
|
|
|
|
ipcom_cmd_qos_print_ds_infor(&gi);
|
|
} while (IP_TRUE);
|
|
|
|
break;
|
|
|
|
default:
|
|
return IPNET_CMD_ERR_UNSUPPORTED_OP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_qos_print_usage
|
|
*===========================================================================
|
|
* Description: Prints the usage for the command.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipnet_cmd_qos_print_usage(void)
|
|
{
|
|
ipcom_printf("NAME" IP_LF);
|
|
ipcom_printf(" qos - controls the QoS features in IPNET" IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf("SYNOPSIS" IP_LF);
|
|
ipcom_printf(" qos [option]... op optype [args]" IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf("DESCRIPTION" IP_LF);
|
|
ipcom_printf(" The qos command is used to configure and view the Quality of Service" IP_LF);
|
|
ipcom_printf(" features within IPNET, except interface queues which uses 'qc'." IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf(" The following options:" IP_LF);
|
|
ipcom_printf(" -4 Use IPv4 as address domain (default)." IP_LF);
|
|
ipcom_printf(" -6 Use IPv6 as address domain." IP_LF);
|
|
ipcom_printf(" -V <tab> Operate on virtual router with index <tab>." IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf(" The following operations (op) exists:" IP_LF);
|
|
ipcom_printf(" add Add something." IP_LF);
|
|
ipcom_printf(" delete Delete something." IP_LF);
|
|
ipcom_printf(" get Lookup and display something." IP_LF);
|
|
ipcom_printf(" list Lookup and display something." IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf(" The following operation types (optype) exists:" IP_LF);
|
|
ipcom_printf(" policy Policy routing." IP_LF);
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
ipcom_printf(" filter Differentiated services(filter and handler)." IP_LF);
|
|
#endif
|
|
ipcom_printf("" IP_LF);
|
|
ipcom_printf(" Policy routing arguments:" IP_LF);
|
|
ipcom_printf(" Add operation:" IP_LF);
|
|
ipcom_printf(" from <addr> Apply this rule if the source address is <addr>" IP_LF);
|
|
ipcom_printf(" to <addr> Apply this rule if the destination address is <addr>" IP_LF);
|
|
ipcom_printf(" proto <p> Apply this rule if the transport protocol is <p>" IP_LF);
|
|
ipcom_printf(" tos <n> Apply this rule if the TOS is <n>" IP_LF);
|
|
ipcom_printf(" tclass <n> Apply this rule if the traffic class is <n>" IP_LF);
|
|
ipcom_printf(" ifindex <if> Apply this rule if the ifindex of the incoming interface is <if>" IP_LF);
|
|
#ifdef IPCOM_USE_INET6
|
|
ipcom_printf(" scope <s> Apply this rule if the scope of the address is <s>" IP_LF);
|
|
#endif
|
|
ipcom_printf(" reverse If this rule is applied, do the lookup based on src instead of dst" IP_LF);
|
|
ipcom_printf(" table <t> Use the routing table with policy ID <t>" IP_LF);
|
|
ipcom_printf(" if the rule matches" IP_LF);
|
|
ipcom_printf(" last Do not look at any more rules, even if no match" IP_LF);
|
|
ipcom_printf(" on this table" IP_LF);
|
|
ipcom_printf(" prio <p> The prio of the rule to add [-32768..32767]" IP_LF);
|
|
ipcom_printf(" Delete/get operation:" IP_LF);
|
|
ipcom_printf(" id <i> The ID of the rule to delete/show" IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
ipcom_printf(" Differentiated services arguments:" IP_LF);
|
|
ipcom_printf(" Add/Delete operation:" IP_LF);
|
|
ipcom_printf(" src <addr> Apply this filter if the source address is <addr>" IP_LF);
|
|
ipcom_printf(" dst <addr> Apply this filter if the destination address is <addr>" IP_LF);
|
|
ipcom_printf(" proto <p> Apply this filter if the transport protocol is <p>" IP_LF);
|
|
ipcom_printf(" tos <n> Apply this filter if the TOS is <n>" IP_LF);
|
|
ipcom_printf(" tclass <n> Apply this filter if the traffic class is <n>" IP_LF);
|
|
ipcom_printf(" srcport <n> Apply this filter if the source port is <n>" IP_LF);
|
|
ipcom_printf(" or from srcport <n> to srcportmax <n>" IP_LF);
|
|
ipcom_printf(" dstport <n> Apply this filter if the destination port is <n>" IP_LF);
|
|
ipcom_printf(" or from dstport <n> to dstportmax <n>" IP_LF);
|
|
ipcom_printf(" srcportmax <n> Apply this filter if the source port" IP_LF);
|
|
ipcom_printf(" from srcport <n> to srcportmax <n>" IP_LF);
|
|
ipcom_printf(" dstportmax <n> Apply this filter if the destination port" IP_LF);
|
|
ipcom_printf(" from dstport <n> to dstportmax <n>" IP_LF);
|
|
ipcom_printf(" local Apply this filter for locally generated packets" IP_LF);
|
|
ipcom_printf(" handler <str> Apply this filter using <str> handler" IP_LF);
|
|
ipcom_printf(" Handler arguments:" IP_LF);
|
|
ipcom_printf(" SimpleMarker Apply simple marker if match this filter" IP_LF);
|
|
ipcom_printf(" srTCM Apply single rate Three Color Marker if match this filter" IP_LF);
|
|
ipcom_printf(" Handler SimpleMarker arguments:" IP_LF);
|
|
ipcom_printf(" ds-val <n> Set DSCP with <n> if match this filter" IP_LF);
|
|
ipcom_printf(" drop-precedence <p> Set drop precedence with <p> if match this filter" IP_LF);
|
|
ipcom_printf(" Handler srTCM arguments:" IP_LF);
|
|
ipcom_printf(" mode <m> Use mode <m> if match this filter" IP_LF);
|
|
ipcom_printf(" CIR <n> Set Committed Information Rate to <n> if match this filter" IP_LF);
|
|
ipcom_printf(" CBS <n> Set Committed Burst Size to <n> if match this filter" IP_LF);
|
|
ipcom_printf(" EBS <n> Set Excess Burst Size to <n> if match this filter" IP_LF);
|
|
ipcom_printf(" ds-green <n> Set DSCP with <n> for green packets if match this filter" IP_LF);
|
|
ipcom_printf(" ds-yellow <n> Set DSCP with <n> for yellow packets if match this filter" IP_LF);
|
|
ipcom_printf(" ds-red <n> Set DSCP with <n> for red packets if match this filter" IP_LF);
|
|
ipcom_printf(" Example:" IP_LF);
|
|
ipcom_printf(" qos add filter dst 192.168.1.0/24 local handler SimpleMarker ds-val 0x10" IP_LF);
|
|
ipcom_printf(" qos add filter srcport 21 local handler SimpleMarker ds-val 0x10" IP_LF);
|
|
ipcom_printf("" IP_LF);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_qos
|
|
*===========================================================================
|
|
* Description: The entry point for the 'qos' shell command.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC int
|
|
ipnet_cmd_qos(int argc, char **argv)
|
|
{
|
|
Ipnet_cmd_qos cmd;
|
|
Ipcom_getopt opt;
|
|
int i;
|
|
char **arg;
|
|
int ret = IPNET_CMD_ERR;
|
|
char *op;
|
|
char *op_type;
|
|
int vr;
|
|
|
|
ipcom_memset(&cmd, 0, sizeof(cmd));
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
cmd.domain = IP_AF_INET;
|
|
#else
|
|
cmd.domain = IP_AF_INET6;
|
|
#endif
|
|
cmd.sock = ipcom_socket(cmd.domain, IP_SOCK_DGRAM, 0);
|
|
if (cmd.sock == IP_INVALID_SOCKET)
|
|
{
|
|
ipcom_perror("Failed to create socket");
|
|
goto cleanup;
|
|
}
|
|
|
|
ipcom_getopt_clear_r(&opt);
|
|
while ((i = ipcom_getopt_r(argc, argv, "46V:", &opt)) != -1)
|
|
{
|
|
switch (i)
|
|
{
|
|
case '4':
|
|
cmd.domain = IP_AF_INET;
|
|
break;
|
|
case '6':
|
|
cmd.domain = IP_AF_INET6;
|
|
break;
|
|
case 'V':
|
|
vr = ipcom_atoi(opt.optarg);
|
|
if (ipcom_setsockopt(cmd.sock, IP_SOL_SOCKET, IP_SO_X_VR, &vr, sizeof(vr)) < 0)
|
|
{
|
|
ipcom_perror("Failed to changed VR");
|
|
goto cleanup;
|
|
}
|
|
break;
|
|
default:
|
|
ipcom_printf("invalid option '%c'"IP_LF, i);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if (argc < opt.optind + 2)
|
|
{
|
|
ipnet_cmd_qos_print_usage();
|
|
goto cleanup;
|
|
}
|
|
|
|
arg = &argv[opt.optind];
|
|
op = *arg;
|
|
cmd.op = ipcom_cmd_str_to_key(ipnet_cmd_qos_ops, op);
|
|
if (cmd.op == -1)
|
|
{
|
|
ipcom_printf("'%s' is an invalid operation"IP_LF, op);
|
|
goto cleanup;
|
|
}
|
|
arg++;
|
|
op_type = *arg;
|
|
cmd.op_type = ipcom_cmd_str_to_key(ipnet_cmd_qos_types, op_type);
|
|
arg++;
|
|
switch (cmd.op_type)
|
|
{
|
|
case IPNET_CMD_QOS_T_POLICY_RT:
|
|
ret = ipnet_cmd_qos_policy_routing(&cmd, arg);
|
|
break;
|
|
#if defined(IPNET_USE_DIFFSERV) && !defined(IPNET_DIFFSERV_CLASSIFIER_MODE_BA)
|
|
case IPNET_CMD_QOS_T_DS_FILTER:
|
|
ret = ipnet_cmd_qos_ds_filter(&cmd, arg);
|
|
break;
|
|
#endif
|
|
default:
|
|
ipcom_printf("'%s' is an invalid operation type"IP_LF, op_type);
|
|
break;
|
|
}
|
|
|
|
if (ret == IPNET_CMD_ERR_UNSUPPORTED_OP)
|
|
ipcom_printf("The operation %s is not supported by type %s" IP_LF, op, op_type);
|
|
|
|
cleanup:
|
|
ipcom_socketclose(cmd.sock);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|