2013-02-08 6 views
10

Se scrivo alcuni moduli del kernel e in tutti loro si specifica che dovrebbero essere il primo (o ultimo) hook netfilter chiamato, in quale ordine verranno effettivamente chiamati?In che ordine vanno gli hook Netfilter, se tutti specificano NF_IP_PRI_LAST o NF_IP_PRI_FIRST?

netfilter_ops_out.hook  = hook_func_out; 
netfilter_ops_out.pf  = PF_INET; 
netfilter_ops_out.hooknum = NF_IP_LOCAL_OUT; 
netfilter_ops_out.priority = NF_IP_PRI_FIRST; 

ret = nf_register_hook(&netfilter_ops_out); 
if (0 > ret) { 
    printk("Error registering netfilter hook: %d\n", ret); 
    return ret; 
}  

netfilter_ops_in.hook  = hook_func_in; 
netfilter_ops_in.pf  = PF_INET; 
netfilter_ops_in.hooknum = NF_IP_LOCAL_IN; 
netfilter_ops_in.priority = NF_IP_PRI_LAST; 

ret = nf_register_hook(&netfilter_ops_in); 
if (0 > ret) { 
    printk("Error registering netfilter hook: %d\n", ret); 
    return ret; 
}  

Sperimentalmente, ho fatto due moduli, insmod li Ed nei due ordini diversi - ma hanno dato lo stesso risultato, il che implica c'è qualche sottordine che non è solo 'primo arrivato, primo servito'. (Non è nemmeno alfabetico ...)

+1

'nf_register_hook()' viene chiamato nella funzione 'module_init'. Un kernel più vecchio: 2.6.18. Un modulo modifica un pacchetto, l'altro lo registra, entrambi usano lo stesso codice di registrazione (sopra). Ma indipendentemente dall'ordine in cui carico i moduli, vedo sempre il pacchetto come modificato nel logger. Ho pensato in qualche modo che dovrei essere in grado di far funzionare il logger prima del modificatore ... ma senza dadi. –

+1

Mi dispiace, la mia spiegazione è appena finita per confondere ulteriormente il problema. Ho quattro ganci, 2 di ogni LOCAL_IN e LOCAL_OUT. I due moduli si agganciano entrambi in entrata e in uscita, ma mi sto concentrando solo sull'ingresso. –

risposta

3

Dai codici nf_register_hook(), possiamo sapere che se due hook appartengono allo stesso nf_hooks [reg-> pf] [reg-> hooknum], la sequenza di esecuzione dell'hook è deciso per priorità. Se la priorità è uguale, la sequenza è "primo arrivato, primo servito". Vedere seguenti codici:

int nf_register_hook(struct nf_hook_ops *reg) 
{ 
    struct nf_hook_ops *elem; 
    int err; 

    err = mutex_lock_interruptible(&nf_hook_mutex); 
    if (err < 0) 
     return err; 
    list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) { 
     if (reg->priority < elem->priority) 
      break; 
    } 
    list_add_rcu(&reg->list, elem->list.prev); 
    mutex_unlock(&nf_hook_mutex); 
#if defined(CONFIG_JUMP_LABEL) 
    static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); 
#endif 
    return 0; 
}