.Nm
.Op Fl d
.Op Fl L Ar location
+.Op Fl P Ar policy
.Op Ar interface ...
.Sh DESCRIPTION
The
When setting a location for a given port, all previous locations are
erased. To erase all location, just use the empty string. There is
currently no way to get the location from the command line.
+.Pp
+.It Fl P Ar policy
+Enable the transmission of LLDP-MED Network Policy TLVs for the given
+interfaces. This option can be repeated several times to specify
+different policies. Format (without spaces!):
+.Pp
+.Em App-Type
+:
+.Ar U
+:
+.Ar T
+:
+.Ar VLAN-ID
+:
+.Ar L2-Prio
+:
+.Ar DSCP
+.Bl -tag -width "XX"
+.It Ar App-Type
+Valid application types (see ANSI/TIA-1057 table 12):
+.Bl -tag -width "X." -compact
+.It Sy 1
+Voice
+.It Sy 2
+Voice Signaling
+.It Sy 3
+Guest Voice
+.It Sy 4
+Guest Voice Signaling
+.It Sy 5
+Softphone Voice
+.It Sy 6
+Video Conferencing
+.It Sy 7
+Streaming Video
+.It Sy 8
+Video Signaling
+.El
+.It Ar U
+Unknown Policy Flag.
+.Bl -tag -width "X." -compact
+.It Sy 0
+Network policy for the specified application type is defined.
+.It Sy 1
+Network policy for the specified application type is required by
+the device but is currently unknown. This is used by Endpoint
+Devices, not by Network Connectivity Devices.
+.El
+.It Ar T
+Tagged Flag.
+.Bl -tag -width "X." -compact
+.It Sy 0
+Untagged VLAN. In this case the VLAN ID and the Layer 2 Priority
+are ignored and only the DSCP value has relevance.
+.It Sy 1
+Tagged VLAN.
+.El
+.It Ar VLAN-ID
+IEEE 802.1q VLAN ID (VID). A value of 1 through 4094 defines a
+VLAN ID. A value of 0 means that only the priority level is
+significant.
+.It Ar L2-Prio
+IEEE 802.1d / IEEE 802.1p Layer 2 Priority, also known as Class of Service
+(CoS), to be used for the specified application type.
+.Bl -tag -width "X." -compact
+.It Sy 1
+Background
+.It Sy 2
+Spare
+.It Sy 0
+Best Effort (default)
+.It Sy 3
+Excellent Effort
+.It Sy 4
+Controlled Load
+.It Sy 5
+Video
+.It Sy 6
+Voice
+.It Sy 7
+Network Control
+.El
+.It Ar DSCP
+DiffServ/Differentiated Services Code Point (DSCP) value as defined
+in IETF RFC 2474 for the specified application type. Value: 0 (default
+per RFC 2475) through 63. Note: The class selector DSCP values are
+backwards compatible for devices that only support the old IP
+precedence Type of Service (ToS) format. (See the RFCs for what
+these values mean.)
+.It Examples:
+.Bl -tag -width "X." -compact
+.It Sy 1:0:1:500:6:46
+Voice (1): not unknown (0), tagged (1), VLAN-ID 500, l2 prio Voice (6), DSCP 46 (EF, Expedited Forwarding)
+.It Sy 2:0:1:500:3:24
+Voice Signaling (2): not unknown (0), tagged (1), VLAN-ID 500, l2 prio Excellent Effort (3), DSCP 24 (CS3, Class Selector 3)
.El
.Sh FILES
.Bl -tag -width "/var/run/lldpd.socketXX" -compact
{ HMSG_GET_CHASSIS, client_handle_port_related },
#ifdef ENABLE_LLDPMED
{ HMSG_SET_LOCATION, client_handle_port_related },
+ { HMSG_SET_POLICY, client_handle_port_related },
#endif
#ifdef ENABLE_DOT1
{ HMSG_GET_VLANS, client_handle_port_related },
}
hardware->h_lport.p_med_cap_enabled |= LLDPMED_CAP_LOCATION;
break;
+ case HMSG_SET_POLICY:
+ p = (char*)&r->data + IFNAMSIZ;
+ for (i=0; i < LLDPMED_APPTYPE_LAST; i++) {
+ hardware->h_lport.p_med_policy[i].type = 0;
+ hardware->h_lport.p_med_policy[i].unknown = 0;
+ hardware->h_lport.p_med_policy[i].tagged = 0;
+ hardware->h_lport.p_med_policy[i].vid = 0;
+ hardware->h_lport.p_med_policy[i].priority = 0;
+ hardware->h_lport.p_med_policy[i].dscp = 0;
+ }
+ if (ctl_msg_unpack_structure(
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY,
+ hardware->h_lport.p_med_policy,
+ 8*sizeof(struct lldpd_med_policy),
+ r, &p) == -1) {
+ LLOG_WARNX("unable to set network policy for %s", ifname);
+ s->hdr.len = -1;
+ return;
+ }
+ hardware->h_lport.p_med_cap_enabled |=
+ LLDPMED_CAP_POLICY;
+ break;
#endif
case HMSG_GET_NB_PORTS:
p = &s->data;
fprintf(stderr, "-L location Enable the transmission of LLDP-MED location TLV for the\n");
fprintf(stderr, " given interfaces. Can be repeated to enable the transmission\n");
fprintf(stderr, " of the location in several formats.\n");
+ fprintf(stderr, "-P policy Enable the transmission of LLDP-MED Network Policy TLVs\n");
+ fprintf(stderr, " for the given interfaces. Can be repeated to specify\n");
+ fprintf(stderr, " different policies.\n");
#endif
fprintf(stderr, "\n");
return -1;
}
+static int
+lldpd_parse_policy(struct lldpd_port *port, const char *policy)
+{
+ const char *e;
+ int app_type = 0;
+ int unknown_policy_flag = 0;
+ int tagged_flag = 0;
+ int vlan_id = 0;
+ int l2_prio = 0;
+ int dscp = 0;
+
+ if (strlen(policy) == 0) {
+ return 0;
+ }
+
+ e = policy;
+
+ /* Application Type: */
+ app_type = atoi(e);
+ if (app_type < 1 || app_type > LLDPMED_APPTYPE_LAST) {
+ LLOG_WARNX("Application Type (%u) out of range.", app_type);
+ goto invalid_policy;
+ }
+
+ /* Unknown Policy Flag (U): */
+ if ((e = strchr(e, ':')) == NULL) {
+ LLOG_WARNX("Expected Unknown Policy Flag (U).");
+ goto invalid_policy;
+ }
+ e = e + 1;
+ unknown_policy_flag = atoi(e);
+ if (unknown_policy_flag < 0 || unknown_policy_flag > 1) {
+ LLOG_WARNX("Unknown Policy Flag (%u) out of range.", unknown_policy_flag);
+ goto invalid_policy;
+ }
+
+ /* Tagged Flag (T): */
+ if ((e = strchr(e, ':')) == NULL) {
+ LLOG_WARNX("Expected Tagged Flag (T).");
+ goto invalid_policy;
+ }
+ e = e + 1;
+ tagged_flag = atoi(e);
+ if (tagged_flag < 0 || tagged_flag > 1) {
+ LLOG_WARNX("Tagged Flag (%u) out of range.", tagged_flag);
+ goto invalid_policy;
+ }
+
+ /* VLAN-ID (VID): */
+ if ((e = strchr(e, ':')) == NULL) {
+ LLOG_WARNX("Expected VLAN ID (VID).");
+ goto invalid_policy;
+ }
+ e = e + 1;
+ vlan_id = atoi(e);
+ if (vlan_id < 0 || vlan_id > 4094) {
+ LLOG_WARNX("VLAN ID (%u) out of range.", vlan_id);
+ goto invalid_policy;
+ }
+
+ /* Layer 2 Priority: */
+ if ((e = strchr(e, ':')) == NULL) {
+ LLOG_WARNX("Expected Layer 2 Priority.");
+ goto invalid_policy;
+ }
+ e = e + 1;
+ l2_prio = atoi(e);
+ if (l2_prio < 0 || l2_prio > 7) {
+ LLOG_WARNX("Layer 2 Priority (%u) out of range.", l2_prio);
+ goto invalid_policy;
+ }
+
+ /* DSCP value: */
+ if ((e = strchr(e, ':')) == NULL) {
+ LLOG_WARNX("Expected DSCP value.");
+ goto invalid_policy;
+ }
+ e = e + 1;
+ dscp = atoi(e);
+ if (dscp < 0 || dscp > 63) {
+ LLOG_WARNX("DSCP value (%u) out of range.", dscp);
+ goto invalid_policy;
+ }
+
+ port->p_med_policy[app_type - 1].type = (u_int8_t) app_type;
+ port->p_med_policy[app_type - 1].unknown = (u_int8_t) unknown_policy_flag;
+ port->p_med_policy[app_type - 1].tagged = (u_int8_t) tagged_flag;
+ port->p_med_policy[app_type - 1].vid = (u_int16_t) vlan_id;
+ port->p_med_policy[app_type - 1].priority = (u_int8_t) l2_prio;
+ port->p_med_policy[app_type - 1].dscp = (u_int8_t) dscp;
+
+ port->p_med_cap_enabled |= LLDPMED_CAP_POLICY;
+ return 0;
+
+invalid_policy:
+ LLOG_WARNX("The format of the policy is invalid (%s)",
+ policy);
+ return -1;
+}
+
static void
set_location(int s, int argc, char *argv[])
{
LLOG_INFO("Location set succesfully for %s", iff->name);
}
}
+
+static void
+set_policy(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, "dP:")) != -1) {
+ switch (ch) {
+ case 'P':
+ if ((lldpd_parse_policy(&port, optarg)) == -1)
+ fatalx("Incorrect Network Policy.");
+ 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_POLICY);
+ strlcpy((char *)&h->data, iff->name, IFNAMSIZ);
+ h->hdr.len += IFNAMSIZ;
+ p = (char*)&h->data + IFNAMSIZ;
+ if (ctl_msg_pack_structure(
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY
+ STRUCT_LLDPD_MED_POLICY,
+ port.p_med_policy,
+ 8*sizeof(struct lldpd_med_policy), h, &p) == -1) {
+ LLOG_WARNX("set_policy: Unable to set Network Policy for %s", iff->name);
+ fatalx("aborting");
+ }
+ if (ctl_msg_send(s, h) == -1)
+ fatalx("set_policy: unable to send request");
+ if (ctl_msg_recv(s, h) == -1)
+ fatalx("set_policy: unable to receive answer");
+ if (h->hdr.type != HMSG_SET_POLICY)
+ fatalx("set_policy: unknown answer type received");
+ LLOG_INFO("Network Policy successfully set for %s", iff->name);
+ }
+}
#endif
int
int ch, s, debug = 1;
char * fmt = "plain";
#define ACTION_SET_LOCATION 1
+#define ACTION_SET_POLICY 2
int action = 0;
/*
* Get and parse command line options
*/
- while ((ch = getopt(argc, argv, "hdf:L:")) != -1) {
+ while ((ch = getopt(argc, argv, "hdf:L:P:")) != -1) {
switch (ch) {
case 'h':
usage();
#else
fprintf(stderr, "LLDP-MED support is not built-in\n");
usage();
+#endif
+ break;
+ case 'P':
+#ifdef ENABLE_LLDPMED
+ action = ACTION_SET_POLICY;
+#else
+ fprintf(stderr, "LLDP-MED support is not built-in\n");
+ usage();
#endif
break;
default:
case ACTION_SET_LOCATION:
set_location(s, argc, argv);
break;
+ case ACTION_SET_POLICY:
+ set_policy(s, argc, argv);
+ break;
#endif
default:
display_interfaces(s, fmt, argc, argv);