From 5c32114da45e7ecc848ef228d1dc1735171798f3 Mon Sep 17 00:00:00 2001 From: Neal Cardwell <ncardwell@google.com> Date: Thu, 28 Nov 2013 13:14:40 -0500 Subject: [PATCH] net-test: packetdrill MPLS support: parse MPLS label stacks in scripts Code to parse script packets using an encapsulation layer that is an MPLS label stack. The syntax looks like: mpls (label 123, tc 1, [S], ttl 255) (label 456, tc 1, [S], ttl 255) This is borrowed from the syntax from tcpdump, which is: MPLS (label 123, exp 1, [S], ttl 255) (label 456, exp 1, [S], ttl 255) We use "tc" because RFC 5462 renamed the EXP ("experimental") field to the TC ("traffic class") field. We use lower-case "mpls" instead of "MPLS" for consistency with other packetdrill protocols, and for ease of typing. Change-Id: I2e797aead8605da9fe3f0461594cf7273d4ef0ec --- gtests/net/packetdrill/Makefile.common | 1 + gtests/net/packetdrill/lexer.l | 4 ++ gtests/net/packetdrill/packet.c | 2 + gtests/net/packetdrill/parser.y | 56 ++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index 89e3e19a..0ec741f5 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 d73e6703..c52669d7 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 310738a5..c52bb143 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 07aa5b37..6203a0ba 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 -- GitLab