flow->ipv6_dst = nh->ip6_dst;
tc_flow = get_unaligned_be32(&nh->ip6_flow);
- flow->nw_tos = ntohl(tc_flow) >> 4;
+ flow->nw_tos = ntohl(tc_flow) >> 20;
flow->ipv6_label = tc_flow & htonl(IPV6_LABEL_MASK);
flow->nw_ttl = nh->ip6_hlim;
flow->nw_proto = IPPROTO_NONE;
}
/* We only process the first fragment. */
- flow->nw_frag = FLOW_NW_FRAG_ANY;
- if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
- flow->nw_frag |= FLOW_NW_FRAG_LATER;
- nexthdr = IPPROTO_FRAGMENT;
- break;
+ if (frag_hdr->ip6f_offlg != htons(0)) {
+ if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) == htons(0)) {
+ flow->nw_frag = FLOW_NW_FRAG_ANY;
+ } else {
+ flow->nw_frag |= FLOW_NW_FRAG_LATER;
+ nexthdr = IPPROTO_FRAGMENT;
+ break;
+ }
}
}
}
}
flow->vlan_tci &= wildcards->vlan_tci_mask;
if (wc & FWW_DL_TYPE) {
- flow->dl_type = 0;
+ flow->dl_type = htons(0);
}
if (wc & FWW_TP_SRC) {
- flow->tp_src = 0;
+ flow->tp_src = htons(0);
}
if (wc & FWW_TP_DST) {
- flow->tp_dst = 0;
+ flow->tp_dst = htons(0);
}
if (wc & FWW_DL_SRC) {
memset(flow->dl_src, 0, sizeof flow->dl_src);
|| fields == NX_HASH_FIELDS_SYMMETRIC_L4;
}
+/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
+ * OpenFlow 1.0 "dl_vlan" value:
+ *
+ * - If it is in the range 0...4095, 'flow->vlan_tci' is set to match
+ * that VLAN. Any existing PCP match is unchanged (it becomes 0 if
+ * 'flow' previously matched packets without a VLAN header).
+ *
+ * - If it is OFP_VLAN_NONE, 'flow->vlan_tci' is set to match a packet
+ * without a VLAN tag.
+ *
+ * - Other values of 'vid' should not be used. */
+void
+flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
+{
+ if (vid == htons(OFP_VLAN_NONE)) {
+ flow->vlan_tci = htons(0);
+ } else {
+ vid &= htons(VLAN_VID_MASK);
+ flow->vlan_tci &= ~htons(VLAN_VID_MASK);
+ flow->vlan_tci |= htons(VLAN_CFI) | vid;
+ }
+}
+
+/* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
+ * range 0...7.
+ *
+ * This function has no effect on the VLAN ID that 'flow' matches.
+ *
+ * After calling this function, 'flow' will not match packets without a VLAN
+ * header. */
+void
+flow_set_vlan_pcp(struct flow *flow, uint8_t pcp)
+{
+ pcp &= 0x07;
+ flow->vlan_tci &= ~htons(VLAN_PCP_MASK);
+ flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
+}
+
/* Puts into 'b' a packet that flow_extract() would parse as having the given
* 'flow'.
*