[libvirt] [PATCH V4 03/10] Make filter creation in root table more flexible
Stefan Berger
stefanb at linux.vnet.ibm.com
Thu Nov 17 15:03:49 UTC 2011
On 11/16/2011 08:02 PM, Eric Blake wrote:
> On 10/26/2011 05:36 AM, Stefan Berger wrote:
>> Use the previously introduced chain priorities to sort the chains for access
>> from an interface's 'root' table and have them created in the proper order.
>> This gets rid of a lot of code that was previously creating the chains in a
>> more hardcoded way.
>>
>> To determine what protocol a filter is used for evaluation do prefix-
>> matching, i.e., the filter 'arp' is used to filter for the 'arp' protocol,
>> 'ipv4' for the 'ipv4' protocol and 'arp-xyz' will also be used to filter
>> for the 'arp' protocol following the prefix 'arp' in its name.
>>
>> Signed-off-by: Stefan Berger<stefanb at linux.vnet.ibm.com>
>>
>> ---
>> src/nwfilter/nwfilter_ebiptables_driver.c | 130 ++++++++++++++++++++++--------
>> 1 file changed, 98 insertions(+), 32 deletions(-)
>>
>>
>> +static int
>> +ebiptablesFilterOrderSort(const virHashKeyValuePairPtr a,
>> + const virHashKeyValuePairPtr b)
>> +{
>> + return *(virNWFilterChainPriority *)a->value -
>> + *(virNWFilterChainPriority *)b->value;
>> +}
> I tend to worry about someone passing INT_MAX and INT_MIN to a qsort
> algorithm, then getting the wrong comparison sense because of integer
> overflow when it uses straight subtraction; so I like to add a comment
> explaining why I know that the valid input was capped and overflow is
> impossible.
>
Values here are limited to range [-1000, 1000]. Added that as a comment now.
>>
>> static void
>> iptablesCheckBridgeNFCallEnabled(bool isIPv6)
>> @@ -3327,6 +3336,56 @@ iptablesCheckBridgeNFCallEnabled(bool is
>> }
>> }
>>
>> +/*
>> + * Given a filtername determine the protocol it is used for evaluating
>> + * We do prefix-matching to determine the protocol.
>> + */
>> +static enum l3_proto_idx
>> +ebtablesGetProtoIdxByFiltername(const char *filtername)
>> +{
>> + enum l3_proto_idx idx;
>> +
>> + for (idx = 0; idx< L3_PROTO_LAST_IDX; idx++) {
>> + if (STRPREFIX(filtername, l3_protocols[idx].val)) {
>> + return idx;
>> + }
>> + }
> This works as long as none of the entries in l3_protocols are a prefix
> of any other entry; is it worth a comment at the declaration of
> l3_protocols warning about this assumption for when new protocol names
> are added to the table?
>
Added a comment there. Though if "abc" comes before "ab", that would
still work, though entries have to be sorted that way then.
>> +
>> + return -1;
>> +}
>> +
>> +static int
>> +ebtablesCreateTmpRootAndSubChains(virBufferPtr buf,
>> + const char *ifname,
>> + virHashTablePtr chains, int direction)
>> +{
>> + int rc = 0, i;
>> +
>> + if (virHashSize(chains) != 0) {
>> + char **filter_names;
>> +
>> + ebtablesCreateTmpRootChain(buf, direction, ifname, 1);
>> + filter_names = (char **)virHashGetKeys(chains,
>> + ebiptablesFilterOrderSort);
> This area of code will be impacted by my comments on 1/10.
>
Conversion done.
>> + if (filter_names == NULL) {
>> + virReportOOMError();
> Your implementation of virHashGetKeys already reported OOM error for all
> error paths except for numElems< 0; but that means that this call to
> virReportOOMError() is either redundant (a second report), or misleading
> (if numElems< 0, you are not OOM, but have a programming bug on hand
> for passing in an invalid hash table in the first place).
>
So I am not reporting an error anymore. If the hash table 'chains' was
NULL, which would then also lead to '<', it would not end up in this
function at all but would have been intercepted earlier.
>> + rc = 1;
> Can we get this updated to use -1 for failures, so that there's less to
> clean up later when we fix this file to match libvirt conventions?
>
Did that now.
There will also be a patch converting all the nwfilter code to return
'-1' upon failure. I got that in my queue, but only for later.
>> + goto err_exit;
>> + }
>> + for (i = 0; filter_names[i]; i++) {
>> + enum l3_proto_idx idx = ebtablesGetProtoIdxByFiltername(
>> + filter_names[i]);
>> + if ((int)idx< 0)
>> + continue;
>> + ebtablesCreateTmpSubChain(buf, direction, ifname, idx,
>> + filter_names[i], 1);
>> + }
>> + virHashFreeKeys(chains, (void **)filter_names);
> Oh, this reminds me of some additional feedback I meant to give on 1/10
> - as part of the documentation you add, be sure to mention that the
> returned array is only valid as long as the underlying hash table is not
> modified (especially if you alter things to return in-hash pointers
> rather than cloning keys) - adding or removing elements, or deleting the
> hash table, will invalidate the returned key array.
>
I added that also as comment to the virHashGetItems() description.
>> @@ -3337,24 +3396,43 @@ ebiptablesApplyNewRules(virConnectPtr co
>> int i;
>> int cli_status;
>> ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst;
>> - int chains_in = 0, chains_out = 0;
>> virBuffer buf = VIR_BUFFER_INITIALIZER;
>> + virHashTablePtr chains_in_set = virHashCreate(10, NULL),
>> + chains_out_set = virHashCreate(10, NULL);
> Style-wise, I would list this as two declarations separated by ';',
> rather than one declaration of two variables separated by ','. That is,
> I find it slightly hard to read stacked declarations that involve
> multi-argument function calls as the initializers.
>
Fixed.
> If patch 1/10 were used as-is, then this patch looks good except for a
> few easy-to-fix nits. But more likely, this will also need a v5 due to
> rebasing on top of changes to how you grab a sorted list of hash keys
> (or key-value pairs).
>
Thanks for the review.
Stefan
More information about the libvir-list
mailing list