static int cmd_faststart(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "configure fast interval support"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } char *action = arg; if ((!strcmp(action, "enable") && (lldpctl_atom_set_int(config, lldpctl_k_config_fast_start_enabled, 1) == NULL)) || (!strcmp(action, "disable") && (lldpctl_atom_set_int(config, lldpctl_k_config_fast_start_enabled, 0) == NULL)) || (!strcmp(action, "delay") && (lldpctl_atom_set_str(config, lldpctl_k_config_fast_start_interval, cmdenv_get(env, "tx-interval")) == NULL))) { log_warnx("lldpctl", "unable to setup fast start. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "configruation for fast start applied"); lldpctl_atom_dec_ref(config); return 1; }
/** * Pause or resume execution of lldpd. * * @param conn The connection to lldpd. * @param pause 1 if we want to pause lldpd, 0 otherwise * @return 1 on success, 0 on error */ static int cmd_pause_resume(lldpctl_conn_t *conn, int pause) { lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_get_int(config, lldpctl_k_config_paused) == pause) { log_debug("lldpctl", "lldpd is already %s", pause?"paused":"resumed"); lldpctl_atom_dec_ref(config); return 1; } if (lldpctl_atom_set_int(config, lldpctl_k_config_paused, pause) == NULL) { log_warnx("lldpctl", "unable to ask lldpd to %s operations. %s", pause?"pause":"resume", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "lldpd should %s operations", pause?"pause":"resume"); lldpctl_atom_dec_ref(config); return 1; }
/* FIXME: see about compressing this with other functions */ static int cmd_chassis_mgmt_advertise(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "lldp management-addresses-advertisements %s", arg?"enable":"disable"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_chassis_mgmt_advertise, arg?1:0) == NULL) { log_warnx("lldpctl", "unable to %s management addresses advertisement: %s", arg?"enable":"disable", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "management addresses advertisement %s", arg?"enabled":"disabled"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_portid_type(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { char *value_str; int value = -1; log_debug("lldpctl", "lldp PortID TLV Subtype"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } value_str = arg; for (lldpctl_map_t *b_map = lldpctl_key_get_map(lldpctl_k_config_lldp_portid_type); b_map->string; b_map++) { if (!strcmp(b_map->string, value_str)) { value = b_map->value; break; } } if (value == -1) { log_warnx("lldpctl", "invalid value"); lldpctl_atom_dec_ref(config); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_lldp_portid_type, value) == NULL) { log_warnx("lldpctl", "unable to set LLDP PortID type." " %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "LLDP PortID TLV type set to new value : %s", value_str); lldpctl_atom_dec_ref(config); return 1; }
/** * Send an "update" request. */ static int cmd_update(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_info("lldpctl", "ask for global update"); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_tx_interval, -1) == NULL) { log_warnx("lldpctl", "unable to ask lldpd for immediate retransmission. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "immediate retransmission requested successfuly"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_update_descriptions(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", lldpctl_last_strerror(conn)); return 0; } if (lldpctl_atom_set_int(config, lldpctl_k_config_ifdescr_update, arg?1:0) == NULL) { log_warnx("lldpctl", "unable to %s interface description update: %s", arg?"enable":"disable", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } log_info("lldpctl", "interface description update %s", arg?"enabled":"disabled"); lldpctl_atom_dec_ref(config); return 1; }
static int cmd_custom_tlv_set(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { lldpctl_atom_t *port; const char *s; const char *name; uint8_t oui[LLDP_TLV_ORG_OUI_LEN]; uint8_t oui_info[LLDP_TLV_ORG_OUI_INFO_MAXLEN]; int oui_info_len = 0; uint16_t subtype = 0; log_debug("lldpctl", "lldp custom-tlv(s) %s", arg?"set":"clear"); if (!arg) goto set; s = cmdenv_get(env, "oui"); if (!s || ( sscanf(s, "%02hhx,%02hhx,%02hhx", &oui[0], &oui[1], &oui[2]) != 3 && sscanf(s, "%02hhX,%02hhX,%02hhX", &oui[0], &oui[1], &oui[2]) != 3) ) { log_warnx("lldpctl", "invalid OUI value '%s'", s); return 0; } s = cmdenv_get(env, "subtype"); if (!s) { log_warnx("lldpctl", "no subtype specified"); return 0; } else { subtype = (uint16_t)atoi(s); if (subtype > 255) { log_warnx("lldpctl", "invalid subtype range value '%s'", s); return 0; } } s = cmdenv_get(env, "oui-info"); /* This info is optional */ if (s) { const char delim[] = ","; char *s_copy = strdup(s); char *token = strtok(s_copy, delim); while (token != NULL) { if (sscanf(token, "%02hhx", &oui_info[oui_info_len]) == 1 || sscanf(token, "%02hhX", &oui_info[oui_info_len]) == 1) oui_info_len++; if (oui_info_len >= sizeof(oui_info)) break; token = strtok(NULL, delim); } free(s_copy); } set: while ((port = cmd_iterate_on_ports(conn, env, &name))) { lldpctl_atom_t *custom_tlvs; if (!arg) { lldpctl_atom_set(port, lldpctl_k_custom_tlvs_clear, NULL); } else if (!(custom_tlvs = lldpctl_atom_get(port, lldpctl_k_custom_tlvs))) { log_warnx("lldpctl", "unable to get custom TLVs for port %s", name); } else { lldpctl_atom_t *tlv = lldpctl_atom_create(custom_tlvs); if (!tlv) { log_warnx("lldpctl", "unable to create new custom TLV for port %s", name); } else { /* Configure custom TLV */ lldpctl_atom_set_buffer(tlv, lldpctl_k_custom_tlv_oui, oui, sizeof(oui)); lldpctl_atom_set_int(tlv, lldpctl_k_custom_tlv_oui_subtype, subtype); lldpctl_atom_set_buffer(tlv, lldpctl_k_custom_tlv_oui_info_string, oui_info, oui_info_len); /* Assign it to port */ lldpctl_atom_set(port, lldpctl_k_custom_tlv, tlv); lldpctl_atom_dec_ref(tlv); } lldpctl_atom_dec_ref(custom_tlvs); } } return 1; }
static int _cmd_medlocation(struct lldpctl_conn_t *conn, struct cmd_env *env, int format) { lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *med_location = NULL, *med_locations = NULL; const char *what = NULL; int ok = 0; med_locations = lldpctl_atom_get(port, lldpctl_k_port_med_locations); if (med_locations == NULL) { log_warnx("lldpctl", "unable to set LLDP-MED location: support seems unavailable"); goto end; } med_location = lldpctl_atom_iter_value(med_locations, lldpctl_atom_iter_next(med_locations, lldpctl_atom_iter(med_locations))); switch (format) { case LLDP_MED_LOCFORMAT_COORD: if ((what = "format", lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format)) == NULL || (what = "latitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_latitude, cmdenv_get(env, "latitude"))) == NULL || (what = "longitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_longitude, cmdenv_get(env, "longitude"))) == NULL || (what = "altitude", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_altitude, cmdenv_get(env, "altitude"))) == NULL || (what = "altitude unit", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_altitude_unit, cmdenv_get(env, "altitude-unit"))) == NULL || (what = "datum", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_geoid, cmdenv_get(env, "datum"))) == NULL) log_warnx("lldpctl", "unable to set LLDP MED location value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); else ok = 1; break; case LLDP_MED_LOCFORMAT_CIVIC: if ((what = "format", lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format)) == NULL || (what = "country", lldpctl_atom_set_str(med_location, lldpctl_k_med_location_country, cmdenv_get(env, "country"))) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED location value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); break; } ok = 1; for (lldpctl_map_t *addr_map = lldpctl_key_get_map(lldpctl_k_med_civicaddress_type); addr_map->string; addr_map++) { lldpctl_atom_t *cael, *caels; const char *value = cmdenv_get(env, addr_map->string); if (!value) continue; caels = lldpctl_atom_get(med_location, lldpctl_k_med_location_ca_elements); cael = lldpctl_atom_create(caels); if (lldpctl_atom_set_str(cael, lldpctl_k_med_civicaddress_type, addr_map->string) == NULL || lldpctl_atom_set_str(cael, lldpctl_k_med_civicaddress_value, value) == NULL || lldpctl_atom_set(med_location, lldpctl_k_med_location_ca_elements, cael) == NULL) { log_warnx("lldpctl", "unable to add a civic address element `%s`. %s", addr_map->string, lldpctl_last_strerror(conn)); ok = 0; } lldpctl_atom_dec_ref(cael); lldpctl_atom_dec_ref(caels); if (!ok) break; } break; case LLDP_MED_LOCFORMAT_ELIN: if (lldpctl_atom_set_int(med_location, lldpctl_k_med_location_format, format) == NULL || lldpctl_atom_set_str(med_location, lldpctl_k_med_location_elin, cmdenv_get(env, "elin")) == NULL) log_warnx("lldpctl", "unable to set LLDP MED location on %s. %s", name, lldpctl_last_strerror(conn)); else ok = 1; break; } if (ok) { if (lldpctl_atom_set(port, lldpctl_k_port_med_locations, med_location) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED location on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP-MED location has been set for port %s", name); } end: lldpctl_atom_dec_ref(med_location); lldpctl_atom_dec_ref(med_locations); lldpctl_atom_dec_ref(port); } return 1; }
static int cmd_medpolicy(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set MED policy"); lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *med_policy = NULL, *med_policies = NULL; const char *what = NULL; med_policies = lldpctl_atom_get(port, lldpctl_k_port_med_policies); if (med_policies == NULL) { log_warnx("lldpctl", "unable to set LLDP-MED policies: support seems unavailable"); goto end; } med_policy = lldpctl_atom_iter_value(med_policies, lldpctl_atom_iter_next(med_policies, lldpctl_atom_iter(med_policies))); if ((what = "application", lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_type, cmdenv_get(env, "application"))) == NULL || (what = "unknown flag", lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_unknown, cmdenv_get(env, "unknown")?1:0)) == NULL || (what = "vlan", cmdenv_get(env, "vlan")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_vid, cmdenv_get(env, "vlan")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_vid, 0)) == NULL || (what = "priority", cmdenv_get(env, "priority")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_priority, cmdenv_get(env, "priority")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_priority, 0)) == NULL || (what = "dscp", cmdenv_get(env, "dscp")? lldpctl_atom_set_str(med_policy, lldpctl_k_med_policy_dscp, cmdenv_get(env, "dscp")): lldpctl_atom_set_int(med_policy, lldpctl_k_med_policy_dscp, 0)) == NULL) log_warnx("lldpctl", "unable to set LLDP MED policy value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); else { if (lldpctl_atom_set(port, lldpctl_k_port_med_policies, med_policy) == NULL) { log_warnx("lldpctl", "unable to set LLDP MED policy on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP-MED policy has been set for port %s", name); } end: lldpctl_atom_dec_ref(med_policy); lldpctl_atom_dec_ref(med_policies); lldpctl_atom_dec_ref(port); } return 1; }
static int cmd_dot3power(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { log_debug("lldpctl", "set dot3 power"); lldpctl_atom_t *iface; while ((iface = cmd_iterate_on_interfaces(conn, env))) { const char *name = lldpctl_atom_get_str(iface, lldpctl_k_interface_name); lldpctl_atom_t *port = lldpctl_get_port(iface); lldpctl_atom_t *dot3_power; const char *what = NULL; int ok = 1; dot3_power = lldpctl_atom_get(port, lldpctl_k_port_dot3_power); if (dot3_power == NULL) { log_warnx("lldpctl", "unable to set Dot3 power: support seems unavailable"); goto end; } if ((what = "device type", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_devicetype, cmdenv_get(env, "device-type"))) == NULL || /* Flags */ (what = "supported flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_supported, cmdenv_get(env, "supported")?1:0)) == NULL || (what = "enabled flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_enabled, cmdenv_get(env, "enabled")?1:0)) == NULL || (what = "paircontrol flag", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_paircontrol, cmdenv_get(env, "paircontrol")?1:0)) == NULL || /* Powerpairs */ (what = "power pairs", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_pairs, cmdenv_get(env, "powerpairs"))) == NULL || /* Class */ (what = "power class", cmdenv_get(env, "class")? lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_class, cmdenv_get(env, "class")): lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_class, 0)) == NULL || (what = "802.3at type", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_type, 0)) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); ok = 0; } else if (cmdenv_get(env, "typeat")) { int typeat = cmdenv_get(env, "typeat")[0] - '0'; const char *source = cmdenv_get(env, "source"); if ((what = "802.3at type", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_type, typeat)) == NULL || (what = "source", lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_source, (!strcmp(source, "primary"))?LLDP_DOT3_POWER_SOURCE_PRIMARY: (!strcmp(source, "backup"))? LLDP_DOT3_POWER_SOURCE_BACKUP: (!strcmp(source, "pse"))? LLDP_DOT3_POWER_SOURCE_PSE: (!strcmp(source, "local"))? LLDP_DOT3_POWER_SOURCE_LOCAL: (!strcmp(source, "both"))? LLDP_DOT3_POWER_SOURCE_BOTH: LLDP_DOT3_POWER_SOURCE_UNKNOWN)) == NULL || (what = "priority", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_priority, cmdenv_get(env, "priority"))) == NULL || (what = "requested power", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_requested, cmdenv_get(env, "requested"))) == NULL || (what = "allocated power", lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_allocated, cmdenv_get(env, "allocated"))) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power value for %s on %s. %s.", what, name, lldpctl_last_strerror(conn)); ok = 0; } } if (ok) { if (lldpctl_atom_set(port, lldpctl_k_port_dot3_power, dot3_power) == NULL) { log_warnx("lldpctl", "unable to set LLDP Dot3 power on %s. %s.", name, lldpctl_last_strerror(conn)); } else log_info("lldpctl", "LLDP Dot3 power has been set for port %s", name); } end: lldpctl_atom_dec_ref(dot3_power); lldpctl_atom_dec_ref(port); } return 1; }