Throw a state decision event if the clock quality changes.

Management messages can cause a change in the clock quality. If this
happens, then it is time to run the Best Master Clock algorithm again.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2013-07-07 21:27:32 +02:00
parent 12ab15818c
commit a367175b0d
3 changed files with 20 additions and 13 deletions

26
clock.c
View File

@ -305,7 +305,7 @@ out:
} }
static int clock_management_set(struct clock *c, struct port *p, static int clock_management_set(struct clock *c, struct port *p,
int id, struct ptp_message *req) int id, struct ptp_message *req, int *changed)
{ {
int respond = 0; int respond = 0;
struct management_tlv *tlv; struct management_tlv *tlv;
@ -324,6 +324,7 @@ static int clock_management_set(struct clock *c, struct port *p,
c->utc_offset = gsn->utc_offset; c->utc_offset = gsn->utc_offset;
c->time_flags = gsn->time_flags; c->time_flags = gsn->time_flags;
c->time_source = gsn->time_source; c->time_source = gsn->time_source;
*changed = 1;
respond = 1; respond = 1;
break; break;
} }
@ -791,9 +792,9 @@ static void clock_forward_mgmt_msg(struct clock *c, struct port *p, struct ptp_m
} }
} }
void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
{ {
int i; int changed = 0, i;
struct management_tlv *mgt; struct management_tlv *mgt;
struct ClockIdentity *tcid, wildcard = { struct ClockIdentity *tcid, wildcard = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
@ -805,10 +806,10 @@ void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
/* Apply this message to the local clock and ports. */ /* Apply this message to the local clock and ports. */
tcid = &msg->management.targetPortIdentity.clockIdentity; tcid = &msg->management.targetPortIdentity.clockIdentity;
if (!cid_eq(tcid, &wildcard) && !cid_eq(tcid, &c->dds.clockIdentity)) { if (!cid_eq(tcid, &wildcard) && !cid_eq(tcid, &c->dds.clockIdentity)) {
return; return changed;
} }
if (msg->tlv_count != 1) { if (msg->tlv_count != 1) {
return; return changed;
} }
mgt = (struct management_tlv *) msg->management.suffix; mgt = (struct management_tlv *) msg->management.suffix;
@ -821,24 +822,24 @@ void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
switch (management_action(msg)) { switch (management_action(msg)) {
case GET: case GET:
if (clock_management_get_response(c, p, mgt->id, msg)) if (clock_management_get_response(c, p, mgt->id, msg))
return; return changed;
break; break;
case SET: case SET:
if (mgt->length == 2 && mgt->id != NULL_MANAGEMENT) { if (mgt->length == 2 && mgt->id != NULL_MANAGEMENT) {
clock_management_send_error(p, msg, WRONG_LENGTH); clock_management_send_error(p, msg, WRONG_LENGTH);
return; return changed;
} }
if (clock_management_set(c, p, mgt->id, msg)) if (clock_management_set(c, p, mgt->id, msg, &changed))
return; return changed;
break; break;
case COMMAND: case COMMAND:
if (mgt->length != 2) { if (mgt->length != 2) {
clock_management_send_error(p, msg, WRONG_LENGTH); clock_management_send_error(p, msg, WRONG_LENGTH);
return; return changed;
} }
break; break;
default: default:
return; return changed;
} }
switch (mgt->id) { switch (mgt->id) {
@ -883,6 +884,7 @@ void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
} }
break; break;
} }
return changed;
} }
struct parent_ds *clock_parent_ds(struct clock *c) struct parent_ds *clock_parent_ds(struct clock *c)
@ -945,6 +947,8 @@ int clock_poll(struct clock *c)
k = N_CLOCK_PFD * i + j; k = N_CLOCK_PFD * i + j;
if (c->pollfd[k].revents & (POLLIN|POLLPRI)) { if (c->pollfd[k].revents & (POLLIN|POLLPRI)) {
event = port_event(c->port[i], j); event = port_event(c->port[i], j);
if (EV_STATE_DECISION_EVENT == event)
sde = 1;
} }
} }

View File

@ -120,8 +120,10 @@ void clock_install_fda(struct clock *c, struct port *p, struct fdarray fda);
* @param c The clock instance. * @param c The clock instance.
* @param p The port on which the message arrived. * @param p The port on which the message arrived.
* @param msg A management message. * @param msg A management message.
* @return One if the management action caused a change that
* implies a state decision event, zero otherwise.
*/ */
void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg); int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg);
/** /**
* Obtain a clock's parent data set. * Obtain a clock's parent data set.

3
port.c
View File

@ -1980,7 +1980,8 @@ enum fsm_event port_event(struct port *p, int fd_index)
case SIGNALING: case SIGNALING:
break; break;
case MANAGEMENT: case MANAGEMENT:
clock_manage(p->clock, p, msg); if (clock_manage(p->clock, p, msg))
event = EV_STATE_DECISION_EVENT;
break; break;
} }