X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=ofproto%2Fofproto.c;h=d773c91cf80d6942481680f5cdd059ff4128e960;hb=27cafc5fc0869236b8cd696eef535eca879a0949;hp=5c9ab9d31540779d617d6c8e7a55028dd325347f;hpb=1c0333b6baf58cb382d78b53305bfb06149793e2;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 5c9ab9d3..d773c91c 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -390,6 +390,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, 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); @@ -422,6 +423,9 @@ ofproto_create(const char *datapath_name, const char *datapath_type, 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) { @@ -437,6 +441,24 @@ 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) { @@ -2103,6 +2125,10 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) 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) { @@ -2115,10 +2141,13 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) 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: @@ -3231,7 +3260,12 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) * 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) {