[ovs-dev] [PATCH 1/3] ofp-parse: Add support for vlan_tci field.

Ben Pfaff blp at nicira.com
Wed Jun 8 20:41:17 UTC 2011


Until now, the flow parser has supported dl_vlan and dl_vlan_pcp but not
the fully maskable vlan_tci that NXM allows.  This adds that support.
---
 lib/ofp-parse.c          |   36 ++++++++++++++++++++++++++++++++++++
 tests/ovs-ofctl.at       |    2 ++
 utilities/ovs-ofctl.8.in |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 3f3ce62..956f1c2 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -184,6 +184,35 @@ error:
 }
 
 static void
+str_to_vlan_tci(const char *str, ovs_be16 *vlan_tcip, ovs_be16 *maskp)
+{
+    uint16_t vlan_tci, mask;
+    char *tail;
+
+    errno = 0;
+    vlan_tci = strtol(str, &tail, 0);
+    if (errno || (*tail != '\0' && *tail != '/')) {
+        goto error;
+    }
+
+    if (*tail == '/') {
+        mask = strtol(tail + 1, &tail, 0);
+        if (errno || *tail != '\0') {
+            goto error;
+        }
+    } else {
+        mask = UINT16_MAX;
+    }
+
+    *vlan_tcip = htons(vlan_tci);
+    *maskp = htons(mask);
+    return;
+
+error:
+    ovs_fatal(0, "%s: bad syntax for vlan_tci", str);
+}
+
+static void
 str_to_ipv6(const char *str_, struct in6_addr *addrp, struct in6_addr *maskp)
 {
     char *str = xstrdup(str_);
@@ -557,6 +586,7 @@ parse_protocol(const char *name, const struct protocol **p_out)
     FIELD(F_IN_PORT,     "in_port",     FWW_IN_PORT)        \
     FIELD(F_DL_VLAN,     "dl_vlan",     0)                  \
     FIELD(F_DL_VLAN_PCP, "dl_vlan_pcp", 0)                  \
+    FIELD(F_VLAN_TCI,    "vlan_tci",    0)                  \
     FIELD(F_DL_SRC,      "dl_src",      FWW_DL_SRC)         \
     FIELD(F_DL_DST,      "dl_dst",      FWW_DL_DST | FWW_ETH_MCAST) \
     FIELD(F_DL_TYPE,     "dl_type",     FWW_DL_TYPE)        \
@@ -616,6 +646,7 @@ parse_field_value(struct cls_rule *rule, enum field_index index,
     uint8_t mac[ETH_ADDR_LEN], mac_mask[ETH_ADDR_LEN];
     ovs_be64 tun_id, tun_mask;
     ovs_be32 ip, mask;
+    ovs_be16 tci, tci_mask;
     struct in6_addr ipv6, ipv6_mask;
     uint16_t port_no;
 
@@ -640,6 +671,11 @@ parse_field_value(struct cls_rule *rule, enum field_index index,
         cls_rule_set_dl_vlan_pcp(rule, str_to_u32(value));
         break;
 
+    case F_VLAN_TCI:
+        str_to_vlan_tci(value, &tci, &tci_mask);
+        cls_rule_set_dl_tci_masked(rule, tci, tci_mask);
+        break;
+
     case F_DL_SRC:
         str_to_mac(value, mac);
         cls_rule_set_dl_src(rule, mac);
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index a7d3b84..a3a8c44 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -121,6 +121,7 @@ actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
 tun_id=0x1234,cookie=0x5678,actions=flood
 actions=drop
 reg0=123,actions=move:NXM_NX_REG0[0..5]->NXM_NX_REG1[26..31],load:55->NXM_NX_REG2[0..31],move:NXM_NX_REG0[0..31]->NXM_NX_TUN_ID[0..31],move:NXM_NX_REG0[0..15]->NXM_OF_VLAN_TCI[]
+vlan_tci=0x1123/0x1fff,actions=drop
 ]])
 AT_CHECK([ovs-ofctl -F nxm -mmm parse-flows flows.txt], [0], [stdout])
 AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0],
@@ -145,6 +146,7 @@ NXT_FLOW_MOD: ADD <any> actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06
 NXT_FLOW_MOD: ADD NXM_NX_TUN_ID(0000000000001234) cookie:0x5678 actions=FLOOD
 NXT_FLOW_MOD: ADD <any> actions=drop
 NXT_FLOW_MOD: ADD NXM_NX_REG0(0000007b) actions=move:NXM_NX_REG0[0..5]->NXM_NX_REG1[26..31],load:0x37->NXM_NX_REG2[],move:NXM_NX_REG0[]->NXM_NX_TUN_ID[0..31],move:NXM_NX_REG0[0..15]->NXM_OF_VLAN_TCI[]
+NXT_FLOW_MOD: ADD NXM_OF_VLAN_TCI_W(1123/1fff) actions=drop
 ]])
 AT_CLEANUP
 
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 2e866dc..2d17d20 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -428,6 +428,43 @@ Extended Match) extension to OpenFlow.  When one of these is specified,
 extension.  If the switch does not support NXM, then \fBovs\-ofctl\fR
 will report a fatal error.
 .
+.IP \fBvlan_tci=\fItci\fR[\fB/\fImask\fR]
+Matches modified VLAN TCI \fItci\fR.  If \fImask\fR is omitted,
+\fItci\fR is the exact VLAN TCI to match; if \fImask\fR is specified,
+then a 1-bit in \fItci\fR indicates that the corresponding bit in
+\fItci\fR must match exactly, and a 0-bit wildcards that bit.  Both
+\fItci\fR and \fImask\fR are 16-bit values that are decimal by
+default; use a \fB0x\fR prefix to specify them in hexadecimal.
+.
+.IP
+The value that \fBvlan_tci\fR matches against is 0 for a packet that
+has no 802.1Q header.  Otherwise, it is the TCI value from the 802.1Q
+header with the CFI bit (with value \fB0x1000\fR) forced to 1.
+.IP
+Examples:
+.RS
+.IP \fBvlan_tci=0\fR
+Match only packets without an 802.1Q header.
+.IP \fBvlan_tci=0xf123\fR
+Match packets tagged with priority 7 in VLAN 0x123.
+.IP \fBvlan_tci=0x1123/0x1fff\fR
+Match packets tagged with VLAN 0x123 (and any priority).
+.IP \fBvlan_tci=0x5000/0xf000\fR
+Match packets tagged with priority 2 (in any VLAN).
+.IP \fBvlan_tci=0/0xfff\fR
+Match packets with no 802.1Q header or tagged with VLAN 0 (and any
+priority).
+.IP \fBvlan_tci=0x5000/0xe000\fR
+Match packets with no 802.1Q header or tagged with priority 2 (in any
+VLAN).
+.IP \fBvlan_tci=0/0xefff\fR
+Match packets with no 802.1Q header or tagged with VLAN 0 and priority
+0.
+.RE
+.IP
+Some of these matching possibilities can also be achieved with
+\fBdl_vlan\fR and \fBdl_vlan_pcp\fR.
+.
 .IP \fBarp_sha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR
 .IQ \fBarp_tha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR
 When \fBdl_type\fR specifies ARP, \fBarp_sha\fR and \fBarp_tha\fR match
-- 
1.7.4.4




More information about the dev mailing list