P4 (langage)

P4 est un langage de programmation permettant d'exprimer la logique de traitement des paquets au sein d'un élément de communication de réseau informatique tel qu'un commutateur, une carte réseau, un routeur ou une appliance afin d'y exécuter des actions.
Le langage de programmation P4 a été proposé par certaines universités aux entreprises en 2014 et est décrit à l'origine dans un document du SIGCOMM CCR intitulé "Programming Protocol-Independent Packet Processors". La dénomination commune se raccourcit à l'acronyme "P4".

Origine 

Le premier atelier sur le langage P4 a eu lieu le  à l'Université de Stanford, il était présidé par Nick McKeown de cette même université et Jennifer Rexford, de l'Université de Princeton.
Le consortium P4.org a publié la spécification finale de la nouvelle version du langage dénommée P416, en , remplaçant la première version du langage, appelée P414.

Principe 

Considéré comme une évolution du Software Defined Networking (SDN), P4 permet de programmer la façon dont le flux est traité par l’acheminement de paquets sur du matériel de transmission de paquets réseaux tels que des routeurs, des commutateurs ou des pare-feux, qu'ils soient matériels ou logiciels. Comme son nom « Programmation de processeurs indépendants des protocoles » l’indique, le langage ne tient pas compte du format d’un paquet. En effet, les développeurs déclarent le traitement d’un paquet dans un programme écrit en langage P4, et le compilateur le met par la suite au format souhaité selon le matériel cible. La programmation en langage P4 est notamment utilisée pour mettre en œuvre les fonctions de transfert de niveau 3 et les fonctions INT. La technologie In-Band Network Telemetry permet à de commutateurs de mesurer de fournir des informations détaillées sur la charge du réseau et de les utiliser pour fournir des mécanismes de contrôle de la congestion et donc mieux gérer la stabilité du réseau à très haut débit.
Il existe deux versions de ce langage : P414 et P416. P416 apporte des changements importants et n'est pas rétrocompatible avec P414. Ainsi, de nombreuses fonctionnalités ont été supprimées du langage de base P414 et sont déjà ou sont destinées à être implémentées dans des bibliothèques externes.

Fonctionnement 

P4 vise la programmation complète du traitement des données sur un équipement réseau. Ce langage est capable de réellement programmer le comportement d’un équipement réseau. Un algorithme de traitement d’un paquet IPv4 pourra être simplement construit. Le format même des paquets est simplement défini dans le programme. L’exemple ci-dessous montre comment analyser (parser) une trame Ethernet.

state parse_ethernet {
    packet.extract(headers.ethernet) {
    transition select(headers.ethernet.ethertype) {
        0x8100: parse_vlan;
        0x9100: parse_vlan;
        0x0800: parse_ipv4;
        0x86dd: parse_ipv6;
        
        default: reject;
    }
}

Une fois l'analyse des paquets entrants effectuée, les en-têtes sont extraites et envoyées dans des tables de type "Match+Actions".
Ces tables contiennent les informations des paquets correspondants ainsi que les protocoles pris en compte pour leur acheminement.
Il ne reste plus qu'à spécifier les actions à exécuter pour les paquets correspondants.
Une fois le programme créé, il suffit de le compiler pour qu’il puisse fonctionner sur le matériel désiré.

Syntaxe 

Un programme de type P4 contient les attributs des composants clés suivants :
 Headers (en-têtes)  Une définition d'en-tête qui décrit la séquence et la structure d'une série de champs. Elle comprend la spécification des largeurs de champs et des contraintes sur les valeurs des champs ;
Parsers  Une définition d'analyseur spécifie comment identifier les en-têtes et les séquences d'en-têtes valides dans les paquets;
 Tables  Les tables match+action sont le mécanisme permettant d'effectuer le traitement des paquets. Le programme P4 définit les champs sur lesquels une table peut correspondre et les actions qu'elle peut exécuter ;
 Actions  P4 supporte la construction d'actions complexes à partir de primitives plus simples, indépendantes du protocole. Ces actions complexes sont disponibles dans les tables match+action ;
 Programmes de contrôle  Le programme de contrôle détermine l'ordre des tables match+action qui sont appliquées à un paquet. Un programme impératif simple décrit le flux de contrôle entre les tables match+action.

#include <core.p4>
#include <v1model.p4>
struct metadata {}
struct headers {}

parser  MyParser(packet_in packet,
    out headers hdr,
    inout metadata meta,
    inout standard_metadata_t standard_metadata) {
    
      state start { transition accept; }
 }
 control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply { } }
 
 control MyIngress (inout headers hdr,
    inout metadata meta,
    inout standard_metadata_t standard_metadata) {
apply {
        if (standard_metadata.ingress_port ==1) {
            standard_metadata.egress_spec =2;
            } else if (standard_metadata.ingress_port ==2) {
                standard_metadata.egress_spec =1;
                }
             }
     }
     
     control MyIngress(inout headers hdr,
        inout metadata meta,
        inout standard_metadata_t standard_metadata) {
        apply { }
        }
control MyComputeChecksum (inout headers hdr, inout metadata meta) {
    apply {}
    }
    control MyComputeChecksum(inout headers hdr, inout metadata meta) {
        apply { }
    control MyDeparser(packet_out packet, in headers hdr){
        apply { }
        }
        
        V1Switch(
            MyParser(),
            MyVerifyChecksum(),
            MyIngress(),
            MyEgress(),
            MyComputeChecksum(),
            MyDeparser(),
        ) main;

Compilateur 

Afin d'être implémenté sur le matériel cible, qui peut être de type matériel ou logiciel, le programme écrit en P4 doit être compilé, c'est-à-dire transformé par le compilateur, en un code objet. Il existe deux compilateurs, un premier utilisé à l'origine pour P414, écrit en Python, et un autre, depuis la version P416, nommé P4C. Ce dernier, fournit par le groupe de développeurs P4 "P4 Language Consortium", est compatible avec les deux versions du langage et est implémenté en C++11, sous licence open-source Apache 2. Le compilateur dispose de deux analyseurs, pour chacun des deux langages. L'analyseur de programme P414 convertit le programme en P416.
P4C effectue un traitement en trois parties :
 Front-end : Indépendamment du matériel cible, il est chargé d'effectuer divers contrôles du programme tels que la syntaxe, la sémantique, afin que le code soit conforme aux spécifications du langage, puis il simplifie et optimise le code au besoin ;
 Mid-end : Il effectue les transformations du code afin qu'il corresponde en partie à la cible, mais n'ajoute pas d'affectations de ressources spécifiques ;
 Backend : Il est chargé de l'allocation des ressources, l'ordonnancement et de la transformation du code en un langage conforme au matériel.

Le compilateur supporte plusieurs types de backend :
 p4c-bmv2  génère du code en format JSON afin que le programme soit compatible pour être implémenté sur des commutateurs logiciels ;
 p4c-ebpf  génère du code au format C qui peut ensuite être compilé en eBPF ;
 p4c-graphs  produit des représentations visuelles d'un programme P4 (des graphiques de flux de contrôle de haut niveau) ;
 p4test  teste le front-end des programmes en P416.

Objectifs 

Le langage P4 a été conçu pour répondre à trois objectifs : 

 Il offre une possibilité de mise à niveau ou de modification sur site : Une fois déployé sur le matériel, le programme peut être modifié dans le cas où le traitement des paquets doit évoluer.
 De plus le langage: P4 n'est lié à aucun protocole réseau et aucun traitement de packet spécifique, il n'a donc pas de notion prédéterminée du format d'un paquet. Cela permet de définir de nouveaux protocoles si nécessaire et élimine les contraintes sur la façon dont les paquets individuels peuvent être corrélés.
 La cible ne bénéficie d'aucune obligation sur le plan matériel: Lors de l'écriture du programme P4, les développeurs définissent les fonctionnalités du traitement des paquets sans se préoccuper des spécificités du matériel cible sur lequel le programme doit être implémenté.

Expérimentations 

P4 est un langage qui est peu utilisé mais qui fait tout de même l'objet d'expérimentations ayant divers objectifs.

Détection d'attaques 

L'implémentation de P4 sur un commutateur de type logiciel montre que le langage peut être utilisé pour de la détection d'attaques, comme les attaques SYN. P4 permet une flexibilité de la mémoire allouée à un dispositif, à la différence d'un matériel réseau standard qui peut avoir une mémoire d'une taille fixe. Sur un matériel implémenté avec P4, il est possible de modifier la taille de la mémoire au besoin, et donc d'enregistrer le trafic réseau. Ainsi, P4 peut aider à la sécurisation de réseau via une connaissance complète du trafic de données au sein du réseau. Cependant, selon les circonstances de l'attaque, l'expérimentation montre que la détection d'attaque est plus difficile.

Surveillance du réseau 

P4 permet de surveiller et visualiser les informations sur l'état du réseau à moindre coût. En effet, à la différence de SDN qui apporte des coûts élevés pour la surveillance du réseau, P4 récupère des informations sur l'état du réseau (identification du commutateur, perte de paquets et occupation de la file d'attente, etc.) sans ajouter de paquets de détection supplémentaires. Une fois ces informations récoltées, le trafic est contrôlé en temps réel en fonction de l'état du réseau, ce qui permet notamment d'éliminer le phénomène de congestion.

Pare-feu logiciel 

Le langage peut être utilisé afin de mettre en place un pare-feu logiciel à moindre coût. Cependant dans une expérimentation, il est démontré que l'efficacité du pare-feu dépend du nombre de paquets qui transitent. Ainsi, s'il peut être plus rapide que certains pare-feux virtualisés quand il y a moins de 1000 paquets, dès que ce seuil est dépassé son efficacité baisse.

Avantages 

Dans le cadre des expérimentations d’implémentation qui ont eu lieu, il a été démontré que le langage P4 dispose de plusieurs avantages. 
Ainsi, il améliore la sécurité du réseau grâce à la mise en place des en-têtes et des règles de traitement des flux qui permettent d’éviter la congestion.
De plus, le langage apporte une certaine flexibilité au niveau des matériels réseaux. En effet, il permet de programmer le traitement des paquets en utilisant uniquement des requêtes et des consultations de tables, indépendamment du matériel sur lequel il est implémenté, contrairement aux matériels réseaux traditionnels qui disposent d’un langage propriétaire. 
Le langage offre également la possibilité d’analyser des trames et, à l’aide du compilateur, gèrent les détails de bas niveau tels que l’allocation de ressources, car il permet de décomposer les ressources de stockage, et l’ordonnancement. 
Avec la version P416 du langage, les créateurs du langage ont mis à disposition des librairies, ce qui est un avantage pour le développement de certaines fonctions spécifiques au matériel.

Inconvénients 

En 2020, le langage P4 est supporté par très peu de matériel ce qui limite son utilisation. Ceci peut être expliqué par le fait que le langage P4 est en développement actif, les fournisseurs de matériels attendent que le langage se stabilise et se démocratise avant de proposer du matériel adapté. P4 laisse aussi beaucoup de détails non spécifiés.
P4 augmente également les risques d'encourir des bugs d'exécution après le déploiement des programmes P4, ou bien des erreurs d'implémentation de protocoles par exemple. L'absence de runtime, logiciel responsable de l'exécution des programmes informatiques, rendent difficile le dépannage de ces bugs.
De plus, selon l'architecture du réseau, il est parfois difficile de traduire les spécificités en P4. Le langage P4 ne définit pas l'interface entre le plan de données et le plan de contrôle, il s'agit d'une spécificité liée au matériel cible.
P4 ne permet d’exécuter des actions qu'à l'intérieur des trames réseaux ou lorsqu'une correspondance table+action a été trouvée les tables de correspondance de P4 ne peuvent pas effectuer de correspondance sur des champs de longueur variable. Ainsi, la comparaison entre plusieurs variables peut être compliquée, notamment lorsque l'on souhaite trouver la plus petite valeur, car P4 ne peut comparer que des valeurs entre elles dans les objets de contrôle et peut les modifier uniquement s'il y a une correspondance dans une table. De plus les tables de correspondance de P4 ne peuvent pas effectuer de correspondance sur des champs de longueur variable.

Références

Bibliographie

Liens externes

Articles connexes 
 Software-defined networking
 OpenFlow
 Langage dédié

Langage de programmation
Réseau informatique
Activités en informatique