diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index 89e3e19abd424bceda6e21b2a396237f7614d6f0..0ec741f5548a41934f055a55e0b80e5430447963 100644 --- a/gtests/net/packetdrill/Makefile.common +++ b/gtests/net/packetdrill/Makefile.common @@ -20,6 +20,7 @@ packetdrill-lib := \ symbols_openbsd.o \ symbols_netbsd.o \ gre_packet.o icmp_packet.o ip_packet.o tcp_packet.o udp_packet.o \ + mpls_packet.o \ run.o run_command.o run_packet.o run_system_call.o \ script.o socket.o system.o \ tcp_options.o tcp_options_iterator.o tcp_options_to_string.o \ diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index d73e6703325908274a235349edfdadaf4a51e8be..c52669d7d648df5783c286277788c230d0e175e7 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -176,6 +176,10 @@ ipv6 return IPV6; icmp return ICMP; udp return UDP; gre return GRE; +mpls return MPLS; +label return LABEL; +tc return TC; +ttl return TTL; inet_addr return INET_ADDR; ack return ACK; eol return EOL; diff --git a/gtests/net/packetdrill/packet.c b/gtests/net/packetdrill/packet.c index 310738a5d14bc551c8b998b170ba2e1e638ddc24..c52bb14392420bb92cce00bf91595676ab23fe6d 100644 --- a/gtests/net/packetdrill/packet.c +++ b/gtests/net/packetdrill/packet.c @@ -31,6 +31,7 @@ #include "ethernet.h" #include "gre_packet.h" #include "ip_packet.h" +#include "mpls_packet.h" /* Info for all types of header we support. */ @@ -39,6 +40,7 @@ struct header_type_info header_types[HEADER_NUM_TYPES] = { { "IPV4", IPPROTO_IPIP, ETHERTYPE_IP, ipv4_header_finish }, { "IPV6", IPPROTO_IPV6, ETHERTYPE_IPV6, ipv6_header_finish }, { "GRE", IPPROTO_GRE, 0, gre_header_finish }, + { "MPLS", 0, ETHERTYPE_MPLS_UC, mpls_header_finish }, { "TCP", IPPROTO_TCP, 0, NULL }, { "UDP", IPPROTO_UDP, 0, NULL }, { "ICMPV4", IPPROTO_ICMP, 0, NULL }, diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 07aa5b378eb118062bf3399e965b4bf219097168..6203a0ba853f89a11493c2324a884c439a33315f 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -95,6 +95,8 @@ #include "ip_packet.h" #include "icmp_packet.h" #include "logging.h" +#include "mpls.h" +#include "mpls_packet.h" #include "tcp_packet.h" #include "udp_packet.h" #include "parse.h" @@ -441,6 +443,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, s64 time_usecs; enum direction_t direction; enum ip_ecn_t ip_ecn; + struct mpls_stack *mpls_stack; + struct mpls mpls_stack_entry; u16 port; s32 window; u32 sequence_number; @@ -474,6 +478,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> FAST_OPEN %token <reserved> ECT0 ECT1 CE ECT01 NO_ECN %token <reserved> IPV4 IPV6 ICMP UDP GRE MTU +%token <reserved> MPLS LABEL TC TTL %token <reserved> OPTION %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER @@ -489,6 +494,9 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <syscall> syscall_spec %type <command> command_spec %type <code> code_spec +%type <mpls_stack> mpls_stack +%type <mpls_stack_entry> mpls_stack_entry +%type <integer> opt_mpls_stack_bottom %type <integer> opt_icmp_mtu %type <string> icmp_type opt_icmp_code flags %type <string> opt_tcp_fast_open_cookie tcp_fast_open_cookie @@ -771,6 +779,54 @@ packet_prefix semantic_error(error); $$ = packet; } +| packet_prefix MPLS mpls_stack ':' { + char *error = NULL; + struct packet *packet = $1; + struct mpls_stack *mpls_stack = $3; + + if (mpls_header_append(packet, mpls_stack, &error)) + semantic_error(error); + free(mpls_stack); + $$ = packet; +} +; + +mpls_stack +: { + $$ = mpls_stack_new(); +} +| mpls_stack mpls_stack_entry { + if (mpls_stack_append($1, $2)) + semantic_error("too many MPLS labels"); + $$ = $1; +} +; + +mpls_stack_entry +: +'(' LABEL INTEGER ',' TC INTEGER ',' opt_mpls_stack_bottom TTL INTEGER ')' { + char *error = NULL; + s64 label = $3; + s64 traffic_class = $6; + bool is_stack_bottom = $8; + s64 ttl = $10; + struct mpls mpls; + + if (new_mpls_stack_entry(label, traffic_class, is_stack_bottom, ttl, + &mpls, &error)) + semantic_error(error); + $$ = mpls; +} +; + +opt_mpls_stack_bottom +: { $$ = 0; } +| '[' WORD ']' ',' { + if (strcmp($2, "S") != 0) + semantic_error("expected [S] for MPLS label stack bottom"); + free($2); + $$ = 1; +} ; icmp_type