3. A Linguagem P4: Visão Geral
3.1. O Paradigma P4: Programabilidade Top-Down do Plano de Dados
A linguagem P4 (acrônimo para Programming Protocol-independent Packet Processors) é uma linguagem de domínio específico, de alto nível, utilizada para determinar exatamente como os pacotes de dados serão processados pelo plano de dados de dispositivos de encaminhamento programáveis. Ela é a materialização do design top-down e do modelo arquitetural PISA, introduzidos na seção anterior.
É fundamental notar que o P4 foi designado para especificar exclusivamente a funcionalidade do plano de dados [2]. Embora o P4 defina parcialmente a interface pela qual os planos de controle e de dados se comunicam — ao declarar quais tabelas e objetos são expostos —, ele não pode ser usado para descrever a lógica ou as funcionalidades do plano de controle.
A Figura 1 ilustra a diferença fundamental entre um switch tradicional (função fixa) e um switch P4 (programável). Em um switch tradicional, o fabricante define o pipeline de processamento e, consequentemente, as funcionalidades do plano de dados. O plano de controle interage com o plano de dados através de uma API fixa para gerenciar tabelas (ex: roteamento, encaminhamento), configurar parâmetros e processar pacotes de controle.
Um switch programável com P4 se diferencia desse modelo de duas formas cruciais:
- As funcionalidades do plano de dados não são pré-definidas pelo fabricante. Elas são explicitamente definidas pelo programa P4. O switch não possui conhecimento prévio de nenhum protocolo de rede específico até ser programado.
- Consequentemente, a interface entre o plano de controle e o plano de dados não é mais fixa. Os objetos pelos quais eles se comunicam (tabelas, parâmetros, contadores) são eles mesmos definidos pelo programa P4. O compilador P4 é responsável por gerar a API que o plano de controle utilizará para se comunicar com o plano de dados que o próprio programa definiu.
Dessa forma, o ambiente P4 é inerentemente independente de protocolos, possibilitando que os programadores expressem qualquer tipo de protocolo ou comportamento de processamento de pacotes que desejem para o plano de dados.
3.2. As Abstrações da Linguagem P4
Diferente das funcionalidades rígidas dos switches tradicionais, a linguagem P4 provê um conjunto de abstrações programáveis de alto nível para definir o comportamento do plano de dados. As principais são:
- Definições de Cabeçalho (Header types): Descrevem o formato (o conjunto de campos e seus tamanhos) de cada cabeçalho dentro de um pacote.
- Parsers (Analisadores): Descrevem as sequências permitidas de cabeçalhos em pacotes recebidos, como identificar essas sequências, e quais cabeçalhos e campos extrair dos pacotes.
- Tabelas (Tables): Associam chaves definidas pelo usuário a ações. As tabelas P4 generalizam as tabelas de switches tradicionais; elas podem ser usadas para implementar tabelas de roteamento, tabelas de consulta de fluxo, listas de controle de acesso (ACLs) e outros tipos de tabelas definidas pelo usuário, incluindo decisões complexas de múltiplas variáveis.
- Ações (Actions): São fragmentos de código que descrevem como os campos de cabeçalho do pacote e os metadados são manipulados. Ações podem incluir dados, que são fornecidos pelo plano de controle em tempo de execução.
- Unidades Match-Action (Match-action units): Realizam a seguinte sequência de operações: 1) Constroem chaves de busca (lookup keys) a partir de campos do pacote ou metadados computados; 2) Realizam a busca na tabela usando a chave construída, escolhendo uma ação (e seus dados associados) para executar; e 3) Finalmente, executam a ação selecionada.
- Fluxo de Controle (Control flow): Expressa um programa imperativo que descreve o processamento de pacotes em um dispositivo target, incluindo a sequência (dependente de dados) de invocações de unidades match-action. O Deparsing (remontagem do pacote) também pode ser executado usando um fluxo de controle.
- Objetos Externos (Extern objects): São construtos específicos da arquitetura que podem ser manipulados por programas P4 através de APIs bem definidas, mas cujo comportamento interno é fixo (ex: unidades de checksum) e, portanto, não programável usando P4.
- Metadados Definidos pelo Usuário (User-defined metadata): Estruturas de dados definidas pelo usuário associadas a cada pacote.
- Metadados Intrínsecos (Intrinsic metadata): Metadados fornecidos pela arquitetura e associados a cada pacote (ex: a porta de entrada onde o pacote foi recebido).
3.3. Compilação, Alvos e Garantias de Desempenho
O fluxo de trabalho do P4 (conforme ilustrado na Figura 2) envolve uma colaboração entre fabricantes de hardware e programadores de rede. Os fabricantes de dispositivos target (o hardware ou software de destino) fornecem a implementação da plataforma, uma definição de arquitetura e um compilador P4 específico para esse target. O programador P4, por sua vez, escreve um programa para essa arquitetura específica, que define o conjunto de componentes programáveis em P4 no target, bem como suas interfaces externas de plano de dados.
A compilação de um programa P4 produz dois artefatos principais:
- Uma configuração do plano de dados, que implementa a lógica de encaminhamento descrita no programa de entrada.
- Uma API do plano de controle, que permite gerenciar o estado dos objetos do plano de dados (ex: popular as tabelas) a partir do plano de controle.
O P4 é uma linguagem de domínio específico projetada para ser implementável em uma vasta gama de targets, incluindo NICs (Placas de Interface de Rede) programáveis, FPGAs, switches de software e ASICs de hardware. Como tal, a linguagem é restrita a construtos que podem ser implementados eficientemente em todas essas plataformas.
Assumindo um custo fixo para operações de busca em tabelas e interações com objetos externos (externs), todos os programas P4 (ou seja, parsers e controls) executam um número constante de operações para cada byte de um pacote de entrada recebido e analisado. Embora os parsers possam conter laços, o próprio tamanho finito do pacote fornece um limite para a execução total do parser. Em outras palavras, sob essas premissas, a complexidade computacional de um programa P4 é linear em relação ao tamanho total de todos os cabeçalhos e nunca depende do tamanho do estado acumulado durante o processamento (ex: o número de fluxos ou o número total de pacotes processados). Essas garantias são necessárias para permitir o processamento de pacotes em alta velocidade em diversas plataformas.
A conformidade P4 (P4 conformance) de um target é definida da seguinte forma: se um target T suporta apenas um subconjunto da linguagem P4 (denominado P4T), os programas escritos em P4T executados no target devem fornecer o comportamento exato descrito na especificação. Targets conformes também podem fornecer extensões de linguagem e elementos extern arbitrários.
3.4. Vantagens do Ambiente P4
Comparado aos sistemas de processamento de pacotes tradicionais (ex: baseados em microcódigo sobre hardware customizado), o P4 oferece vantagens significativas [2]:
- Flexibilidade: O P4 permite que muitas políticas de encaminhamento de pacotes sejam expressas como programas, em contraste com switches tradicionais, que expõem mecanismos de encaminhamento de função-fixa.
- Expressividade: O P4 pode expressar algoritmos sofisticados de processamento de pacotes, independentes de hardware, usando apenas operações de propósito geral e buscas em tabelas. Tais programas são portáteis entre targets de hardware que implementam a mesma arquitetura.
- Mapeamento e Gerenciamento de Recursos: Programas P4 descrevem recursos de armazenamento de forma abstrata (ex: "endereço IPv4 de origem"). O compilador mapeia esses campos para os recursos de hardware disponíveis e gerencia detalhes de baixo nível, como alocação e agendamento.
- Engenharia de Software: O P4 oferece benefícios importantes da engenharia de software, como checagem de tipos, encapsulamento (ocultação de informações) e reuso de código.
- Bibliotecas de Componentes: Bibliotecas fornecidas por fabricantes podem ser usadas para encapsular funções específicas de hardware em construtos P4 portáteis de alto nível.
- Desacoplamento da Evolução de Hardware e Software: Os fabricantes de targets podem usar arquiteturas abstratas para desacoplar ainda mais a evolução dos detalhes arquiteturais de baixo nível do processamento de alto nível.
- Depuração: Os fabricantes podem fornecer modelos de software de uma arquitetura para auxiliar no desenvolvimento e depuração de programas P4.