Some invalid ports (those above the maximum port number supported by the
datapath, including OpenFlow reserved ports that are not translated by OVS
into some other number) will be rejected by the datapath. It's better to
catch these early and send back an appropriate OpenFlow error code, rather
than to just get EINVAL from the kernel and have to guess at the problem.
Reported-by: Aaron Rosen <arosen@clemson.edu>
/* NXT_ROLE_REQUEST specified an invalid role. */
NXBRC_BAD_ROLE = 0x201,
/* NXT_ROLE_REQUEST specified an invalid role. */
NXBRC_BAD_ROLE = 0x201,
+
+ /* The in_port in an ofp_packet_out request is invalid. */
+ NXBRC_BAD_IN_PORT = 0x202
};
/* Additional "code" values for OFPET_FLOW_MOD_FAILED. */
};
/* Additional "code" values for OFPET_FLOW_MOD_FAILED. */
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
int error;
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
int error;
+ if (flow->in_port >= ofproto->max_ports && flow->in_port < OFPP_MAX) {
+ return ofp_mkerr_nicira(OFPET_BAD_REQUEST, NXBRC_BAD_IN_PORT);
+ }
+
error = validate_actions(ofp_actions, n_ofp_actions, flow,
ofproto->max_ports);
if (!error) {
error = validate_actions(ofp_actions, n_ofp_actions, flow,
ofproto->max_ports);
if (!error) {
struct ofpbuf request;
struct flow flow;
size_t n_ofp_actions;
struct ofpbuf request;
struct flow flow;
size_t n_ofp_actions;
int error;
COVERAGE_INC(ofproto_packet_out);
int error;
COVERAGE_INC(ofproto_packet_out);
+ /* Get in_port and partially validate it.
+ *
+ * We don't know what range of ports the ofproto actually implements, but
+ * we do know that only certain reserved ports (numbered OFPP_MAX and
+ * above) are valid. */
+ in_port = ntohs(opo->in_port);
+ if (in_port >= OFPP_MAX && in_port != OFPP_LOCAL && in_port != OFPP_NONE) {
+ return ofp_mkerr_nicira(OFPET_BAD_REQUEST, NXBRC_BAD_IN_PORT);
+ }
+
- flow_extract(&payload, 0, 0, ntohs(opo->in_port), &flow);
+ flow_extract(&payload, 0, 0, in_port, &flow);
error = p->ofproto_class->packet_out(p, &payload, &flow,
ofp_actions, n_ofp_actions);
ofpbuf_delete(buffer);
error = p->ofproto_class->packet_out(p, &payload, &flow,
ofp_actions, n_ofp_actions);
ofpbuf_delete(buffer);