IPv4 DSCP match: Add IPv4 DSCP field match feature

Note: Now regression test sets *and* tests the IPv4 DSCP bits.  Test
script was renamed from test_set_nw_tos to test_set_n_match_nw_tos.
This commit is contained in:
Mikio Hara
2009-10-20 14:15:15 -07:00
committed by Glen Gibb
parent a3a79e21e8
commit 1c9b2f7b2d
13 changed files with 103 additions and 48 deletions
+2 -1
View File
@@ -1431,9 +1431,10 @@ static int flow_stats_dump_callback(struct sw_flow *flow, void *private)
memcpy(ofs->match.dl_dst, flow->key.dl_dst, ETH_ALEN);
ofs->match.dl_vlan = flow->key.dl_vlan;
ofs->match.dl_type = flow->key.dl_type;
ofs->match.nw_tos = flow->key.nw_tos;
ofs->match.nw_proto = flow->key.nw_proto;
ofs->match.nw_src = flow->key.nw_src;
ofs->match.nw_dst = flow->key.nw_dst;
ofs->match.nw_proto = flow->key.nw_proto;
ofs->match.dl_vlan_pcp = flow->key.dl_vlan_pcp;
ofs->match.tp_src = flow->key.tp_src;
ofs->match.tp_dst = flow->key.tp_dst;
+18 -9
View File
@@ -1,3 +1,4 @@
/*
* Distributed under the terms of the GNU GPL version 2.
* Copyright (c) 2007, 2008 The Board of Trustees of The Leland
@@ -34,9 +35,10 @@ int flow_fields_match(const struct sw_flow_key *a, const struct sw_flow_key *b,
&& (w & OFPFW_DL_SRC || !memcmp(a->dl_src, b->dl_src, ETH_ALEN))
&& (w & OFPFW_DL_DST || !memcmp(a->dl_dst, b->dl_dst, ETH_ALEN))
&& (w & OFPFW_DL_TYPE || a->dl_type == b->dl_type)
&& (w & OFPFW_NW_TOS || a->nw_tos == b->nw_tos)
&& (w & OFPFW_NW_PROTO || a->nw_proto == b->nw_proto)
&& !((a->nw_src ^ b->nw_src) & src_mask)
&& !((a->nw_dst ^ b->nw_dst) & dst_mask)
&& (w & OFPFW_NW_PROTO || a->nw_proto == b->nw_proto)
&& (w & OFPFW_TP_SRC || a->tp_src == b->tp_src)
&& (w & OFPFW_TP_DST || a->tp_dst == b->tp_dst));
}
@@ -93,19 +95,21 @@ void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from)
memcpy(to->dl_dst, from->dl_dst, ETH_ALEN);
to->dl_type = from->dl_type;
to->nw_src = to->nw_dst = to->nw_proto = 0;
to->nw_tos = to->nw_proto = to->nw_src = to->nw_dst = 0;
to->tp_src = to->tp_dst = 0;
memset(to->pad, 0, sizeof(to->pad));
#define OFPFW_TP (OFPFW_TP_SRC | OFPFW_TP_DST)
#define OFPFW_NW (OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO)
#define OFPFW_NW (OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK)
if (to->wildcards & OFPFW_DL_TYPE) {
/* Can't sensibly match on network or transport headers if the
* data link type is unknown. */
to->wildcards |= OFPFW_NW | OFPFW_TP;
} else if (from->dl_type == htons(ETH_P_IP)) {
to->nw_tos = from->nw_tos & 0xfc;
to->nw_proto = from->nw_proto;
to->nw_src = from->nw_src;
to->nw_dst = from->nw_dst;
to->nw_proto = from->nw_proto;
if (to->wildcards & OFPFW_NW_PROTO) {
/* Can't sensibly match on transport headers if the
@@ -142,9 +146,10 @@ void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from)
memcpy(to->dl_src, from->dl_src, ETH_ALEN);
memcpy(to->dl_dst, from->dl_dst, ETH_ALEN);
to->dl_type = from->dl_type;
to->nw_tos = from->nw_tos;
to->nw_proto = from->nw_proto;
to->nw_src = from->nw_src;
to->nw_dst = from->nw_dst;
to->nw_proto = from->nw_proto;
to->tp_src = from->tp_src;
to->tp_dst = from->tp_dst;
to->dl_vlan_pcp = from->dl_vlan_pcp;
@@ -310,9 +315,11 @@ EXPORT_SYMBOL(flow_replace_acts);
/* Prints a representation of 'key' to the kernel log. */
void print_flow(const struct sw_flow_key *key)
{
printk("wild%08x port%04x:vlan%04x vlan_pcp%02x mac%02x:%02x:%02x:%02x:%02x:%02x"
"->%02x:%02x:%02x:%02x:%02x:%02x "
"proto%04x ip%u.%u.%u.%u->%u.%u.%u.%u port%d->%d\n",
printk("wild %08x port %04x vlan-vid %04x vlan-pcp %02x "
"src-mac %02x:%02x:%02x:%02x:%02x:%02x "
"dst-mac %02x:%02x:%02x:%02x:%02x:%02x "
"frm-type %04x ip-tos %02x ip-proto %02x "
"src-ip %u.%u.%u.%u dst-ip %u.%u.%u.%u tp-src %d tp-dst %d\n",
key->wildcards, ntohs(key->in_port), ntohs(key->dl_vlan),
key->dl_vlan_pcp,
key->dl_src[0], key->dl_src[1], key->dl_src[2],
@@ -320,6 +327,7 @@ void print_flow(const struct sw_flow_key *key)
key->dl_dst[0], key->dl_dst[1], key->dl_dst[2],
key->dl_dst[3], key->dl_dst[4], key->dl_dst[5],
ntohs(key->dl_type),
key->nw_tos, key->nw_proto,
((unsigned char *)&key->nw_src)[0],
((unsigned char *)&key->nw_src)[1],
((unsigned char *)&key->nw_src)[2],
@@ -406,9 +414,10 @@ int flow_extract(struct sk_buff *skb, uint16_t in_port,
if (key->dl_type == htons(ETH_P_IP) && iphdr_ok(skb)) {
struct iphdr *nh = ip_hdr(skb);
int th_ofs = nh_ofs + nh->ihl * 4;
key->nw_tos = nh->tos & 0xfc;
key->nw_proto = nh->protocol;
key->nw_src = nh->saddr;
key->nw_dst = nh->daddr;
key->nw_proto = nh->protocol;
skb_set_transport_header(skb, th_ofs);
/* Transport layer. */
+4 -2
View File
@@ -41,8 +41,10 @@ struct sw_flow_key {
uint16_t tp_dst; /* TCP/UDP destination port. */
uint8_t dl_src[ETH_ALEN]; /* Ethernet source address. */
uint8_t dl_dst[ETH_ALEN]; /* Ethernet destination address. */
uint8_t nw_proto; /* IP protocol. */
uint8_t dl_vlan_pcp; /* Input VLAN priority. */
uint8_t nw_tos; /* IPv4 DSCP */
uint8_t nw_proto; /* IP protocol. */
uint8_t pad[3];
uint32_t wildcards; /* Wildcard fields (host byte order). */
uint32_t nw_src_mask; /* 1-bit in each significant nw_src bit. */
uint32_t nw_dst_mask; /* 1-bit in each significant nw_dst bit. */
@@ -67,7 +69,7 @@ static inline int flow_keys_equal(const struct sw_flow_key *a,
*/
static inline void check_key_align(void)
{
BUILD_BUG_ON(sizeof(struct sw_flow_key) != 44);
BUILD_BUG_ON(sizeof(struct sw_flow_key) != 48);
}
/* We keep actions as a separate structure because we need to be able to
+6 -4
View File
@@ -332,7 +332,7 @@ enum ofp_action_type {
OFPAT_SET_DL_DST, /* Ethernet destination address. */
OFPAT_SET_NW_SRC, /* IP source address. */
OFPAT_SET_NW_DST, /* IP destination address. */
OFPAT_SET_NW_TOS, /* IP ToS/DSCP field (6 bits). */
OFPAT_SET_NW_TOS, /* IP ToS (DSCP field, 6 bits). */
OFPAT_SET_TP_SRC, /* TCP/UDP source port. */
OFPAT_SET_TP_DST, /* TCP/UDP destination port. */
OFPAT_VENDOR = 0xffff
@@ -402,7 +402,7 @@ OFP_ASSERT(sizeof(struct ofp_action_tp_port) == 8);
struct ofp_action_nw_tos {
uint16_t type; /* OFPAT_SET_TW_SRC/DST. */
uint16_t len; /* Length is 8. */
uint8_t nw_tos; /* IP ToS/DSCP (6 bits). */
uint8_t nw_tos; /* IP ToS (DSCP field, 6 bits). */
uint8_t pad[3];
};
OFP_ASSERT(sizeof(struct ofp_action_nw_tos) == 8);
@@ -477,9 +477,10 @@ enum ofp_flow_wildcards {
OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT,
OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */
OFPFW_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */
/* Wildcard all fields. */
OFPFW_ALL = ((1 << 21) - 1)
OFPFW_ALL = ((1 << 22) - 1)
};
/* The wildcards for ICMP type and code fields use the transport source
@@ -513,8 +514,9 @@ struct ofp_match {
uint8_t dl_vlan_pcp; /* Input VLAN priority. */
uint8_t pad1[1]; /* Align to 64-bits */
uint16_t dl_type; /* Ethernet frame type. */
uint8_t nw_tos; /* IP ToS (actually DSCP field, 6 bits). */
uint8_t nw_proto; /* IP protocol. */
uint8_t pad2[3]; /* Align to 64-bits */
uint8_t pad2[2]; /* Align to 64-bits */
uint32_t nw_src; /* IP source address. */
uint32_t nw_dst; /* IP destination address. */
uint16_t tp_src; /* TCP/UDP source port. */
+8 -4
View File
@@ -165,9 +165,10 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, struct flow *flow)
if (flow->dl_type == htons(ETH_TYPE_IP)) {
const struct ip_header *nh = pull_ip(&b);
if (nh) {
flow->nw_tos = nh->ip_tos & 0xfc;
flow->nw_proto = nh->ip_proto;
flow->nw_src = nh->ip_src;
flow->nw_dst = nh->ip_dst;
flow->nw_proto = nh->ip_proto;
packet->l4 = b.data;
if (!IP_IS_FRAGMENT(nh->ip_frag_off)) {
if (flow->nw_proto == IP_TYPE_TCP) {
@@ -232,9 +233,10 @@ flow_fill_match(struct ofp_match *to, const struct flow *from,
memcpy(to->dl_src, from->dl_src, ETH_ADDR_LEN);
memcpy(to->dl_dst, from->dl_dst, ETH_ADDR_LEN);
to->dl_type = from->dl_type;
to->nw_tos = from->nw_tos;
to->nw_proto = from->nw_proto;
to->nw_src = from->nw_src;
to->nw_dst = from->nw_dst;
to->nw_proto = from->nw_proto;
to->tp_src = from->tp_src;
to->tp_dst = from->tp_dst;
to->dl_vlan_pcp = from->dl_vlan_pcp;
@@ -244,11 +246,13 @@ void
flow_print(FILE *stream, const struct flow *flow)
{
fprintf(stream,
"port%04x:vlan%04x vlan_pcp%02x mac"ETH_ADDR_FMT"->"ETH_ADDR_FMT" "
"proto%04x ip"IP_FMT"->"IP_FMT" port%d->%d",
"port %04x vlan-vid %04x vlan-pcp %02x src-mac "ETH_ADDR_FMT" "
"dst-mac "ETH_ADDR_FMT" frm-type %04x ip-tos %02x ip-proto %02x "
"src-ip "IP_FMT" dst-ip "IP_FMT" tp-src %d tp-dst %d",
ntohs(flow->in_port), ntohs(flow->dl_vlan), flow->dl_vlan_pcp,
ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst),
ntohs(flow->dl_type),
flow->nw_tos, flow->nw_proto,
IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst),
ntohs(flow->tp_src), ntohs(flow->tp_dst));
}
+4 -2
View File
@@ -56,10 +56,12 @@ struct flow {
uint16_t tp_dst; /* TCP/UDP destination port. */
uint8_t dl_src[6]; /* Ethernet source address. */
uint8_t dl_dst[6]; /* Ethernet destination address. */
uint8_t nw_proto; /* IP protocol. */
uint8_t dl_vlan_pcp; /* Input VLAN priority. */
uint8_t nw_tos; /* IPv4 DSCP. */
uint8_t nw_proto; /* IP protocol. */
uint8_t pad[3];
};
BUILD_ASSERT_DECL(sizeof(struct flow) == 32);
BUILD_ASSERT_DECL(sizeof(struct flow) == 36);
int flow_extract(struct ofpbuf *, uint16_t in_port, struct flow *);
void flow_fill_match(struct ofp_match *, const struct flow *,
+3
View File
@@ -161,6 +161,7 @@ ofp_packet_in(struct ds *string, const void *oh, size_t len, int verbosity)
match.dl_type = flow.dl_type;
match.nw_proto = flow.nw_proto;
match.dl_vlan_pcp = flow.dl_vlan_pcp;
match.nw_tos = flow.nw_tos;
match.nw_src = flow.nw_src;
match.nw_dst = flow.nw_dst;
match.tp_src = flow.tp_src;
@@ -700,6 +701,8 @@ ofp_match_to_string(const struct ofp_match *om, int verbosity)
(w & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT, verbosity);
print_ip_netmask(&f, "nw_dst=", om->nw_dst,
(w & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT, verbosity);
print_wild(&f, "nw_tos=", w & OFPFW_NW_TOS, verbosity,
"%u", om->nw_tos);
if (!skip_proto) {
print_wild(&f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
"%u", om->nw_proto);
+13 -7
View File
@@ -805,14 +805,11 @@ sub run_black_box_test {
}
sub create_flow_mod_from_udp {
my ( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, $chg_field, $chg_val, $vlan_id ) = @_;
my ( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, $chg_field, $chg_val, $vlan_id, $nw_tos ) = @_;
my $flow_mod_pkt;
$flow_mod_pkt =
create_flow_mod_from_udp_action( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards,
'OFPFC_ADD', $chg_field, $chg_val, $vlan_id );
$flow_mod_pkt = create_flow_mod_from_udp_action( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, 'OFPFC_ADD', $chg_field, $chg_val, $vlan_id, $nw_tos );
return $flow_mod_pkt;
}
@@ -995,8 +992,7 @@ sub combine_args {
}
sub create_flow_mod_from_udp_action {
my ( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, $mod_type, $chg_field, $chg_val, $vlan_id ) = @_;
my ( $ofp, $udp_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, $mod_type, $chg_field, $chg_val, $vlan_id, $nw_tos) = @_;
if ( $mod_type ne 'drop'
&& $mod_type ne 'OFPFC_ADD'
@@ -1052,6 +1048,13 @@ sub create_flow_mod_from_udp_action {
$dl_vlan_pcp = 0x0;
}
my $match_nw_tos;
if (defined $nw_tos) {
$match_nw_tos = $nw_tos & 0xfc;
} else {
$match_nw_tos = 0;
}
my $match_args = {
wildcards => $wildcards,
in_port => $in_port,
@@ -1062,6 +1065,7 @@ sub create_flow_mod_from_udp_action {
dl_vlan_pcp => $dl_vlan_pcp,
nw_src => $src_ip,
nw_dst => $dst_ip,
nw_tos => $match_nw_tos,
nw_proto => 17, #udp
tp_src => ${ $udp_pkt->{UDP_pdu} }->SrcPort,
tp_dst => ${ $udp_pkt->{UDP_pdu} }->DstPort
@@ -1320,6 +1324,7 @@ sub for_all_wildcards {
0x003f00 => 'NW_SRC',
0x0fc000 => 'NW_DST',
0x100000 => 'DL_VLAN_PCP',
0x200000 => 'NW_TOS',
);
# Disable "1 ||" below for a more complete test
@@ -1760,6 +1765,7 @@ sub create_flow_mod_from_icmp_action {
dl_vlan_pcp => 0x00,
nw_src => $src_ip,
nw_dst => $dst_ip,
nw_tos => 0,
nw_proto => 1, #ICMP
tp_src => $icmp_type,
tp_dst => $icmp_code
@@ -5,7 +5,7 @@ use strict;
use OF::Includes;
sub send_expect_exact {
my ($ofp, $sock, $options_ref, $in_port_offset, $out_port_offset, $max_idle, $pkt_len) = @_;
my ($ofp, $sock, $options_ref, $in_port_offset, $out_port_offset, $max_idle, $pkt_len, $vlan_id) = @_;
my $in_port = $in_port_offset + $$options_ref{'port_base'};
my $out_port = $out_port_offset + $$options_ref{'port_base'};
@@ -17,12 +17,13 @@ sub send_expect_exact {
my $pkt_payload = [map {int(rand(256))} (1..($pkt_len - 8 - 4 - 16 - 14))];
# This is the packet we are sending... - Jean II
my $test_nw_tos = 0xa9;
my $test_pkt_args = {
DA => "00:00:00:00:00:0" . ($out_port + 1),
SA => "00:00:00:00:00:0" . ($in_port + 1),
src_ip => "192.168.200." . ($in_port + 1),
dst_ip => "192.168.201." . ($out_port + 1),
tos => 0xa9,
tos => $test_nw_tos,
ttl => 64,
len => $pkt_len,
src_port => 1,
@@ -52,7 +53,7 @@ sub send_expect_exact {
my $flags = $enums{'OFPFF_SEND_FLOW_REM'}; # want flow expiry
my $nw_tos = 0x56;
my $flow_mod_pkt = create_flow_mod_from_udp_action($ofp, $test_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, 'OFPFC_ADD', 'nw_tos', $nw_tos);
my $flow_mod_pkt = create_flow_mod_from_udp_action($ofp, $test_pkt, $in_port, $out_port, $max_idle, $flags, $wildcards, 'OFPFC_ADD', 'nw_tos', $nw_tos, $vlan_id, $test_nw_tos);
#print HexDump($flow_mod_pkt);
+1 -1
View File
@@ -39,7 +39,7 @@ test_forward_exact_modify_action/run.pl
test_forward_wildcard_modify_action/run.pl
test_flow_mod_check/run.pl
test_set_nw_dst/run.pl
test_set_nw_tos/run.pl
test_set_n_match_nw_tos/run.pl
## ICMP handling Tests
test_forward_exact_icmp_port/run.pl
+2 -1
View File
@@ -806,6 +806,7 @@ fill_flow_stats(struct ofpbuf *buffer, struct sw_flow *flow,
memcpy(ofs->match.dl_dst, flow->key.flow.dl_dst, ETH_ADDR_LEN);
ofs->match.dl_vlan = flow->key.flow.dl_vlan;
ofs->match.dl_type = flow->key.flow.dl_type;
ofs->match.nw_tos = flow->key.flow.nw_tos;
ofs->match.nw_src = flow->key.flow.nw_src;
ofs->match.nw_dst = flow->key.flow.nw_dst;
ofs->match.nw_proto = flow->key.flow.nw_proto;
@@ -1063,7 +1064,7 @@ add_flow(struct datapath *dp, const struct sender *sender,
execute_actions(dp, buffer, &key,
ofm->actions, actions_len, false);
} else {
error = -ESRCH;
error = -ESRCH;
}
}
return error;
+24 -12
View File
@@ -43,6 +43,9 @@
#include "packets.h"
#include "timeval.h"
#define THIS_MODULE VLM_chain
#include "vlog.h"
/* Internal function used to compare fields in flow. */
static inline int
flow_fields_match(const struct flow *a, const struct flow *b, uint32_t w,
@@ -54,9 +57,10 @@ flow_fields_match(const struct flow *a, const struct flow *b, uint32_t w,
&& (w & OFPFW_DL_SRC || eth_addr_equals(a->dl_src, b->dl_src))
&& (w & OFPFW_DL_DST || eth_addr_equals(a->dl_dst, b->dl_dst))
&& (w & OFPFW_DL_TYPE || a->dl_type == b->dl_type)
&& (w & OFPFW_NW_TOS || a->nw_tos == b->nw_tos)
&& (w & OFPFW_NW_PROTO || a->nw_proto == b->nw_proto)
&& !((a->nw_src ^ b->nw_src) & src_mask)
&& !((a->nw_dst ^ b->nw_dst) & dst_mask)
&& (w & OFPFW_NW_PROTO || a->nw_proto == b->nw_proto)
&& (w & OFPFW_TP_SRC || a->tp_src == b->tp_src)
&& (w & OFPFW_TP_DST || a->tp_dst == b->tp_dst));
}
@@ -112,19 +116,21 @@ flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from)
memcpy(to->flow.dl_dst, from->dl_dst, ETH_ADDR_LEN);
to->flow.dl_type = from->dl_type;
to->flow.nw_src = to->flow.nw_dst = to->flow.nw_proto = 0;
to->flow.nw_tos = to->flow.nw_proto = to->flow.nw_src = to->flow.nw_dst = 0;
to->flow.tp_src = to->flow.tp_dst = 0;
memset(to->flow.pad, 0, sizeof(to->flow.pad));
#define OFPFW_TP (OFPFW_TP_SRC | OFPFW_TP_DST)
#define OFPFW_NW (OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO)
#define OFPFW_NW (OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK)
if (to->wildcards & OFPFW_DL_TYPE) {
/* Can't sensibly match on network or transport headers if the
* data link type is unknown. */
to->wildcards |= OFPFW_NW | OFPFW_TP;
} else if (from->dl_type == htons(ETH_TYPE_IP)) {
to->flow.nw_tos = from->nw_tos & 0xfc;
to->flow.nw_proto = from->nw_proto;
to->flow.nw_src = from->nw_src;
to->flow.nw_dst = from->nw_dst;
to->flow.nw_proto = from->nw_proto;
if (to->wildcards & OFPFW_NW_PROTO) {
/* Can't sensibly match on transport headers if the network
@@ -169,11 +175,11 @@ flow_alloc(size_t actions_len)
{
struct sw_flow_actions *sfa;
size_t size = sizeof *sfa + actions_len;
struct sw_flow *flow = malloc(sizeof *flow);
struct sw_flow *flow = calloc(1, sizeof *flow);
if (!flow)
return NULL;
sfa = malloc(size);
sfa = calloc(1, size);
if (!sfa) {
free(flow);
return NULL;
@@ -240,16 +246,20 @@ void
print_flow(const struct sw_flow_key *key)
{
const struct flow *f = &key->flow;
printf("wild%08x port%04x:vlan%04x vlan_pcp%02x mac%02x:%02x:%02x:%02x:%02x:%02x"
"->%02x:%02x:%02x:%02x:%02x:%02x "
"proto%04x ip%u.%u.%u.%u->%u.%u.%u.%u port%d->%d\n",
key->wildcards, ntohs(f->in_port), ntohs(f->dl_vlan),
f->dl_vlan_pcp,
VLOG_INFO("wild %08x port %04x vlan-vid %04x vlan-pcp %02x "
"src-mac %02x:%02x:%02x:%02x:%02x:%02x "
"dst-mac %02x:%02x:%02x:%02x:%02x:%02x "
"frm-type %04x ip-tos %02x ip-src %u.%u.%u.%u ip-dst %u.%u.%u.%u "
"ip-proto %04x tp-src %d tp-dst %d pad %02x%02x%02x\n",
key->wildcards, ntohs(f->in_port),
ntohs(f->dl_vlan), f->dl_vlan_pcp,
f->dl_src[0], f->dl_src[1], f->dl_src[2],
f->dl_src[3], f->dl_src[4], f->dl_src[5],
f->dl_dst[0], f->dl_dst[1], f->dl_dst[2],
f->dl_dst[3], f->dl_dst[4], f->dl_dst[5],
ntohs(f->dl_type),
f->nw_tos,
((unsigned char *)&f->nw_src)[0],
((unsigned char *)&f->nw_src)[1],
((unsigned char *)&f->nw_src)[2],
@@ -258,7 +268,9 @@ print_flow(const struct sw_flow_key *key)
((unsigned char *)&f->nw_dst)[1],
((unsigned char *)&f->nw_dst)[2],
((unsigned char *)&f->nw_dst)[3],
ntohs(f->tp_src), ntohs(f->tp_dst));
f->nw_proto,
ntohs(f->tp_src), ntohs(f->tp_dst),
f->pad[0], f->pad[1], f->pad[2]);
}
bool flow_timeout(struct sw_flow *flow)
@@ -109,7 +109,7 @@ static const value_string names_ofp_action_type[] = {
#define NUM_PORT_CONFIG_FLAGS 7
#define NUM_PORT_STATE_FLAGS 1
#define NUM_PORT_FEATURES_FLAGS 12
#define NUM_WILDCARDS 11
#define NUM_WILDCARDS 12
#define NUM_CAPABILITIES_FLAGS 6
#define NUM_FLOW_MOD_FLAGS 3
#define NUM_SF_REPLY_FLAGS 1
@@ -440,6 +440,7 @@ static gint ofp_match_dl_vlan_pcp = -1;
static gint ofp_match_dl_type = -1;
static gint ofp_match_nw_src = -1;
static gint ofp_match_nw_dst = -1;
static gint ofp_match_nw_tos = -1;
static gint ofp_match_nw_proto = -1;
static gint ofp_match_arp_opcode= -1;
static gint ofp_match_tp_src = -1;
@@ -1023,6 +1024,9 @@ void proto_register_openflow()
{ &ofp_match_wildcards[10],
{ " VLAN priority", "of.wildcard_dl_vlan_pcp" , FT_UINT32, BASE_DEC, VALS(wildcard_choice), OFPFW_DL_VLAN_PCP, "VLAN priority", HFILL }},
{ &ofp_match_wildcards[11],
{ " IPv4 DSCP", "of.wildcard_nw_tos" , FT_UINT32, BASE_DEC, VALS(wildcard_choice), OFPFW_NW_TOS, "IPv4 DSCP", HFILL }},
{ &ofp_table_stats_wildcards[0],
{ " Input port", "of.wildcard_in_port" , FT_UINT32, BASE_DEC, VALS(ts_wildcard_choice), OFPFW_IN_PORT, "Input Port", HFILL }},
@@ -1086,6 +1090,9 @@ void proto_register_openflow()
{ &ofp_match_dl_vlan_pcp,
{ "Input VLAN priority", "of.match_dl_vlan_pcp", FT_UINT8, BASE_DEC, NO_STRINGS, NO_MASK, "Input VLAN priority", HFILL }},
{ &ofp_match_nw_tos,
{ "IPv4 DSCP", "of.match_nw_tos", FT_UINT8, BASE_DEC, NO_STRINGS, NO_MASK, "IPv4 DSCP", HFILL }},
{ &ofp_match_tp_src,
{ "TCP/UDP Src Port", "of.match_tp_src", FT_UINT16, BASE_DEC, NO_STRINGS, NO_MASK, "TCP/UDP Source Port", HFILL }},
@@ -2188,6 +2195,11 @@ static void dissect_match(proto_tree* tree, proto_item* item, tvbuff_t *tvb, pac
else
*offset += 2;
if( ~wildcards & OFPFW_NW_TOS )
add_child(match_tree, ofp_match_nw_tos, tvb, offset, 1);
else
*offset += 1;
/* Save NW proto for later */
guint8 nw_proto = tvb_get_guint8( tvb, *offset);
@@ -2199,7 +2211,7 @@ static void dissect_match(proto_tree* tree, proto_item* item, tvbuff_t *tvb, pac
else
*offset += 1;
dissect_pad(match_tree, offset, 3);
dissect_pad(match_tree, offset, 2);
if( ~wildcards & OFPFW_NW_SRC_MASK )
add_child(match_tree, ofp_match_nw_src, tvb, offset, 4);