[ovs-dev] [PATCH 2/3] auto-attach: Add auto-attach support to ofproto layer

Flynn, Dennis R (Dennis) drflynn at avaya.com
Wed Oct 1 14:43:14 UTC 2014


diff --git a/lib/odp-util.h b/lib/odp-util.h
index 11b54dd..61b71b1 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -40,6 +40,7 @@ struct pkt_metadata;
     SPR(SLOW_BFD,        "bfd",        "Consists of BFD packets")       \
     SPR(SLOW_LACP,       "lacp",       "Consists of LACP packets")      \
     SPR(SLOW_STP,        "stp",        "Consists of STP packets")       \
+    SPR(SLOW_LLDP,       "lldp",       "Consists of LLDP packets")    \
     SPR(SLOW_CONTROLLER, "controller",                                  \
         "Sends \"packet-in\" messages to the OpenFlow controller")      \
     SPR(SLOW_ACTION,     "action",                                      \
diff --git a/ofproto/ofproto-dpif-monitor.c b/ofproto/ofproto-dpif-monitor.c
index 764c7b1..fd1f628 100644
--- a/ofproto/ofproto-dpif-monitor.c
+++ b/ofproto/ofproto-dpif-monitor.c
@@ -35,6 +35,10 @@
#include "util.h"
#include "vlog.h"

+#ifdef ENABLE_AUTO_ATTACH
+#include "ovs-lldp.h"
+#endif
+
VLOG_DEFINE_THIS_MODULE(ofproto_dpif_monitor);

 /* Converts the time in millisecond to heap priority. */
@@ -42,7 +46,7 @@ VLOG_DEFINE_THIS_MODULE(ofproto_dpif_monitor);
/* Converts the heap priority to time in millisecond. */
#define PRIO_TO_MSEC(PRIO) (LLONG_MAX - (PRIO))

-/* Monitored port.  It owns references to ofport, bfd, cfm structs. */
+/* Monitored port.  It owns references to ofport, bfd, cfm, and lldp structs. */
struct mport {
     struct hmap_node hmap_node;       /* In monitor_hmap. */
     struct heap_node heap_node;       /* In monitor_heap. */
@@ -50,6 +54,7 @@ struct mport {

     struct cfm *cfm;                  /* Reference to cfm. */
     struct bfd *bfd;                  /* Reference to bfd. */
+    struct lldp *lldp;                /* Reference to lldp. */
     uint8_t hw_addr[OFP_ETH_ALEN];    /* Hardware address. */
};

@@ -85,11 +90,18 @@ static void monitor_run(void);
static void monitor_mport_run(struct mport *, struct ofpbuf *);

 static void mport_register(const struct ofport_dpif *, struct bfd *,
-                           struct cfm *, uint8_t[ETH_ADDR_LEN])
+                           struct cfm *,
+#ifdef ENABLE_AUTO_ATTACH
+                           struct lldp *,
+#endif
+                           uint8_t[ETH_ADDR_LEN])
     OVS_REQUIRES(monitor_mutex);
static void mport_unregister(const struct ofport_dpif *)
     OVS_REQUIRES(monitor_mutex);
static void mport_update(struct mport *, struct bfd *, struct cfm *,
+#ifdef ENABLE_AUTO_ATTACH
+                         struct lldp *,
+#endif
                          uint8_t[ETH_ADDR_LEN]) OVS_REQUIRES(monitor_mutex);
static struct mport *mport_find(const struct ofport_dpif *)
     OVS_REQUIRES(monitor_mutex);
@@ -114,7 +126,11 @@ mport_find(const struct ofport_dpif *ofport) OVS_REQUIRES(monitor_mutex)
  * if it doesn't exist.  Otherwise, just updates its fields. */
static void
mport_register(const struct ofport_dpif *ofport, struct bfd *bfd,
+#ifdef ENABLE_AUTO_ATTACH
+               struct cfm *cfm, struct lldp *lldp, uint8_t *hw_addr)
+#else
                struct cfm *cfm, uint8_t *hw_addr)
+#endif
     OVS_REQUIRES(monitor_mutex)
{
     struct mport *mport = mport_find(ofport);
@@ -125,7 +141,11 @@ mport_register(const struct ofport_dpif *ofport, struct bfd *bfd,
         hmap_insert(&monitor_hmap, &mport->hmap_node, hash_pointer(ofport, 0));
         heap_insert(&monitor_heap, &mport->heap_node, 0);
     }
+#ifdef ENABLE_AUTO_ATTACH
+    mport_update(mport, bfd, cfm, lldp, hw_addr);
+#else
     mport_update(mport, bfd, cfm, hw_addr);
+#endif
}

 /* Removes mport from monitor_hmap and monitor_heap and frees it. */
@@ -136,7 +156,11 @@ mport_unregister(const struct ofport_dpif *ofport)
     struct mport *mport = mport_find(ofport);

     if (mport) {
+#ifdef ENABLE_AUTO_ATTACH
+        mport_update(mport, NULL, NULL, NULL, NULL);
+#else
         mport_update(mport, NULL, NULL, NULL);
+#endif
         hmap_remove(&monitor_hmap, &mport->hmap_node);
         heap_remove(&monitor_heap, &mport->heap_node);
         free(mport);
@@ -145,7 +169,10 @@ mport_unregister(const struct ofport_dpif *ofport)

 /* Updates the fields of an existing mport struct. */
static void
-mport_update(struct mport *mport, struct bfd *bfd, struct cfm *cfm,
+mport_update(struct mport *mport, struct bfd *bfd, struct cfm *cfm,
+#ifdef ENABLE_AUTO_ATTACH
+             struct lldp *lldp,
+#endif
              uint8_t hw_addr[ETH_ADDR_LEN]) OVS_REQUIRES(monitor_mutex)
{
     ovs_assert(mport);
@@ -158,12 +185,22 @@ mport_update(struct mport *mport, struct bfd *bfd, struct cfm *cfm,
         bfd_unref(mport->bfd);
         mport->bfd = bfd_ref(bfd);
     }
+#ifdef ENABLE_AUTO_ATTACH
+    if (mport->lldp != lldp) {
+        lldp_unref(mport->lldp);
+        mport->lldp = lldp_ref(lldp);
+    }
+#endif
     if (hw_addr && memcmp(mport->hw_addr, hw_addr, ETH_ADDR_LEN)) {
         memcpy(mport->hw_addr, hw_addr, ETH_ADDR_LEN);
     }
-    /* If bfd/cfm is added or reconfigured, move the mport on top of the heap
+    /* If bfd/cfm/lldp is added or reconfigured, move the mport on top of the heap
      * so that the monitor thread can run the mport next time it wakes up. */
+#ifdef ENABLE_AUTO_ATTACH
+    if (mport->bfd || mport->cfm || mport->lldp) {
+#else
     if (mport->bfd || mport->cfm) {
+#endif
         heap_change(&monitor_heap, &mport->heap_node, LLONG_MAX);
     }
}
@@ -270,6 +307,14 @@ monitor_mport_run(struct mport *mport, struct ofpbuf *packet)
         bfd_put_packet(mport->bfd, packet, mport->hw_addr);
         ofproto_dpif_send_packet(mport->ofport, packet);
     }
+#ifdef ENABLE_AUTO_ATTACH
+    if (mport->lldp && lldp_should_send_packet(mport->lldp)) {
+        ofpbuf_clear(packet);
+        lldp_put_packet(mport->lldp, packet, mport->hw_addr);
+        ofproto_dpif_send_packet(mport->ofport, packet);
+    }
+#endif
+
     if (mport->cfm) {
         cfm_run(mport->cfm);
         cfm_wait(mport->cfm);
@@ -278,9 +323,17 @@ monitor_mport_run(struct mport *mport, struct ofpbuf *packet)
         bfd_run(mport->bfd);
         bfd_wait(mport->bfd);
     }
+#ifdef ENABLE_AUTO_ATTACH
+    if (mport->lldp) {
+        lldp_wait(mport->lldp);
+    }
+#endif
     /* Computes the next wakeup time for this mport. */
     next_wake_time = MIN(bfd_wake_time(mport->bfd),
                          cfm_wake_time(mport->cfm));
+#ifdef ENABLE_AUTO_ATTACH
+    next_wake_time = MIN(next_wake_time,lldp_wake_time(mport->lldp));
+#endif
     heap_change(&monitor_heap, &mport->heap_node,
                 MSEC_TO_PRIO(next_wake_time));
}
@@ -293,13 +346,24 @@ monitor_mport_run(struct mport *mport, struct ofpbuf *packet)
void
ofproto_dpif_monitor_port_update(const struct ofport_dpif *ofport,
                                  struct bfd *bfd, struct cfm *cfm,
+#ifdef ENABLE_AUTO_ATTACH
+                                 struct lldp *lldp,
+#endif
                                  uint8_t hw_addr[ETH_ADDR_LEN])
{
     ovs_mutex_lock(&monitor_mutex);
+#ifdef ENABLE_AUTO_ATTACH
+    if (!cfm && !bfd && !lldp) {
+#else
     if (!cfm && !bfd) {
+#endif
         mport_unregister(ofport);
     } else {
+#ifdef ENABLE_AUTO_ATTACH
+        mport_register(ofport, bfd, cfm, lldp, hw_addr);
+#else
         mport_register(ofport, bfd, cfm, hw_addr);
+#endif
     }
     ovs_mutex_unlock(&monitor_mutex);

diff --git a/ofproto/ofproto-dpif-monitor.h b/ofproto/ofproto-dpif-monitor.h
index 2c466c2..3b2789a 100644
--- a/ofproto/ofproto-dpif-monitor.h
+++ b/ofproto/ofproto-dpif-monitor.h
@@ -22,12 +22,16 @@

 struct bfd;
struct cfm;
+struct lldp;
struct ofport_dpif;

 void ofproto_dpif_monitor_port_send_soon(const struct ofport_dpif *);

 void ofproto_dpif_monitor_port_update(const struct ofport_dpif *,
                                       struct bfd *, struct cfm *,
+#ifdef ENABLE_AUTO_ATTACH
+                                      struct lldp *,
+#endif
                                       uint8_t[OFP_ETH_ALEN]);

 #endif /* ofproto-dpif-monitor.h */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index ee8a22d..a1b9fa6 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -32,6 +32,11 @@
#include "lacp.h"
#include "learn.h"
#include "list.h"
+
+#ifdef ENABLE_AUTO_ATTACH
+#include "ovs-lldp.h"
+#endif
+
#include "mac-learning.h"
#include "mcast-snooping.h"
#include "meta-flow.h"
@@ -164,6 +169,9 @@ struct xport {

     struct cfm *cfm;                 /* CFM handle or null. */
     struct bfd *bfd;                 /* BFD handle or null. */
+#ifdef ENABLE_AUTO_ATTACH
+    struct lldp *lldp;               /* LLDP handle or null. */
+#endif
};

 struct xlate_ctx {
@@ -858,6 +866,9 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
                  struct ofport_dpif *ofport, ofp_port_t ofp_port,
                  odp_port_t odp_port, const struct netdev *netdev,
                  const struct cfm *cfm, const struct bfd *bfd,
+#ifdef ENABLE_AUTO_ATTACH
+                 const struct lldp *lldp,
+#endif
                  struct ofport_dpif *peer, int stp_port_no,
                  const struct rstp_port *rstp_port,
                  const struct ofproto_port_queue *qdscp_list, size_t n_qdscp,
@@ -885,6 +896,13 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
     xlate_xport_set(xport, odp_port, netdev, cfm, bfd, stp_port_no,
                     rstp_port, config, state, is_tunnel, may_enable);

+#ifdef ENABLE_AUTO_ATTACH
+    if (xport->lldp != lldp) {
+        lldp_unref(xport->lldp);
+        xport->lldp = lldp_ref(lldp);
+    }
+#endif
+
     if (xport->peer) {
         xport->peer->peer = NULL;
     }
@@ -945,6 +963,9 @@ xlate_xport_remove(struct xlate_cfg *xcfg, struct xport *xport)
     rstp_port_unref(xport->rstp_port);
     cfm_unref(xport->cfm);
     bfd_unref(xport->bfd);
+#ifdef ENABLE_AUTO_ATTACH
+    lldp_unref(xport->lldp);
+#endif
     free(xport);
}

@@ -2463,7 +2484,16 @@ process_special(struct xlate_ctx *ctx, const struct flow *flow,
                 : rstp_process_packet(xport, packet);
         }
         return SLOW_STP;
-    } else {
+    }
+#ifdef ENABLE_AUTO_ATTACH
+    else if (xport->lldp && lldp_should_process_flow(flow, wc)) {
+        if (packet) {
+            lldp_process_packet(xport->lldp, packet);
+        }
+        return SLOW_LLDP;
+    }
+#endif
+    else {
         return 0;
     }
}
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 5ef20b1..8c5be0d 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -15,6 +15,7 @@
#ifndef OFPROTO_DPIF_XLATE_H
#define OFPROTO_DPIF_XLATE_H 1

+#include <config.h>
#include "flow.h"
#include "meta-flow.h"
#include "odp-util.h"
@@ -23,6 +24,9 @@
#include "ofproto-dpif.h"
#include "ofproto.h"
#include "stp.h"
+#ifdef ENABLE_AUTO_ATTACH
+#include "ovs-lldp.h"
+#endif

 struct bfd;
struct bond;
@@ -166,8 +170,11 @@ void xlate_bundle_remove(struct ofbundle *);

 void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *,
                       struct ofport_dpif *, ofp_port_t, odp_port_t,
-                      const struct netdev *, const struct cfm *,
-                      const struct bfd *, struct ofport_dpif *peer,
+                      const struct netdev *, const struct cfm *, const struct bfd *,
+#ifdef ENABLE_AUTO_ATTACH
+                      const struct lldp *,
+#endif
+                      struct ofport_dpif *peer,
                       int stp_port_no,
                       const struct rstp_port *rstp_port,
                       const struct ofproto_port_queue *qdscp,
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 6a59098..19532a5 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -29,6 +29,9 @@
#include "connmgr.h"
#include "coverage.h"
#include "cfm.h"
+#ifdef ENABLE_AUTO_ATTACH
+#include "ovs-lldp.h"
+#endif
#include "dpif.h"
#include "dynamic-string.h"
#include "fail-open.h"
@@ -158,6 +161,9 @@ struct ofport_dpif {
     struct list bundle_node;    /* In struct ofbundle's "ports" list. */
     struct cfm *cfm;            /* Connectivity Fault Management, if any. */
     struct bfd *bfd;            /* BFD, if any. */
+#ifdef ENABLE_AUTO_ATTACH
+    struct lldp *lldp;          /* lldp, if any. */
+#endif
     bool may_enable;            /* May be enabled in bonds. */
     bool is_tunnel;             /* This port is a tunnel. */
     bool is_layer3;             /* This is a layer 3 port. */
@@ -638,8 +644,11 @@ type_run(const char *type)
                     : -1;
                 xlate_ofport_set(ofproto, ofport->bundle, ofport,
                                  ofport->up.ofp_port, ofport->odp_port,
-                                 ofport->up.netdev, ofport->cfm,
-                                 ofport->bfd, ofport->peer, stp_port,
+                                 ofport->up.netdev, ofport->cfm, ofport->bfd,
+#ifdef ENABLE_AUTO_ATTACH
+                                 ofport->lldp,
+#endif
+                                 ofport->peer, stp_port,
                                  ofport->rstp_port, ofport->qdscp,
                                  ofport->n_qdscp, ofport->up.pp.config,
                                  ofport->up.pp.state, ofport->is_tunnel,
@@ -1628,6 +1637,9 @@ port_construct(struct ofport *port_)
     port->bundle = NULL;
     port->cfm = NULL;
     port->bfd = NULL;
+#ifdef ENABLE_AUTO_ATTACH
+    port->lldp = NULL;
+#endif
     port->may_enable = false;
     port->stp_port = NULL;
     port->stp_state = STP_DISABLED;
@@ -1769,6 +1781,9 @@ port_modified(struct ofport *port_)
     }

     ofproto_dpif_monitor_port_update(port, port->bfd, port->cfm,
+#ifdef ENABLE_AUTO_ATTACH
+                                     port->lldp,
+#endif
                                      port->up.pp.hw_addr);

     if (port->is_tunnel && tnl_port_reconfigure(port, port->up.netdev,
@@ -1895,6 +1910,9 @@ set_cfm(struct ofport *ofport_, const struct cfm_settings *s)
     ofport->cfm = NULL;
out:
     ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
+#ifdef ENABLE_AUTO_ATTACH
+                                     ofport->lldp,
+#endif
                                      ofport->up.pp.hw_addr);
     return error;
}
@@ -1937,6 +1955,9 @@ set_bfd(struct ofport *ofport_, const struct smap *cfg)
         ofproto->backer->need_revalidate = REV_RECONFIGURE;
     }
     ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
+#ifdef ENABLE_AUTO_ATTACH
+                                     ofport->lldp,
+#endif
                                      ofport->up.pp.hw_addr);
     return 0;
}
@@ -1963,6 +1984,89 @@ get_bfd_status(struct ofport *ofport_, struct smap *smap)

     return ret;
}
+
+#ifdef ENABLE_AUTO_ATTACH
+static int
+set_lldp(struct ofport *ofport_,
+         const struct smap *cfg)
+{
+    struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
+    int error;
+
+    if (!ofport->lldp) {
+        struct ofproto_dpif *ofproto;
+
+        ofproto = ofproto_dpif_cast(ofport->up.ofproto);
+        ofproto->backer->need_revalidate = REV_RECONFIGURE;
+        ofport->lldp = lldp_create(ofport->up.netdev, ofport_->mtu, cfg);
+
+        if (ofport->lldp) {
+        } else {
+            /* If LLDP is not enabled, it won't be created. */
+            return 0;
+        }
+    }
+
+    if (ofport->lldp) {
+        if (lldp_configure(ofport->lldp)) {
+            ofproto_dpif_monitor_port_update(ofport,
+                                             ofport->bfd,
+                                             ofport->cfm,
+                                             ofport->lldp,
+                                             ofport->up.pp.hw_addr);
+            return 0;
+        }
+    }
+
+    error = EINVAL;
+    lldp_unref(ofport->lldp);
+    ofport->lldp = NULL;
+
+    return error;
+}
+
+static bool
+get_lldp_status(const struct ofport *ofport_,
+               struct lldp_status *status OVS_UNUSED)
+{
+    struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
+
+    return ofport->lldp ? true : false;
+}
+
+static int
+set_aa(struct ofproto *ofproto OVS_UNUSED,
+       const struct aa_settings *s)
+{
+    return aa_configure(s);
+}
+
+static int
+aa_mapping_set(struct ofproto *ofproto_ OVS_UNUSED, void *aux,
+               const struct aa_mapping_settings *s)
+{
+    return aa_mapping_register(aux, s);
+}
+
+static int
+aa_mapping_unset(struct ofproto *ofproto OVS_UNUSED, void *aux)
+{
+    return aa_mapping_unregister(aux);
+}
+
+static int
+aa_vlan_get_queued(struct ofproto *ofproto OVS_UNUSED, struct list **list)
+{
+    return aa_get_vlan_queued(list);
+}
+
+static unsigned int
+aa_vlan_get_queue_size(struct ofproto *ofproto OVS_UNUSED)
+{
+    return aa_get_vlan_queue_size();
+}
+#endif
+


 /* Spanning Tree. */

@@ -5411,6 +5515,15 @@ const struct ofproto_class ofproto_dpif_class = {
     set_cfm,
     cfm_status_changed,
     get_cfm_status,
+#ifdef ENABLE_AUTO_ATTACH
+    set_lldp,
+    get_lldp_status,
+    set_aa,
+    aa_mapping_set,
+    aa_mapping_unset,
+    aa_vlan_get_queued,
+    aa_vlan_get_queue_size,
+#endif
     set_bfd,
     bfd_status_changed,
     get_bfd_status,
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index de354ec..a4c0d19 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -55,6 +55,8 @@ struct ofputil_flow_mod;
struct bfd_cfg;
struct meter;
struct ofoperation;
+#ifdef ENABLE_AUTO_ATTACH
+#endif

 extern struct ovs_mutex ofproto_mutex;

@@ -1341,6 +1343,69 @@ struct ofproto_class {
     int (*get_cfm_status)(const struct ofport *ofport,
                           struct cfm_status *status);

+#ifdef ENABLE_AUTO_ATTACH
+    /* Configures LLDP on 'ofport'.
+     *
+     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+     * support LLDP, as does a null pointer. */
+    int (*set_lldp)(struct ofport *ofport, const struct smap *cfg);
+
+    /* Checks the status of LLDP configured on 'ofport'.  Returns true if the
+     * port's LLDP status was successfully stored into '*status'.  Returns false
+     * if the port did not have LLDP configured, in which case '*status' is
+     * indeterminate.
+     *
+     * The caller must provide and owns '*status', but it does not own and must
+     * not modify or free the array returned in 'status->rmps'. */
+    bool (*get_lldp_status)(const struct ofport *ofport,
+                            struct lldp_status *status);
+
+    /* Configures Auto Attach.
+     *
+     * If 'ofproto_aa_settings' is nonnull, configures Auto Attach according
+     * to its members.
+     *
+     * If 'ofproto_aa_settings' is null, removes any Auto Attach configuration.
+     */
+    int (*set_aa)(struct ofproto *ofproto,
+                  const struct aa_settings *s);
+
+    /* If 's' is nonnull, this function registers a mapping associated with
+     * client data pointer 'aux' in 'ofproto'.  If 'aux' is already registered
+    * then this function updates its configuration to 's'.  Otherwise, this
+    * function registers a new mapping.
+     *
+     * An implementation that does not support mapping at all may set
+     * it to NULL or return EOPNOTSUPP.  An implementation that supports
+     * only a subset of the functionality should implement what it can
+     * and return 0.
+     */
+    int (*aa_mapping_set)(struct ofproto *ofproto, void *aux,
+                          const struct aa_mapping_settings *s);
+
+    /* If 's' is nonnull, this function unregisters a mapping associated with
+     * client data pointer 'aux' in 'ofproto'.  If 'aux' is already registered
+    * then this function updates its configuration to 's'.  Otherwise, this
+    * function unregisters a new mapping.
+     *
+     * An implementation that does not support mapping at all may set
+     * it to NULL or return EOPNOTSUPP.  An implementation that supports
+     * only a subset of the functionality should implement what it can
+     * and return 0.
+     */
+    int (*aa_mapping_unset)(struct ofproto *ofproto, void *aux);
+
+    /*
+     * Returns the VLAN that has been added by Auto Attach.
+     */
+    int (*aa_vlan_get_queued)(struct ofproto *ofproto, struct list **list);
+
+    /*
+     * Returns the number of VLAN that have been changed by Auto Attach.
+     */
+    unsigned int (*aa_vlan_get_queue_size)(struct ofproto *ofproto);
+#endif
+
     /* Configures BFD on 'ofport'.
      *
      * If 'cfg' is NULL, or 'cfg' does not contain the key value pair
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 7b1d478..14d78f0 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1020,6 +1020,85 @@ ofproto_port_set_queues(struct ofproto *ofproto, ofp_port_t ofp_port,
             : EOPNOTSUPP);
}


+/* LLDP configuration. */
+#ifdef ENABLE_AUTO_ATTACH
+void
+ofproto_port_set_lldp(struct ofproto *ofproto,
+                      ofp_port_t ofp_port,
+                      const struct smap *cfg)
+{
+    struct ofport *ofport;
+    int error;
+
+    ofport = ofproto_get_port(ofproto, ofp_port);
+    if (!ofport) {
+        VLOG_WARN("%s: cannot configure LLDP on nonexistent port %"PRIu16,
+                  ofproto->name, ofp_port);
+        return;
+    }
+    error = (ofproto->ofproto_class->set_lldp
+             ? ofproto->ofproto_class->set_lldp(ofport, cfg)
+             : EOPNOTSUPP);
+    if (error) {
+        VLOG_WARN("%s: lldp configuration on port %"PRIu16" (%s) failed (%s)",
+                  ofproto->name, ofp_port, netdev_get_name(ofport->netdev),
+                  ovs_strerror(error));
+    }
+}
+
+int
+ofproto_set_aa(struct ofproto *ofproto, void *aux OVS_UNUSED,
+               const struct aa_settings *s)
+{
+    if (!ofproto->ofproto_class->set_aa) {
+        return EOPNOTSUPP;
+    }
+    ofproto->ofproto_class->set_aa(ofproto, s);
+    return 0;
+}
+
+int
+ofproto_aa_mapping_register(struct ofproto *ofproto, void *aux,
+                            const struct aa_mapping_settings *s)
+{
+    if (!ofproto->ofproto_class->aa_mapping_set) {
+        return EOPNOTSUPP;
+    }
+    ofproto->ofproto_class->aa_mapping_set(ofproto, aux, s);
+    return 0;
+}
+
+int
+ofproto_aa_mapping_unregister(struct ofproto *ofproto, void *aux)
+{
+    if (!ofproto->ofproto_class->aa_mapping_unset) {
+        return EOPNOTSUPP;
+    }
+    ofproto->ofproto_class->aa_mapping_unset(ofproto, aux);
+    return 0;
+}
+
+int
+ofproto_aa_vlan_get_queued(struct ofproto *ofproto,
+                           struct list **list)
+{
+    if (!ofproto->ofproto_class->aa_vlan_get_queued) {
+        return EOPNOTSUPP;
+    }
+    ofproto->ofproto_class->aa_vlan_get_queued(ofproto, list);
+    return 0;
+}
+
+unsigned int
+ofproto_aa_vlan_get_queue_size(struct ofproto *ofproto)
+{
+    if (!ofproto->ofproto_class->aa_vlan_get_queue_size) {
+        return EOPNOTSUPP;
+    }
+    return ofproto->ofproto_class->aa_vlan_get_queue_size(ofproto);
+}
+#endif
+
/* Connectivity Fault Management configuration. */

 /* Clears the CFM configuration from 'ofp_port' on 'ofproto'. */
@@ -1185,7 +1264,8 @@ ofproto_mirror_unregister(struct ofproto *ofproto, void *aux)
/* Retrieves statistics from mirror associated with client data pointer
  * 'aux' in 'ofproto'.  Stores packet and byte counts in 'packets' and
  * 'bytes', respectively.  If a particular counters is not supported,
- * the appropriate argument is set to UINT64_MAX. */
+ * the appropriate argument is set to UINT64_MAX.
+ */
int
ofproto_mirror_get_stats(struct ofproto *ofproto, void *aux,
                          uint64_t *packets, uint64_t *bytes)
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index d60b198..9ce22c3 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -45,6 +45,14 @@ struct ofport;
struct ofproto;
struct shash;
struct simap;
+struct smap;
+struct netdev_stats;
+#ifdef ENABLE_AUTO_ATTACH
+struct list;
+struct lldp_status;
+struct aa_settings;
+struct aa_mapping_settings;
+#endif

 /* Needed for the lock annotations. */
extern struct ovs_mutex ofproto_mutex;
@@ -421,6 +429,19 @@ int ofproto_mirror_unregister(struct ofproto *, void *aux);
int ofproto_mirror_get_stats(struct ofproto *, void *aux,
                              uint64_t *packets, uint64_t *bytes);

+#ifdef ENABLE_AUTO_ATTACH
+void ofproto_port_set_lldp(struct ofproto *ofproto, ofp_port_t ofp_port,
+                           const struct smap *cfg);
+int ofproto_set_aa(struct ofproto *ofproto, void *aux,
+                   const struct aa_settings *s);
+int ofproto_aa_mapping_register(struct ofproto *ofproto, void *aux,
+                             const struct aa_mapping_settings *s);
+int ofproto_aa_mapping_unregister(struct ofproto *ofproto, void *aux);
+int ofproto_aa_vlan_get_queued(struct ofproto *ofproto,
+                               struct list **list);
+unsigned int ofproto_aa_vlan_get_queue_size(struct ofproto *ofproto);
+#endif
+
int ofproto_set_flood_vlans(struct ofproto *, unsigned long *flood_vlans);
bool ofproto_is_mirror_output_bundle(const struct ofproto *, void *aux);

--
1.7.12.4






More information about the dev mailing list