Subscription time limit
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 <jbenc@redhat.com>
This commit is contained in:
		
							parent
							
								
									5104e3e56b
								
							
						
					
					
						commit
						0e8efe418c
					
				
							
								
								
									
										38
									
								
								clock.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								clock.c
									
									
									
									
									
								
							| @ -66,6 +66,7 @@ struct clock_subscriber { | ||||
| 	struct PortIdentity targetPortIdentity; | ||||
| 	struct address addr; | ||||
| 	UInteger16 sequenceId; | ||||
| 	time_t expiration; | ||||
| }; | ||||
| 
 | ||||
| struct clock { | ||||
| @ -134,10 +135,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, uint16_t duration) | ||||
| { | ||||
| 	struct clock_subscriber *s; | ||||
| 	int i, remove = 1; | ||||
| 	struct timespec now; | ||||
| 
 | ||||
| 	for (i = 0; i < EVENT_BITMASK_CNT; i++) { | ||||
| 		if (bitmask[i]) { | ||||
| @ -154,6 +156,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 + duration; | ||||
| 			} else { | ||||
| 				remove_subscriber(s); | ||||
| 			} | ||||
| @ -171,24 +175,33 @@ 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 + duration; | ||||
| 	s->sequenceId = 0; | ||||
| 	LIST_INSERT_HEAD(&c->subscribers, s, list); | ||||
| } | ||||
| 
 | ||||
| static void clock_get_subscription(struct clock *c, struct ptp_message *req, | ||||
| 				   uint8_t *bitmask) | ||||
| 				   uint8_t *bitmask, uint16_t *duration) | ||||
| { | ||||
| 	struct clock_subscriber *s; | ||||
| 	struct timespec now; | ||||
| 
 | ||||
| 	LIST_FOREACH(s, &c->subscribers, list) { | ||||
| 		if (!memcmp(&s->targetPortIdentity, &req->header.sourcePortIdentity, | ||||
| 			    sizeof(struct PortIdentity))) { | ||||
| 			memcpy(bitmask, s->events, EVENT_BITMASK_CNT); | ||||
| 			clock_gettime(CLOCK_MONOTONIC, &now); | ||||
| 			if (s->expiration < now.tv_sec) | ||||
| 				*duration = 0; | ||||
| 			else | ||||
| 				*duration = s->expiration - now.tv_sec; | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 	/* A client without entry means the client has no subscriptions. */ | ||||
| 	memset(bitmask, 0, EVENT_BITMASK_CNT); | ||||
| 	*duration = 0; | ||||
| } | ||||
| 
 | ||||
| static void clock_flush_subscriptions(struct clock *c) | ||||
| @ -200,6 +213,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) | ||||
| { | ||||
| @ -410,7 +438,7 @@ static int clock_management_get_response(struct clock *c, struct port *p, | ||||
| 			break; | ||||
| 		} | ||||
| 		sen = (struct subscribe_events_np *)tlv->data; | ||||
| 		clock_get_subscription(c, req, sen->bitmask); | ||||
| 		clock_get_subscription(c, req, sen->bitmask, &sen->duration); | ||||
| 		respond = 1; | ||||
| 		break; | ||||
| 	} | ||||
| @ -450,7 +478,8 @@ static int clock_management_set(struct clock *c, struct port *p, | ||||
| 		break; | ||||
| 	case SUBSCRIBE_EVENTS_NP: | ||||
| 		sen = (struct subscribe_events_np *)tlv->data; | ||||
| 		clock_update_subscription(c, req, sen->bitmask); | ||||
| 		clock_update_subscription(c, req, sen->bitmask, | ||||
| 					  sen->duration); | ||||
| 		respond = 1; | ||||
| 		break; | ||||
| 	} | ||||
| @ -1103,6 +1132,7 @@ int clock_poll(struct clock *c) | ||||
| 	if (sde) | ||||
| 		handle_state_decision_event(c); | ||||
| 
 | ||||
| 	clock_prune_subscriptions(c); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								tlv.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								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->duration = ntohs(sen->duration); | ||||
| 		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->duration = htons(sen->duration); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user