Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

tests: Add more tests for VLAN match encoding and decoding.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Simon Horman <horms@verge.net.au
  • Loading branch information...
commit df778240e1e311f7eba9dfda4f5f8bf0f915ae5f 1 parent b592e72
Ben Pfaff blp authored

Showing 3 changed files with 278 additions and 0 deletions. Show diff stats Hide diff stats

  1. +115 0 DESIGN
  2. +87 0 tests/ovs-ofctl.at
  3. +76 0 utilities/ovs-ofctl.c
115 DESIGN
@@ -152,6 +152,121 @@ sends flow_removed message --- --- --- % %
152 152 receive the generated messages.)
153 153
154 154
  155 +VLAN Matching
  156 +=============
  157 +
  158 +The 802.1Q VLAN header causes more trouble than any other 4 bytes in
  159 +networking. More specifically, three versions of OpenFlow and Open
  160 +vSwitch have among them four different ways to match the contents and
  161 +presence of the VLAN header. The following table describes how each
  162 +version works.
  163 +
  164 + Match NXM OF1.0 OF1.1 OF1.2
  165 + ----- --------- ----------- ----------- ------------
  166 + [1] 0000/0000 ????/1,??/? ????/1,??/? 0000/0000,--
  167 + [2] 0000/ffff ffff/0,??/? ffff/0,??/? 0000/ffff,--
  168 + [3] 1xxx/1fff 0xxx/0,??/1 0xxx/0,??/1 1xxx/ffff,--
  169 + [4] z000/f000 ????/1,0y/0 fffe/0,0y/0 1000/1000,0y
  170 + [5] zxxx/ffff 0xxx/0,0y/0 0xxx/0,0y/0 1xxx/ffff,0y
  171 + [6] 0000/0fff <none> <none> <none>
  172 + [7] 0000/f000 <none> <none> <none>
  173 + [8] 0000/efff <none> <none> <none>
  174 + [9] 1001/1001 <none> <none> 1001/1001,--
  175 + [10] 3000/3000 <none> <none> <none>
  176 +
  177 +Each column is interpreted as follows.
  178 +
  179 + - Match: See the list below.
  180 +
  181 + - NXM: xxxx/yyyy means NXM_OF_VLAN_TCI_W with value xxxx and mask
  182 + yyyy. A mask of 0000 is equivalent to omitting
  183 + NXM_OF_VLAN_TCI(_W), a mask of ffff is equivalent to
  184 + NXM_OF_VLAN_TCI.
  185 +
  186 + - OF1.0 and OF1.1: wwww/x,yy/z means dl_vlan wwww, OFPFW_DL_VLAN
  187 + x, dl_vlan_pcp yy, and OFPFW_DL_VLAN_PCP z. ? means that the
  188 + given nibble is ignored (and conventionally 0 for wwww or z,
  189 + conventionally 1 for x or z). <none> means that the given match
  190 + is not supported.
  191 +
  192 + - OF1.2: xxxx/yyyy,zz means OXM_OF_VLAN_VID_W with value xxxx and
  193 + mask yyyy, and OXM_OF_VLAN_PCP (which is not maskable) with
  194 + value zz. A mask of 0000 is equivalent to omitting
  195 + OXM_OF_VLAN_VID(_W), a mask of ffff is equivalent to
  196 + OXM_OF_VLAN_VID. -- means that OXM_OF_VLAN_PCP is omitted.
  197 + <none> means that the given match is not supported.
  198 +
  199 +The matches are:
  200 +
  201 + [1] Matches any packet, that is, one without an 802.1Q header or with
  202 + an 802.1Q header with any TCI value.
  203 +
  204 + [2] Matches only packets without an 802.1Q header.
  205 +
  206 + NXM: Any match with (vlan_tci == 0) and (vlan_tci_mask & 0x1000)
  207 + != 0 is equivalent to the one listed in the table.
  208 +
  209 + OF1.0: The spec doesn't define behavior if dl_vlan is set to
  210 + 0xffff and OFPFW_DL_VLAN_PCP is not set.
  211 +
  212 + OF1.1: The spec says explicitly to ignore dl_vlan_pcp when
  213 + dl_vlan is set to 0xffff.
  214 +
  215 + OF1.2: The spec doesn't say what should happen if (vlan_vid == 0)
  216 + and (vlan_vid_mask & 0x1000) != 0 but (vlan_vid_mask != 0x1000),
  217 + but it would be straightforward to also interpret as [2].
  218 +
  219 + [3] Matches only packets that have an 802.1Q header with VID xxx (and
  220 + any PCP).
  221 +
  222 + [4] Matches only packets that have an 802.1Q header with PCP y (and
  223 + any VID).
  224 +
  225 + NXM: z is ((y << 1) | 1).
  226 +
  227 + OF1.0: The spec isn't very clear, but OVS implements it this way.
  228 +
  229 + OF1.2: Presumably other masks such that (vlan_vid_mask & 0x1fff)
  230 + == 0x1000 would also work, but the spec doesn't define their
  231 + behavior.
  232 +
  233 + [5] Matches only packets that have an 802.1Q header with VID xxx and
  234 + PCP y.
  235 +
  236 + NXM: z is ((y << 1) | 1).
  237 +
  238 + OF1.2: Presumably other masks such that (vlan_vid_mask & 0x1fff)
  239 + == 0x1fff would also work.
  240 +
  241 + [6] Matches packets with no 802.1Q header or with an 802.1Q header
  242 + with a VID of 0. Only possible with NXM.
  243 +
  244 + [7] Matches packets with no 802.1Q header or with an 802.1Q header
  245 + with a PCP of 0. Only possible with NXM.
  246 +
  247 + [8] Matches packets with no 802.1Q header or with an 802.1Q header
  248 + with both VID and PCP of 0. Only possible with NXM.
  249 +
  250 + [9] Matches only packets that have an 802.1Q header with an
  251 + odd-numbered VID (and any PCP). Only possible with NXM and
  252 + OF1.2. (This is just an example; one can match on any desired
  253 + VID bit pattern.)
  254 +
  255 +[10] Matches only packets that have an 802.1Q header with an
  256 + odd-numbered PCP (and any VID). Only possible with NXM. (This
  257 + is just an example; one can match on any desired VID bit
  258 + pattern.)
  259 +
  260 +Additional notes:
  261 +
  262 + - OF1.2: The top three bits of OXM_OF_VLAN_VID are fixed to zero,
  263 + so bits 13, 14, and 15 in the masks listed in the table may be
  264 + set to arbitrary values, as long as the corresponding value bits
  265 + are also zero. The suggested ffff mask for [2], [3], and [5]
  266 + allows a shorter OXM representation (the mask is omitted) than
  267 + the minimal 1fff mask.
  268 +
  269 +
155 270 Flow Cookies
156 271 ============
157 272
87 tests/ovs-ofctl.at
@@ -1645,6 +1645,93 @@ OXM_OF_IN_PORT(00000001), OXM_OF_ETH_TYPE(0800)
1645 1645 ])
1646 1646 AT_CLEANUP
1647 1647
  1648 +dnl Check all of the patterns mentioned in the "VLAN Matching" section
  1649 +dnl in the DESIGN file at top level.
  1650 +AT_SETUP([ovs-ofctl check-vlan])
  1651 +AT_KEYWORDS([VLAN])
  1652 +
  1653 +dnl [1]
  1654 +AT_CHECK([ovs-ofctl check-vlan 0000 0000], [0], [dnl
  1655 + -> 0000/0000
  1656 +NXM: <any> -> 0000/0000
  1657 +OF1.0: 0000/1,00/1 -> 0000/0000
  1658 +OF1.1: 0000/1,00/1 -> 0000/0000
  1659 +])
  1660 +
  1661 +dnl [2]
  1662 +AT_CHECK([ovs-ofctl check-vlan 0000 ffff], [0], [dnl
  1663 +vlan_tci=0x0000 -> 0000/ffff
  1664 +NXM: NXM_OF_VLAN_TCI(0000) -> 0000/ffff
  1665 +OF1.0: ffff/0,00/1 -> 0000/ffff
  1666 +OF1.1: ffff/0,00/1 -> 0000/ffff
  1667 +])
  1668 +
  1669 +dnl [3]
  1670 +AT_CHECK([ovs-ofctl check-vlan 1abc 1fff], [0], [dnl
  1671 +dl_vlan=2748 -> 1abc/1fff
  1672 +NXM: NXM_OF_VLAN_TCI_W(1abc/1fff) -> 1abc/1fff
  1673 +OF1.0: 0abc/0,00/1 -> 1abc/1fff
  1674 +OF1.1: 0abc/0,00/1 -> 1abc/1fff
  1675 +])
  1676 +
  1677 +dnl [4]
  1678 +AT_CHECK([ovs-ofctl check-vlan b000 f000], [0], [dnl
  1679 +dl_vlan_pcp=5 -> b000/f000
  1680 +NXM: NXM_OF_VLAN_TCI_W(b000/f000) -> b000/f000
  1681 +OF1.0: 0000/1,05/0 -> b000/f000
  1682 +OF1.1: fffe/0,05/0 -> b000/f000
  1683 +])
  1684 +
  1685 +dnl [5]
  1686 +AT_CHECK([ovs-ofctl check-vlan babc ffff], [0], [dnl
  1687 +dl_vlan=2748,dl_vlan_pcp=5 -> babc/ffff
  1688 +NXM: NXM_OF_VLAN_TCI(babc) -> babc/ffff
  1689 +OF1.0: 0abc/0,05/0 -> babc/ffff
  1690 +OF1.1: 0abc/0,05/0 -> babc/ffff
  1691 +])
  1692 +
  1693 +dnl [6]
  1694 +AT_CHECK([ovs-ofctl check-vlan 0000 0fff], [0], [dnl
  1695 +vlan_tci=0x0000/0x0fff -> 0000/0fff
  1696 +NXM: NXM_OF_VLAN_TCI_W(0000/0fff) -> 0000/0fff
  1697 +OF1.0: 0000/0,00/1 -> 1000/1fff
  1698 +OF1.1: 0000/0,00/1 -> 1000/1fff
  1699 +])
  1700 +
  1701 +dnl [7]
  1702 +AT_CHECK([ovs-ofctl check-vlan 0000 f000], [0], [dnl
  1703 +vlan_tci=0x0000/0xf000 -> 0000/f000
  1704 +NXM: NXM_OF_VLAN_TCI_W(0000/f000) -> 0000/f000
  1705 +OF1.0: ffff/0,00/1 -> 0000/ffff
  1706 +OF1.1: ffff/0,00/1 -> 0000/ffff
  1707 +])
  1708 +
  1709 +dnl [8]
  1710 +AT_CHECK([ovs-ofctl check-vlan 0000 efff], [0], [dnl
  1711 +vlan_tci=0x0000/0xefff -> 0000/efff
  1712 +NXM: NXM_OF_VLAN_TCI_W(0000/efff) -> 0000/efff
  1713 +OF1.0: 0000/0,00/0 -> 1000/ffff
  1714 +OF1.1: 0000/0,00/0 -> 1000/ffff
  1715 +])
  1716 +
  1717 +dnl [9]
  1718 +AT_CHECK([ovs-ofctl check-vlan 1001 1001], [0], [dnl
  1719 +vlan_tci=0x1001/0x1001 -> 1001/1001
  1720 +NXM: NXM_OF_VLAN_TCI_W(1001/1001) -> 1001/1001
  1721 +OF1.0: 0001/0,00/1 -> 1001/1fff
  1722 +OF1.1: 0001/0,00/1 -> 1001/1fff
  1723 +])
  1724 +
  1725 +dnl [10]
  1726 +AT_CHECK([ovs-ofctl check-vlan 3000 3000], [0], [dnl
  1727 +vlan_tci=0x3000/0x3000 -> 3000/3000
  1728 +NXM: NXM_OF_VLAN_TCI_W(3000/3000) -> 3000/3000
  1729 +OF1.0: 0000/1,01/0 -> 3000/f000
  1730 +OF1.1: fffe/0,01/0 -> 3000/f000
  1731 +])
  1732 +AT_CHECK
  1733 +AT_CLEANUP
  1734 +
1648 1735 dnl Check that "-F openflow10" rejects a flow_mod with unsupported features,
1649 1736 dnl such as tunnels and metadata.
1650 1737 AT_SETUP([ovs-ofctl -F option and NXM features])
76 utilities/ovs-ofctl.c
@@ -2528,6 +2528,81 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
2528 2528 ds_destroy(&in);
2529 2529 }
2530 2530
  2531 +/* "check-vlan VLAN_TCI VLAN_TCI_MASK": converts the specified vlan_tci and
  2532 + * mask values to and from various formats and prints the results. */
  2533 +static void
  2534 +ofctl_check_vlan(int argc OVS_UNUSED, char *argv[])
  2535 +{
  2536 + struct cls_rule rule;
  2537 +
  2538 + char *string_s;
  2539 + struct ofputil_flow_mod fm;
  2540 +
  2541 + struct ofpbuf nxm;
  2542 + struct cls_rule nxm_rule;
  2543 + int nxm_match_len;
  2544 + char *nxm_s;
  2545 +
  2546 + struct ofp10_match of10_match;
  2547 + struct cls_rule of10_rule;
  2548 +
  2549 + struct ofp11_match of11_match;
  2550 + struct cls_rule of11_rule;
  2551 +
  2552 + enum ofperr error;
  2553 +
  2554 + cls_rule_init_catchall(&rule, OFP_DEFAULT_PRIORITY);
  2555 + rule.flow.vlan_tci = htons(strtoul(argv[1], NULL, 16));
  2556 + rule.wc.vlan_tci_mask = htons(strtoul(argv[2], NULL, 16));
  2557 +
  2558 + /* Convert to and from string. */
  2559 + string_s = cls_rule_to_string(&rule);
  2560 + printf("%s -> ", string_s);
  2561 + fflush(stdout);
  2562 + parse_ofp_str(&fm, -1, string_s, false);
  2563 + printf("%04"PRIx16"/%04"PRIx16"\n",
  2564 + ntohs(fm.cr.flow.vlan_tci),
  2565 + ntohs(fm.cr.wc.vlan_tci_mask));
  2566 +
  2567 + /* Convert to and from NXM. */
  2568 + ofpbuf_init(&nxm, 0);
  2569 + nxm_match_len = nx_put_match(&nxm, false, &rule, htonll(0), htonll(0));
  2570 + nxm_s = nx_match_to_string(nxm.data, nxm_match_len);
  2571 + error = nx_pull_match(&nxm, nxm_match_len, 0, &nxm_rule, NULL, NULL);
  2572 + printf("NXM: %s -> ", nxm_s);
  2573 + if (error) {
  2574 + printf("%s\n", ofperr_to_string(error));
  2575 + } else {
  2576 + printf("%04"PRIx16"/%04"PRIx16"\n",
  2577 + ntohs(nxm_rule.flow.vlan_tci),
  2578 + ntohs(nxm_rule.wc.vlan_tci_mask));
  2579 + }
  2580 + free(nxm_s);
  2581 + ofpbuf_uninit(&nxm);
  2582 +
  2583 + /* Convert to and from OpenFlow 1.0. */
  2584 + ofputil_cls_rule_to_ofp10_match(&rule, &of10_match);
  2585 + ofputil_cls_rule_from_ofp10_match(&of10_match, 0, &of10_rule);
  2586 + printf("OF1.0: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
  2587 + ntohs(of10_match.dl_vlan),
  2588 + (of10_match.wildcards & htonl(OFPFW10_DL_VLAN)) != 0,
  2589 + of10_match.dl_vlan_pcp,
  2590 + (of10_match.wildcards & htonl(OFPFW10_DL_VLAN_PCP)) != 0,
  2591 + ntohs(of10_rule.flow.vlan_tci),
  2592 + ntohs(of10_rule.wc.vlan_tci_mask));
  2593 +
  2594 + /* Convert to and from OpenFlow 1.1. */
  2595 + ofputil_cls_rule_to_ofp11_match(&rule, &of11_match);
  2596 + ofputil_cls_rule_from_ofp11_match(&of11_match, 0, &of11_rule);
  2597 + printf("OF1.1: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
  2598 + ntohs(of11_match.dl_vlan),
  2599 + (of11_match.wildcards & htonl(OFPFW11_DL_VLAN)) != 0,
  2600 + of11_match.dl_vlan_pcp,
  2601 + (of11_match.wildcards & htonl(OFPFW11_DL_VLAN_PCP)) != 0,
  2602 + ntohs(of11_rule.flow.vlan_tci),
  2603 + ntohs(of11_rule.wc.vlan_tci_mask));
  2604 +}
  2605 +
2531 2606 /* "print-error ENUM": Prints the type and code of ENUM for every OpenFlow
2532 2607 * version. */
2533 2608 static void
@@ -2609,6 +2684,7 @@ static const struct command all_commands[] = {
2609 2684 { "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match },
2610 2685 { "parse-ofp11-actions", 0, 0, ofctl_parse_ofp11_actions },
2611 2686 { "parse-ofp11-instructions", 0, 0, ofctl_parse_ofp11_instructions },
  2687 + { "check-vlan", 2, 2, ofctl_check_vlan },
2612 2688 { "print-error", 1, 1, ofctl_print_error },
2613 2689 { "ofp-print", 1, 2, ofctl_ofp_print },
2614 2690

0 comments on commit df77824

Please sign in to comment.
Something went wrong with that request. Please try again.