])
AT_CLEANUP
+AT_SETUP([ovs-ofctl parse-ofp10-match])
+AT_KEYWORDS([OF1.0])
+AT_DATA([test-data], [dnl
+# in_port=65534
+003820fe fffe 000000000000 000000000000 0000 00 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_src=00:01:02:03:04:05
+003820fb 0000 000102030405 000000000000 0000 00 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_dst=10:20:30:40:50:60
+003820f7 0000 000000000000 102030405060 0000 00 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_vlan=291
+003820fd 0000 000000000000 000000000000 0123 00 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_vlan_pcp=5
+002820ff 0000 000000000000 000000000000 0000 05 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_vlan=291,dl_vlan_pcp=4
+002820fd 0000 000000000000 000000000000 0123 04 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# vlan_tci=0x0000
+003820fd 0000 000000000000 000000000000 ffff 00 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+dnl dl_vlan_pcp doesn't make sense when dl_vlan is "none", so
+dnl OVS ignores it and drops it on output.
+# vlan_tci=0x0000
+# 1: 28 -> 38
+# 20: 05 -> 00
+002820fd 0000 000000000000 000000000000 ffff 05 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+dnl Invalid VID and PCP discards out-of-range bits:
+# dl_vlan=256,dl_vlan_pcp=7
+# 18: f1 -> 01
+# 20: ff -> 07
+002820fd 0000 000000000000 000000000000 f100 ff 00 0000 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# dl_type=0x1234
+003820ef 0000 000000000000 000000000000 0000 00 00 1234 00 00 0000 dnl
+00000000 00000000 0000 0000
+
+# ip,nw_proto=5
+003820cf 0000 000000000000 000000000000 0000 00 00 0800 00 05 0000 dnl
+00000000 00000000 0000 0000
+
+dnl Ignore nw_proto if not IP or ARP:
+# dl_type=0x1234,nw_proto=5
+# normal: 3: cf -> ef
+# normal: 25: 05 -> 00
+& ofp_util|INFO|normalization changed ofp_match, details:
+& ofp_util|INFO| pre: dl_type=0x1234,nw_proto=5
+& ofp_util|INFO|post: dl_type=0x1234
+003820cf 0000 000000000000 000000000000 0000 00 00 1234 00 05 0000 dnl
+00000000 00000000 0000 0000
+
+# ip,nw_tos=252
+001820ef 0000 000000000000 000000000000 0000 00 00 0800 fc 00 0000 dnl
+00000000 00000000 0000 0000
+
+dnl Ignore nw_tos if not IP:
+# arp,nw_tos=4
+# 24: 05 -> 04
+# normal: 1: 18 -> 38
+# normal: 24: 04 -> 00
+& ofp_util|INFO|normalization changed ofp_match, details:
+& ofp_util|INFO| pre: arp,nw_tos=4
+& ofp_util|INFO|post: arp
+001820ef 0000 000000000000 000000000000 0000 00 00 0806 05 00 0000 dnl
+00000000 00000000 0000 0000
+
+dnl Low 2 bits of invalid TOS are forced to 0:
+# ip,nw_tos=48
+# 24: 31 -> 30
+001820ef 0000 000000000000 000000000000 0000 00 00 0800 31 00 0000 dnl
+00000000 00000000 0000 0000
+
+# arp,arp_op=2
+003820cf 0000 000000000000 000000000000 0000 00 00 0806 00 02 0000 dnl
+00000000 00000000 0000 0000
+
+# ip,nw_src=192.168.128.85
+003800ef 0000 000000000000 000000000000 0000 00 00 0800 00 00 0000 dnl
+c0a88055 00000000 0000 0000
+
+# ip,nw_src=192.168.128.0/24
+# 31: 55 -> 00
+003808ef 0000 000000000000 000000000000 0000 00 00 0800 00 00 0000 dnl
+c0a88055 00000000 0000 0000
+
+# ip,nw_dst=192.168.128.85
+003020ef 0000 000000000000 000000000000 0000 00 00 0800 00 00 0000 dnl
+00000000 c0a88055 0000 0000
+
+# ip,nw_dst=192.168.128.0/24
+# 35: 55 -> 00
+003220ef 0000 000000000000 000000000000 0000 00 00 0800 00 00 0000 dnl
+00000000 c0a88055 0000 0000
+
+# arp,nw_src=192.168.128.85
+003800ef 0000 000000000000 000000000000 0000 00 00 0806 00 00 0000 dnl
+c0a88055 00000000 0000 0000
+
+# arp,nw_src=192.168.128.0/24
+# 31: 55 -> 00
+003808ef 0000 000000000000 000000000000 0000 00 00 0806 00 00 0000 dnl
+c0a88055 00000000 0000 0000
+
+# arp,nw_dst=192.168.128.85
+003020ef 0000 000000000000 000000000000 0000 00 00 0806 00 00 0000 dnl
+00000000 c0a88055 0000 0000
+
+# arp,nw_dst=192.168.128.0/24
+# 35: 55 -> 00
+003220ef 0000 000000000000 000000000000 0000 00 00 0806 00 00 0000 dnl
+00000000 c0a88055 0000 0000
+
+dnl Ignore nw_src if not IP or ARP:
+# dl_type=0x1234,nw_src=192.168.128.0/24
+# 31: 55 -> 00
+# normal: 2: 08 -> 20
+# normal: 28: c0 -> 00
+# normal: 29: a8 -> 00
+# normal: 30: 80 -> 00
+& ofp_util|INFO|normalization changed ofp_match, details:
+& ofp_util|INFO| pre: dl_type=0x1234,nw_src=192.168.128.0/24
+& ofp_util|INFO|post: dl_type=0x1234
+003808ef 0000 000000000000 000000000000 0000 00 00 1234 00 00 0000 dnl
+c0a88055 00000000 0000 0000
+
+dnl Ignore nw_dst if not IP or ARP:
+# dl_type=0x1234,nw_dst=192.168.128.0/24
+# 35: 55 -> 00
+# normal: 1: 32 -> 38
+# normal: 32: c0 -> 00
+# normal: 33: a8 -> 00
+# normal: 34: 80 -> 00
+& ofp_util|INFO|normalization changed ofp_match, details:
+& ofp_util|INFO| pre: dl_type=0x1234,nw_dst=192.168.128.0/24
+& ofp_util|INFO|post: dl_type=0x1234
+003220ef 0000 000000000000 000000000000 0000 00 00 1234 00 00 0000 dnl
+00000000 c0a88055 0000 0000
+
+# tcp,tp_src=443
+0038208f 0000 000000000000 000000000000 0000 00 00 0800 00 06 0000 dnl
+00000000 00000000 01bb 0000
+
+# tcp,tp_dst=443
+0038204f 0000 000000000000 000000000000 0000 00 00 0800 00 06 0000 dnl
+00000000 00000000 0000 01bb
+
+# udp,tp_src=443
+0038208f 0000 000000000000 000000000000 0000 00 00 0800 00 11 0000 dnl
+00000000 00000000 01bb 0000
+
+# udp,tp_dst=443
+0038204f 0000 000000000000 000000000000 0000 00 00 0800 00 11 0000 dnl
+00000000 00000000 0000 01bb
+
+# icmp,icmp_type=5
+0038208f 0000 000000000000 000000000000 0000 00 00 0800 00 01 0000 dnl
+00000000 00000000 0005 0000
+
+# icmp,icmp_code=8
+0038204f 0000 000000000000 000000000000 0000 00 00 0800 00 01 0000 dnl
+00000000 00000000 0000 0008
+
+dnl Ignore tp_src if not TCP or UDP:
+# ip,nw_proto=21,tp_src=443
+# normal: 3: 8f -> cf
+# normal: 36: 01 -> 00
+# normal: 37: bb -> 00
+& ofp_util|INFO|normalization changed ofp_match, details:
+& ofp_util|INFO| pre: ip,nw_proto=21,tp_src=443
+& ofp_util|INFO|post: ip,nw_proto=21
+0038208f 0000 000000000000 000000000000 0000 00 00 0800 00 15 0000 dnl
+00000000 00000000 01bb 0000
+
+dnl Ignore tp_dst if not TCP or UDP:
+# ip,nw_proto=21,tp_dst=443
+# normal: 3: 4f -> cf
+# normal: 38: 01 -> 00
+# normal: 39: bb -> 00
+dnl The normalization details are suppressed here due to rate-limiting.
+0038204f 0000 000000000000 000000000000 0000 00 00 0800 00 15 0000 dnl
+00000000 00000000 0000 01bb
+
+])
+sed '/^[[#&]]/d' < test-data > input.txt
+sed -n 's/^# //p; /^$/p' < test-data > expout
+sed -n 's/^& //p' < test-data > experr
+AT_CAPTURE_FILE([input.txt])
+AT_CAPTURE_FILE([expout])
+AT_CAPTURE_FILE([experr])
+AT_CHECK(
+ [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-ofp10-match < input.txt],
+ [0], [expout], [experr])
+AT_CLEANUP
+
AT_SETUP([ovs-ofctl parse-ofp11-match])
AT_KEYWORDS([OF1.1])
AT_DATA([test-data], [dnl
}
static void
-print_differences(const void *a_, size_t a_len,
+print_differences(const char *prefix,
+ const void *a_, size_t a_len,
const void *b_, size_t b_len)
{
const uint8_t *a = a_;
for (i = 0; i < MIN(a_len, b_len); i++) {
if (a[i] != b[i]) {
- printf("%2zu: %02"PRIx8" -> %02"PRIx8"\n", i, a[i], b[i]);
+ printf("%s%2zu: %02"PRIx8" -> %02"PRIx8"\n",
+ prefix, i, a[i], b[i]);
}
}
for (i = a_len; i < b_len; i++) {
- printf("%2zu: (none) -> %02"PRIx8"\n", i, b[i]);
+ printf("%s%2zu: (none) -> %02"PRIx8"\n", prefix, i, b[i]);
}
for (i = b_len; i < a_len; i++) {
- printf("%2zu: %02"PRIx8" -> (none)\n", i, a[i]);
+ printf("%s%2zu: %02"PRIx8" -> (none)\n", prefix, i, a[i]);
}
}
ofpbuf_init(&of10_out, 0);
ofpacts_put_openflow10(ofpacts.data, ofpacts.size, &of10_out);
- print_differences(of10_in.data, of10_in.size,
+ print_differences("", of10_in.data, of10_in.size,
of10_out.data, of10_out.size);
putchar('\n');
ds_destroy(&in);
}
+/* "parse-ofp10-match": reads a series of ofp10_match specifications as hex
+ * bytes from stdin, converts them to cls_rules, prints them as strings on
+ * stdout, and then converts them back to hex bytes and prints any differences
+ * from the input. */
+static void
+ofctl_parse_ofp10_match(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
+{
+ struct ds in;
+
+ ds_init(&in);
+ while (!ds_get_preprocessed_line(&in, stdin)) {
+ struct ofpbuf match_in;
+ struct ofp10_match match_out;
+ struct ofp10_match match_normal;
+ struct cls_rule rule;
+
+ /* Parse hex bytes. */
+ ofpbuf_init(&match_in, 0);
+ if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
+ ovs_fatal(0, "Trailing garbage in hex data");
+ }
+ if (match_in.size != sizeof(struct ofp10_match)) {
+ ovs_fatal(0, "Input is %zu bytes, expected %zu",
+ match_in.size, sizeof(struct ofp10_match));
+ }
+
+ /* Convert to cls_rule and print. */
+ ofputil_cls_rule_from_ofp10_match(match_in.data, OFP_DEFAULT_PRIORITY,
+ &rule);
+ cls_rule_print(&rule);
+
+ /* Convert back to ofp10_match and print differences from input. */
+ ofputil_cls_rule_to_ofp10_match(&rule, &match_out);
+ print_differences("", match_in.data, match_in.size,
+ &match_out, sizeof match_out);
+
+ /* Normalize, then convert and compare again. */
+ ofputil_normalize_rule(&rule);
+ ofputil_cls_rule_to_ofp10_match(&rule, &match_normal);
+ print_differences("normal: ", &match_out, sizeof match_out,
+ &match_normal, sizeof match_normal);
+ putchar('\n');
+
+ ofpbuf_uninit(&match_in);
+ }
+ ds_destroy(&in);
+}
+
/* "parse-ofp11-match": reads a series of ofp11_match specifications as hex
* bytes from stdin, converts them to cls_rules, prints them as strings on
* stdout, and then converts them back to hex bytes and prints any differences
/* Convert back to ofp11_match and print differences from input. */
ofputil_cls_rule_to_ofp11_match(&rule, &match_out);
- print_differences(match_in.data, match_in.size,
+ print_differences("", match_in.data, match_in.size,
&match_out, sizeof match_out);
putchar('\n');
ofpbuf_init(&of11_out, 0);
ofpacts_put_openflow11_actions(ofpacts.data, ofpacts.size, &of11_out);
- print_differences(of11_in.data, of11_in.size,
+ print_differences("", of11_in.data, of11_in.size,
of11_out.data, of11_out.size);
putchar('\n');
ofpacts_put_openflow11_instructions(ofpacts.data, ofpacts.size,
&of11_out);
- print_differences(of11_in.data, of11_in.size,
+ print_differences("", of11_in.data, of11_in.size,
of11_out.data, of11_out.size);
putchar('\n');
{ "parse-nxm", 0, 0, ofctl_parse_nxm },
{ "parse-oxm", 0, 0, ofctl_parse_oxm },
{ "parse-ofp10-actions", 0, 0, ofctl_parse_ofp10_actions },
+ { "parse-ofp10-match", 0, 0, ofctl_parse_ofp10_match },
{ "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match },
{ "parse-ofp11-actions", 0, 0, ofctl_parse_ofp11_actions },
{ "parse-ofp11-instructions", 0, 0, ofctl_parse_ofp11_instructions },