blob: 37bf8f427c1a0d236a92ee4f76a2ad5afcf25b17 [file] [log] [blame]
/*
* ffcontrol.c: Fast Forward Control
*
* Copyright (C) 2007 Mindspeed Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "cmm.h"
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <bits/sockaddr.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include "ffbridge.h"
#include "pppoe.h"
#include "cmmd.h"
#include "fpp.h"
struct denyRuleList * denyRules = NULL;
struct asymFFRuleList * asymFFRules = NULL;
#ifdef WIFI_ENABLE
struct wifi_ff_entry glbl_wifi_ff_ifs[MAX_WIFI_FF_IFS];
#endif
/*****************************************************************
* cmmFcIsLocal()
*
*
******************************************************************/
static int cmmFcIsLocal(FCI_CLIENT *fci_handle, struct nf_conntrack *ct, struct flow *flow_orig, struct RtEntry **rtEntryOrig)
{
char saddr_buf[INET6_ADDRSTRLEN], daddr_buf[INET6_ADDRSTRLEN];
int iif;
/* Filter local->outside connections, iif = 0 because packets doesn't go through pre-routing hook */
iif = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IIF);
if (!iif)
goto local;
/* Filter local->local connections */
if (iif == LO_IFINDEX)
goto local;
if (!*rtEntryOrig)
{
*rtEntryOrig = __cmmRouteGet(flow_orig);
if (!*rtEntryOrig)
goto local;
}
if ((*rtEntryOrig)->type != RTN_UNICAST)
goto local;
return 0;
local:
if (*rtEntryOrig)
{
____cmmRouteDeregister(*rtEntryOrig, "originator");
*rtEntryOrig = NULL;
}
cmm_print(DEBUG_WARNING, "%s: conntrack local dst:%s src:%s\n", __func__,
inet_ntop(flow_orig->family, flow_orig->sAddr, saddr_buf, INET6_ADDRSTRLEN),
inet_ntop(flow_orig->family, flow_orig->dAddr, daddr_buf, INET6_ADDRSTRLEN));
return 1;
}
/*****************************************************************
* cmmIsConntrack4Allowed()
*
*
******************************************************************/
#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
int cmmFcIsConntrack4Allowed(FCI_CLIENT *fci_handle, struct nf_conntrack *ct, struct RtEntry **rtEntryOrig)
{
struct denyRuleList * temp;
denyRule_t tempRule;
unsigned int sAddr, dAddr;
struct flow flow_orig;
char saddr_buf[INET_ADDRSTRLEN], raddr_buf[INET_ADDRSTRLEN];
sAddr = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
dAddr = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
/* Multicast connections are not forwarded */
if (MULTICAST(dAddr)) {
cmm_print(DEBUG_WARNING, "%s: conntrack multicast dst:%s:%x src:%s:%x\n", __func__,
inet_ntop(AF_INET, &sAddr, saddr_buf, sizeof(saddr_buf)),sAddr,
inet_ntop(AF_INET, &dAddr, raddr_buf, sizeof(raddr_buf)),dAddr);
goto refused;
}
flow_orig.family = AF_INET;
flow_orig.sAddr = &sAddr;
flow_orig.dAddr = &dAddr;
flow_orig.iifindex = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IFINDEX);
flow_orig.fwmark = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_MARK);
if (cmmFcIsLocal(fci_handle, ct, &flow_orig, rtEntryOrig)) {
cmm_print(DEBUG_INFO, "%s: local connection refused\n", __func__);
goto refused;
}
/*Go through each rule to see if it is allowed*/
for(temp = denyRules ; temp != NULL ; temp = temp->next)
{
for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next)
{
unsigned int temp = 0;
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int temp_shift = tempRule->value;
#endif
const void *ret = nfct_get_attr(ct, tempRule->type);
if(ret == NULL) { //If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept)
cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, connection refused\n", __func__);
break;
}
memcpy(&temp, ret, tempRule->width);
temp &= tempRule->mask;
#if __BYTE_ORDER == __BIG_ENDIAN
// bytes shift only in case of short type and big endian
if ( tempRule->width == 2) {
temp_shift = tempRule->value << 16;
}
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width);
if (memcmp(&temp, &temp_shift, tempRule->width)) {
#else
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width);
if (memcmp(&temp, &tempRule->value, tempRule->width)) {
#endif
cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__);
break;
} else {
cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__);
}
}
/*
* We reach the end of the list meaning all the values matched
* So the conntrack is not allowed to be FastForwarded
*/
if(tempRule == NULL)
{
cmm_print(DEBUG_INFO, "%s: conntrack refused by rules\n", __func__);
goto refused;
}
cmm_print(DEBUG_INFO, "%s: check next deny rule\n", __func__);
}
cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__);
return 1;
refused:
return 0;
}
/*****************************************************************
* cmmIsConntrack6Allowed()
*
*
******************************************************************/
int cmmFcIsConntrack6Allowed(FCI_CLIENT *fci_handle, struct nf_conntrack * ct, struct RtEntry **rtEntryOrig)
{
struct denyRuleList * temp;
denyRule_t tempRule;
struct flow flow_orig;
const unsigned int *Saddr, *SaddrReply;
/*Local connections are not Fast Forwarded*/
Saddr = nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC);
SaddrReply = nfct_get_attr(ct, ATTR_REPL_IPV6_SRC);
if ((SaddrReply[0] & ntohl(0xff000000)) == ntohl(0xff000000))
{
goto refused;
}
flow_orig.family = AF_INET6;
flow_orig.sAddr = Saddr;
flow_orig.dAddr = SaddrReply;
flow_orig.iifindex = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IFINDEX);
flow_orig.fwmark = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_MARK);
if (cmmFcIsLocal(fci_handle, ct, &flow_orig, rtEntryOrig)) {
cmm_print(DEBUG_INFO, "%s: local connection refused\n", __func__);
goto refused;
}
/*Go through each rule to see if it is allowed*/
for(temp = denyRules ; temp != NULL ; temp = temp->next)
{
for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next)
{
unsigned int temp = 0;
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int temp_shift = tempRule->value;
#endif
struct in6_addr *valueIpV6Ret, valueIpV6Tmp ;
if ((tempRule->type == ATTR_ORIG_IPV6_SRC )|| (tempRule->type == ATTR_ORIG_IPV6_DST )
|| (tempRule->type == ATTR_REPL_IPV6_SRC ) || (tempRule->type == ATTR_REPL_IPV6_DST )) {
valueIpV6Ret = (struct in6_addr *)nfct_get_attr(ct, tempRule->type);
if(valueIpV6Ret == NULL) {//If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept)
cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, jumps to next rule\n", __func__);
break;
}
if(16 != tempRule->width) {//width of IPv6 address should be of 16 bytes
cmm_print(DEBUG_ERROR, "%s: Incorrect width in the rule, jumps to next rule\n", __func__);
break;
}
memcpy(&valueIpV6Tmp.s6_addr[0], &valueIpV6Ret->s6_addr[0], tempRule->width);
if (memcmp(&valueIpV6Tmp.s6_addr[0], &tempRule->valueIpV6.s6_addr[0], tempRule->width)) {
cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__);
break;
} else {
cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__);
}
}
else {
const void *ret = nfct_get_attr(ct, tempRule->type);
if(ret == NULL) {//If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept)
cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, jumps to next rule\n", __func__);
break;
}
memcpy(&temp, ret, tempRule->width);
temp &= tempRule->mask;
#if __BYTE_ORDER == __BIG_ENDIAN
// bytes shift only in case of short type and big endian
if ( tempRule->width == 2) {
temp_shift = tempRule->value << 16;
}
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width);
if (memcmp(&temp, &temp_shift, tempRule->width)) {
#else
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width);
if (memcmp(&temp, &tempRule->value, tempRule->width)) {
#endif
cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__);
break;
} else {
cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__);
}
}
}
/*
* We reach the end of the list meaning all the values matched
* So the conntrack is not allowed to be FastForwarded
*/
if(tempRule == NULL)
{
cmm_print(DEBUG_INFO, "%s: conntrack refused by rules\n", __func__);
goto refused;
}
cmm_print(DEBUG_INFO, "%s: check next deny rule\n", __func__);
}
cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__);
return 1;
refused:
return 0;
}
/*****************************************************************
* cmmFcStop
*
*
******************************************************************/
int cmmFcStop(struct cli_def * cli, char *command, char *argv[], int argc)
{
cli_print(cli, "Killing cmm ...\n");
kill(0, SIGTERM);
return CLI_OK;
}
/*****************************************************************
* cmmFcActivate
*
*
******************************************************************/
int cmmFcActivate(struct cli_def * cli, char *command, char *argv[], int argc)
{
int val;
int family;
if (argc < 1)
goto usage;
//Check if it is a digit. atoi() returns 0 if not digit
if(! isdigit(*argv[0]))
goto usage;
val = atoi(argv[0]);
if (globalConf.enable != val)
{
if (val == 0)
{
/*Reset Forward Engine*/
cmmFeReset(globalConf.cli.fci_handle);
globalConf.enable = val;
}
else if (val == 1)
{
/*Reset Forward Engine*/
cmmFeReset(globalConf.cli.fci_handle);
globalConf.enable = val;
/*Get already existing ipv4 conntrack*/
family = AF_INET;
if (nfct_query(globalConf.ct.catch_handle, NFCT_Q_DUMP, (void *) &family) < 0)
cmm_print(DEBUG_ERROR, "%s: nfct_query(NFCT_Q_DUMP) %s\n", __func__, strerror(errno));
/*Get already existing ipv6 conntrack*/
family = AF_INET6;
if (nfct_query(globalConf.ct.catch_handle, NFCT_Q_DUMP, (void *) &family) < 0)
cmm_print(DEBUG_ERROR, "%s: nfct_query(NFCT_Q_DUMP) %s\n", __func__, strerror(errno));
}
else
goto usage;
}
return CLI_OK;
usage:
cli_print(cli, "Usage: activate <0 1>");
return CLI_OK;
}
/*****************************************************************
* cmmFcDesactivate
*
*
******************************************************************/
int cmmFcActivateShow(struct cli_def * cli, char *command, char *argv[], int argc)
{
cli_print(cli, "%d", globalConf.enable);
return CLI_OK;
}
/*****************************************************************
* cmmFcDesactivate
*
*
******************************************************************/
int cmmFcDebug(struct cli_def * cli, char *command, char *argv[], int argc)
{
int val;
int flag = 0;
if (argc < 2)
goto usage;
if (strncmp(argv[0], "command", strlen(argv[0])) == 0)
flag = DEBUG_COMMAND;
else if (strncmp(argv[0], "error", strlen(argv[0])) == 0)
flag = DEBUG_ERROR;
else if (strncmp(argv[0], "warning", strlen(argv[0])) == 0)
flag = DEBUG_WARNING;
else if (strncmp(argv[0], "info", strlen(argv[0])) == 0)
flag = DEBUG_INFO;
else
goto usage;
//Check if it is a digit. atoi() returns 0 if not digit
if(! isdigit(*argv[1]))
goto usage;
val = atoi(argv[1]);
if (val == 0)
globalConf.debug_level &= ~flag;
else if (val == 1)
globalConf.debug_level |= flag;
else
goto usage;
return CLI_OK;
usage:
cli_print(cli, "Usage: set debug <command error warning info> <0 1>");
return CLI_OK;
}
/*****************************************************************
* cmmFcDebugShow
*
*
******************************************************************/
int cmmFcDebugShow(struct cli_def * cli, char *command, char *argv[], int argc)
{
cli_print(cli, "command:\t%s", (globalConf.debug_level & DEBUG_COMMAND) ? "printed": "not printed");
cli_print(cli, "error: \t%s", (globalConf.debug_level & DEBUG_ERROR) ? "printed": "not printed");
cli_print(cli, "warning:\t%s", (globalConf.debug_level & DEBUG_WARNING) ? "printed": "not printed");
cli_print(cli, "info: \t%s", (globalConf.debug_level & DEBUG_INFO) ? "printed": "not printed");
return CLI_OK;
}
/*****************************************************************
* cmmFcAsymFFRuleAddAtrribut()
*
*
******************************************************************/
asymFFRule_t cmmFcAsymFFRuleAddAttribut(asymFFRule_t rule, int attributType, int attributValue, char *attrStrValue, int attributWidth, int mask)
{
asymFFRule_t temp;
temp = (asymFFRule_t) malloc(sizeof(asymFFRule));
if (temp ==NULL)
return rule;
temp->next = rule;
temp->type = attributType;
temp->value = attributValue;
strcpy(temp->strValue,attrStrValue);
temp->width = attributWidth;
temp->mask = mask;
return temp;
}
/*****************************************************************
* cmmFcAsymFFListAddRule()
*
*
******************************************************************/
struct asymFFRuleList * cmmFcAsymFFListAddRule(struct asymFFRuleList *list, char * ruleName, asymFFRule_t rule)
{
struct asymFFRuleList * temp;
temp = (struct asymFFRuleList *) malloc(sizeof(struct asymFFRuleList));
if (temp == NULL)
return list;
temp->next = list;
temp->rule = rule;
strncpy(temp->name, ruleName, sizeof(temp->name));
return temp;
}
/*****************************************************************
* cmmFcAsymFFRulesShow()
*
* Print rules on CLI
******************************************************************/
int cmmFcAsymFFRulesShow(struct cli_def * cli, char *command, char *argv[], int argc)
{
struct asymFFRuleList *rulesList;
struct asymFFRule *rule;
for(rulesList = asymFFRules ; rulesList != NULL ; rulesList = rulesList->next)
{
cli_print(cli, "\n%s:", rulesList->name);
for(rule = rulesList->rule ; rule != NULL ; rule = rule->next)
{
switch(rule->type)
{
case ATTR_ORIG_PORT_SRC:
cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_SRC_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_ORIG_PORT_DST:
cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_DST_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_ORIG_L4PROTO:
if (rule->value == IPPROTO_TCP)
cli_print(cli, "\t%s: tcp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else if (rule->value == IPPROTO_UDP)
cli_print(cli, "\t%s: udp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else if (rule->value == IPPROTO_IPIP)
cli_print(cli, "\t%s: ipip (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else
cli_print(cli, "\t%s: unknown (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
break;
case ATTR_L3PROTO:
if (rule->value == AF_INET)
cli_print(cli, "\t%s: ipv4 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask);
else if (rule->value == AF_INET6)
cli_print(cli, "\t%s: ipv6 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask);
break;
case ATTR_ORIG_COMCERTO_FP_IIF:
cli_print(cli, "\tinterface: %s", rule->strValue);
break;
default:
cli_print(cli, "\tERROR");
}
}
}
return CLI_OK;
}
/*****************************************************************
* cmmFcIsConntrackAsymFastForwarded()
*
*
******************************************************************/
int cmmFcIsConntrackAsymFastForwarded(struct nf_conntrack *ct)
{
struct asymFFRuleList * temp;
asymFFRule_t tempRule;
int iif;
struct interface *itf;
/*Go through each rule to see if it is allowed*/
for(temp = asymFFRules ; temp != NULL ; temp = temp->next)
{
for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next)
{
unsigned int temp = 0;
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int temp_shift = tempRule->value;
#endif
const void *ret = nfct_get_attr(ct, tempRule->type);
if(ret == NULL) { //If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept)
cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, connection refused\n", __func__);
break;
}
if(tempRule->type == ATTR_ORIG_COMCERTO_FP_IIF)
{
memcpy(&iif, ret, tempRule->width);
itf = __itf_find(iif);
if (!itf) {
cmm_print(DEBUG_ERROR, "%s: can't get inteface details from conntrack\n", __func__);
goto out;
}
if(!strcmp(itf->ifname,tempRule->strValue)) {
cmm_print(DEBUG_INFO, "%s: interface attribute matched, check next atribute\n", __func__);
}
else {
cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__);
break;
}
}
else {
memcpy(&temp, ret, tempRule->width);
temp &= tempRule->mask;
#if __BYTE_ORDER == __BIG_ENDIAN
// bytes shift only in case of short type and big endian
if ( tempRule->width == 2) {
temp_shift = tempRule->value << 16;
}
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width);
if (memcmp(&temp, &temp_shift, tempRule->width)) {
#else
cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width);
if (memcmp(&temp, &tempRule->value, tempRule->width)) {
#endif
cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__);
break;
} else {
cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__);
}
}
}
/*
* We reach the end of the list meaning all the values matched
* So the conntrack should be asymmetrically FastForwarded
*/
if(tempRule == NULL)
{
cmm_print(DEBUG_INFO, "%s: conntrack should be asym forwarded as per rules\n", __func__);
goto asym_forward;
}
cmm_print(DEBUG_INFO, "%s: check next Asym Fastpath rule\n", __func__);
}
//cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__);
out:
return 0;
asym_forward:
return 1;
}
/*****************************************************************
* cmmFcRuleAddAtrribut()
*
*
******************************************************************/
denyRule_t cmmFcRuleAddAttribut(denyRule_t rule, int attributType, int attributValue, int attributWidth, int mask, const u_int8_t *attrValIpV6)
{
denyRule_t temp;
if ( (attributWidth == 16) && (attrValIpV6 == NULL) )
return rule;
temp = (denyRule_t) malloc(sizeof(denyRule));
if (temp ==NULL)
return rule;
temp->next = rule;
temp->type = attributType;
temp->value = attributValue;
temp->width = attributWidth;
temp->mask = mask;
if (attributWidth == 16)
memcpy(&temp->valueIpV6.s6_addr[0], attrValIpV6, attributWidth) ;
return temp;
}
/*****************************************************************
* cmmFcListAddRule()
*
*
******************************************************************/
struct denyRuleList * cmmFcListAddRule(struct denyRuleList *list, char * ruleName, denyRule_t rule)
{
struct denyRuleList * temp;
temp = (struct denyRuleList *) malloc(sizeof(struct denyRuleList));
if (temp == NULL)
return list;
temp->next = list;
temp->rule = rule;
strncpy(temp->name, ruleName, sizeof(temp->name));
return temp;
}
/*****************************************************************
* cmmFcRulesShow()
*
* Print rules on CLI
******************************************************************/
int cmmFcRulesShow(struct cli_def * cli, char *command, char *argv[], int argc)
{
struct denyRuleList *rulesList;
struct denyRule *rule;
char *ipv4Address;
struct in_addr tmp;
char ipv6Address[INET6_ADDRSTRLEN];
for(rulesList = denyRules ; rulesList != NULL ; rulesList = rulesList->next)
{
cli_print(cli, "\n%s:", rulesList->name);
for(rule = rulesList->rule ; rule != NULL ; rule = rule->next)
{
switch(rule->type)
{
case ATTR_ORIG_PORT_SRC:
cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_SRC_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_ORIG_PORT_DST:
cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_DST_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_REPL_PORT_SRC:
cli_print(cli, "\t%s: %d mask %x", ATTR_REPL_PORT_SRC_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_REPL_PORT_DST:
cli_print(cli, "\t%s: %d mask %x", ATTR_REPL_PORT_DST_STR, ntohs(rule->value), rule->mask);
break;
case ATTR_MARK:
cli_print(cli, "\t%s: %d mask %x", ATTR_MARK_STR, rule->value, rule->mask);
break;
case ATTR_ORIG_IPV4_SRC:
tmp.s_addr = (unsigned int)rule->value ;
ipv4Address = inet_ntoa(tmp) ;
if (ipv4Address == NULL){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_SRC_STR, ipv4Address, rule->mask);
break;
case ATTR_ORIG_IPV4_DST:
tmp.s_addr = (unsigned int)rule->value ;
ipv4Address = inet_ntoa(tmp) ;
if (ipv4Address == NULL){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_DST_STR, ipv4Address, rule->mask);
break;
case ATTR_REPL_IPV4_SRC:
tmp.s_addr = (unsigned int)rule->value ;
ipv4Address = inet_ntoa(tmp) ;
if (ipv4Address == NULL){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_SRC_STR, ipv4Address, rule->mask);
break;
case ATTR_REPL_IPV4_DST:
tmp.s_addr = (unsigned int)rule->value ;
ipv4Address = inet_ntoa(tmp) ;
if (ipv4Address == NULL){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_DST_STR, ipv4Address, rule->mask);
break;
case ATTR_ORIG_IPV6_SRC:
if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV6_SRC_STR, ipv6Address, rule->mask);
break;
case ATTR_ORIG_IPV6_DST:
if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_DST_STR, ipv6Address, rule->mask);
break;
case ATTR_REPL_IPV6_SRC:
if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_SRC_STR, ipv6Address, rule->mask);
break;
case ATTR_REPL_IPV6_DST:
if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address");
break;
}
cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_DST_STR, ipv6Address, rule->mask);
break;
case ATTR_ORIG_L4PROTO:
case ATTR_REPL_L4PROTO:
if (rule->value == IPPROTO_TCP)
cli_print(cli, "\t%s: tcp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else if (rule->value == IPPROTO_UDP)
cli_print(cli, "\t%s: udp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else if (rule->value == IPPROTO_IPIP)
cli_print(cli, "\t%s: ipip (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
else
cli_print(cli, "\t%s: unknown (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask);
case ATTR_L3PROTO:
if (rule->value == AF_INET)
cli_print(cli, "\t%s: ipv4 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask);
else if (rule->value == AF_INET6)
cli_print(cli, "\t%s: ipv6 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask);
break;
default:
cli_print(cli, "\tERROR");
}
}
}
return CLI_OK;
}
/*****************************************************************
* cmmFcParser()
*
* Returns 0 if the parser succeed
*
******************************************************************/
int cmmFcParser(char *confFilePath)
{
FILE * fp;
char buf[150], buf1[30], buf2[30], buf3[50], buf4[30], buf5[30], tempName[30], tempName1[30];
denyRule_t rule = NULL;
denyRule_t copy_rule = NULL;
denyRule_t head_rule = NULL;
asymFFRule_t aff_rule = NULL;
int asymff_config = 0;
char attrSValue[IFNAMSIZ+1]={0};
int check_port_is_last_option = 0;
int check_ipv4_is_last_option = 0;
int check_ipv6_is_last_option = 0;
int vlan_config = 0, log_config = 0, tun_config = 0;
unsigned int attrType, attrValue, ret = 0, number;
u_int8_t *attrValueV6 = NULL ;
int attrWidth;
unsigned int mask;
#ifdef WIFI_ENABLE
struct wifi_ff_entry *wifi_if = NULL;
int ii;
int wifi_config = 0;
#endif
fp = fopen(confFilePath , "r");
if(fp == NULL)
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error opening %s\n", confFilePath);
return -1;
}
#ifdef WIFI_ENABLE
memset( glbl_wifi_ff_ifs, 0, sizeof(struct wifi_ff_entry) * MAX_WIFI_FF_IFS );
#endif
tempName[0] = '\0';
tempName1[0] = '\0';
while(fgets(buf, sizeof(buf), fp))
{
number = sscanf(buf, "%29s%29s%49s%29s%29s", buf1, buf2, buf3, buf4, buf5); /* leave 1 byte for '\0' */
// Check if it is a comment line
if (buf1[0] == '#')
continue;
if (number == -1)
continue;
else if (number == 2)
{
if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "vlan") == 0))
{
vlan_config = 1;
log_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 0;
#endif
asymff_config = 0;
tun_config = 0;
check_port_is_last_option = 1;
continue;
}
if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "logging") == 0))
{
log_config = 1;
vlan_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 0;
#endif
asymff_config = 0;
tun_config = 0;
check_port_is_last_option = 0;
continue;
}
#ifdef WIFI_ENABLE
if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "wifi_fastforward") == 0))
{
log_config = 0;
vlan_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 1;
#endif
asymff_config = 0;
tun_config = 0;
check_port_is_last_option = 0;
/* Get Free WiFi fastforward entry */
for( ii = 0; ii < MAX_WIFI_FF_IFS; ii++ )
{
if (!glbl_wifi_ff_ifs[ii].used)
{
wifi_if = &glbl_wifi_ff_ifs[ii];
glbl_wifi_ff_ifs[ii].used = 1;
glbl_wifi_ff_ifs[ii].vapid = ii;
break;
}
}
if( ii == MAX_WIFI_FF_IFS )
wifi_if = NULL;
cmm_print(DEBUG_ERROR, "cmmFcParser: WiFi interface parsed \n");
continue;
}
#endif
if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "tun") == 0))
{
log_config = 0;
vlan_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 0;
#endif
tun_config = 1;
check_port_is_last_option = 0;
continue;
}
goto fail_parsing;
}
else if ((number != 3) && (number != 5))
{
fail_parsing:
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\n Number of parameter per line must be 3\n");
ret = -1;
break;
}
else
{
// Scan options
if ((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "fastforward") == 0))
{
if(rule && strlen(tempName))
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
strncpy(tempName, buf3, 20);
rule = NULL;
check_port_is_last_option = 0;
vlan_config = 0;
log_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 0;
#endif
asymff_config = 0;
}
else if ((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "asym_fastforward") == 0))
{
if(aff_rule && strlen(tempName1))
asymFFRules = cmmFcAsymFFListAddRule(asymFFRules, tempName1, aff_rule);
strncpy(tempName1, buf3, 20);
aff_rule = NULL;
check_port_is_last_option = 0;
vlan_config = 0;
log_config = 0;
#ifdef WIFI_ENABLE
wifi_config = 0;
#endif
asymff_config = 1;
}
else if(strcasecmp(buf1, "option") == 0)
{
if (vlan_config)
{
if (strcasecmp(buf2, "policy") == 0)
{
if (strcasecmp(buf3,"allow") == 0)
{
globalConf.vlan_policy = ALLOW;
continue;
}
if (strcasecmp(buf3,"prohibit") == 0)
{
globalConf.vlan_policy = PROHIBIT;
continue;
}
if (strcasecmp(buf3,"manual") == 0)
{
globalConf.vlan_policy = MANUAL;
continue;
}
}
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nLine: \"%s\"\n", buf);
ret = -1;
break;
}
else if (check_port_is_last_option) {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"port\" must be in last position in options list\n");
ret = -1;
break;
}
if (log_config)
{
if (strcasecmp(buf2, "file") == 0)
{
globalConf.logFile = fopen(buf3 , "a");
if (globalConf.logFile)
{
globalConf.log_level |= DEBUG_STDERR;
pthread_mutex_init(&globalConf.logMutex, NULL);
setlinebuf(globalConf.logFile);
}
else
cmm_print(DEBUG_CRIT, "cmmFcParser: Opening logfile %s returned error %s.\n", buf3, strerror(errno));
continue;
}
else if (strcasecmp(buf2, "command") == 0)
{
if (atoi(buf3) == 1)
globalConf.log_level |= DEBUG_COMMAND;
continue;
}
else if (strcasecmp(buf2, "error") == 0)
{
if (atoi(buf3) == 1)
globalConf.log_level |= DEBUG_ERROR;
continue;
}
else if (strcasecmp(buf2, "warning") == 0)
{
if (atoi(buf3) == 1)
globalConf.log_level |= DEBUG_WARNING;
continue;
}
else if (strcasecmp(buf2, "info") == 0)
{
if (atoi(buf3) == 1)
globalConf.log_level |= DEBUG_INFO;
continue;
}
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2);
ret = -1;
break;
}
if(tun_config)
{
if(strcasecmp(buf2, "proto") == 0)
{
if(strcasecmp(buf3, "IPIP") == 0)
{
globalConf.tun_proto = IPPROTO_IPIP;
globalConf.tun_family = AF_INET6;
continue;
}
break;
}
break;
}
#ifdef WIFI_ENABLE
if(wifi_config)
{
if (strcasecmp(buf2, "ifname") == 0)
{
if (wifi_if)
{
strcpy(wifi_if->ifname, buf3);
}
cmm_print(DEBUG_ERROR, "cmmFcParser: WiFi name: %s \n", wifi_if->ifname);
continue;
}
else if (strcasecmp(buf2, "direct_path_rx") == 0)
{
if (wifi_if)
wifi_if->direct_path_rx = atoi(buf3);
continue;
}
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2);
ret = -1;
break;
}
#endif
if(asymff_config)
{
if(strcmp(buf2, "orig_src_port") == 0)
{
attrType = ATTR_ORIG_PORT_SRC;
attrValue = atoi(buf3);
attrSValue[0] = '\0';
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask);
}
else if(strcmp(buf2, "orig_dst_port") == 0)
{
attrType = ATTR_ORIG_PORT_DST;
attrValue = atoi(buf3);
attrSValue[0] = '\0';
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask);
}
else if(strcmp(buf2, "l3proto") == 0)
{
if(strcmp(buf3, "ipv4") == 0) {
attrValue = AF_INET /*ETH_P_IP*/;
attrSValue[0] = '\0';
attrType = ATTR_L3PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else if(strcmp(buf3, "ipv6") == 0) {
attrValue = AF_INET6 /*ETH_P_IPV6*/;
attrSValue[0] = '\0';
attrType = ATTR_L3PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3);
ret = -1;
break;
}
aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask);
}
else if(strcmp(buf2, "l4proto") == 0)
{
if(strcmp(buf3, "tcp") == 0) {
attrValue = IPPROTO_TCP;
attrSValue[0] = '\0';
attrType = ATTR_ORIG_L4PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else if(strcmp(buf3, "udp") == 0) {
attrValue = IPPROTO_UDP;
attrSValue[0] = '\0';
attrType = ATTR_ORIG_L4PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3);
ret = -1;
break;
}
aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask);
}
else if (strcasecmp(buf2, "interface") == 0)
{
attrValue = 0;
strcpy(attrSValue,buf3);
attrType = ATTR_ORIG_COMCERTO_FP_IIF;
attrWidth = sizeof(int);
mask = 0x000000FF;
aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask);
}
continue;
}
if (check_ipv4_is_last_option) {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"ip_v4_addr\" must be in last position in options list\n");
ret = -1;
break;
}
if (check_ipv6_is_last_option) {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"ip_v6_addr\" must be in last position in options list\n");
ret = -1;
break;
}
// Scan options
if(strcmp(buf2, "orig_src_port") == 0)
{
attrType = ATTR_ORIG_PORT_SRC;
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "orig_dst_port") == 0)
{
attrType = ATTR_ORIG_PORT_DST;
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "repl_src_port") == 0)
{
attrType = ATTR_REPL_PORT_SRC;
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "repl_dst_port") == 0)
{
attrType = ATTR_REPL_PORT_DST;
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
mask = 0x0000FFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "mark") == 0)
{
attrType = ATTR_MARK;
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned int);
if(strcmp(buf4, "mask") == 0)
mask = atoi(buf5);
else
{
mask = 0xFFFFFFFF;
}
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "proto") == 0)
{
if(strcmp(buf3, "tcp") == 0) {
attrValue = IPPROTO_TCP;
attrType = ATTR_ORIG_L4PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else if(strcmp(buf3, "udp") == 0) {
attrValue = IPPROTO_UDP;
attrType = ATTR_ORIG_L4PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else if(strcmp(buf3, "ipv4") == 0) {
attrValue = AF_INET /*ETH_P_IP*/;
attrType = ATTR_L3PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else if(strcmp(buf3, "ipv6") == 0) {
attrValue = AF_INET6 /*ETH_P_IPV6*/;
attrType = ATTR_L3PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;
}
else {
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
/*attrType = ATTR_ORIG_L4PROTO;
attrWidth = sizeof(unsigned char);
mask = 0x000000FF;*/
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "port") == 0)
{
attrValue = atoi(buf3);
attrWidth = sizeof(unsigned short);
if ((attrValue < 1) || (attrValue> 65535))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3);
ret = -1;
break;
}
attrValue = ntohs(attrValue);
head_rule = rule;
// Port option. It is like 4 differents rules
attrType = ATTR_ORIG_PORT_SRC;
mask = 0x0000FFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_ORIG_PORT_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_PORT_SRC;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
// The last one will be added to the list later
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_PORT_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
check_port_is_last_option = 1;
}
else if(strcmp(buf2, "orig_src_ipv4") == 0)
{
struct in_addr addr;
if (!inet_aton(buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValue = addr.s_addr;
attrWidth = sizeof(unsigned int);
attrType = ATTR_ORIG_IPV4_SRC;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "orig_dst_ipv4") == 0)
{
struct in_addr addr;
if (!inet_aton(buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValue = addr.s_addr;
attrWidth = sizeof(unsigned int);
attrType = ATTR_ORIG_IPV4_DST;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "reply_src_ipv4") == 0)
{
struct in_addr addr;
if (!inet_aton(buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValue = addr.s_addr;
attrWidth = sizeof(unsigned int);
attrType = ATTR_REPL_IPV4_SRC;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "reply_dst_ipv4") == 0)
{
struct in_addr addr;
if (!inet_aton(buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValue = addr.s_addr;
attrWidth = sizeof(unsigned int);
attrType = ATTR_REPL_IPV4_DST;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "ip_v4_addr") == 0)
{
struct in_addr addr;
if (!inet_aton(buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValue = addr.s_addr;
attrWidth = sizeof(unsigned int);
mask = 0xFFFFFFFF;
// this option is like 4 differents rules
head_rule = rule;
attrType = ATTR_ORIG_IPV4_SRC;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_ORIG_IPV4_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_IPV4_SRC;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_IPV4_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
// The last one will be added to the list later
check_ipv4_is_last_option = 1;
}
else if(strcmp(buf2, "orig_src_ipv6") == 0)
{
struct in6_addr addr;
if (!inet_pton(AF_INET6, buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValueV6 = addr.s6_addr;
attrValue = 0;
attrWidth = 16;
attrType = ATTR_ORIG_IPV6_SRC;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "orig_dst_ipv6") == 0)
{
struct in6_addr addr;
if (!inet_pton(AF_INET6, buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValueV6 = addr.s6_addr;
attrValue = 0;
attrWidth = 16;
attrType = ATTR_ORIG_IPV6_DST;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "reply_src_ipv6") == 0)
{
struct in6_addr addr;
if (!inet_pton(AF_INET6, buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValueV6 = addr.s6_addr;
attrValue = 0;
attrWidth = 16;
attrType = ATTR_REPL_IPV6_SRC;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "reply_dst_ipv6") == 0)
{
struct in6_addr addr;
if (!inet_pton(AF_INET6, buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValueV6 = addr.s6_addr;
attrValue = 0;
attrWidth = 16;
attrType = ATTR_REPL_IPV6_DST;
mask = 0xFFFFFFFF;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
}
else if(strcmp(buf2, "ip_v6_addr") == 0)
{
struct in6_addr addr;
if (!inet_pton(AF_INET6, buf3, &addr))
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3);
ret = -1;
break;
}
attrValueV6 = addr.s6_addr;
attrValue = 0;
attrWidth = 16;
mask = 0xFFFFFFFF;
// this option is like 4 differents rules
head_rule = rule;
attrType = ATTR_ORIG_IPV6_SRC;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_ORIG_IPV6_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_IPV6_SRC;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
copy_rule = head_rule;
rule = NULL;
while(copy_rule) {
rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL);
copy_rule = copy_rule->next;
}
attrType = ATTR_REPL_IPV6_DST;
rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6);
// The last one will be added to the list later
check_ipv6_is_last_option = 1;
}
else
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2);
ret = -1;
break;
}
}
else
{
cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\n The string is %s\nThe expected string is: config fastforward <rule_name> or option <attribut_name> <attribut_value>\n", buf);
// TODO: Some memory to free when we enter in that case
ret = -1;
break;
}
}
}
if(aff_rule && strlen(tempName1))
asymFFRules = cmmFcAsymFFListAddRule(asymFFRules, tempName1, aff_rule);
if(rule && strlen(tempName))
denyRules = cmmFcListAddRule(denyRules, tempName, rule);
fclose(fp);
return ret;
}
/*****************************************************************
* cmmRxCmd
*
*
******************************************************************/
static int cmmRxCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmRxSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmStatCmd
*
*
******************************************************************/
static int cmmStatCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmStatSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmm4rdIdConvCmd
*
*
******************************************************************/
static int cmm4rdIdConvCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call tunnel 4rd id conversion set process function*/
cmm4rdIdConvSetProcess(argv, 0, argc, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmDPDSaQueryCmd
*
*
******************************************************************/
static int cmmDPDSaQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmDPDSaQuerySetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
#ifdef C2000_DPI
/*****************************************************************
* cmmDPIEnableCmd
*
*
******************************************************************/
static int cmmDPIEnableCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmDPIFlagSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
#endif
/*****************************************************************
* cmmAsymFFEnableCmd
*
*
******************************************************************/
static int cmmAsymFFEnableCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmAsymFFSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmShowRxCmd
*
*
******************************************************************/
static int cmmShowRxCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmRxShowProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmShowStatCmd
*
*
******************************************************************/
static int cmmShowStatCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Stat process function*/
cmmStatShowProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryRxCmd
*
*
******************************************************************/
static int cmmQueryRxCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmRxQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryRtCmd
*
*
******************************************************************/
static int cmmQueryRtCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmRtQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryCtCmd
*
*
******************************************************************/
static int cmmQueryCtCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmCtQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryMacVlanCmd
*
*
******************************************************************/
static int cmmQueryMacVlanCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call MacVlan process function*/
cmmMacVlanQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * cmmQueryV6CtCmd
* *
* *
* ******************************************************************/
static int cmmQueryV6CtCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmCt6QueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryPPPoECmd
*
*
******************************************************************/
static int cmmQueryPPPoECmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call PPPoE process function*/
cmmPPPoEQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * cmmQueryVlanCmd
* *
* *
* ******************************************************************/
static int cmmQueryVlanCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Vlan process function*/
cmmVlanQuery(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * * cmmQueryMc4Cmd
* * *
* * *
* * ******************************************************************/
static int cmmQueryMc4Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Multicast IPV4 process function*/
cmmMc4QueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * * * cmmQueryMc6Cmd
* * * *
* * * *
* * * ******************************************************************/
static int cmmQueryMc6Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Multicast IPV4 process function*/
cmmMc6QueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * * * * cmmQueryQmCmd
* * * * *
* * * * *
* * * * ******************************************************************/
static int cmmQueryQmCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Multicast IPV4 process function*/
cmmQmQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * * * * * cmmQueryQmCmd
* * * * * *
* * * * * *
* * * * * ******************************************************************/
static int cmmQmExptRateQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Multicast IPV4 process function*/
cmmQmExptRateQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* * * cmmSaQueryCmd
* * *
* * *
* * ******************************************************************/
static int cmmSaQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Sa Query process function*/
cmmSAQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmQueryNatptCmd
*
*
******************************************************************/
static int cmmQueryNatptCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call NATPT process function*/
cmmNATPTQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
#ifdef AUTO_BRIDGE
/*****************************************************************
* cmmQueryL2FlowCmd
*
*
******************************************************************/
static int cmmQueryL2FlowCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call L2Flow query function*/
cmmL2FlowQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
#endif
/*****************************************************************
* cmmQosCmds
*
*
******************************************************************/
static int cmmQmCmds(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call QM process function*/
cmmQmSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmMc4Cmd
*
*
******************************************************************/
static int cmmMc4Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmMc4SetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmMc6Cmd
*
*
******************************************************************/
static int cmmMc6Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RX process function*/
cmmMc6SetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmMspMem
*
*
******************************************************************/
static int cmmMspMem(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Memory DIsplay function */
prfMspMS( globalConf.cli.daemon_handle,argc, argv);
return CLI_OK;
}
/*****************************************************************
* cmmMspMem
*
*
******************************************************************/
static int cmmMspMemW(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Memory DIsplay function */
prfMspMSW( globalConf.cli.daemon_handle,argc, argv);
return CLI_OK;
}
/*****************************************************************
* cmmMspMem
******************************************************************/
static int cmmMspCT(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Memory DIsplay function */
prfMspCT(globalConf.cli.daemon_handle,argc, argv );
return CLI_OK;
}
/*
** Performance mesaurement and tracing
*/
/* Busy CPU */
static int cmmPTBusyCPU(struct cli_def * cli, char *command, char *argv[], int argc) {
prfPTBusyCPU( globalConf.cli.daemon_handle,argc, argv);
return CLI_OK;
}
/* Tracing/profiling */
static int cmmPTsetmask(struct cli_def * cli, char *command, char *argv[], int argc) {
prfPTsetmask( globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmPTstart(struct cli_def * cli, char *command, char *argv[], int argc) {
prfPTstart(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmPTswitch(struct cli_def * cli, char *command, char *argv[], int argc) {
prfPTswitch(globalConf.cli.daemon_handle, argc,argv);
return CLI_OK;
}
static int cmmPTshow(struct cli_def * cli, char *command, char *argv[], int argc) {
prfPTshow(globalConf.cli.daemon_handle, argc,argv);
return CLI_OK;
}
static int cmmPTstatus(struct cli_def * cli, char *command, char *argv[], int argc) {
prfStatus(globalConf.cli.daemon_handle,argc, argv);
return CLI_OK;
}
/*****************************************************************
* cmmVlan commands
*
*
******************************************************************/
static int cmmVlanCliAdd(struct cli_def *cli, char *command, char *argv[], int argc)
{
/*Call vlan process function*/
vlanAddProcess(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmVlanCliDelete(struct cli_def *cli, char *command, char *argv[], int argc)
{
/*Call vlan process function*/
vlanDeleteProcess(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
/*****************************************************************
* cmmPktCap commands
*
*
******************************************************************/
static int cmmPktCapSlice(struct cli_def *cli, char *command, char *argv[], int argc)
{
PktCapSliceProcess(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmPktCapStat(struct cli_def *cli, char *command, char *argv[], int argc)
{
PktCapStatProcess(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmPktCapFilter(struct cli_def *cli, char *command, char *argv[], int argc)
{
PktCapFilterProcess(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmPktCapQuery(struct cli_def *cli, char *command, char *argv[], int argc)
{
PktCapQueryProcess(cli , globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmIcc commands
*
*
******************************************************************/
static int cmmIccReset(struct cli_def *cli, char *command, char *argv[], int argc)
{
IccReset(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmIccThreshold(struct cli_def *cli, char *command, char *argv[], int argc)
{
IccThreshold(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmIccAdd(struct cli_def *cli, char *command, char *argv[], int argc)
{
IccAdd(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmIccDelete(struct cli_def *cli, char *command, char *argv[], int argc)
{
IccDelete(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmIccQuery(struct cli_def *cli, char *command, char *argv[], int argc)
{
IccQuery(globalConf.cli.daemon_handle, argc, argv);
return CLI_OK;
}
static int cmmQueryTnlCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
cmmTnlQueryProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmSetTimeoutCLI
******************************************************************/
static int cmmSetTimeoutCLI(struct cli_def * cli, char *command, char *argv[], int argc)
{
timeoutSet(globalConf.cli.daemon_handle, argv, argc);
return CLI_OK;
}
static int cmmSetRouteCLI(struct cli_def * cli, char *command, char *argv[], int argc)
{
cmmRouteSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
static int cmmFFControlCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
cmmFFControlProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
static int cmmIpv4Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
cmmCtChangeProcess4(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
static int cmmIpv6Cmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
cmmCtChangeProcess6(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
int cmmFFControlProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
int cpt = tabStart;
cmmd_ff_ctrl_cmd_t cmd;
char rcvBuffer[256];
char enable;
int rc;
if(!keywords[cpt])
goto usage;
if(strcasecmp(keywords[cpt], "enable") == 0)
enable = 1;
else if (strcasecmp(keywords[cpt], "disable") == 0)
enable = 0;
else
goto usage;
cmd.enable = enable;
// Send message to forward engine
cmm_print(DEBUG_COMMAND, "Send CMD_CMMTD_IPV4_FF_CONTROL cmd to daemon len=%d\n",sizeof(cmmd_ff_ctrl_cmd_t));
rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_IPV4_FF_CONTROL, (unsigned short *) &cmd, sizeof(cmmd_ff_ctrl_cmd_t), rcvBuffer);
if (rc != 2) /* we expect 2 bytes in response */
{
cmm_print(DEBUG_STDERR, "CMD_CMMTD_IPV4_FF_CONTROL unexpected response length %d\n", rc);
return -1;
}
else if ((((u_int16_t*)rcvBuffer)[0]) != CMMD_ERR_OK)
{
cmm_print(DEBUG_STDERR, "Error %d received from CMM Deamon for CMD_CMMTD_IPV4_FF_CONTROL\n", ((u_int16_t*)rcvBuffer)[0]);
return -1;
}
return 0;
usage:
cmm_print(DEBUG_ERROR, "Usage: set ff <enable disable>\n");
return -1;
}
int cmmIPsecSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
int cpt = tabStart;
fpp_ipsec_cmd_t cmd;
char rcvBuffer[256];
char enable;
if(!keywords[cpt])
goto usage;
else if(strcasecmp(keywords[cpt], "pre-frag") == 0)
{
if(!keywords[++cpt])
goto usage;
if(strcasecmp(keywords[cpt], "enable") == 0)
enable = 1;
else if (strcasecmp(keywords[cpt], "disable") == 0)
enable = 0;
else
goto usage;
cmd.pre_frag_en = enable;
// Send message to forward engine
cmm_print(DEBUG_COMMAND, "Send CMD_IPSEC_FRAG_CFG cmd to daemon len=%d\n",sizeof(fpp_ipsec_cmd_t));
if(cmmSendToDaemon(daemon_handle, FPP_CMD_IPSEC_FRAG_CFG, (unsigned short *) &cmd, sizeof(fpp_ipsec_cmd_t), rcvBuffer) == 4)
{
if ( ((unsigned short *)rcvBuffer)[0] != 0) {
cmm_print(DEBUG_STDERR, "Error %d while sending message to daemon\n", ((unsigned short *)rcvBuffer)[0]);
return ((unsigned short *)rcvBuffer)[0];
}
}
return 0;
}
usage:
cmm_print(DEBUG_ERROR, "Usage: set ipsec pre-frag <enable disable>\n");
return -1;
}
int cmmExptCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call exception path process function*/
cmmExptSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
int cmmRtpCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call RTP process function*/
cmmRTPSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
int cmmSocketCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call Socket process function*/
cmmSocketSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
int cmmNatptCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call NAT-PT process function*/
cmmNATPTSetProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
int cmmAltConfCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call AltConf process function*/
cmmAltConfClient(argc, argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
static void cliCallback(struct cli_def *cliHandle, char *format)
{
if (format[0] && cliHandle->client)
fprintf(cliHandle->client, "%s\r\n", format);
}
/*****************************************************************
* cmmBridgeControlCmd
*
*
******************************************************************/
static int cmmBridgeControlCmd(struct cli_def * cli, char *command, char *argv[], int argc)
{
/*Call L2Flow query function*/
cmmBridgeControlProcess(argv, 0, globalConf.cli.daemon_handle);
return CLI_OK;
}
/*****************************************************************
* cmmCliThread()
*
*
*
******************************************************************/
static void *cmmCliThread(void *data)
{
struct cmm_cli *ctx = data;
cmm_print(DEBUG_INFO, "%s: pid %d\n", __func__, getpid());
while (1)
{
ctx->sock2 = accept(ctx->sock, NULL, 0);
if (ctx->sock2 < 0)
{
cmm_print(DEBUG_ERROR, "%s: accept() %s\n", __func__, strerror(errno));
break;
}
cli_loop(ctx->handle, ctx->sock2);
cmm_print(DEBUG_INFO, "%s: cli_loop exiting\n", __func__);
close(ctx->sock2);
}
cmm_print(DEBUG_INFO, "%s: exiting\n", __func__);
kill (0, SIGTERM);
pthread_exit(NULL);
return NULL;
}
/*****************************************************************
* cmmCliInit()
*
*
*
******************************************************************/
int cmmCliInit(struct cmm_cli *ctx)
{
struct sockaddr_in serveraddr;
struct cli_command *c;
int on;
cmm_print(DEBUG_INFO, "%s\n", __func__);
ctx->fci_handle = fci_open(FCILIB_FF_TYPE, 0);
if (!ctx->fci_handle)
{
cmm_print(DEBUG_ERROR, "%s: fci_open() failed, %s\n", __func__, strerror(errno));
goto err0;
}
#ifdef NEW_IPC
ctx->daemon_handle = cmm_open();
if (!ctx->daemon_handle)
{
cmm_print(DEBUG_ERROR, "%s: cmm_open() failed, %s\n", __func__, strerror(errno));
goto err1;
}
#else
ctx->daemon_handle = globalConf.cmmPid;
#endif
ctx->handle = cli_init();
if (!ctx->handle)
{
cmm_print(DEBUG_ERROR, "%s: cli_init() failed\n", __func__);
goto err2;
}
cli_set_hostname(ctx->handle, "cmm");
cli_set_banner(ctx->handle, "Welcome to the Fast Forward Contrack module monitor CLI");
cli_print_callback(ctx->handle, cliCallback);
cli_allow_user(ctx->handle, "admin", "admin");
c = cli_register_command(ctx->handle, NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "connections", cmmCtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of fast forwarded connections");
cli_register_command(ctx->handle, c, "fpp_route", cmmFPPRtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the fpp route entries used by the fast forwarded connections");
cli_register_command(ctx->handle, c, "route", cmmRtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the route entries used by the fast forwarded connections");
cli_register_command(ctx->handle, c, "neighbor", cmmNeighShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the neighbor entries used by the fast forwarded connections");
cli_register_command(ctx->handle, c, "rules", cmmFcRulesShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of non fast forwardable connections");
cli_register_command(ctx->handle, c, "debug_level", cmmFcDebugShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the debug level");
cli_register_command(ctx->handle, c, "activate", cmmFcActivateShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show if cmm is activated or not");
cli_register_command(ctx->handle, c, "pppoe", cmmPPPoELocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the pppoe entries used by the fast forwarded connections");
cli_register_command(ctx->handle, c, "vlan", cmmVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the vlan entries programmmed");
cli_register_command(ctx->handle, c, "macvlan", cmmMacVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the macvlan entries programmmed");
cli_register_command(ctx->handle, c, "rx", cmmShowRxCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show ICC, Bridge status");
cli_register_command(ctx->handle, c, "stat", cmmShowStatCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show Statistics");
cli_register_command(ctx->handle, c, "sa_query_timer", cmmSaQueryTimerShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the DPD SA query timer configuration");
cli_register_command(ctx->handle, c, "sec-connections", cmmFlowLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the local table of secure connections");
cli_register_command(ctx->handle, c, "relay", cmmRelayLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show pppoe relay entries used by the fast forwarded connections");
cli_register_command(ctx->handle, c, "mc6", cmmMc6Show, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of V6 multicat listeners");
cli_register_command(ctx->handle, c, "mc4", cmmMc4Show, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of V4 multicat listeners");
#ifdef C2000_DPI
cli_register_command(ctx->handle, c, "dpi", cmmDPIEnableShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the DPI flag status");
#endif
cli_register_command(ctx->handle, c, "asym_fastforward", cmmAsymFFEnableShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the Asymmetric fast forward status");
cli_register_command(ctx->handle, c, "asym_ff_rules", cmmFcAsymFFRulesShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of asymmetric fast forwardable connections");
}
c = cli_register_command(ctx->handle, NULL, "query", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "pppoe", cmmQueryPPPoECmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query PPPoE entries on FPP");
cli_register_command(ctx->handle, c, "rx", cmmQueryRxCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Bridge entries on FPP");
cli_register_command(ctx->handle, c, "route", cmmQueryRtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Route entries on FPP");
cli_register_command(ctx->handle, c, "connections", cmmQueryCtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Connection entries on FPP");
cli_register_command(ctx->handle, c, "macvlan", cmmQueryMacVlanCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Macvlan interfaces on FPP");
cli_register_command(ctx->handle, c, "v6connections", cmmQueryV6CtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query IPV6Connection entries on FPP");
cli_register_command(ctx->handle, c, "vlan", cmmQueryVlanCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query VLAN entries on FPP");
cli_register_command(ctx->handle, c, "mc4", cmmQueryMc4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Multicast IPV4 entries on FPP");
cli_register_command(ctx->handle, c, "mc6", cmmQueryMc6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Multicast IPV6 entries on FPP");
cli_register_command(ctx->handle, c, "qm", cmmQueryQmCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query QOS configuration on FPP");
cli_register_command(ctx->handle, c, "qmexptrate", cmmQmExptRateQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Exception rate configured on FPP");
cli_register_command(ctx->handle, c, "sa", cmmSaQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query for SA details");
cli_register_command(ctx->handle, c, "natpt", cmmQueryNatptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query NAT-PT connections");
cli_register_command(ctx->handle, c, "pktcapture", cmmPktCapQuery, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query packet capture config parameters");
cli_register_command(ctx->handle, c, "tunnels",cmmQueryTnlCmd , PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query tunnel parameters");
#ifdef AUTO_BRIDGE
cli_register_command(ctx->handle, c, "l2flows", cmmQueryL2FlowCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query L2Flows entries on FPP");
#endif
}
// cli_register_command(ctx->handle, pshow, "eth_icc", cmmEthIccShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the pppoe entries used by the fast forwarded connections");
c = cli_register_command(ctx->handle, NULL, "set", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "activate", cmmFcActivate, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Activate or desactivate fast forwarding");
cli_register_command(ctx->handle, c, "debug", cmmFcDebug, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Debug level");
cli_register_command(ctx->handle, c, "rx", cmmRxCmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage RX module (ICC, Bridge ...)");
cli_register_command(ctx->handle, c, "qm", cmmQmCmds, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage QM module (QOS, Rate Limiting ...)");
cli_register_command(ctx->handle, c, "mc6", cmmMc6Cmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage MC6 module (IpV6 multicast)");
cli_register_command(ctx->handle, c, "mc4", cmmMc4Cmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage MC4 module (IPv4 multicast)");
cli_register_command(ctx->handle, c, "timeout", cmmSetTimeoutCLI, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Set UDP/TCP/IPIP timeout value in FPP");
cli_register_command(ctx->handle, c, "route", cmmSetRouteCLI, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Set Extended Route");
cli_register_command(ctx->handle, c, "ff", cmmFFControlCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable fast forward");
cli_register_command(ctx->handle, c, "stat", cmmStatCmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage Statistics (PPPoE, Bridge ...)");
cli_register_command(ctx->handle, c, "expt_queue", cmmExptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Exception Path Queuing");
cli_register_command(ctx->handle, c, "socket", cmmSocketCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Socket module");
cli_register_command(ctx->handle, c, "rtp", cmmRtpCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage RTP-relay module");
cli_register_command(ctx->handle, c, "natpt", cmmNatptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage NAT-PT module");
cli_register_command(ctx->handle, c, "sa_query_timer", cmmDPDSaQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable SA query timer");
cli_register_command(ctx->handle, c, "config", cmmAltConfCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Alternate Configuration module");
cli_register_command(ctx->handle, c, "bridge", cmmBridgeControlCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage automatic bridging");
#ifdef C2000_DPI
cli_register_command(ctx->handle, c, "dpi", cmmDPIEnableCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable Global DPI flag");
#endif
cli_register_command(ctx->handle, c, "asym_fastforward", cmmAsymFFEnableCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable Asymmetric Fast forward");
cli_register_command(ctx->handle, c, "4rd-id-conversion", cmm4rdIdConvCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable 4rd Ipv4 header ID conversion");
}
c = cli_register_command(ctx->handle, NULL, "ipv4", cmmIpv4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
cli_register_command(ctx->handle, c, "update", cmmIpv4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Update IPv4 Connection");
c = cli_register_command(ctx->handle, NULL, "ipv6", cmmIpv6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
cli_register_command(ctx->handle, c, "update", cmmIpv6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Update IPv6 Connection");
cli_register_command(ctx->handle, NULL, "stop", cmmFcStop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Kill cmm");
c = cli_register_command(ctx->handle, NULL, "prf",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "busycpu",cmmPTBusyCPU, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Measure available CPU cycles");
cli_register_command(ctx->handle, c, "status", cmmPTstatus, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show status of profiling/CPU measurement");
c = cli_register_command(ctx->handle, c, "trace", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "setmask", cmmPTsetmask, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set module mask");
cli_register_command(ctx->handle, c, "start", cmmPTstart, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Start trace");
cli_register_command(ctx->handle, c, "switch", cmmPTswitch, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Stop or switch trace and show inactive trace");
cli_register_command(ctx->handle, c, "showtrace", cmmPTshow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show inactive trace");
}
}
c = cli_register_command(ctx->handle, NULL, "mspmem",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "ct", cmmMspCT, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of fast forwarded connections");
cli_register_command(ctx->handle, c, "bytes", cmmMspMem, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show msp memory in host order");
cli_register_command(ctx->handle, c, "words", cmmMspMemW, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show msp memory in network order");
}
c = cli_register_command(ctx->handle, NULL, "vlan",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "add", cmmVlanCliAdd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Register vlan entry with fpp");
cli_register_command(ctx->handle, c, "delete", cmmVlanCliDelete, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Deregister vlan with fpp");
cli_register_command(ctx->handle, c, "show", cmmVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Deregister vlan with fpp");
}
c = cli_register_command(ctx->handle, NULL, "pktcapture", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "slice", cmmPktCapSlice, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Register packet capture size with fpp");
cli_register_command(ctx->handle, c, "status", cmmPktCapStat, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Enable/disable packet capture on LAN/WAN with fpp");
cli_register_command(ctx->handle, c, "filter", cmmPktCapFilter, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Register first-level-filter string for LAN/WAN with fpp");
}
c = cli_register_command(ctx->handle, NULL, "icc", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "");
if (c)
{
cli_register_command(ctx->handle, c, "reset", cmmIccReset, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Reset ICC");
cli_register_command(ctx->handle, c, "threshold", cmmIccThreshold, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Set ICC threshold values");
cli_register_command(ctx->handle, c, "add", cmmIccAdd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Add ICC table entry");
cli_register_command(ctx->handle, c, "delete", cmmIccDelete, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Delete ICC table entry");
cli_register_command(ctx->handle, c, "query", cmmIccQuery, PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Query ICC table values");
}
ctx->sock = socket(AF_INET, SOCK_STREAM, 0);
if (ctx->sock < 0)
{
cmm_print(DEBUG_ERROR, "%s: socket() %s\n", __func__, strerror(errno));
goto err3;
}
on = 1;
setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(2103);
if (bind(ctx->sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
{
cmm_print(DEBUG_ERROR, "%s: bind() %s\n", __func__, strerror(errno));
goto err4;
}
if (listen(ctx->sock, 1) < 0)
{
cmm_print(DEBUG_ERROR, "%s: listen() %s\n", __func__, strerror(errno));
goto err4;
}
if (pthread_create(&ctx->pthread, NULL, cmmCliThread, ctx) < 0)
{
cmm_print(DEBUG_CRIT, "%s: pthread_create() failed, %s\n", __func__, strerror(errno));
goto err4;
}
return 0;
err4:
close(ctx->sock);
err3:
cli_done(ctx->handle);
err2:
#ifdef NEW_IPC
cmm_close(ctx->daemon_handle);
err1:
#endif
fci_close(ctx->fci_handle);
err0:
return -1;
}
void cmmCliExit(struct cmm_cli *ctx)
{
cmm_print(DEBUG_INFO, "%s\n", __func__);
#if defined(__UCLIBC__)
/* workaround uclibc pthread_cancel() bug, force thread to exit */
close(ctx->sock);
close(ctx->sock2);
#endif
pthread_cancel(ctx->pthread);
pthread_join(ctx->pthread, NULL);
#if !defined(__UCLIBC__)
close(ctx->sock);
close(ctx->sock2);
#endif
cli_done(ctx->handle);
ctx->handle = 0;
#ifdef NEW_IPC
cmm_close(ctx->daemon_handle);
#endif
fci_close(ctx->fci_handle);
cmm_print(DEBUG_INFO, "%s: exiting\n", __func__);
}