port: Accept multiple TLVs on receive.

Path trace TLVs and Follow-Up info TLVs might be mixed in among other
random TLVs.  This patch fixes the parsing code to find these TLVs even
when multiple other TLVs are present.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2018-02-23 22:49:57 -08:00
parent ecb5fa8ffb
commit a003b4c36e
1 changed files with 23 additions and 21 deletions

44
port.c
View File

@ -453,16 +453,18 @@ static int follow_up_info_append(struct port *p, struct ptp_message *m)
static struct follow_up_info_tlv *follow_up_info_extract(struct ptp_message *m) static struct follow_up_info_tlv *follow_up_info_extract(struct ptp_message *m)
{ {
struct follow_up_info_tlv *f; struct follow_up_info_tlv *f;
f = (struct follow_up_info_tlv *) m->follow_up.suffix; struct tlv_extra *extra;
if (m->tlv_count != 1 || TAILQ_FOREACH(extra, &m->tlv_list, list) {
f->type != TLV_ORGANIZATION_EXTENSION || f = (struct follow_up_info_tlv *) extra->tlv;
f->length != sizeof(*f) - sizeof(f->type) - sizeof(f->length) || if (f->type == TLV_ORGANIZATION_EXTENSION &&
// memcmp(f->id, ieee8021_id, sizeof(ieee8021_id)) || f->length == sizeof(*f) - sizeof(f->type) - sizeof(f->length) &&
f->subtype[0] || f->subtype[1] || f->subtype[2] != 1) { // memcmp(f->id, ieee8021_id, sizeof(ieee8021_id)) &&
return NULL; !f->subtype[0] && !f->subtype[1] && f->subtype[2] == 1) {
return f;
}
} }
return f; return NULL;
} }
static void free_foreign_masters(struct port *p) static void free_foreign_masters(struct port *p)
@ -530,8 +532,9 @@ static int path_trace_append(struct port *p, struct ptp_message *m,
static int path_trace_ignore(struct port *p, struct ptp_message *m) static int path_trace_ignore(struct port *p, struct ptp_message *m)
{ {
struct ClockIdentity cid;
struct path_trace_tlv *ptt; struct path_trace_tlv *ptt;
struct ClockIdentity cid;
struct tlv_extra *extra;
int i, cnt; int i, cnt;
if (!p->path_trace_enabled) { if (!p->path_trace_enabled) {
@ -540,18 +543,17 @@ static int path_trace_ignore(struct port *p, struct ptp_message *m)
if (msg_type(m) != ANNOUNCE) { if (msg_type(m) != ANNOUNCE) {
return 0; return 0;
} }
if (m->tlv_count != 1) { TAILQ_FOREACH(extra, &m->tlv_list, list) {
return 1; ptt = (struct path_trace_tlv *) extra->tlv;
} if (ptt->type != TLV_PATH_TRACE) {
ptt = (struct path_trace_tlv *) m->announce.suffix; continue;
if (ptt->type != TLV_PATH_TRACE) { }
return 1; cnt = path_length(ptt);
} cid = clock_identity(p->clock);
cnt = path_length(ptt); for (i = 0; i < cnt; i++) {
cid = clock_identity(p->clock); if (0 == memcmp(&ptt->cid[i], &cid, sizeof(cid)))
for (i = 0; i < cnt; i++) { return 1;
if (0 == memcmp(&ptt->cid[i], &cid, sizeof(cid))) }
return 1;
} }
return 0; return 0;
} }