nwfilter: add support for connlimit match

This patch adds support for the connlimit match in iptables that is used
to limit the number of outgoing directions.
This commit is contained in:
Stefan Berger 2010-04-20 17:14:38 -04:00
parent c8f4dcca6a
commit abce152a49
3 changed files with 50 additions and 13 deletions

View File

@ -875,6 +875,11 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
.datatype = DATATYPE_UINT8,\ .datatype = DATATYPE_UINT8,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDSCP),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDSCP),\
/*.validator = dscpValidator,*/\ /*.validator = dscpValidator,*/\
},\
{\
.name = "connlimit-above",\
.datatype = DATATYPE_UINT16,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataConnlimitAbove),\
} }
#define COMMON_PORT_PROPS(STRUCT) \ #define COMMON_PORT_PROPS(STRUCT) \

View File

@ -153,6 +153,7 @@ struct _ipHdrDataDef {
nwItemDesc dataDstIPFrom; nwItemDesc dataDstIPFrom;
nwItemDesc dataDstIPTo; nwItemDesc dataDstIPTo;
nwItemDesc dataDSCP; nwItemDesc dataDSCP;
nwItemDesc dataConnlimitAbove;
}; };

View File

@ -815,7 +815,8 @@ static int
iptablesHandleIpHdr(virBufferPtr buf, iptablesHandleIpHdr(virBufferPtr buf,
virNWFilterHashTablePtr vars, virNWFilterHashTablePtr vars,
ipHdrDataDefPtr ipHdr, ipHdrDataDefPtr ipHdr,
int directionIn) int directionIn,
bool *skipRule, bool *skipMatch)
{ {
char ipaddr[INET6_ADDRSTRLEN], char ipaddr[INET6_ADDRSTRLEN],
number[20]; number[20];
@ -944,6 +945,24 @@ iptablesHandleIpHdr(virBufferPtr buf,
number); number);
} }
if (HAS_ENTRY_ITEM(&ipHdr->dataConnlimitAbove)) {
if (directionIn) {
// only support for limit in outgoing dir.
*skipRule = true;
} else {
if (printDataType(vars,
number, sizeof(number),
&ipHdr->dataConnlimitAbove))
goto err_exit;
virBufferVSprintf(buf,
" -m connlimit %s --connlimit-above %s",
ENTRY_GET_NEG_SIGN(&ipHdr->dataConnlimitAbove),
number);
*skipMatch = true;
}
}
return 0; return 0;
err_exit: err_exit:
@ -1063,6 +1082,8 @@ _iptablesCreateRuleInstance(int directionIn,
: iptables_cmd_path; : iptables_cmd_path;
unsigned int bufUsed; unsigned int bufUsed;
bool srcMacSkipped = false; bool srcMacSkipped = false;
bool skipRule = false;
bool skipMatch = false;
if (!iptables_cmd) { if (!iptables_cmd) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
@ -1096,7 +1117,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.tcpHdrFilter.ipHdr, &rule->p.tcpHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
if (iptablesHandlePortData(&buf, if (iptablesHandlePortData(&buf,
@ -1140,7 +1162,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.udpHdrFilter.ipHdr, &rule->p.udpHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
if (iptablesHandlePortData(&buf, if (iptablesHandlePortData(&buf,
@ -1171,7 +1194,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.udpliteHdrFilter.ipHdr, &rule->p.udpliteHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
break; break;
@ -1197,7 +1221,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.espHdrFilter.ipHdr, &rule->p.espHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
break; break;
@ -1223,7 +1248,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.ahHdrFilter.ipHdr, &rule->p.ahHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
break; break;
@ -1249,7 +1275,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.sctpHdrFilter.ipHdr, &rule->p.sctpHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
if (iptablesHandlePortData(&buf, if (iptablesHandlePortData(&buf,
@ -1283,7 +1310,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.icmpHdrFilter.ipHdr, &rule->p.icmpHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPType)) { if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPType)) {
@ -1341,7 +1369,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.igmpHdrFilter.ipHdr, &rule->p.igmpHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
break; break;
@ -1367,7 +1396,8 @@ _iptablesCreateRuleInstance(int directionIn,
if (iptablesHandleIpHdr(&buf, if (iptablesHandleIpHdr(&buf,
vars, vars,
&rule->p.allHdrFilter.ipHdr, &rule->p.allHdrFilter.ipHdr,
directionIn)) directionIn,
&skipRule, &skipMatch))
goto err_exit; goto err_exit;
break; break;
@ -1376,7 +1406,8 @@ _iptablesCreateRuleInstance(int directionIn,
return -1; return -1;
} }
if (srcMacSkipped && bufUsed == virBufferUse(&buf)) { if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) ||
skipRule) {
virBufferFreeAndReset(&buf); virBufferFreeAndReset(&buf);
return 0; return 0;
} }
@ -1385,10 +1416,10 @@ _iptablesCreateRuleInstance(int directionIn,
target = accept_target; target = accept_target;
else { else {
target = "DROP"; target = "DROP";
match = NULL; skipMatch = true;
} }
if (match) if (match && !skipMatch)
virBufferVSprintf(&buf, " %s", match); virBufferVSprintf(&buf, " %s", match);