• Pablo Neira Ayuso's avatar
    netfilter: nfnetlink: add batch support and use it from nf_tables · 0628b123
    Pablo Neira Ayuso authored
    This patch adds a batch support to nfnetlink. Basically, it adds
    two new control messages:
    
    * NFNL_MSG_BATCH_BEGIN, that indicates the beginning of a batch,
      the nfgenmsg->res_id indicates the nfnetlink subsystem ID.
    
    * NFNL_MSG_BATCH_END, that results in the invocation of the
      ss->commit callback function. If not specified or an error
      ocurred in the batch, the ss->abort function is invoked
      instead.
    
    The end message represents the commit operation in nftables, the
    lack of end message results in an abort. This patch also adds the
    .call_batch function that is only called from the batch receival
    path.
    
    This patch adds atomic rule updates and dumps based on
    bitmask generations. This allows to atomically commit a set of
    rule-set updates incrementally without altering the internal
    state of existing nf_tables expressions/matches/targets.
    
    The idea consists of using a generation cursor of 1 bit and
    a bitmask of 2 bits per rule. Assuming the gencursor is 0,
    then the genmask (expressed as a bitmask) can be interpreted
    as:
    
    00 active in the present, will be active in the next generation.
    01 inactive in the present, will be active in the next generation.
    10 active in the present, will be deleted in the next generation.
     ^
     gencursor
    
    Once you invoke the transition to the next generation, the global
    gencursor is updated:
    
    00 active in the present, will be active in the next generation.
    01 active in the present, needs to zero its future, it becomes 00.
    10 inactive in the present, delete now.
    ^
    gencursor
    
    If a dump is in progress and nf_tables enters a new generation,
    the dump will stop and return -EBUSY to let userspace know that
    it has to retry again. In order to invalidate dumps, a global
    genctr counter is increased everytime nf_tables enters a new
    generation.
    
    This new operation can be used from the user-space utility
    that controls the firewall, eg.
    
    nft -f restore
    
    The rule updates contained in `file' will be applied atomically.
    
    cat file
    -----
    add filter INPUT ip saddr 1.1.1.1 counter accept #1
    del filter INPUT ip daddr 2.2.2.2 counter drop   #2
    -EOF-
    
    Note that the rule 1 will be inactive until the transition to the
    next generation, the rule 2 will be evicted in the next generation.
    
    There is a penalty during the rule update due to the branch
    misprediction in the packet matching framework. But that should be
    quickly resolved once the iteration over the commit list that
    contain rules that require updates is finished.
    
    Event notification happens once the rule-set update has been
    committed. So we skip notifications is case the rule-set update
    is aborted, which can happen in case that the rule-set is tested
    to apply correctly.
    
    This patch squashed the following patches from Pablo:
    
    * nf_tables: atomic rule updates and dumps
    * nf_tables: get rid of per rule list_head for commits
    * nf_tables: use per netns commit list
    * nfnetlink: add batch support and use it from nf_tables
    * nf_tables: all rule updates are transactional
    * nf_tables: attach replacement rule after stale one
    * nf_tables: do not allow deletion/replacement of stale rules
    * nf_tables: remove unused NFTA_RULE_FLAGS
    Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
    0628b123
nf_tables_core.c 5.01 KB