static void ofport_destroy__(struct ofport *);
static void ofport_destroy(struct ofport *);
-static int rule_create(struct ofproto *, const struct cls_rule *,
+static int rule_create(struct ofproto *,
+ const struct cls_rule *, uint8_t table_id,
const union ofp_action *, size_t n_actions,
uint16_t idle_timeout, uint16_t hard_timeout,
ovs_be64 flow_cookie, bool send_flow_removed,
{
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
if (ofport && ofproto->ofproto_class->set_cfm) {
- ofproto->ofproto_class->set_cfm(ofport, NULL, NULL, 0);
+ ofproto->ofproto_class->set_cfm(ofport, NULL);
}
}
/* Configures connectivity fault management on 'ofp_port' in 'ofproto'. Takes
- * basic configuration from the configuration members in 'cfm', and the set of
- * remote maintenance points from the 'n_remote_mps' elements in 'remote_mps'.
- * Ignores the statistics members of 'cfm'.
+ * basic configuration from the configuration members in 'cfm', and the remote
+ * maintenance point ID from remote_mpid. Ignores the statistics members of
+ * 'cfm'.
*
* This function has no effect if 'ofproto' does not have a port 'ofp_port'. */
void
ofproto_port_set_cfm(struct ofproto *ofproto, uint16_t ofp_port,
- const struct cfm *cfm,
- const uint16_t *remote_mps, size_t n_remote_mps)
+ const struct cfm_settings *s)
{
struct ofport *ofport;
int error;
return;
}
+ /* XXX: For configuration simplicity, we only support one remote_mpid
+ * outside of the CFM module. It's not clear if this is the correct long
+ * term solution or not. */
error = (ofproto->ofproto_class->set_cfm
- ? ofproto->ofproto_class->set_cfm(ofport, cfm,
- remote_mps, n_remote_mps)
+ ? ofproto->ofproto_class->set_cfm(ofport, s)
: EOPNOTSUPP);
if (error) {
VLOG_WARN("%s: CFM configuration on port %"PRIu16" (%s) failed (%s)",
}
}
-/* Returns the connectivity fault management object associated with 'ofp_port'
- * within 'ofproto', or a null pointer if 'ofproto' does not have a port
- * 'ofp_port' or if that port does not have CFM configured. The caller must
- * not modify or destroy the returned object. */
-const struct cfm *
-ofproto_port_get_cfm(struct ofproto *ofproto, uint16_t ofp_port)
-{
- struct ofport *ofport;
- const struct cfm *cfm;
-
- ofport = ofproto_get_port(ofproto, ofp_port);
- return (ofport
- && ofproto->ofproto_class->get_cfm
- && !ofproto->ofproto_class->get_cfm(ofport, &cfm)) ? cfm : NULL;
-}
-
/* Checks the status of LACP negotiation for 'ofp_port' within ofproto.
* Returns 1 if LACP partner information for 'ofp_port' is up-to-date,
* 0 if LACP partner information is not current (generally indicating a
const union ofp_action *actions, size_t n_actions)
{
struct rule *rule;
- rule_create(p, cls_rule, actions, n_actions, 0, 0, 0, false, &rule);
+ rule_create(p, cls_rule, 0, actions, n_actions, 0, 0, 0, false, &rule);
}
/* Searches for a rule with matching criteria exactly equal to 'target' in
struct ofport *port = ofproto_get_port(ofproto, ofp_port);
if (port) {
if (port->ofproto->ofproto_class->set_cfm) {
- port->ofproto->ofproto_class->set_cfm(port, NULL, NULL, 0);
+ port->ofproto->ofproto_class->set_cfm(port, NULL);
}
if (port->ofproto->ofproto_class->bundle_remove) {
port->ofproto->ofproto_class->bundle_remove(port);
* flow table, and stores the new rule into '*rulep'. Returns 0 on success,
* otherwise a positive errno value or OpenFlow error code. */
static int
-rule_create(struct ofproto *ofproto, const struct cls_rule *cls_rule,
+rule_create(struct ofproto *ofproto,
+ const struct cls_rule *cls_rule, uint8_t table_id,
const union ofp_action *actions, size_t n_actions,
uint16_t idle_timeout, uint16_t hard_timeout,
ovs_be64 flow_cookie, bool send_flow_removed,
struct rule *rule;
int error;
+ if (table_id == 0xff) {
+ if (ofproto->n_tables > 1) {
+ error = ofproto->ofproto_class->rule_choose_table(ofproto,
+ cls_rule,
+ &table_id);
+ if (error) {
+ return error;
+ }
+ assert(table_id < ofproto->n_tables);
+ } else {
+ table_id = 0;
+ }
+ }
+
rule = ofproto->ofproto_class->rule_alloc();
if (!rule) {
error = ENOMEM;
rule->ofproto = ofproto;
rule->cr = *cls_rule;
+ rule->table_id = table_id;
rule->flow_cookie = flow_cookie;
rule->created = time_msec();
rule->idle_timeout = idle_timeout;
ofproto->ofproto_class->get_netflow_ids(ofproto, engine_type, engine_id);
}
+/* Checks the fault status of CFM for 'ofp_port' within 'ofproto'. Returns 1
+ * if CFM is faulted (generally indiciating a connectivity problem), 0 if CFM
+ * is not faulted, and -1 if CFM is not enabled on 'ofp_port'. */
+int
+ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port)
+{
+ struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
+ return (ofport && ofproto->ofproto_class->get_cfm_fault
+ ? ofproto->ofproto_class->get_cfm_fault(ofport)
+ : -1);
+}
+
static void
query_aggregate_stats(struct ofproto *ofproto, struct cls_rule *target,
ovs_be16 out_port, uint8_t table_id,
}
buf_err = ofconn_pktbuf_retrieve(ofconn, fm->buffer_id, &packet, &in_port);
- error = rule_create(p, &fm->cr, fm->actions, fm->n_actions,
+ error = rule_create(p, &fm->cr, fm->table_id, fm->actions, fm->n_actions,
fm->idle_timeout, fm->hard_timeout, fm->cookie,
fm->flags & OFPFF_SEND_FLOW_REM, &rule);
if (error) {