From 608cb51caa7d4a435741def667b52401421b51cb Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 5 Jun 2010 19:51:55 +0200 Subject: [PATCH] Add support for 802.3at. This includes send and receive support as well as SNMP support. 802.3at seems to not define OID that should be used as well as the mapping for bit values. Therefore, the implementation is a wild guess of what is consistent with 802.1ab. --- CHANGELOG | 2 +- man/lldpctl.8 | 29 +++++++++++++ src/agent.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++- src/display.c | 48 +++++++++++++++++++++ src/lldp.c | 35 +++++++++++++++- src/lldp.h | 18 ++++++++ src/lldpctl.c | 95 ++++++++++++++++++++++++++++------------- src/lldpd.h | 8 +++- 8 files changed, 314 insertions(+), 35 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 50e1aaa4..8b3d7032 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,7 +17,7 @@ lldpd (0.5.1) + Allow to set LLDP-MED network policy from lldpctl, thanks to a patch from Philipp Kempgen. + Allow to set LLDP-MED POE-MDI from lldpctl. - + Handle Dot3 POE-MDI TLV (802.3af). + + Handle Dot3 POE-MDI TLV (802.3af and 802.3at). + Allow to set Dot3 POE-MDI from lldpctl. + Add a summary of available options in "lldpd -h" and "lldpctl -h", thanks to a patch from Jorge Boncompte. diff --git a/man/lldpctl.8 b/man/lldpctl.8 index c1f3ccd6..eb7040d5 100644 --- a/man/lldpctl.8 +++ b/man/lldpctl.8 @@ -354,6 +354,17 @@ The format of this option is (without spaces): .Ar powerpairs : .Ar class +[ : +.Ar powertype +: +.Ar source +: +.Ar priority +: +.Ar requested +: +.Ar allocated +] .Bl -tag -width "XX" .It Ar type Valid types are: @@ -401,6 +412,24 @@ means that MDI power is enabled on the given port. .Ar paircontrol is used to indicate if the pair selection can be controlled on the given port. +.Pp +.Ar powertype , +.Ar source , +.Ar priority +(and remaining values) are optional. They are only requested in +conformance with 802.3at. +.Ar type +should be either 1 or 2. For the possible values of the next two +fields, see the possible values of +.Ar source +and +.Ar priority +for LLDP-MED MDI/POE. +.Ar requested +and +.Ar allocated +are respectively the PD requested power value and the PSE allocated +power value. This should be expressed in tenth of watts from 1 to 255. .El .Sh FILES .Bl -tag -width "/var/run/lldpd.socketXX" -compact diff --git a/src/agent.c b/src/agent.c index 882bb00b..47eeac85 100644 --- a/src/agent.c +++ b/src/agent.c @@ -407,7 +407,12 @@ header_tprvindexed_table(struct variable *vp, oid *name, size_t *length, #define LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL 15 #define LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS 16 #define LLDP_SNMP_LOCAL_DOT3_POWER_CLASS 17 -#define LLDP_SNMP_LOCAL_DOT1_PVID 18 +#define LLDP_SNMP_LOCAL_DOT3_POWER_TYPE 18 +#define LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE 19 +#define LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY 20 +#define LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED 21 +#define LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED 22 +#define LLDP_SNMP_LOCAL_DOT1_PVID 23 /* Remote ports */ #define LLDP_SNMP_REMOTE_CIDSUBTYPE 1 #define LLDP_SNMP_REMOTE_CID 2 @@ -431,7 +436,12 @@ header_tprvindexed_table(struct variable *vp, oid *name, size_t *length, #define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL 20 #define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS 21 #define LLDP_SNMP_REMOTE_DOT3_POWER_CLASS 22 -#define LLDP_SNMP_REMOTE_DOT1_PVID 23 +#define LLDP_SNMP_REMOTE_DOT3_POWER_TYPE 23 +#define LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE 24 +#define LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY 25 +#define LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED 26 +#define LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED 27 +#define LLDP_SNMP_REMOTE_DOT1_PVID 28 /* Local vlans */ #define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1 /* Remote vlans */ @@ -1131,6 +1141,46 @@ agent_h_local_port(struct variable *vp, oid *name, size_t *length, return (u_char *)&long_ret; } break; + case LLDP_SNMP_LOCAL_DOT3_POWER_TYPE: + if (hardware->h_lport.p_power.devicetype && + hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + *var_len = 1; + bit = (((hardware->h_lport.p_power.powertype == + LLDP_DOT3_POWER_8023AT_TYPE1)?1:0) << 7) | + (((hardware->h_lport.p_power.devicetype == + LLDP_DOT3_POWER_PSE)?0:1) << 6); + return (u_char *)&bit; + } + break; + case LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE: + if (hardware->h_lport.p_power.devicetype && + hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + *var_len = 1; + bit = swap_bits(hardware->h_lport.p_power.source%(1<<2)); + return (u_char *)&bit; + } + break; + case LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY: + if (hardware->h_lport.p_power.devicetype && + hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = hardware->h_lport.p_power.priority; + return (u_char *)&long_ret; + } + break; + case LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED: + if (hardware->h_lport.p_power.devicetype && + hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = hardware->h_lport.p_power.requested; + return (u_char *)&long_ret; + } + break; + case LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED: + if (hardware->h_lport.p_power.devicetype && + hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = hardware->h_lport.p_power.allocated; + return (u_char *)&long_ret; + } + break; #endif #ifdef ENABLE_DOT1 case LLDP_SNMP_LOCAL_DOT1_PVID: @@ -1289,6 +1339,46 @@ agent_h_remote_port(struct variable *vp, oid *name, size_t *length, return (u_char *)&long_ret; } break; + case LLDP_SNMP_REMOTE_DOT3_POWER_TYPE: + if (port->p_power.devicetype && + port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + *var_len = 1; + bit = (((port->p_power.powertype == + LLDP_DOT3_POWER_8023AT_TYPE1)?1:0) << 7) | + (((port->p_power.devicetype == + LLDP_DOT3_POWER_PSE)?0:1) << 6); + return (u_char *)&bit; + } + break; + case LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE: + if (port->p_power.devicetype && + port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + *var_len = 1; + bit = swap_bits(port->p_power.source%(1<<2)); + return (u_char *)&bit; + } + break; + case LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY: + if (port->p_power.devicetype && + port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = port->p_power.priority; + return (u_char *)&long_ret; + } + break; + case LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED: + if (port->p_power.devicetype && + port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = port->p_power.requested; + return (u_char *)&long_ret; + } + break; + case LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED: + if (port->p_power.devicetype && + port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + long_ret = port->p_power.allocated; + return (u_char *)&long_ret; + } + break; #endif #ifdef ENABLE_DOT1 case LLDP_SNMP_REMOTE_DOT1_PVID: @@ -1441,6 +1531,16 @@ static struct variable8 lldp_vars[] = { {1, 5, 4623, 1, 2, 2, 1, 5}}, {LLDP_SNMP_LOCAL_DOT3_POWER_CLASS, ASN_INTEGER, RONLY, agent_h_local_port, 8, {1, 5, 4623, 1, 2, 2, 1, 6}}, + {LLDP_SNMP_LOCAL_DOT3_POWER_TYPE, ASN_OCTET_STR, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 2, 1, 7}}, + {LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE, ASN_OCTET_STR, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 2, 1, 8}}, + {LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY, ASN_INTEGER, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 2, 1, 9}}, + {LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED, ASN_INTEGER, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 2, 1, 10}}, + {LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED, ASN_INTEGER, RONLY, agent_h_local_port, 8, + {1, 5, 4623, 1, 2, 2, 1, 11}}, {LLDP_SNMP_LOCAL_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_local_port, 8, {1, 5, 4623, 1, 2, 3, 1, 1}}, {LLDP_SNMP_LOCAL_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_local_port, 8, @@ -1483,6 +1583,16 @@ static struct variable8 lldp_vars[] = { {1, 5, 4623, 1, 3, 2, 1, 5}}, {LLDP_SNMP_REMOTE_DOT3_POWER_CLASS, ASN_INTEGER, RONLY, agent_h_remote_port, 8, {1, 5, 4623, 1, 3, 2, 1, 6}}, + {LLDP_SNMP_REMOTE_DOT3_POWER_TYPE, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 2, 1, 7}}, + {LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 2, 1, 8}}, + {LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY, ASN_INTEGER, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 2, 1, 9}}, + {LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED, ASN_INTEGER, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 2, 1, 10}}, + {LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED, ASN_INTEGER, RONLY, agent_h_remote_port, 8, + {1, 5, 4623, 1, 3, 2, 1, 11}}, {LLDP_SNMP_REMOTE_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8, {1, 5, 4623, 1, 3, 3, 1, 1}}, {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8, diff --git a/src/display.c b/src/display.c index e3c1dd4b..cde5fa02 100644 --- a/src/display.c +++ b/src/display.c @@ -263,6 +263,25 @@ static const struct value_string port_dot3_power_class_map[] = { { 5, "class 4" }, { 0, NULL } }; + +static const struct value_string port_dot3_power_pse_source_map[] = { + { LLDP_DOT3_POWER_SOURCE_BOTH, "PSE + Local" }, + { LLDP_DOT3_POWER_SOURCE_PSE, "PSE" }, + { 0, NULL } +}; + +static const struct value_string port_dot3_power_pd_source_map[] = { + { LLDP_DOT3_POWER_SOURCE_BACKUP, "Backup source" }, + { LLDP_DOT3_POWER_SOURCE_PRIMARY, "Primary power source" }, + { 0, NULL } +}; + +static const struct value_string port_dot3_power_priority_map[] = { + { LLDPMED_POW_PRIO_CRITICAL, "critical" }, + { LLDPMED_POW_PRIO_HIGH, "high" }, + { LLDPMED_POW_PRIO_LOW, "low" }, + { 0, NULL }, +}; #endif static const struct value_string chassis_capability_map[] = { @@ -922,6 +941,35 @@ display_port(struct writer * w, struct lldpd_port *port) tag_data(w, map_lookup(port_dot3_power_class_map, port->p_power.class)); tag_end(w); + + /* 802.3at */ + if (port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + tag_start(w, "power-type", "Power type"); + tag_data(w, u2str(port->p_power.powertype)); + tag_end(w); + + tag_start(w, "source", "Power Source"); + tag_data(w, map_lookup( + (port->p_power.devicetype == LLDP_DOT3_POWER_PSE)? + port_dot3_power_pse_source_map: + port_dot3_power_pd_source_map, + port->p_power.source)); + tag_end(w); + + tag_start(w, "priority", "Power Priority"); + tag_data(w, map_lookup(port_dot3_power_priority_map, + port->p_power.priority)); + tag_end(w); + + tag_start(w, "requested", "PD requested power Value"); + tag_data(w, u2str(port->p_power.requested * 100)); + tag_end(w); + + tag_start(w, "allocated", "PSE allocated power Value"); + tag_data(w, u2str(port->p_power.allocated * 100)); + tag_end(w); + } + tag_end(w); } #endif diff --git a/src/lldp.c b/src/lldp.c index b48b4759..28680f28 100644 --- a/src/lldp.c +++ b/src/lldp.c @@ -210,8 +210,23 @@ lldp_send(struct lldpd *global, (( port->p_power.enabled %(1<< 1))<<2) | (( port->p_power.paircontrol %(1<< 1))<<3))) && POKE_UINT8(port->p_power.pairs) && - POKE_UINT8(port->p_power.class) && - POKE_END_LLDP_TLV)) + POKE_UINT8(port->p_power.class))) + goto toobig; + /* 802.3at */ + if (port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + if (!( + POKE_UINT8(( + (((port->p_power.powertype == + LLDP_DOT3_POWER_8023AT_TYPE1)?1:0) << 7) | + (((port->p_power.devicetype == + LLDP_DOT3_POWER_PSE)?0:1) << 6) | + ((port->p_power.source %(1<< 2))<<4) | + ((port->p_power.priority %(1<< 2))<<0))) && + POKE_UINT16(port->p_power.requested) && + POKE_UINT16(port->p_power.allocated))) + goto toobig; + } + if (!(POKE_END_LLDP_TLV)) goto toobig; } #endif @@ -613,6 +628,22 @@ lldp_decode(struct lldpd *cfg, char *frame, int s, LLDP_DOT3_POWER_PSE:LLDP_DOT3_POWER_PD; port->p_power.pairs = PEEK_UINT8; port->p_power.class = PEEK_UINT8; + /* 802.3at? */ + if (tlv_size >= 12) { + port->p_power.powertype = PEEK_UINT8; + port->p_power.source = + (port->p_power.powertype & (1<<5 | 1<<4)) >> 4; + port->p_power.priority = + (port->p_power.powertype & (1<<1 | 1<<0)); + port->p_power.powertype = + (port->p_power.powertype & (1<<7))? + LLDP_DOT3_POWER_8023AT_TYPE1: + LLDP_DOT3_POWER_8023AT_TYPE2; + port->p_power.requested = PEEK_UINT16; + port->p_power.allocated = PEEK_UINT16; + } else + port->p_power.powertype = + LLDP_DOT3_POWER_8023AT_OFF; break; default: /* Unknown Dot3 TLV, ignore it */ diff --git a/src/lldp.h b/src/lldp.h index 08f36ffa..06a15d67 100644 --- a/src/lldp.h +++ b/src/lldp.h @@ -127,6 +127,24 @@ enum { #define LLDP_DOT3_POWERPAIRS_SIGNAL 1 #define LLDP_DOT3_POWERPAIRS_SPARE 2 +/* Dot3 Power type (for 802.3at) */ +#define LLDP_DOT3_POWER_8023AT_OFF 0 +#define LLDP_DOT3_POWER_8023AT_TYPE1 1 +#define LLDP_DOT3_POWER_8023AT_TYPE2 2 + +/* Dot3 power source */ +#define LLDP_DOT3_POWER_SOURCE_UNKNOWN 0 +#define LLDP_DOT3_POWER_SOURCE_PRIMARY 1 +#define LLDP_DOT3_POWER_SOURCE_PSE 1 +#define LLDP_DOT3_POWER_SOURCE_BACKUP 2 +#define LLDP_DOT3_POWER_SOURCE_BOTH 3 + +/* Dot3 power priority */ +#define LLDP_DOT3_POWER_PRIO_UNKNOWN 0 +#define LLDP_DOT3_POWER_PRIO_CRITICAL 1 +#define LLDP_DOT3_POWER_PRIO_HIGH 2 +#define LLDP_DOT3_POWER_PRIO_LOW 3 + /* PMD Auto-Negotiation Advertised Capability field, from RFC 3636 */ #define LLDP_DOT3_LINK_AUTONEG_OTHER 0x8000 #define LLDP_DOT3_LINK_AUTONEG_10BASE_T 0x4000 diff --git a/src/lldpctl.c b/src/lldpctl.c index 91bcd158..bab295de 100644 --- a/src/lldpctl.c +++ b/src/lldpctl.c @@ -464,22 +464,18 @@ static int lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) { const char *e; - int device_type = 0; - int supported = 0; - int enabled = 0; - int paircontrol = 0; - int powerpairs = 0; - int class = 0; + struct lldpd_dot3_power target; if (strlen(poe) == 0) return 0; e = poe; + memset(&target, 0, sizeof(target)); /* Device type */ if (!strncmp(e, "PD", 2)) - device_type = LLDP_DOT3_POWER_PD; + target.devicetype = LLDP_DOT3_POWER_PD; else if (!strncmp(e, "PSE", 3)) - device_type = LLDP_DOT3_POWER_PSE; + target.devicetype = LLDP_DOT3_POWER_PSE; else { LLOG_WARNX("Device type should be either 'PD' or 'PSE'."); goto invalid_dot3_poe; @@ -490,9 +486,9 @@ lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) LLOG_WARNX("Expected power support."); goto invalid_dot3_poe; } - supported = atoi(++e); - if (supported < 0 || supported > 1) { - LLOG_WARNX("Power support should be 1 or 0, not %d", supported); + target.supported = atoi(++e); + if (target.supported > 1) { + LLOG_WARNX("Power support should be 1 or 0, not %d", target.supported); goto invalid_dot3_poe; } @@ -501,9 +497,9 @@ lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) LLOG_WARNX("Expected power ability."); goto invalid_dot3_poe; } - enabled = atoi(++e); - if (enabled < 0 || enabled > 1) { - LLOG_WARNX("Power ability should be 1 or 0, not %d", enabled); + target.enabled = atoi(++e); + if (target.enabled > 1) { + LLOG_WARNX("Power ability should be 1 or 0, not %d", target.enabled); goto invalid_dot3_poe; } @@ -512,9 +508,10 @@ lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) LLOG_WARNX("Expected power pair control ability."); goto invalid_dot3_poe; } - paircontrol = atoi(++e); - if (paircontrol < 0 || paircontrol > 1) { - LLOG_WARNX("Power pair control ability should be 1 or 0, not %d", paircontrol); + target.paircontrol = atoi(++e); + if (target.paircontrol > 1) { + LLOG_WARNX("Power pair control ability should be 1 or 0, not %d", + target.paircontrol); goto invalid_dot3_poe; } @@ -523,9 +520,9 @@ lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) LLOG_WARNX("Expected power pairs."); goto invalid_dot3_poe; } - powerpairs = atoi(++e); - if (powerpairs < 1 || powerpairs > 2) { - LLOG_WARNX("Power pairs should be 1 or 2, not %d.", powerpairs); + target.pairs = atoi(++e); + if (target.pairs < 1 || target.pairs > 2) { + LLOG_WARNX("Power pairs should be 1 or 2, not %d.", target.pairs); goto invalid_dot3_poe; } @@ -534,18 +531,58 @@ lldpd_parse_dot3_power(struct lldpd_port *port, const char *poe) LLOG_WARNX("Expected power class."); goto invalid_dot3_poe; } - class = atoi(++e); - if (class < 0 || class > 5) { - LLOG_WARNX("Power class out of range (%d).", class); + target.class = atoi(++e); + if (target.class > 5) { + LLOG_WARNX("Power class out of range (%d).", target.class); + goto invalid_dot3_poe; + } + /* 802.3at */ + if ((e = strchr(e, ':')) == NULL) { + target.powertype = LLDP_DOT3_POWER_8023AT_OFF; + goto no8023at; + } + /* 802.3at: Power type */ + target.powertype = atoi(++e); + if ((target.powertype != LLDP_DOT3_POWER_8023AT_TYPE1) && + (target.powertype != LLDP_DOT3_POWER_8023AT_TYPE2)) { + LLOG_WARNX("Incorrect power type (%d).", target.powertype); + goto invalid_dot3_poe; + } + /* 802.3at: Source */ + if ((e = strchr(e, ':')) == NULL) { + LLOG_WARNX("Expected power source."); + goto invalid_dot3_poe; + } + target.source = atoi(++e); + if (target.source > 3) { + LLOG_WARNX("Power source out of range (%d).", target.source); + goto invalid_dot3_poe; + } + /* 802.3at: priority */ + if ((e = strchr(e, ':')) == NULL) { + LLOG_WARNX("Expected power priority."); + goto invalid_dot3_poe; + } + target.priority = atoi(++e); + if (target.priority > 3) { + LLOG_WARNX("Power priority out of range (%d).", target.priority); + goto invalid_dot3_poe; + } + /* 802.3at: requested */ + if ((e = strchr(e, ':')) == NULL) { + LLOG_WARNX("Expected requested power value."); + goto invalid_dot3_poe; + } + target.requested = atoi(++e); + /* 802.3at: allocated */ + if ((e = strchr(e, ':')) == NULL) { + LLOG_WARNX("Expected allocated power value."); goto invalid_dot3_poe; } + target.allocated = atoi(++e); - port->p_power.devicetype = device_type; - port->p_power.supported = supported; - port->p_power.enabled = enabled; - port->p_power.paircontrol = paircontrol; - port->p_power.pairs = powerpairs; - port->p_power.class = class; + no8023at: + memcpy(&port->p_power, &target, sizeof(target)); return 0; invalid_dot3_poe: diff --git a/src/lldpd.h b/src/lldpd.h index 20770bc2..f03bd142 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -111,7 +111,7 @@ struct lldpd_dot3_macphy { u_int16_t mau_type; }; -#define STRUCT_LLDPD_DOT3_POWER "(bbbbbb)" +#define STRUCT_LLDPD_DOT3_POWER "(bbbbbbbbbww)" struct lldpd_dot3_power { u_int8_t devicetype; u_int8_t supported; @@ -119,6 +119,12 @@ struct lldpd_dot3_power { u_int8_t paircontrol; u_int8_t pairs; u_int8_t class; + u_int8_t powertype; /* If set to LLDP_DOT3_POWER_8023AT_OFF, + following fields have no meaning */ + u_int8_t source; + u_int8_t priority; + u_int16_t requested; + u_int16_t allocated; }; #endif -- 2.39.5