Also add SNMP support for lldpXdot3LocPowerTable.
.Op Fl L Ar location
.Op Fl P Ar policy
.Op Fl O Ar poe
+.Op Fl o Ar poe
.Op Ar interface ...
.Sh DESCRIPTION
The
this kind of representation.
.El
.Pp
+This option is distinct of
+.Fl o
+option. You may want to use both options at the same time.
+.Pp
The format of this option is (without spaces):
.Pp
.Em type
.Ar priority
:
.Ar value
-:
.Bl -tag -width "XX"
.It Ar type
Valid types are:
by a PD device from the PSE device. This value should range from 0 to
1023 tenth of watts.
.El
+.It Fl o Ar poe
+Enable the transmission of Dot3 POE-MDI TLV for the given
+interfaces. One can act as a PD (power consumer) or a PSE (power
+provider). This option is distinct of the
+.Fl O
+option. You might want to use both. Contrary to LLDP-MED POE-MDI TLV,
+Dot3 POE-MDI TLV are strictly per-port values.
+.Pp
+The format of this option is (without spaces):
+.Pp
+.Em type
+:
+.Ar supported
+:
+.Ar enabled
+:
+.Ar paircontrol
+:
+.Ar powerpairs
+:
+.Ar class
+.Bl -tag -width "XX"
+.It Ar type
+Valid types are:
+.Bl -tag -width "XXX." -compact
+.It Sy PSE
+Power Sourcing Entity (power provider)
+.It Sy PD
+Power Device (power consumer)
+.El
+.It Ar powerpairs
+Valid sources are:
+.Bl -tag -width "X." -compact
+.It Sy 1
+The signal pairs only are in use.
+.It Sy 2
+The spare pairs only are in use.
+.El
+.It Ar class
+Five classes are available:
+.Bl -tag -width "X." -compact
+.It Sy 1
+class 0
+.It Sy 2
+class 1
+.It Sy 3
+class 2
+.It Sy 4
+class 3
+.It Sy 5
+class 4
+.It Sy 0
+no class
+.El
+.El
+.Pp
+.Ar supported ,
+.Ar enabled
+and
+.Ar paircontrol
+can be set to to 0 or 1.
+.Ar supported
+means that MDI power is supported on the given port.
+.Ar enabled
+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.
.El
.Sh FILES
.Bl -tag -width "/var/run/lldpd.socketXX" -compact
#define LLDP_SNMP_LOCAL_DOT3_AGG_STATUS 9
#define LLDP_SNMP_LOCAL_DOT3_AGG_ID 10
#define LLDP_SNMP_LOCAL_DOT3_MFS 11
-#define LLDP_SNMP_LOCAL_DOT1_PVID 12
+#define LLDP_SNMP_LOCAL_DOT3_POWER_DEVICETYPE 12
+#define LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT 13
+#define LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED 14
+#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
/* Remote ports */
#define LLDP_SNMP_REMOTE_CIDSUBTYPE 1
#define LLDP_SNMP_REMOTE_CID 2
case LLDP_SNMP_LOCAL_DOT3_MFS:
long_ret = hardware->h_lport.p_mfs;
return (u_char *)&long_ret;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_DEVICETYPE:
+ if (hardware->h_lport.p_power.devicetype) {
+ long_ret = (hardware->h_lport.p_power.devicetype ==
+ LLDP_DOT3_POWER_PSE)?1:2;
+ return (u_char *)&long_ret;
+ }
+ break;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT:
+ if (hardware->h_lport.p_power.devicetype) {
+ long_ret = (hardware->h_lport.p_power.supported)?1:2;
+ return (u_char *)&long_ret;
+ }
+ break;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED:
+ if (hardware->h_lport.p_power.devicetype) {
+ long_ret = (hardware->h_lport.p_power.enabled)?1:2;
+ return (u_char *)&long_ret;
+ }
+ break;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL:
+ if (hardware->h_lport.p_power.devicetype) {
+ long_ret = (hardware->h_lport.p_power.paircontrol)?1:2;
+ return (u_char *)&long_ret;
+ }
+ break;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS:
+ if (hardware->h_lport.p_power.devicetype) {
+ long_ret = hardware->h_lport.p_power.pairs;
+ return (u_char *)&long_ret;
+ }
+ break;
+ case LLDP_SNMP_LOCAL_DOT3_POWER_CLASS:
+ if (hardware->h_lport.p_power.devicetype && hardware->h_lport.p_power.class) {
+ long_ret = hardware->h_lport.p_power.class;
+ return (u_char *)&long_ret;
+ }
+ break;
#endif
#ifdef ENABLE_DOT1
case LLDP_SNMP_LOCAL_DOT1_PVID:
default:
break;
}
- return NULL;
+ if (!exact && (name[*length-1] < MAX_SUBID))
+ return agent_h_local_port(vp, name, length,
+ exact, var_len, write_method);
+ return NULL;
}
#ifdef ENABLE_DOT1
{1, 5, 4623, 1, 2, 1, 1, 3}},
{LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_local_port, 8,
{1, 5, 4623, 1, 2, 1, 1, 4}},
+ {LLDP_SNMP_LOCAL_DOT3_POWER_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_local_port, 8,
+ {1, 5, 4623, 1, 2, 2, 1, 1}},
+ {LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8,
+ {1, 5, 4623, 1, 2, 2, 1, 2}},
+ {LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
+ {1, 5, 4623, 1, 2, 2, 1, 3}},
+ {LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL, ASN_INTEGER, RONLY, agent_h_local_port, 8,
+ {1, 5, 4623, 1, 2, 2, 1, 4}},
+ {LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS, ASN_INTEGER, RONLY, agent_h_local_port, 8,
+ {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_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,
{ HMSG_SET_POLICY, client_handle_port_related },
{ HMSG_SET_POWER, client_handle_port_related },
#endif
+#ifdef ENABLE_DOT3
+ { HMSG_SET_DOT3_POWER, client_handle_port_related },
+#endif
#ifdef ENABLE_DOT1
{ HMSG_GET_VLANS, client_handle_port_related },
#endif
break;
}
break;
+#endif
+#ifdef ENABLE_DOT3
+ case HMSG_SET_DOT3_POWER:
+ p = (char*)&r->data + IFNAMSIZ;
+ memset(&hardware->h_lport.p_power, 0,
+ sizeof(struct lldpd_dot3_power));
+ if (ctl_msg_unpack_structure(STRUCT_LLDPD_DOT3_POWER,
+ &hardware->h_lport.p_power,
+ sizeof(struct lldpd_dot3_power),
+ r, &p) == -1) {
+ LLOG_WARNX("unable to set POE-MDI for %s",
+ ifname);
+ s->hdr.len = -1;
+ return;
+ }
+ break;
#endif
case HMSG_GET_NB_PORTS:
p = &s->data;
POKE_UINT16(port->p_mfs) &&
POKE_END_LLDP_TLV))
goto toobig;
+ /* Power */
+ if (port->p_power.devicetype) {
+ if (!(
+ POKE_START_LLDP_TLV(LLDP_TLV_ORG) &&
+ POKE_BYTES(dot3, sizeof(dot3)) &&
+ POKE_UINT8(LLDP_TLV_DOT3_POWER) &&
+ POKE_UINT8((
+ (((2 - port->p_power.devicetype) %(1<< 1))<<0) |
+ (( port->p_power.supported %(1<< 1))<<1) |
+ (( 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))
+ goto toobig;
+ }
#endif
#ifdef ENABLE_LLDPMED
extern void
display_interfaces(int s, const char * fmt, int argc, char *argv[]);
-#define LLDPCTL_ARGS "hdf:L:P:O:"
+#define LLDPCTL_ARGS "hdf:L:P:O:o:"
static void
usage(void)
fprintf(stderr, "-O poe Enable the trabsmission of LLDP-MED POE-MDI TLV\n");
fprintf(stderr, " for the given interfaces.\n");
#endif
+#ifdef ENABLE_DOT3
+ fprintf(stderr, "-o poe Enable the trabsmission of Dot3 POE-MDI TLV\n");
+ fprintf(stderr, " for the given interfaces.\n");
+#endif
fprintf(stderr, "\n");
LLOG_WARNX("The format POE-MDI is invalid (%s)", poe);
return -1;
}
+#endif
+
+#ifdef ENABLE_DOT3
+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;
+
+ if (strlen(poe) == 0)
+ return 0;
+ e = poe;
+ /* Device type */
+ if (!strncmp(e, "PD", 2))
+ device_type = LLDP_DOT3_POWER_PD;
+ else if (!strncmp(e, "PSE", 3))
+ device_type = LLDP_DOT3_POWER_PSE;
+ else {
+ LLOG_WARNX("Device type should be either 'PD' or 'PSE'.");
+ goto invalid_dot3_poe;
+ }
+
+ /* Supported */
+ if ((e = strchr(e, ':')) == NULL) {
+ 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);
+ goto invalid_dot3_poe;
+ }
+
+ /* Enabled */
+ if ((e = strchr(e, ':')) == NULL) {
+ 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);
+ goto invalid_dot3_poe;
+ }
+
+ /* Pair control */
+ if ((e = strchr(e, ':')) == NULL) {
+ 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);
+ goto invalid_dot3_poe;
+ }
+
+ /* Power pairs */
+ if ((e = strchr(e, ':')) == NULL) {
+ 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);
+ goto invalid_dot3_poe;
+ }
+
+ /* Class */
+ if ((e = strchr(e, ':')) == NULL) {
+ 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);
+ goto invalid_dot3_poe;
+ }
+
+ 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;
+ return 0;
+
+ invalid_dot3_poe:
+ LLOG_WARNX("The format POE-MDI is invalid (%s)", poe);
+ return -1;
+}
+#endif
+
+#ifdef ENABLE_LLDPMED
static void
set_location(int s, int argc, char *argv[])
{
}
#endif
+#ifdef ENABLE_DOT3
+static void
+set_dot3_power(int s, int argc, char *argv[])
+{
+ int i, ch;
+ struct interfaces ifs;
+ struct lldpd_interface *iff;
+ struct lldpd_port port;
+ void *p;
+ struct hmsg *h;
+
+ if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL)
+ fatal(NULL);
+
+ memset(&port, 0, sizeof(struct lldpd_port));
+ optind = 1;
+ while ((ch = getopt(argc, argv, LLDPCTL_ARGS)) != -1) {
+ switch (ch) {
+ case 'o':
+ if ((lldpd_parse_dot3_power(&port, optarg)) == -1)
+ fatalx("Incorrect POE-MDI.");
+ break;
+ }
+ }
+
+ get_interfaces(s, &ifs);
+ TAILQ_FOREACH(iff, &ifs, next) {
+ if (optind < argc) {
+ for (i = optind; i < argc; i++)
+ if (strncmp(argv[i], iff->name, IFNAMSIZ) == 0)
+ break;
+ if (i == argc)
+ continue;
+ }
+
+ ctl_msg_init(h, HMSG_SET_DOT3_POWER);
+ strlcpy((char *)&h->data, iff->name, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
+ p = (char*)&h->data + IFNAMSIZ;
+ if (ctl_msg_pack_structure(STRUCT_LLDPD_DOT3_POWER,
+ &port.p_power,
+ sizeof(struct lldpd_dot3_power), h, &p) == -1) {
+ LLOG_WARNX("set_dot3_power: Unable to set POE-MDI for %s", iff->name);
+ fatalx("aborting");
+ }
+ if (ctl_msg_send(s, h) == -1)
+ fatalx("set_dot3_power: unable to send request");
+ if (ctl_msg_recv(s, h) == -1)
+ fatalx("set_dot3_power: unable to receive answer");
+ if (h->hdr.type != HMSG_SET_DOT3_POWER)
+ fatalx("set_dot3_power: unknown answer type received");
+ LLOG_INFO("Dot3 POE-MDI successfully set for %s", iff->name);
+ }
+}
+#endif
+
int
main(int argc, char *argv[])
{
#define ACTION_SET_LOCATION (1 << 0)
#define ACTION_SET_POLICY (1 << 1)
#define ACTION_SET_POWER (1 << 2)
+#define ACTION_SET_DOT3_POWER (1 << 3)
int action = 0;
/*
#else
fprintf(stderr, "LLDP-MED support is not built-in\n");
usage();
+#endif
+ break;
+ case 'o':
+#ifdef ENABLE_DOT3
+ action |= ACTION_SET_DOT3_POWER;
+#else
+ fprintf(stderr, "Dot3 support is not built-in\n");
+ usage();
#endif
break;
default:
set_policy(s, argc, argv);
if (action & ACTION_SET_POWER)
set_power(s, argc, argv);
+#endif
+#ifdef ENABLE_DOT3
+ if (action & ACTION_SET_DOT3_POWER)
+ set_dot3_power(s, argc, argv);
#endif
if (!action)
display_interfaces(s, fmt, argc, argv);
HMSG_SET_LOCATION,
HMSG_SET_POLICY,
HMSG_SET_POWER,
+ HMSG_SET_DOT3_POWER,
HMSG_SHUTDOWN
};