This cleans up the CFM library a bit by pushing logic into the
packets library.
---
 lib/cfm.c     |   23 ++++++-----------------
 lib/packets.c |   27 +++++++++++++++++++++++++++
 lib/packets.h |    4 ++++
 3 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/lib/cfm.c b/lib/cfm.c
index d618dc5..aeb7144 100644
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -365,36 +365,29 @@ cfm_should_process_flow(const struct flow *flow)
 void
 cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p)
 {
-    struct ccm *ccm;
     uint16_t ccm_mpid;
     uint32_t ccm_seq;
     uint8_t ccm_interval;
+    const uint8_t *ccm_maid;
     struct remote_mp *rmp;
 
     struct cfm_internal *cfmi        = cfm_to_internal(cfm);
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
 
-    ccm = ofpbuf_at(p, (uint8_t *)p->l3 - (uint8_t *)p->data, CCM_LEN);
 
-    if (!ccm) {
+    if (!parse_ccm(p, &ccm_mpid, &ccm_maid, &ccm_interval, &ccm_seq)) {
         VLOG_INFO_RL(&rl, "Received an un-parseable 802.1ag CCM heartbeat.");
         return;
     }
 
-    if (ccm->opcode != 1) {
-        VLOG_INFO_RL(&rl, "Received an unsupported 802.1ag message. "
-                     "(opcode %u)", ccm->opcode);
-        return;
-    }
-
-    if (memcmp(ccm->maid, cfm->maid, sizeof ccm->maid)) {
+    if (memcmp(ccm_maid, cfm->maid, CCM_MAID_LEN)) {
         uint32_t hash;
         struct remote_maid *rmaid;
 
-        hash = hash_bytes(ccm->maid, sizeof ccm->maid, 0);
+        hash = hash_bytes(ccm_maid, CCM_MAID_LEN, 0);
 
         HMAP_FOR_EACH_IN_BUCKET (rmaid, node, hash, &cfm->x_remote_maids) {
-            if (memcmp(rmaid->maid, ccm->maid, sizeof rmaid->maid) == 0) {
+            if (memcmp(rmaid->maid, ccm_maid, sizeof rmaid->maid) == 0) {
                 rmaid->recv_time = time_msec();
                 return;
             }
@@ -402,15 +395,11 @@ cfm_process_heartbeat(struct cfm *cfm, const struct 
ofpbuf *p)
 
         rmaid            = xzalloc(sizeof *rmaid);
         rmaid->recv_time = time_msec();
-        memcpy(rmaid->maid, ccm->maid, sizeof rmaid->maid);
+        memcpy(rmaid->maid, ccm_maid, sizeof rmaid->maid);
         hmap_insert(&cfm->x_remote_maids, &rmaid->node, hash);
         return;
     }
 
-    ccm_mpid     = ntohs(ccm->mpid);
-    ccm_seq      = ntohl(ccm->seq);
-    ccm_interval = ccm->flags & 0x7;
-
     rmp = lookup_remote_mp(&cfm->remote_mps, ccm_mpid);
 
     if (!rmp) {
diff --git a/lib/packets.c b/lib/packets.c
index 8c8f79c..530b31b 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -241,6 +241,33 @@ compose_ccm(uint16_t mpid, uint8_t maid[CCM_MAID_LEN],
     memset(ccm->zero, 0, 16);
 }
 
+/* Given an ofpbuf 'b', parses the ccm message contained within.  If 'b' is not
+ * parseable, returns false.  Otherwise returns true and populates the given
+ * parameters with the parsed values.  'b' must have it's header pointers
+ * populated. */
+bool
+parse_ccm(const struct ofpbuf *b, uint16_t *mpid, const uint8_t **maid,
+          uint8_t *interval, uint32_t *seq)
+{
+    const struct ccm *ccm;
+
+    ccm = ofpbuf_at(b, (uint8_t *)b->l3 - (uint8_t *)b->data, CCM_LEN);
+
+    if (ccm && ccm->opcode == 1) {
+        *mpid = ntohs(ccm->mpid);
+        *maid = ccm->maid;
+        *seq = ntohl(ccm->seq);
+        *interval = ccm->flags & 0x7;
+        return true;
+    } else {
+        *mpid = 0;
+        *maid = NULL;
+        *interval = 0;
+        *seq = 0;
+        return false;
+    }
+}
+
 /* Populates 'pdu' with a LACP PDU comprised of 'actor' and 'partner'. */
 void
 compose_lacp_pdu(const struct lacp_info *actor,
diff --git a/lib/packets.h b/lib/packets.h
index 3134fb8..dd91e9d 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -424,6 +424,10 @@ void
 compose_ccm(uint16_t mpid, uint8_t maid[CCM_MAID_LEN],
             uint8_t interval, uint32_t seq, struct ccm *);
 
+bool
+parse_ccm(const struct ofpbuf *, uint16_t *mpid, const uint8_t **maid,
+          uint8_t *interval, uint32_t *seq);
+
 /* Masks for lacp_info state member. */
 #define LACP_STATE_ACT  0x01 /* Activity. Active or passive? */
 #define LACP_STATE_TIME 0x02 /* Timeout. Short or long timeout? */
-- 
1.7.4.1

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to