X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=ofproto%2Fofproto.c;h=d773c91cf80d6942481680f5cdd059ff4128e960;hb=548de4ddb3efed9b7e5e543fec636ae5f077eda7;hp=8c10f19a14463002223beef9330f47850d208287;hpb=fa2bad0ffc080ba8751421bdc2465f883d26e8bc;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 8c10f19a..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: @@ -2594,7 +2623,7 @@ ofproto_get_netflow_ids(const struct ofproto *ofproto, /* Checks the fault status of CFM for 'ofp_port' within 'ofproto'. Returns a * bitmask of 'cfm_fault_reason's to indicate a CFM fault (generally * indicating a connectivity problem). Returns zero if CFM is not faulted, - * and -1 if CFM is not enabled on 'port'. */ + * and -1 if CFM is not enabled on 'ofp_port'. */ int ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port) { @@ -2604,6 +2633,19 @@ ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port) : -1); } +/* Checks the operational status reported by the remote CFM endpoint of + * 'ofp_port' Returns 1 if operationally up, 0 if operationally down, and -1 + * if CFM is not enabled on 'ofp_port' or does not support operational status. + */ +int +ofproto_port_get_cfm_opup(const struct ofproto *ofproto, uint16_t ofp_port) +{ + struct ofport *ofport = ofproto_get_port(ofproto, ofp_port); + return (ofport && ofproto->ofproto_class->get_cfm_opup + ? ofproto->ofproto_class->get_cfm_opup(ofport) + : -1); +} + /* Gets the MPIDs of the remote maintenance points broadcasting to 'ofp_port' * within 'ofproto'. Populates 'rmps' with an array of MPIDs owned by * 'ofproto', and 'n_rmps' with the number of MPIDs in 'rmps'. Returns a @@ -3218,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) {