return error;
}
+static int
+vport_get_status(const struct ofport *ofport_, char **errp)
+{
+ struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
+ char *peer_name;
+
+ if (!netdev_vport_is_patch(ofport->up.netdev) || ofport->peer) {
+ return 0;
+ }
+
+ peer_name = netdev_vport_patch_peer(ofport->up.netdev);
+ if (!peer_name) {
+ return 0;
+ }
+ *errp = xasprintf("No usable peer '%s' exists in '%s' datapath.",
+ peer_name, ofport->up.ofproto->type);
+ free(peer_name);
+ return EINVAL;
+}
+
static int
port_get_lacp_stats(const struct ofport *ofport_, struct lacp_slave_stats *stats)
{
port_del,
port_set_config,
port_get_stats,
+ vport_get_status,
port_dump_start,
port_dump_next,
port_dump_done,
int (*port_get_stats)(const struct ofport *port,
struct netdev_stats *stats);
+ /* Get status of the virtual port (ex. tunnel, patch).
+ *
+ * Returns '0' if 'port' is not a virtual port or has no errors.
+ * Otherwise, stores the error string in '*errp' and returns positive errno
+ * value. The caller is responsible for freeing '*errp' (with free()).
+ *
+ * This function may be a null pointer if the ofproto implementation does
+ * not support any virtual ports or their states.
+ */
+ int (*vport_get_status)(const struct ofport *port, char **errp);
+
/* Port iteration functions.
*
* The client might not be entirely in control of the ports within an
return error;
}
+int
+ofproto_vport_get_status(const struct ofproto *ofproto, ofp_port_t ofp_port,
+ char **errp)
+{
+ struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
+
+ return (ofport && ofproto->ofproto_class->vport_get_status)
+ ? ofproto->ofproto_class->vport_get_status(ofport, errp)
+ : EOPNOTSUPP;
+}
+
static int
update_port(struct ofproto *ofproto, const char *name)
{
const struct smap *cfg);
int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
+int ofproto_vport_get_status(const struct ofproto *, ofp_port_t ofp_port,
+ char **errp);
+
int ofproto_port_query_by_name(const struct ofproto *, const char *devname,
struct ofproto_port *);
iface_refresh_ofproto_status(struct iface *iface)
{
int current;
+ int error;
+ char *errp = NULL;
if (iface_is_synthetic(iface)) {
return;
}
+ error = ofproto_vport_get_status(iface->port->bridge->ofproto,
+ iface->ofp_port, &errp);
+ if (error && error != EOPNOTSUPP) {
+ /* Need to verify to avoid race with transaction from
+ * 'bridge_reconfigure' that clears errors explicitly. */
+ ovsrec_interface_verify_error(iface->cfg);
+ ovsrec_interface_set_error(iface->cfg,
+ errp ? errp : ovs_strerror(error));
+ free(errp);
+ }
+
current = ofproto_port_is_lacp_current(iface->port->bridge->ofproto,
iface->ofp_port);
if (current >= 0) {