mirror of
https://github.com/openvswitch/ovs
synced 2025-08-29 13:27:59 +00:00
ofp-util: Add OpenFlow 1.5 packet-out support
This patch implements the encoding and decoding of the new packet-out format defined in OpenFlow 1.5. Test cases are provided to verify the encoding and decoding. This patch is based on [1] and [2]. [1] https://github.com/jean2/openvswitch/commits/jean/ext-427 [2] https://mail.openvswitch.org/pipermail/ovs-dev/2017-April/331032.html Signed-off-by: Jean Tourrilhes <jt@labs.hpe.com> Signed-off-by: Zoltan Balogh <zoltan.balogh@ericsson.com> Co-authored-by: Jan Scheurich <jan.scheurich@ericsson.com> Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
parent
35eb6326d5
commit
577bfa9f68
@ -349,14 +349,6 @@ definitive as OpenFlow 1.5 is not yet published.
|
|||||||
|
|
||||||
(required for OF1.5+ if metering is supported)
|
(required for OF1.5+ if metering is supported)
|
||||||
|
|
||||||
* Enable setting all pipeline fields in packet-out
|
|
||||||
|
|
||||||
Prototype for OVS was done during specification.
|
|
||||||
|
|
||||||
(EXT-427)
|
|
||||||
|
|
||||||
(required for OF1.5+)
|
|
||||||
|
|
||||||
* Port properties for pipeline fields
|
* Port properties for pipeline fields
|
||||||
|
|
||||||
Prototype for OVS was done during specification.
|
Prototype for OVS was done during specification.
|
||||||
|
1
NEWS
1
NEWS
@ -42,6 +42,7 @@ Post-v2.7.0
|
|||||||
* Bundles now support hashing by just nw_src or nw_dst.
|
* Bundles now support hashing by just nw_src or nw_dst.
|
||||||
* The "learn" action now supports a "limit" option (see ovs-ofctl(8)).
|
* The "learn" action now supports a "limit" option (see ovs-ofctl(8)).
|
||||||
* The port status bit OFPPS_LIVE now reflects link aliveness.
|
* The port status bit OFPPS_LIVE now reflects link aliveness.
|
||||||
|
* OpenFlow 1.5 packet-out is now supported.
|
||||||
- Fedora Packaging:
|
- Fedora Packaging:
|
||||||
* OVN services are no longer restarted automatically after upgrade.
|
* OVN services are no longer restarted automatically after upgrade.
|
||||||
- Add --cleanup option to command 'ovs-appctl exit' (see ovs-vswitchd(8)).
|
- Add --cleanup option to command 'ovs-appctl exit' (see ovs-vswitchd(8)).
|
||||||
|
@ -150,4 +150,17 @@ struct ofp15_group_desc_stats {
|
|||||||
};
|
};
|
||||||
OFP_ASSERT(sizeof(struct ofp15_group_desc_stats) == 16);
|
OFP_ASSERT(sizeof(struct ofp15_group_desc_stats) == 16);
|
||||||
|
|
||||||
|
/* Send packet (controller -> datapath). */
|
||||||
|
struct ofp15_packet_out {
|
||||||
|
ovs_be32 buffer_id; /* ID assigned by datapath (-1 if none). */
|
||||||
|
ovs_be16 actions_len; /* Size of action array in bytes. */
|
||||||
|
uint8_t pad[2];
|
||||||
|
/* Followed by:
|
||||||
|
* - Match
|
||||||
|
* - List of actions
|
||||||
|
* - Packet data
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
OFP_ASSERT(sizeof(struct ofp15_packet_out) == 8);
|
||||||
|
|
||||||
#endif /* openflow/openflow-1.5.h */
|
#endif /* openflow/openflow-1.5.h */
|
||||||
|
@ -177,8 +177,10 @@ enum ofpraw {
|
|||||||
|
|
||||||
/* OFPT 1.0 (13): struct ofp10_packet_out, uint8_t[]. */
|
/* OFPT 1.0 (13): struct ofp10_packet_out, uint8_t[]. */
|
||||||
OFPRAW_OFPT10_PACKET_OUT,
|
OFPRAW_OFPT10_PACKET_OUT,
|
||||||
/* OFPT 1.1+ (13): struct ofp11_packet_out, uint8_t[]. */
|
/* OFPT 1.1-1.4 (13): struct ofp11_packet_out, uint8_t[]. */
|
||||||
OFPRAW_OFPT11_PACKET_OUT,
|
OFPRAW_OFPT11_PACKET_OUT,
|
||||||
|
/* OFPT 1.5+ (13): struct ofp15_packet_out, uint8_t[]. */
|
||||||
|
OFPRAW_OFPT15_PACKET_OUT,
|
||||||
|
|
||||||
/* OFPT 1.0 (14): struct ofp10_flow_mod, uint8_t[8][]. */
|
/* OFPT 1.0 (14): struct ofp10_flow_mod, uint8_t[8][]. */
|
||||||
OFPRAW_OFPT10_FLOW_MOD,
|
OFPRAW_OFPT10_FLOW_MOD,
|
||||||
@ -561,7 +563,8 @@ enum ofptype {
|
|||||||
|
|
||||||
/* Controller command messages. */
|
/* Controller command messages. */
|
||||||
OFPTYPE_PACKET_OUT, /* OFPRAW_OFPT10_PACKET_OUT.
|
OFPTYPE_PACKET_OUT, /* OFPRAW_OFPT10_PACKET_OUT.
|
||||||
* OFPRAW_OFPT11_PACKET_OUT. */
|
* OFPRAW_OFPT11_PACKET_OUT.
|
||||||
|
* OFPRAW_OFPT15_PACKET_OUT. */
|
||||||
OFPTYPE_FLOW_MOD, /* OFPRAW_OFPT10_FLOW_MOD.
|
OFPTYPE_FLOW_MOD, /* OFPRAW_OFPT10_FLOW_MOD.
|
||||||
* OFPRAW_OFPT11_FLOW_MOD.
|
* OFPRAW_OFPT11_FLOW_MOD.
|
||||||
* OFPRAW_NXT_FLOW_MOD. */
|
* OFPRAW_NXT_FLOW_MOD. */
|
||||||
|
@ -4205,7 +4205,27 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
|
|||||||
|
|
||||||
ofpbuf_clear(ofpacts);
|
ofpbuf_clear(ofpacts);
|
||||||
match_init_catchall(&po->flow_metadata);
|
match_init_catchall(&po->flow_metadata);
|
||||||
if (raw == OFPRAW_OFPT11_PACKET_OUT) {
|
if (raw == OFPRAW_OFPT15_PACKET_OUT) {
|
||||||
|
enum ofperr error;
|
||||||
|
const struct ofp15_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
|
||||||
|
|
||||||
|
po->buffer_id = ntohl(opo->buffer_id);
|
||||||
|
error = oxm_pull_match_loose(&b, NULL, &po->flow_metadata);
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!po->flow_metadata.wc.masks.in_port.ofp_port) {
|
||||||
|
return OFPERR_OFPBRC_BAD_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ofpacts_pull_openflow_actions(&b, ntohs(opo->actions_len),
|
||||||
|
oh->version, NULL, NULL,
|
||||||
|
ofpacts);
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
} else if (raw == OFPRAW_OFPT11_PACKET_OUT) {
|
||||||
enum ofperr error;
|
enum ofperr error;
|
||||||
ofp_port_t in_port;
|
ofp_port_t in_port;
|
||||||
const struct ofp11_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
|
const struct ofp11_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
|
||||||
@ -7065,9 +7085,7 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po,
|
|||||||
case OFP11_VERSION:
|
case OFP11_VERSION:
|
||||||
case OFP12_VERSION:
|
case OFP12_VERSION:
|
||||||
case OFP13_VERSION:
|
case OFP13_VERSION:
|
||||||
case OFP14_VERSION:
|
case OFP14_VERSION: {
|
||||||
case OFP15_VERSION:
|
|
||||||
case OFP16_VERSION: {
|
|
||||||
struct ofp11_packet_out *opo;
|
struct ofp11_packet_out *opo;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@ -7083,6 +7101,24 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OFP15_VERSION:
|
||||||
|
case OFP16_VERSION: {
|
||||||
|
struct ofp15_packet_out *opo;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* The final argument is just an estimate of the space required. */
|
||||||
|
msg = ofpraw_alloc(OFPRAW_OFPT15_PACKET_OUT, ofp_version,
|
||||||
|
size + NXM_TYPICAL_LEN);
|
||||||
|
ofpbuf_put_zeros(msg, sizeof *opo);
|
||||||
|
oxm_put_match(msg, &po->flow_metadata, ofp_version);
|
||||||
|
len = ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
|
||||||
|
ofp_version);
|
||||||
|
opo = msg->msg;
|
||||||
|
opo->buffer_id = htonl(po->buffer_id);
|
||||||
|
opo->actions_len = htons(len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
OVS_NOT_REACHED();
|
OVS_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -796,6 +796,27 @@ tcp,vlan_tci=0x0000,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,nw_src=192
|
|||||||
])
|
])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
AT_SETUP([OFPT_PACKET_OUT - OF1.5])
|
||||||
|
AT_KEYWORDS([ofp-print packet-out])
|
||||||
|
AT_CHECK([ovs-ofctl ofp-print "\
|
||||||
|
06 0d 00 30 11 22 33 44 ff ff ff 00 00 10 00 00 \
|
||||||
|
00 01 00 10 80 00 00 04 00 00 00 01 00 00 00 00 \
|
||||||
|
00 00 00 10 ff ff ff fb 05 dc 00 00 00 00 00 00 \
|
||||||
|
"], [0], [dnl
|
||||||
|
OFPT_PACKET_OUT (OF1.5) (xid=0x11223344): in_port=1 actions=FLOOD buffer=0xffffff00
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl missing in_port
|
||||||
|
AT_CHECK([ovs-ofctl ofp-print "\
|
||||||
|
06 0d 00 40 11 22 33 44 ff ff ff 00 00 10 00 00 \
|
||||||
|
00 01 00 20 80 00 04 08 00 00 00 00 00 00 00 03 \
|
||||||
|
80 00 4C 08 00 00 00 00 00 00 00 05 00 00 00 00 \
|
||||||
|
00 00 00 10 ff ff ff fb 05 dc 00 00 00 00 00 00 \
|
||||||
|
"], [0], [dnl
|
||||||
|
OFPT_PACKET_OUT (OF1.5) (xid=0x11223344): ***decode error: OFPBRC_BAD_PORT***
|
||||||
|
])
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
# The flow is formatted with cls_rule_format() for the low-verbosity case.
|
# The flow is formatted with cls_rule_format() for the low-verbosity case.
|
||||||
AT_SETUP([OFPT_FLOW_MOD - OF1.0 - low verbosity])
|
AT_SETUP([OFPT_FLOW_MOD - OF1.0 - low verbosity])
|
||||||
AT_KEYWORDS([ofp-print])
|
AT_KEYWORDS([ofp-print])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user