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:
+2
-1
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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 *,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-3
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user