[Devel] [PATCH RH7] netfilter: drop/reaquire nfnl_lock on request_module() in nft_log module
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Jul 17 16:19:06 MSK 2020
On 07/17/2020 03:39 PM, Andrey Ryabinin wrote:
>
>
> On 7/16/20 3:37 PM, Konstantin Khorenko wrote:
>> +static int nf_logger_find_get_lock(int pf, enum nf_log_type type)
>> +{
>> + struct nf_logger *logger;
>> + int ret = 0;
>> +
>> + logger = loggers[pf][type];
>> + if (logger == NULL) {
>> + nfnl_unlock(NFNL_SUBSYS_NFTABLES);
>> + request_module("nf-logger-%u-%u", pf, type);
>> + nfnl_lock(NFNL_SUBSYS_NFTABLES);
>> + ret = -EAGAIN;
>
> nfnetlink_rcv_batch() has special error path for EAGAIN:
> /* The lock was released to autoload some module, we
> * have to abort and start from scratch using the
> * original skb.
> */
> if (err == -EAGAIN) {
> status |= NFNL_BATCH_REPLAY;
> goto done;
> }
>
>
> Yet, nf_logger_find_get_lock() don't return immediately with EAGAIN, but continues and potentially replaces EAGAIN with ENOENT.
> Why?
Well, this is the original logic, i did not change it.
The idea is:
* if loggers[pf][type] is not registered, try to load the appropriate module
// the module load could fail, we keep it in mind
* next check loggers[pf][type] once again - and if it's empty again after our attempt to load the module
(and thus to register desired loggers[pf][type]),
then we don't need to return -EAGAIN, because
- next module load attempt could also fail to register loggers[pf][type] and we get in a loop
- we just don't want to try loading module more than once
=> in case loggers[pf][type] is still empty after single module load attempt =>
something is deadly wrong, return -ENOENT, no need to probe it once more
- another case - try_module_get() fails - we also don't want to retry in this case
>> + }
>> +
>> + rcu_read_lock();
>> + logger = rcu_dereference(loggers[pf][type]);
>> +
>> + if ((logger == NULL) ||
>> + ((ret == 0) && !try_module_get(logger->me))) {
>> + ret = -ENOENT;
>> + }
>> + rcu_read_unlock();
>> + return ret;
>> +}
>> +
> .
>
More information about the Devel
mailing list