From 548109b2074a484a40a61bbbe7690f0ef308952e Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Tue, 16 Dec 2008 11:23:43 +0100 Subject: [PATCH] Add Maximum Frame Size support. For Linux, we just use MTU as MFS. --- src/agent.c | 12 ++++++++++++ src/lldp.c | 25 +++++++++++++++++++++++++ src/lldp.h | 7 +++++++ src/lldpctl.c | 2 ++ src/lldpd.c | 2 +- src/lldpd.h | 3 ++- 6 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/agent.c b/src/agent.c index e65ad028..6a779700 100644 --- a/src/agent.c +++ b/src/agent.c @@ -325,6 +325,7 @@ header_tprvindexed_table(struct variable *vp, oid *name, size_t *length, #define LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU 8 #define LLDP_SNMP_LOCAL_DOT3_AGG_STATUS 9 #define LLDP_SNMP_LOCAL_DOT3_AGG_ID 10 +#define LLDP_SNMP_LOCAL_DOT3_MFS 11 /* Remote ports */ #define LLDP_SNMP_REMOTE_CIDSUBTYPE 1 #define LLDP_SNMP_REMOTE_CID 2 @@ -341,6 +342,7 @@ header_tprvindexed_table(struct variable *vp, oid *name, size_t *length, #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU 13 #define LLDP_SNMP_REMOTE_DOT3_AGG_STATUS 14 #define LLDP_SNMP_REMOTE_DOT3_AGG_ID 15 +#define LLDP_SNMP_REMOTE_DOT3_MFS 16 /* Local vlans */ #define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1 /* Remote vlans */ @@ -857,6 +859,9 @@ agent_h_local_port(struct variable *vp, oid *name, size_t *length, case LLDP_SNMP_LOCAL_DOT3_AGG_ID: long_ret = hardware->h_lport.p_aggregid; return (u_char *)&long_ret; + case LLDP_SNMP_LOCAL_DOT3_MFS: + long_ret = hardware->h_lport.p_mfs; + return (u_char *)&long_ret; #endif default: break; @@ -968,6 +973,9 @@ agent_h_remote_port(struct variable *vp, oid *name, size_t *length, case LLDP_SNMP_REMOTE_DOT3_AGG_ID: long_ret = hardware->h_rport->p_aggregid; return (u_char *)&long_ret; + case LLDP_SNMP_REMOTE_DOT3_MFS: + long_ret = hardware->h_rport->p_mfs; + return (u_char *)&long_ret; #endif default: break; @@ -1104,6 +1112,8 @@ static struct variable8 lldp_vars[] = { {1, 5, 4623, 1, 2, 3, 1, 1}}, {LLDP_SNMP_LOCAL_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_local_port, 8, {1, 5, 4623, 1, 2, 3, 1, 2}}, + {LLDP_SNMP_LOCAL_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 4, 1, 1}}, #endif /* Remote ports */ {LLDP_SNMP_REMOTE_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 4}}, @@ -1128,6 +1138,8 @@ static struct variable8 lldp_vars[] = { {1, 5, 4623, 1, 3, 3, 1, 1}}, {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8, {1, 5, 4623, 1, 3, 3, 1, 2}}, + {LLDP_SNMP_REMOTE_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 4, 1, 1}}, #endif #ifdef ENABLE_DOT1 /* Local vlans */ diff --git a/src/lldp.c b/src/lldp.c index c455dfb3..5d406ca6 100644 --- a/src/lldp.c +++ b/src/lldp.c @@ -50,6 +50,7 @@ lldp_send(struct lldpd *global, struct lldpd_chassis *chassis, const u_int8_t dot3[] = LLDP_TLV_ORG_DOT3; struct lldp_aggreg aggreg; struct lldp_macphy macphy; + struct lldp_mfs mfs; #endif #ifdef ENABLE_LLDPMED int i; @@ -248,6 +249,19 @@ lldp_send(struct lldpd *global, struct lldpd_chassis *chassis, IOV_NEW; iov[c].iov_base = &macphy; iov[c].iov_len = sizeof(macphy); + + /* MFS */ + memset(&mfs, 0, sizeof(mfs)); + mfs.tlv_head.type_len = LLDP_TLV_HEAD(LLDP_TLV_ORG, + sizeof(mfs.tlv_org_id) + + sizeof(mfs.tlv_org_subtype) + + sizeof(mfs.mfs)); + memcpy(mfs.tlv_org_id, dot3, sizeof(mfs.tlv_org_id)); + mfs.tlv_org_subtype = LLDP_TLV_DOT3_MFS; + mfs.mfs = htons(port->p_mfs); + IOV_NEW; + iov[c].iov_base = &mfs; + iov[c].iov_len = sizeof(mfs); #endif #ifdef ENABLE_LLDPMED @@ -640,6 +654,17 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, ntohl(*(u_int32_t*)(frame + f + 5)); f += size; break; + case LLDP_TLV_DOT3_MFS: + if (size < 6) { + LLOG_WARNX("too short mfs tlv " + "received on %s", + hardware->h_ifname); + goto malformed; + } + port->p_mfs = + ntohs(*(u_int16_t*)(frame + f + 4)); + f += size; + break; default: /* Unknown Dot3 TLV, ignore it */ f += size; diff --git a/src/lldp.h b/src/lldp.h index ebda46df..10a28523 100644 --- a/src/lldp.h +++ b/src/lldp.h @@ -227,6 +227,13 @@ struct lldp_macphy { u_int16_t mau; } __attribute__ ((__packed__)); +struct lldp_mfs { + struct lldp_tlv_head tlv_head; + u_int8_t tlv_org_id[3]; + u_int8_t tlv_org_subtype; + u_int16_t mfs; +} __attribute__ ((__packed__)); + struct lldp_end { struct lldp_tlv_head tlv_head; } __attribute__ ((__packed__)); diff --git a/src/lldpctl.c b/src/lldpctl.c index cd94ad10..4c3af910 100644 --- a/src/lldpctl.c +++ b/src/lldpctl.c @@ -705,6 +705,8 @@ display_port(struct lldpd_port *port) } printf(" PortDescr: "); pretty_print(port->p_descr); #ifdef ENABLE_DOT3 + if (port->p_mfs) + printf(" MTU: %d\n", port->p_mfs); if (port->p_aggregid) printf("\n Port is aggregated. PortAggregID: %d\n", port->p_aggregid); diff --git a/src/lldpd.c b/src/lldpd.c index 44d9b726..f0b34a54 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -195,7 +195,7 @@ lldpd_iface_init_mtu(struct lldpd *global, struct lldpd_hardware *hardware) LLOG_WARN("unable to get MTU of %s, using 1500", hardware->h_ifname); hardware->h_mtu = 1500; } else - hardware->h_mtu = ifr.ifr_mtu; + hardware->h_mtu = hardware->h_lport.p_mfs = ifr.ifr_mtu; } int diff --git a/src/lldpd.h b/src/lldpd.h index 80fcc185..3e437a55 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -145,6 +145,7 @@ struct lldpd_port { char *p_id; int p_id_len; char *p_descr; + u_int16_t p_mfs; #ifdef ENABLE_DOT3 #define STRUCT_LLDPD_PORT_DOT3 "lbbww" @@ -166,7 +167,7 @@ struct lldpd_port { #endif }; -#define STRUCT_LLDPD_PORT "(bCs" STRUCT_LLDPD_PORT_DOT3 STRUCT_LLDPD_PORT_DOT1 ")" +#define STRUCT_LLDPD_PORT "(bCsw" STRUCT_LLDPD_PORT_DOT3 STRUCT_LLDPD_PORT_DOT1 ")" struct lldpd_frame { int size; -- 2.39.5