ofproto->frag_handling = OFPC_FRAG_NORMAL;
hmap_init(&ofproto->ports);
shash_init(&ofproto->port_by_name);
+ ofproto->max_ports = OFPP_MAX;
ofproto->tables = NULL;
ofproto->n_tables = 0;
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
return 0;
}
+/* Must be called (only) by an ofproto implementation in its constructor
+ * function. See the large comment on 'construct' in struct ofproto_class for
+ * details. */
void
ofproto_init_tables(struct ofproto *ofproto, int n_tables)
{
}
}
+/* To be optionally called (only) by an ofproto implementation in its
+ * constructor function. See the large comment on 'construct' in struct
+ * ofproto_class for details.
+ *
+ * Sets the maximum number of ports to 'max_ports'. The ofproto generic layer
+ * will then ensure that actions passed into the ofproto implementation will
+ * not refer to OpenFlow ports numbered 'max_ports' or higher. If this
+ * function is not called, there will be no such restriction.
+ *
+ * Reserved ports numbered OFPP_MAX and higher are special and not subject to
+ * the 'max_ports' restriction. */
+void
+ofproto_init_max_ports(struct ofproto *ofproto, uint16_t max_ports)
+{
+ assert(max_ports <= OFPP_MAX);
+ ofproto->max_ports = max_ports;
+}
+
uint64_t
ofproto_get_datapath_id(const struct ofproto *ofproto)
{
if (error) {
goto exit_free_ofpacts;
}
+ if (po.in_port >= p->max_ports && po.in_port < OFPP_MAX) {
+ error = OFPERR_NXBRC_BAD_IN_PORT;
+ goto exit_free_ofpacts;
+ }
/* Get payload. */
if (po.buffer_id != UINT32_MAX) {
ofpbuf_use_const(payload, po.packet, po.packet_len);
}
- /* Send out packet. */
+ /* Verify actions against packet, then send packet if successful. */
flow_extract(payload, 0, 0, po.in_port, &flow);
- error = p->ofproto_class->packet_out(p, payload, &flow,
- po.ofpacts, po.ofpacts_len);
+ error = ofpacts_check(po.ofpacts, po.ofpacts_len, &flow, p->max_ports);
+ if (!error) {
+ error = p->ofproto_class->packet_out(p, payload, &flow,
+ po.ofpacts, po.ofpacts_len);
+ }
ofpbuf_delete(payload);
exit_free_ofpacts:
* dropped from OpenFlow in the near future. There is no good error
* code, so just state that the flow table is full. */
error = OFPERR_OFPFMFC_ALL_TABLES_FULL;
- } else {
+ }
+ if (!error) {
+ error = ofpacts_check(fm.ofpacts, fm.ofpacts_len,
+ &fm.cr.flow, ofproto->max_ports);
+ }
+ if (!error) {
error = handle_flow_mod__(ofconn_get_ofproto(ofconn), ofconn, &fm, oh);
}
if (error) {