nwfilter: Extend XML parser and gen. to support state attr.

The patch below extends the XML parser and generator so that every l3 protocol
now can have a state attribute.
This commit is contained in:
Stefan Berger 2010-10-07 06:37:31 -04:00
parent b0f34a6a1a
commit 1be31f5479
3 changed files with 175 additions and 13 deletions

View File

@ -44,6 +44,7 @@
#include "nwfilter_params.h"
#include "nwfilter_conf.h"
#include "domain_conf.h"
#include "c-ctype.h"
#define VIR_FROM_THIS VIR_FROM_NWFILTER
@ -157,6 +158,7 @@ static const char srcportend_str[] = "srcportend";
static const char dstportstart_str[] = "dstportstart";
static const char dstportend_str[] = "dstportend";
static const char dscp_str[] = "dscp";
static const char state_str[] = "state";
#define SRCMACADDR srcmacaddr_str
#define SRCMACMASK srcmacmask_str
@ -179,6 +181,7 @@ static const char dscp_str[] = "dscp";
#define DSTPORTSTART dstportstart_str
#define DSTPORTEND dstportend_str
#define DSCP dscp_str
#define STATE state_str
/**
@ -414,9 +417,11 @@ union data {
};
typedef bool (*valueValidator)(enum attrDatatype datatype, union data *valptr,
virNWFilterRuleDefPtr nwf);
virNWFilterRuleDefPtr nwf,
nwItemDesc *item);
typedef bool (*valueFormatter)(virBufferPtr buf,
virNWFilterRuleDefPtr nwf);
virNWFilterRuleDefPtr nwf,
nwItemDesc *item);
typedef struct _virXMLAttr2Struct virXMLAttr2Struct;
struct _virXMLAttr2Struct
@ -441,7 +446,8 @@ static const struct int_map macProtoMap[] = {
static bool
checkMacProtocolID(enum attrDatatype datatype, union data *value,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
int32_t res = -1;
@ -468,7 +474,8 @@ checkMacProtocolID(enum attrDatatype datatype, union data *value,
static bool
macProtocolIDFormatter(virBufferPtr buf,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
const char *str = NULL;
bool asHex = true;
@ -519,7 +526,8 @@ checkValidMask(unsigned char *data, int len)
static bool
checkMACMask(enum attrDatatype datatype ATTRIBUTE_UNUSED,
union data *macMask,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
return checkValidMask(macMask->uc, 6);
}
@ -545,7 +553,8 @@ static const struct int_map arpOpcodeMap[] = {
static bool
arpOpcodeValidator(enum attrDatatype datatype,
union data *value,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
int32_t res = -1;
@ -569,7 +578,8 @@ arpOpcodeValidator(enum attrDatatype datatype,
static bool
arpOpcodeFormatter(virBufferPtr buf,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
const char *str = NULL;
@ -604,7 +614,8 @@ static const struct int_map ipProtoMap[] = {
static bool checkIPProtocolID(enum attrDatatype datatype,
union data *value,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
int32_t res = -1;
@ -628,7 +639,8 @@ static bool checkIPProtocolID(enum attrDatatype datatype,
static bool
formatIPProtocolID(virBufferPtr buf,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
const char *str = NULL;
bool asHex = true;
@ -649,7 +661,8 @@ formatIPProtocolID(virBufferPtr buf,
static bool
dscpValidator(enum attrDatatype datatype, union data *val,
virNWFilterRuleDefPtr nwf)
virNWFilterRuleDefPtr nwf,
nwItemDesc *item ATTRIBUTE_UNUSED)
{
uint8_t dscp = val->ui;
if (dscp > 63)
@ -660,6 +673,128 @@ dscpValidator(enum attrDatatype datatype, union data *val,
return 1;
}
static const struct int_map stateMatchMap[] = {
INTMAP_ENTRY(RULE_FLAG_STATE_NEW , "NEW"),
INTMAP_ENTRY(RULE_FLAG_STATE_ESTABLISHED , "ESTABLISHED"),
INTMAP_ENTRY(RULE_FLAG_STATE_RELATED , "RELATED"),
INTMAP_ENTRY(RULE_FLAG_STATE_INVALID , "INVALID"),
INTMAP_ENTRY(RULE_FLAG_STATE_NONE , "NONE"),
INTMAP_ENTRY_LAST,
};
static int
parseStringItems(const struct int_map *int_map,
const char *input, int32_t *flags, char sep)
{
int rc = 0;
unsigned int i, j;
bool found;
i = 0;
while (input[i]) {
found = false;
while (c_isspace(input[i]) || input[i] == sep)
i++;
if (!input[i])
break;
for (j = 0; int_map[j].val; j++) {
if (STRCASEEQLEN(&input[i], int_map[j].val,
strlen(int_map[j].val))) {
*flags |= int_map[j].attr;
i += strlen(int_map[j].val);
found = true;
break;
}
}
if (!found) {
rc = 1;
break;
}
}
return rc;
}
static int
printStringItems(virBufferPtr buf, const struct int_map *int_map,
int32_t flags, const char *sep)
{
unsigned int i, c = 0;
int32_t last_attr = 0;
for (i = 0; int_map[i].val; i++) {
if (last_attr != int_map[i].attr &&
flags & int_map[i].attr) {
if (c >= 1)
virBufferVSprintf(buf, "%s", sep);
virBufferVSprintf(buf, "%s", int_map[i].val);
c++;
}
last_attr = int_map[i].attr;
}
return 0;
}
static int
parseStateMatch(const char *statematch, int32_t *flags)
{
int rc = parseStringItems(stateMatchMap, statematch, flags, ',');
if ((*flags & RULE_FLAG_STATE_NONE))
*flags = RULE_FLAG_STATE_NONE;
return rc;
}
void
virNWFilterPrintStateMatchFlags(virBufferPtr buf, const char *prefix,
int32_t flags, bool disp_none)
{
if (!disp_none && (flags & RULE_FLAG_STATE_NONE))
return;
virBufferVSprintf(buf, "%s", prefix);
printStringItems(buf, stateMatchMap, flags, ",");
}
static bool
stateValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union data *val,
virNWFilterRuleDefPtr nwf,
nwItemDesc *item)
{
char *input = val->c;
int32_t flags = 0;
if (parseStateMatch(input, &flags))
return 0;
item->u.u16 = flags;
nwf->flags |= flags;
item->datatype = DATATYPE_UINT16;
return 1;
}
static bool
stateFormatter(virBufferPtr buf,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item)
{
virNWFilterPrintStateMatchFlags(buf, "", item->u.u16, true);
return true;
}
#define COMMON_MAC_PROPS(STRUCT) \
{\
.name = SRCMACADDR,\
@ -926,6 +1061,13 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
.name = "connlimit-above",\
.datatype = DATATYPE_UINT16,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataConnlimitAbove),\
},\
{\
.name = STATE,\
.datatype = DATATYPE_STRING,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataState),\
.validator = stateValidator,\
.formatter = stateFormatter,\
}
#define COMMON_PORT_PROPS(STRUCT) \
@ -1422,7 +1564,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr node,
*flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS | flags_set;
item->datatype = datatype >> 1;
if (validator) {
if (!validator(datatype >> 1, &data, nwf)) {
if (!validator(datatype >> 1, &data, nwf, item)) {
rc = -1;
*flags = 0;
}
@ -2533,7 +2675,7 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf,
virBufferVSprintf(buf, " %s='",
att[i].name);
if (att[i].formatter) {
if (!att[i].formatter(buf, def)) {
if (!att[i].formatter(buf, def, item)) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("formatter for %s %s reported error"),
type,

View File

@ -28,11 +28,14 @@
# include <stdint.h>
# include <stddef.h>
# include <stdbool.h>
# include "internal.h"
# include "util.h"
# include "hash.h"
# include "xml.h"
# include "buf.h"
# include "network.h"
/* XXX
@ -179,6 +182,7 @@ struct _ipHdrDataDef {
nwItemDesc dataDstIPFrom;
nwItemDesc dataDstIPTo;
nwItemDesc dataDSCP;
nwItemDesc dataState;
nwItemDesc dataConnlimitAbove;
nwItemDesc dataComment;
};
@ -353,10 +357,25 @@ enum virNWFilterEbtablesTableType {
# define MAX_RULE_PRIORITY 1000
enum virNWFilterRuleFlags {
RULE_FLAG_NO_STATEMATCH = (1 << 0),
RULE_FLAG_NO_STATEMATCH = (1 << 0),
RULE_FLAG_STATE_NEW = (1 << 1),
RULE_FLAG_STATE_ESTABLISHED = (1 << 2),
RULE_FLAG_STATE_RELATED = (1 << 3),
RULE_FLAG_STATE_INVALID = (1 << 4),
RULE_FLAG_STATE_NONE = (1 << 5),
};
# define IPTABLES_STATE_FLAGS \
(RULE_FLAG_STATE_NEW | \
RULE_FLAG_STATE_ESTABLISHED | \
RULE_FLAG_STATE_RELATED | \
RULE_FLAG_STATE_INVALID | \
RULE_FLAG_STATE_NONE)
void virNWFilterPrintStateMatchFlags(virBufferPtr buf, const char *prefix,
int32_t flags, bool disp_none);
typedef struct _virNWFilterRuleDef virNWFilterRuleDef;
typedef virNWFilterRuleDef *virNWFilterRuleDefPtr;
struct _virNWFilterRuleDef {

View File

@ -534,6 +534,7 @@ virNWFilterConfLayerInit;
virNWFilterConfLayerShutdown;
virNWFilterLockFilterUpdates;
virNWFilterUnlockFilterUpdates;
virNWFilterPrintStateMatchFlags;
# nwfilter_params.h