Add expiration time to subscriptions; they need to be renewed before they
expiry. This way, the subscription automatically times out when phc2sys is
killed.

Signed-off-by: Jiri Benc <jb...@redhat.com>
---
 clock.c |   27 +++++++++++++++++++++++++--
 tlv.c   |    8 ++++++++
 tlv.h   |    1 +
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/clock.c b/clock.c
index c66a04064ff8..29d58b0c2461 100644
--- a/clock.c
+++ b/clock.c
@@ -67,6 +67,7 @@ struct clock_subscriber {
        struct PortIdentity targetPortIdentity;
        struct address addr;
        UInteger16 sequenceId;
+       time_t expiration;
 };
 
 struct clock {
@@ -135,10 +136,11 @@ static void remove_subscriber(struct clock_subscriber *s)
 }
 
 static void clock_update_subscription(struct clock *c, struct ptp_message *req,
-                                     uint8_t *bitmask)
+                                     uint8_t *bitmask, unsigned int valid_time)
 {
        struct clock_subscriber *s;
        int i, remove = 1;
+       struct timespec now;
 
        for (i = 0; i < EVENT_BITMASK_CNT; i++) {
                if (bitmask[i]) {
@@ -155,6 +157,8 @@ static void clock_update_subscription(struct clock *c, 
struct ptp_message *req,
                        if (!remove) {
                                s->addr = req->address;
                                memcpy(s->events, bitmask, EVENT_BITMASK_CNT);
+                               clock_gettime(CLOCK_MONOTONIC, &now);
+                               s->expiration = now.tv_sec + valid_time;
                        } else {
                                remove_subscriber(s);
                        }
@@ -172,6 +176,8 @@ static void clock_update_subscription(struct clock *c, 
struct ptp_message *req,
        s->targetPortIdentity = req->header.sourcePortIdentity;
        s->addr = req->address;
        memcpy(s->events, bitmask, EVENT_BITMASK_CNT);
+       clock_gettime(CLOCK_MONOTONIC, &now);
+       s->expiration = now.tv_sec + valid_time;
        s->sequenceId = 0;
        LIST_INSERT_HEAD(&c->subscribers, s, list);
 }
@@ -185,6 +191,21 @@ static void clock_flush_subscriptions(struct clock *c)
        }
 }
 
+static void clock_prune_subscriptions(struct clock *c)
+{
+       struct clock_subscriber *s, *tmp;
+       struct timespec now;
+
+       clock_gettime(CLOCK_MONOTONIC, &now);
+       LIST_FOREACH_SAFE(s, &c->subscribers, list, tmp) {
+               if (s->expiration <= now.tv_sec) {
+                       pr_info("subscriber %s timed out",
+                               pid2str(&s->targetPortIdentity));
+                       remove_subscriber(s);
+               }
+       }
+}
+
 void clock_send_notification(struct clock *c, struct ptp_message *msg,
                             int msglen, enum notification event)
 {
@@ -443,7 +464,8 @@ static int clock_management_cmd_response(struct clock *c, 
struct port *p,
                        break;
                }
                sen = (struct subscribe_events_np *)tlv->data;
-               clock_update_subscription(c, req, sen->bitmask);
+               clock_update_subscription(c, req, sen->bitmask,
+                                         sen->valid_time);
                respond = 1;
                break;
        }
@@ -1108,6 +1130,7 @@ int clock_poll(struct clock *c)
        if (sde)
                handle_state_decision_event(c);
 
+       clock_prune_subscriptions(c);
        return 0;
 }
 
diff --git a/tlv.c b/tlv.c
index 430410f75397..60df3575b5f0 100644
--- a/tlv.c
+++ b/tlv.c
@@ -62,6 +62,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t 
data_len,
        struct port_ds_np *pdsnp;
        struct time_status_np *tsn;
        struct grandmaster_settings_np *gsn;
+       struct subscribe_events_np *sen;
        struct mgmt_clock_description *cd;
        int extra_len = 0, len;
        uint8_t *buf;
@@ -245,6 +246,8 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t 
data_len,
        case SUBSCRIBE_EVENTS_NP:
                if (data_len != sizeof(struct subscribe_events_np))
                        goto bad_length;
+               sen = (struct subscribe_events_np *)m->data;
+               sen->valid_time = ntohs(sen->valid_time);
                break;
        case SAVE_IN_NON_VOLATILE_STORAGE:
        case RESET_NON_VOLATILE_STORAGE:
@@ -277,6 +280,7 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
        struct port_ds_np *pdsnp;
        struct time_status_np *tsn;
        struct grandmaster_settings_np *gsn;
+       struct subscribe_events_np *sen;
        struct mgmt_clock_description *cd;
        switch (m->id) {
        case CLOCK_DESCRIPTION:
@@ -341,6 +345,10 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
                pdsnp->neighborPropDelayThresh = 
htonl(pdsnp->neighborPropDelayThresh);
                pdsnp->asCapable = htonl(pdsnp->asCapable);
                break;
+       case SUBSCRIBE_EVENTS_NP:
+               sen = (struct subscribe_events_np *)m->data;
+               sen->valid_time = htons(sen->valid_time);
+               break;
        }
 }
 
diff --git a/tlv.h b/tlv.h
index 10ed301fdc04..c383c822684b 100644
--- a/tlv.h
+++ b/tlv.h
@@ -201,6 +201,7 @@ struct port_ds_np {
 #define EVENT_BITMASK_CNT 32
 
 struct subscribe_events_np {
+       uint16_t      valid_time; /* seconds */
        uint8_t       bitmask[EVENT_BITMASK_CNT];
 } PACKED;
 
-- 
1.7.6.5


------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get 
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to