IPSet protocol version 7

La version 7 d'ipset est sortie récemment (mais pas encore dans la branche principale du noyau, elle devrait arriver en 4.20 ou 5.0). Et Wifirst y est un peu pour quelques chose.

Nous utilisons massivement les ipset sur nos équipements, notamment car ils permettent de configurer un pare-feu basé sur iptables entièrement vers netlink (et aussi car il permet de rendre dynamique un pare-feu iptables classique, sans ajouter/modifier de règles). C'est donc assez naturellement que nous avons également commencé à les utiliser pour configurer une partie de notre QoS (commande tc). Nous avons ainsi ajouté le support des ipset par tc-ematch dans pyroute2.

Il restait cependant un problème pour nous qui n'utilisons que du netlink. Pour convertir le nom d'un ipset en un index utilisable par le noyau pour ajouter la règle, le module tc-ematch fait ceci :

static int
get_set_byname(const char *setname, struct xt_set_info *info)
{
    struct ip_set_req_get_set req;
    int res;

    req.op = IP_SET_OP_GET_BYNAME;
    strlcpy(req.set.name, setname, IPSET_MAXNAMELEN);
    res = do_getsockopt(&req);
    if (res != 0)
        return -1;
    if (req.set.index == IPSET_INVALID_ID)
        return -1;
    info->index = req.set.index;
    return 0;
}   

Ils utilisent donc getsockopt plutôt que netlink. C'est un peu dommage pour un module qui autrement fonctionne entièrement en netlink. Nous avons donc proposé un patch permettant d'exporter ces index, en ajoutant un flag pour contrôler son affichage afin de ne pas casser les outils existants en espace utilisateur. Pour les curieux, cette interface via getsockopt a quatre options définies dans ip_set.h.

Ce patch a été refusé, le mainteneur ne souhaitant pas introduire ce type de changement sans augmenter le numéro de version du protocol. IPSet version sept était donc né ! Quelques mois après notre demande initiale, le mainteneur a proposé sa version, ajoutant deux commandes ip_set_byname et ip_set_byindex.

Peu après sa mise à disposition, nous avons pu tester et travailler sur la gestion par pyroute2 de ces commandes avec pour but de supprimer nos patchs maintenus en interne.