Skip to content
Snippets Groups Projects
Commit 5c32114d authored by Neal Cardwell's avatar Neal Cardwell
Browse files

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
parent 73371412
No related branches found
No related tags found
No related merge requests found
...@@ -20,6 +20,7 @@ packetdrill-lib := \ ...@@ -20,6 +20,7 @@ packetdrill-lib := \
symbols_openbsd.o \ symbols_openbsd.o \
symbols_netbsd.o \ symbols_netbsd.o \
gre_packet.o icmp_packet.o ip_packet.o tcp_packet.o udp_packet.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 \ run.o run_command.o run_packet.o run_system_call.o \
script.o socket.o system.o \ script.o socket.o system.o \
tcp_options.o tcp_options_iterator.o tcp_options_to_string.o \ tcp_options.o tcp_options_iterator.o tcp_options_to_string.o \
......
...@@ -176,6 +176,10 @@ ipv6 return IPV6; ...@@ -176,6 +176,10 @@ ipv6 return IPV6;
icmp return ICMP; icmp return ICMP;
udp return UDP; udp return UDP;
gre return GRE; gre return GRE;
mpls return MPLS;
label return LABEL;
tc return TC;
ttl return TTL;
inet_addr return INET_ADDR; inet_addr return INET_ADDR;
ack return ACK; ack return ACK;
eol return EOL; eol return EOL;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ethernet.h" #include "ethernet.h"
#include "gre_packet.h" #include "gre_packet.h"
#include "ip_packet.h" #include "ip_packet.h"
#include "mpls_packet.h"
/* Info for all types of header we support. */ /* Info for all types of header we support. */
...@@ -39,6 +40,7 @@ struct header_type_info header_types[HEADER_NUM_TYPES] = { ...@@ -39,6 +40,7 @@ struct header_type_info header_types[HEADER_NUM_TYPES] = {
{ "IPV4", IPPROTO_IPIP, ETHERTYPE_IP, ipv4_header_finish }, { "IPV4", IPPROTO_IPIP, ETHERTYPE_IP, ipv4_header_finish },
{ "IPV6", IPPROTO_IPV6, ETHERTYPE_IPV6, ipv6_header_finish }, { "IPV6", IPPROTO_IPV6, ETHERTYPE_IPV6, ipv6_header_finish },
{ "GRE", IPPROTO_GRE, 0, gre_header_finish }, { "GRE", IPPROTO_GRE, 0, gre_header_finish },
{ "MPLS", 0, ETHERTYPE_MPLS_UC, mpls_header_finish },
{ "TCP", IPPROTO_TCP, 0, NULL }, { "TCP", IPPROTO_TCP, 0, NULL },
{ "UDP", IPPROTO_UDP, 0, NULL }, { "UDP", IPPROTO_UDP, 0, NULL },
{ "ICMPV4", IPPROTO_ICMP, 0, NULL }, { "ICMPV4", IPPROTO_ICMP, 0, NULL },
......
...@@ -95,6 +95,8 @@ ...@@ -95,6 +95,8 @@
#include "ip_packet.h" #include "ip_packet.h"
#include "icmp_packet.h" #include "icmp_packet.h"
#include "logging.h" #include "logging.h"
#include "mpls.h"
#include "mpls_packet.h"
#include "tcp_packet.h" #include "tcp_packet.h"
#include "udp_packet.h" #include "udp_packet.h"
#include "parse.h" #include "parse.h"
...@@ -441,6 +443,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -441,6 +443,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
s64 time_usecs; s64 time_usecs;
enum direction_t direction; enum direction_t direction;
enum ip_ecn_t ip_ecn; enum ip_ecn_t ip_ecn;
struct mpls_stack *mpls_stack;
struct mpls mpls_stack_entry;
u16 port; u16 port;
s32 window; s32 window;
u32 sequence_number; u32 sequence_number;
...@@ -474,6 +478,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -474,6 +478,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> FAST_OPEN %token <reserved> FAST_OPEN
%token <reserved> ECT0 ECT1 CE ECT01 NO_ECN %token <reserved> ECT0 ECT1 CE ECT01 NO_ECN
%token <reserved> IPV4 IPV6 ICMP UDP GRE MTU %token <reserved> IPV4 IPV6 ICMP UDP GRE MTU
%token <reserved> MPLS LABEL TC TTL
%token <reserved> OPTION %token <reserved> OPTION
%token <floating> FLOAT %token <floating> FLOAT
%token <integer> INTEGER HEX_INTEGER %token <integer> INTEGER HEX_INTEGER
...@@ -489,6 +494,9 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -489,6 +494,9 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <syscall> syscall_spec %type <syscall> syscall_spec
%type <command> command_spec %type <command> command_spec
%type <code> code_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 <integer> opt_icmp_mtu
%type <string> icmp_type opt_icmp_code flags %type <string> icmp_type opt_icmp_code flags
%type <string> opt_tcp_fast_open_cookie tcp_fast_open_cookie %type <string> opt_tcp_fast_open_cookie tcp_fast_open_cookie
...@@ -771,6 +779,54 @@ packet_prefix ...@@ -771,6 +779,54 @@ packet_prefix
semantic_error(error); semantic_error(error);
$$ = packet; $$ = 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 icmp_type
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment