next_load_segment(const struct ofpact_set_field *sf,
struct mf_subfield *dst, uint64_t *value)
{
- int w = sf->field->n_bytes;
+ int n_bits = sf->field->n_bits;
+ int n_bytes = sf->field->n_bytes;
int start = dst->ofs + dst->n_bits;
- if (start < 8 * w) {
+ if (start < n_bits) {
dst->field = sf->field;
- dst->ofs = bitwise_scan(&sf->mask, w, 1, start, 8 * w);
- if (dst->ofs < 8 * w) {
- dst->n_bits = bitwise_scan(&sf->mask, w, 0, dst->ofs + 1,
- MIN(dst->ofs + 64, 8 * w)) - dst->ofs;
- *value = bitwise_get(&sf->value, w, dst->ofs, dst->n_bits);
+ dst->ofs = bitwise_scan(&sf->mask, n_bytes, 1, start, n_bits);
+ if (dst->ofs < n_bits) {
+ dst->n_bits = bitwise_scan(&sf->mask, n_bytes, 0, dst->ofs + 1,
+ MIN(dst->ofs + 64, n_bits)) - dst->ofs;
+ *value = bitwise_get(&sf->value, n_bytes, dst->ofs, dst->n_bits);
return true;
}
}
])
OVS_VSWITCHD_STOP
AT_CLEANUP
+
+AT_SETUP([reg_load <-> set_field translation corner case])
+AT_KEYWORDS([ofp-actions])
+OVS_VSWITCHD_START
+dnl In OpenFlow 1.3, set_field always sets all the bits in the field,
+dnl but when we translate to NXAST_LOAD we need to only set the bits that
+dnl actually exist (e.g. mpls_label only has 20 bits) otherwise OVS rejects
+dnl the "load" action as invalid. Check that we do this correctly.
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 mpls,actions=set_field:10-\>mpls_label])
+AT_CHECK([ovs-ofctl -O OpenFlow10 dump-flows br0 | ofctl_strip], [0], [dnl
+NXST_FLOW reply:
+ mpls actions=load:0xa->OXM_OF_MPLS_LABEL[[]]
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP