existing code assumed only one tlv was attached to management messages - a management tlv that started at management.suffix. If an authentication tlv is attached, these checks fail as there are now two tlvs.
In addition, it is conceivable that the management tlv is attached after the authentication tlv, to fix this, use the tailq to search for the management tlv instead of assuming suffix is the beginning of the management tlv. Signed-off-by: Clay Kaiser <clay.kai...@ibm.com> --- clock.c | 20 +++++++++++++------- msg.h | 26 ++++++++++++++++++++++++-- pmc.c | 8 ++++---- pmc_agent.c | 8 +++++--- pmc_common.c | 23 +++++++++++++++++++++++ pmc_common.h | 2 ++ port.c | 6 +++--- 7 files changed, 74 insertions(+), 19 deletions(-) diff --git a/clock.c b/clock.c index 785384b..9f454d2 100644 --- a/clock.c +++ b/clock.c @@ -198,8 +198,7 @@ static int clock_alttime_offset_append(struct clock *c, int key, struct ptp_mess uint8_t clock_alttime_offset_get_key(struct ptp_message *req) { struct management_tlv_datum *mtd; - struct management_tlv *mgt = - (struct management_tlv *) req->management.suffix; + struct management_tlv *mgt = management_tlv_get(req); /* * The data field of incoming management request messages is @@ -628,7 +627,7 @@ static int clock_management_set(struct clock *c, struct port *p, struct management_tlv *tlv; int k, key, respond = 0; - tlv = (struct management_tlv *) req->management.suffix; + tlv = management_tlv_get(req); switch (id) { case MID_PRIORITY1: @@ -1624,8 +1623,9 @@ tmv_t clock_ingress_time(struct clock *c) int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) { - int changed = 0, res, answers; + int changed = 0, res, answers, count = 0; struct port *piter; + struct tlv_extra *extra; struct management_tlv *mgt; struct ClockIdentity *tcid, wildcard = { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -1639,10 +1639,16 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) if (!cid_eq(tcid, &wildcard) && !cid_eq(tcid, &c->dds.clockIdentity)) { return changed; } - if (msg_tlv_count(msg) != 1) { - return changed; + + TAILQ_FOREACH(extra, &msg->tlv_list, list) { + if (extra->tlv->type != TLV_AUTHENTICATION) + count++; } - mgt = (struct management_tlv *) msg->management.suffix; + if (count != 1) + return changed; + mgt = management_tlv_get(msg); + if (!mgt) + return changed; /* The correct length according to the management ID is checked diff --git a/msg.h b/msg.h index 0b4c5f0..54baa10 100644 --- a/msg.h +++ b/msg.h @@ -249,6 +249,24 @@ static inline uint8_t management_action(struct ptp_message *m) return m->management.flags & 0x0f; } +/** + * Obtain the first management TLV from management message. + * @param m A management message. + * @return A pointer to the first management TLV. + */ +static inline struct management_tlv *management_tlv_get(struct ptp_message *msg) +{ + struct tlv_extra *extra; + TAILQ_FOREACH(extra, &msg->tlv_list, list) { + switch(extra->tlv->type) { + case TLV_MANAGEMENT: + case TLV_MANAGEMENT_ERROR_STATUS: + return (struct management_tlv *) extra->tlv; + } + } + return NULL; +} + /** * Obtain the data field from the TLV in a management message. * @param m A management message. @@ -257,7 +275,9 @@ static inline uint8_t management_action(struct ptp_message *m) static inline void *management_tlv_data(struct ptp_message *msg) { struct management_tlv *mgt; - mgt = (struct management_tlv *) msg->management.suffix; + mgt = management_tlv_get(msg); + if (!mgt) + return NULL; return mgt->data; } @@ -269,7 +289,9 @@ static inline void *management_tlv_data(struct ptp_message *msg) static inline int management_tlv_id(struct ptp_message *m) { struct management_tlv *mgt; - mgt = (struct management_tlv *) m->management.suffix; + mgt = management_tlv_get(m); + if (!mgt) + return 0; return mgt->id; } diff --git a/pmc.c b/pmc.c index bc87058..6888a9a 100644 --- a/pmc.c +++ b/pmc.c @@ -198,11 +198,11 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) fprintf(fp, "\t%s seq %hu %s ", pid2str(&msg->header.sourcePortIdentity), msg->header.sequenceId, pmc_action_string(action)); - if (msg_tlv_count(msg) != 1) { + extra = pmc_get_mgt_tlv(msg); + if (!extra) { goto out; } - extra = TAILQ_FIRST(&msg->tlv_list); - tlv = (struct TLV *) msg->management.suffix; + tlv = extra->tlv; if (tlv->type == TLV_MANAGEMENT) { fprintf(fp, "MANAGEMENT "); } else if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) { @@ -212,7 +212,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) fprintf(fp, "unknown-tlv "); goto out; } - mgt = (struct management_tlv *) msg->management.suffix; + mgt = (struct management_tlv *) tlv; if (mgt->length == 2 && mgt->id != MID_NULL_MANAGEMENT) { fprintf(fp, "empty-tlv "); goto out; diff --git a/pmc_agent.c b/pmc_agent.c index 62d1a86..5b22686 100644 --- a/pmc_agent.c +++ b/pmc_agent.c @@ -72,15 +72,17 @@ static int check_clock_identity(struct pmc_agent *node, struct ptp_message *msg) static int is_msg_mgt(struct ptp_message *msg) { + struct tlv_extra *extra; struct TLV *tlv; if (msg_type(msg) != MANAGEMENT) return 0; if (management_action(msg) != RESPONSE) return 0; - if (msg_tlv_count(msg) != 1) + extra = pmc_get_mgt_tlv(msg); + if (!extra) return 0; - tlv = (struct TLV *) msg->management.suffix; + tlv = extra->tlv; if (tlv->type == TLV_MANAGEMENT) return 1; if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) @@ -92,7 +94,7 @@ static int get_mgt_err_id(struct ptp_message *msg) { struct management_error_status *mgt; - mgt = (struct management_error_status *)msg->management.suffix; + mgt = (struct management_error_status *) management_tlv_get(msg); return mgt->id; } diff --git a/pmc_common.c b/pmc_common.c index 59e4488..80dfe74 100644 --- a/pmc_common.c +++ b/pmc_common.c @@ -710,6 +710,29 @@ int pmc_get_transport_fd(struct pmc *pmc) return pmc->fdarray.fd[FD_GENERAL]; } +struct tlv_extra *pmc_get_mgt_tlv(struct ptp_message *msg) { + int count = 0; + struct tlv_extra *extra, *tlv = NULL; + + TAILQ_FOREACH(extra, &msg->tlv_list, list) { + switch(extra->tlv->type) { + case TLV_AUTHENTICATION: + break; + case TLV_MANAGEMENT: + case TLV_MANAGEMENT_ERROR_STATUS: + tlv = extra; + default: + count++; + break; + } + } + + if (count == 1) + return tlv; + + return NULL; +} + int pmc_send_get_action(struct pmc *pmc, int id) { int datalen, pdulen; diff --git a/pmc_common.h b/pmc_common.h index 3add048..7050087 100644 --- a/pmc_common.h +++ b/pmc_common.h @@ -37,6 +37,8 @@ void pmc_destroy(struct pmc *pmc); int pmc_get_transport_fd(struct pmc *pmc); +struct tlv_extra *pmc_get_mgt_tlv(struct ptp_message *msg); + int pmc_send_get_action(struct pmc *pmc, int id); int pmc_send_set_action(struct pmc *pmc, int id, void *data, int datasize); diff --git a/port.c b/port.c index d52a2a5..1835700 100644 --- a/port.c +++ b/port.c @@ -1188,7 +1188,7 @@ static int port_management_set(struct port *target, struct port_ds_np *pdsnp; int respond = 0; - tlv = (struct management_tlv *) req->management.suffix; + tlv = management_tlv_get(req); switch (id) { case MID_PORT_DATA_SET_NP: @@ -3174,7 +3174,7 @@ int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg) if (target != portnum(p) && target != 0xffff) { return 0; } - mgt = (struct management_tlv *) msg->management.suffix; + mgt = management_tlv_get(msg); switch (management_action(msg)) { case GET: @@ -3228,7 +3228,7 @@ int port_management_error(struct PortIdentity pid, struct port *ingress, struct tlv_extra *extra; int err = 0; - mgt = (struct management_tlv *) req->management.suffix; + mgt = management_tlv_get(req); msg = port_management_reply(pid, ingress, req); if (!msg) { return -1; -- 2.42.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel