]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpcli: split actions.c in several files
authorVincent Bernat <bernat@luffy.cx>
Tue, 22 Jan 2013 21:49:33 +0000 (22:49 +0100)
committerVincent Bernat <bernat@luffy.cx>
Tue, 22 Jan 2013 21:49:33 +0000 (22:49 +0100)
We need `configure` to be more modulable.

src/client/Makefile.am
src/client/client.h
src/client/commands.c
src/client/conf-dot3.c [new file with mode: 0644]
src/client/conf-med.c [moved from src/client/actions.c with 51% similarity]
src/client/conf-power.c [new file with mode: 0644]
src/client/conf.c [new file with mode: 0644]

index 8d768bae9453e6270e7640ad115c7782fd2f0dbd..cd2b4f97b41efaf62edd1bd12c82f812e9ff1c9a 100644 (file)
@@ -6,7 +6,8 @@ install-exec-local: lldpcli
 uninstall-local:
        cd $(DESTDIR)$(sbindir) && rm -f lldpctl
 
-lldpcli_SOURCES  = client.h lldpcli.c display.c actions.c \
+lldpcli_SOURCES  = client.h lldpcli.c display.c \
+       conf.c conf-med.c conf-dot3.c conf-power.c \
        commands.c show.c \
        misc.c tokenizer.c \
        writer.h text_writer.c kv_writer.c
index 0e1d73c6193ad073c39dea30fa5c6450bd2800a4..459e40496b23acd453c92dd17fea3de317caf9a3 100644 (file)
@@ -92,6 +92,8 @@ int cmd_store_env_value_and_pop2(struct lldpctl_conn_t *, struct writer *,
     struct cmd_env *, void *);
 int cmd_store_env_value_and_pop3(struct lldpctl_conn_t *, struct writer *,
     struct cmd_env *, void *);
+int cmd_store_something_env_value_and_pop2(const char *, struct cmd_env *,
+    void *);
 lldpctl_atom_t* cmd_iterate_on_interfaces(struct lldpctl_conn_t *,
     struct cmd_env *);
 void cmd_restrict_ports(struct cmd_node *);
@@ -114,8 +116,12 @@ void display_configuration(lldpctl_conn_t *, struct writer *);
 void register_commands_show(struct cmd_node *);
 void register_commands_watch(struct cmd_node *);
 
-/* actions.c */
+/* conf*.c */
 void register_commands_configure(struct cmd_node *);
+void register_commands_configure_med(struct cmd_node *);
+void register_commands_configure_dot3(struct cmd_node *);
+void register_commands_medpow(struct cmd_node *);
+void register_commands_dot3pow(struct cmd_node *);
 
 /* tokenizer.c */
 int tokenize_line(const char*, int*, char***);
index 869ecdacd8afbeb34783519a8da7e55465bb3b68..d16259ce24b7b5ea06bdfcdb04f82c4d52ddb8db 100644 (file)
@@ -606,6 +606,13 @@ cmd_store_env_value_and_pop3(struct lldpctl_conn_t *conn, struct writer *w,
        return (cmdenv_put(env, key, cmdenv_arg(env)) != -1 &&
            cmdenv_pop(env, 3) != -1);
 }
+int
+cmd_store_something_env_value_and_pop2(const char *what,
+    struct cmd_env *env, void *value)
+{
+       return (cmdenv_put(env, what, value) != -1 &&
+           cmdenv_pop(env, 2) != -1);
+}
 
 /**
  * Provide an iterator on all interfaces contained in "ports".
diff --git a/src/client/conf-dot3.c b/src/client/conf-dot3.c
new file mode 100644 (file)
index 0000000..5588f75
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- mode: c; c-file-style: "openbsd" -*- */
+/*
+ * Copyright (c) 2013 Vincent Bernat <bernat@luffy.cx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <string.h>
+
+#include "client.h"
+#include "../log.h"
+
+/**
+ * Commands to configure dot3
+ */
+void
+register_commands_configure_dot3(struct cmd_node *configure)
+{
+       struct cmd_node *configure_dot3 = commands_new(
+               configure,
+               "dot3", "Dot3 configuration",
+               NULL, NULL, NULL);
+       register_commands_dot3pow(configure_dot3);
+}
similarity index 51%
rename from src/client/actions.c
rename to src/client/conf-med.c
index 85af9dc3783f57d1586563c361ccad7bb9faab80..4aef70c91dfa5f4b6aae64aeff7eb925e94bc13e 100644 (file)
@@ -235,150 +235,6 @@ cmd_medpolicy(struct lldpctl_conn_t *conn, struct writer *w,
        return 1;
 }
 
-static int
-cmd_medpower(struct lldpctl_conn_t *conn, struct writer *w,
-    struct cmd_env *env, void *arg)
-{
-       log_debug("lldpctl", "set MED 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 *med_power;
-               const char *what = NULL;
-
-               med_power = lldpctl_atom_get(port, lldpctl_k_port_med_power);
-               if (med_power == NULL) {
-                       log_warnx("lldpctl", "unable to set LLDP-MED power: support seems unavailable");
-                       goto end;
-               }
-
-               if ((what = "device type", lldpctl_atom_set_str(med_power,
-                           lldpctl_k_med_power_type,
-                           cmdenv_get(env, "device-type"))) == NULL ||
-                   (what = "power source", lldpctl_atom_set_str(med_power,
-                       lldpctl_k_med_power_source,
-                       cmdenv_get(env, "source"))) == NULL ||
-                   (what = "power priority", lldpctl_atom_set_str(med_power,
-                       lldpctl_k_med_power_priority,
-                       cmdenv_get(env, "priority"))) == NULL ||
-                   (what = "power value", lldpctl_atom_set_str(med_power,
-                       lldpctl_k_med_power_val,
-                       cmdenv_get(env, "value"))) == NULL)
-                       log_warnx("lldpctl",
-                           "unable to set LLDP MED power value for %s on %s. %s.",
-                           what, name, lldpctl_last_strerror(conn));
-               else {
-                       if (lldpctl_atom_set(port, lldpctl_k_port_med_power,
-                               med_power) == NULL) {
-                               log_warnx("lldpctl", "unable to set LLDP MED power on %s. %s.",
-                                   name, lldpctl_last_strerror(conn));
-                       } else
-                               log_info("lldpctl", "LLDP-MED power has been set for port %s",
-                                   name);
-               }
-
-       end:
-               lldpctl_atom_dec_ref(med_power);
-               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;
-}
-
 /**
  * Register `configure med location coordinate` commands.
  */
@@ -517,31 +373,12 @@ cmd_check_application_but_no(struct cmd_env *env, void *arg)
        return 1;
 }
 static int
-cmd_store_something_env_value_and_pop2(const char *what,
-    struct cmd_env *env, void *value)
-{
-       return (cmdenv_put(env, what, value) != -1 &&
-           cmdenv_pop(env, 2) != -1);
-}
-static int
 cmd_store_app_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
     struct cmd_env *env, void *value)
 {
        return cmd_store_something_env_value_and_pop2("application", env, value);
 }
 static int
-cmd_store_powerpairs_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
-    struct cmd_env *env, void *value)
-{
-       return cmd_store_something_env_value_and_pop2("powerpairs", env, value);
-}
-static int
-cmd_store_class_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
-    struct cmd_env *env, void *value)
-{
-       return cmd_store_something_env_value_and_pop2("class", env, value);
-}
-static int
 cmd_store_prio_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
     struct cmd_env *env, void *value)
 {
@@ -619,294 +456,18 @@ register_commands_medpol(struct cmd_node *configure_med)
        }
 }
 
-static int
-cmd_check_type_but_no(struct cmd_env *env, void *arg)
-{
-       const char *what = arg;
-       if (!cmdenv_get(env, "device-type")) return 0;
-       if (cmdenv_get(env, what)) return 0;
-       return 1;
-}
-static int
-cmd_check_typeat_but_no(struct cmd_env *env, void *arg)
-{
-       const char *what = arg;
-       if (!cmdenv_get(env, "typeat")) return 0;
-       if (cmdenv_get(env, what)) return 0;
-       return 1;
-}
-static int
-cmd_check_type(struct cmd_env *env, const char *type)
-{
-       const char *etype = cmdenv_get(env, "device-type");
-       if (!etype) return 0;
-       return (!strcmp(type, etype));
-}
-static int
-cmd_check_pse(struct cmd_env *env, void *arg)
-{
-       return cmd_check_type(env, "pse");
-}
-static int
-cmd_check_pd(struct cmd_env *env, void *arg)
-{
-       return cmd_check_type(env, "pd");
-}
-
-static void
-register_commands_pow_source(struct cmd_node *source)
-{
-       commands_new(source,
-           "unknown", "Unknown power source",
-           NULL, cmd_store_env_value_and_pop2, "source");
-       commands_new(source,
-           "primary", "Primary power source",
-           cmd_check_pse, cmd_store_env_value_and_pop2, "source");
-       commands_new(source,
-           "backup", "Backup power source",
-           cmd_check_pse, cmd_store_env_value_and_pop2, "source");
-       commands_new(source,
-           "pse", "Power source is PSE",
-           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
-       commands_new(source,
-           "local", "Local power source",
-           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
-       commands_new(source,
-           "both", "Both PSE and local source available",
-           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
-}
-
-static void
-register_commands_pow_priority(struct cmd_node *priority, int key)
-{
-       for (lldpctl_map_t *prio_map =
-                lldpctl_key_get_map(key);
-            prio_map->string;
-            prio_map++) {
-               char *tag = strdup(totag(prio_map->string)); /* TODO: memory leak, happens once */
-               commands_new(
-                       priority,
-                       tag,
-                       prio_map->string,
-                       NULL, cmd_store_prio_env_value_and_pop2, prio_map->string);
-       }
-}
-
-/**
- * Register `configure med power` commands.
- */
-static void
-register_commands_medpow(struct cmd_node *configure_med)
-{
-       struct cmd_node *configure_medpower = commands_new(
-               configure_med,
-               "power", "MED power configuration",
-               NULL, NULL, NULL);
-
-       commands_new(
-               configure_medpower,
-               NEWLINE, "Apply new MED power configuration",
-               cmd_check_env, cmd_medpower, "device-type,source,priority,value");
-
-       /* Type: PSE or PD */
-       commands_new(
-               configure_medpower,
-               "pd", "MED power consumer",
-               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
-       commands_new(
-               configure_medpower,
-               "pse", "MED power provider",
-               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
-
-       /* Source */
-       struct cmd_node *source = commands_new(
-               configure_medpower,
-               "source", "MED power source",
-               cmd_check_type_but_no, NULL, "source");
-       register_commands_pow_source(source);
-
-       /* Priority */
-       struct cmd_node *priority = commands_new(
-               configure_medpower,
-               "priority", "MED power priority",
-               cmd_check_type_but_no, NULL, "priority");
-       register_commands_pow_priority(priority, lldpctl_k_med_power_priority);
-
-       /* Value */
-       commands_new(
-               commands_new(configure_medpower,
-                   "value", "MED power value",
-                   cmd_check_type_but_no, NULL, "value"),
-               NULL, "MED power value in milliwatts",
-               NULL, cmd_store_env_value_and_pop2, "value");
-}
-
-static int
-cmd_check_env_power(struct cmd_env *env, void *nothing)
-{
-       /* We need type and powerpair but if we have typeat, we also request
-        * source, priority, requested and allocated. */
-       if (!cmdenv_get(env, "device-type")) return 0;
-       if (!cmdenv_get(env, "powerpairs")) return 0;
-       if (cmdenv_get(env, "typeat")) {
-               return (!!cmdenv_get(env, "source") &&
-                   !!cmdenv_get(env, "priority") &&
-                   !!cmdenv_get(env, "requested") &&
-                   !!cmdenv_get(env, "allocated"));
-       }
-       return 1;
-}
-
 /**
- * Register `configure med dot3` commands.
- */
-static void
-register_commands_dot3pow(struct cmd_node *configure_dot3)
-{
-       struct cmd_node *configure_dot3power = commands_new(
-               configure_dot3,
-               "power", "Dot3 power configuration",
-               NULL, NULL, NULL);
-
-       commands_new(
-               configure_dot3power,
-               NEWLINE, "Apply new Dot3 power configuration",
-               cmd_check_env_power, cmd_dot3power, NULL);
-
-       /* Type: PSE or PD */
-       commands_new(
-               configure_dot3power,
-               "pd", "Dot3 power consumer",
-               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
-       commands_new(
-               configure_dot3power,
-               "pse", "Dot3 power provider",
-               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
-
-       /* Flags */
-       commands_new(
-               configure_dot3power,
-               "supported", "MDI power support present",
-               cmd_check_type_but_no, cmd_store_env_and_pop, "supported");
-       commands_new(
-               configure_dot3power,
-               "enabled", "MDI power support enabled",
-               cmd_check_type_but_no, cmd_store_env_and_pop, "enabled");
-       commands_new(
-               configure_dot3power,
-               "paircontrol", "MDI power pair can be selected",
-               cmd_check_type_but_no, cmd_store_env_and_pop, "paircontrol");
-
-       /* Power pairs */
-       struct cmd_node *powerpairs = commands_new(
-               configure_dot3power,
-               "powerpairs", "Which pairs are currently used for power (mandatory)",
-               cmd_check_type_but_no, NULL, "powerpairs");
-       for (lldpctl_map_t *pp_map =
-                lldpctl_key_get_map(lldpctl_k_dot3_power_pairs);
-            pp_map->string;
-            pp_map++) {
-               commands_new(
-                       powerpairs,
-                       pp_map->string,
-                       pp_map->string,
-                       NULL, cmd_store_powerpairs_env_value_and_pop2, pp_map->string);
-       }
-
-       /* Class */
-       struct cmd_node *class = commands_new(
-               configure_dot3power,
-               "class", "Power class",
-               cmd_check_type_but_no, NULL, "class");
-       for (lldpctl_map_t *class_map =
-                lldpctl_key_get_map(lldpctl_k_dot3_power_class);
-            class_map->string;
-            class_map++) {
-               const char *tag = strdup(totag(class_map->string));
-               commands_new(
-                       class,
-                       tag,
-                       class_map->string,
-                       NULL, cmd_store_class_env_value_and_pop2, class_map->string);
-       }
-
-       /* 802.3at type */
-       struct cmd_node *typeat = commands_new(
-               configure_dot3power,
-               "type", "802.3at device type",
-               cmd_check_type_but_no, NULL, "typeat");
-       commands_new(typeat,
-           "1", "802.3at type 1",
-           NULL, cmd_store_env_value_and_pop2, "typeat");
-       commands_new(typeat,
-           "2", "802.3at type 2",
-           NULL, cmd_store_env_value_and_pop2, "typeat");
-
-       /* Source */
-       struct cmd_node *source = commands_new(
-               configure_dot3power,
-               "source", "802.3at dot3 power source (mandatory)",
-               cmd_check_typeat_but_no, NULL, "source");
-       register_commands_pow_source(source);
-
-       /* Priority */
-       struct cmd_node *priority = commands_new(
-               configure_dot3power,
-               "priority", "802.3at dot3 power priority (mandatory)",
-               cmd_check_typeat_but_no, NULL, "priority");
-       register_commands_pow_priority(priority, lldpctl_k_dot3_power_priority);
-
-       /* Values */
-       commands_new(
-               commands_new(configure_dot3power,
-                   "requested", "802.3at dot3 power value requested (mandatory)",
-                   cmd_check_typeat_but_no, NULL, "requested"),
-               NULL, "802.3at power value requested in milliwatts",
-               NULL, cmd_store_env_value_and_pop2, "requested");
-       commands_new(
-               commands_new(configure_dot3power,
-                   "allocated", "802.3at dot3 power value allocated (mandatory)",
-                   cmd_check_typeat_but_no, NULL, "allocated"),
-               NULL, "802.3at power value allocated in milliwatts",
-               NULL, cmd_store_env_value_and_pop2, "allocated");
-}
-
-/**
- * Register `configure` and `no configure` commands.
+ * Register "configure med *"
  */
 void
-register_commands_configure(struct cmd_node *root)
+register_commands_configure_med(struct cmd_node *configure)
 {
-       int has_med  = (lldpctl_key_get_map(
-                   lldpctl_k_med_policy_type)[0].string != NULL);
-       int has_dot3 = (lldpctl_key_get_map(
-                   lldpctl_k_dot3_power_class)[0].string != NULL);
-       if (!has_med && !has_dot3) return;
-
-       struct cmd_node *configure = commands_new(
-               root,
-               "configure",
-               "Change system settings",
+       struct cmd_node *configure_med = commands_new(
+               configure,
+               "med", "MED configuration",
                NULL, NULL, NULL);
-       cmd_restrict_ports(configure);
-
-       if (has_med) {
-               struct cmd_node *configure_med = commands_new(
-                       configure,
-                       "med", "MED configuration",
-                       NULL, NULL, NULL);
 
-               register_commands_medloc(configure_med);
-               register_commands_medpol(configure_med);
-               register_commands_medpow(configure_med);
-       }
-
-       if (has_dot3) {
-               struct cmd_node *configure_dot3 = commands_new(
-                       configure,
-                       "dot3", "Dot3 configuration",
-                       NULL, NULL, NULL);
-
-               register_commands_dot3pow(configure_dot3);
-       }
+       register_commands_medloc(configure_med);
+       register_commands_medpol(configure_med);
+       register_commands_medpow(configure_med);
 }
diff --git a/src/client/conf-power.c b/src/client/conf-power.c
new file mode 100644 (file)
index 0000000..b529a76
--- /dev/null
@@ -0,0 +1,437 @@
+/* -*- mode: c; c-file-style: "openbsd" -*- */
+/*
+ * Copyright (c) 2013 Vincent Bernat <bernat@luffy.cx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <string.h>
+
+#include "client.h"
+#include "../log.h"
+
+static int
+cmd_medpower(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *arg)
+{
+       log_debug("lldpctl", "set MED 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 *med_power;
+               const char *what = NULL;
+
+               med_power = lldpctl_atom_get(port, lldpctl_k_port_med_power);
+               if (med_power == NULL) {
+                       log_warnx("lldpctl", "unable to set LLDP-MED power: support seems unavailable");
+                       goto end;
+               }
+
+               if ((what = "device type", lldpctl_atom_set_str(med_power,
+                           lldpctl_k_med_power_type,
+                           cmdenv_get(env, "device-type"))) == NULL ||
+                   (what = "power source", lldpctl_atom_set_str(med_power,
+                       lldpctl_k_med_power_source,
+                       cmdenv_get(env, "source"))) == NULL ||
+                   (what = "power priority", lldpctl_atom_set_str(med_power,
+                       lldpctl_k_med_power_priority,
+                       cmdenv_get(env, "priority"))) == NULL ||
+                   (what = "power value", lldpctl_atom_set_str(med_power,
+                       lldpctl_k_med_power_val,
+                       cmdenv_get(env, "value"))) == NULL)
+                       log_warnx("lldpctl",
+                           "unable to set LLDP MED power value for %s on %s. %s.",
+                           what, name, lldpctl_last_strerror(conn));
+               else {
+                       if (lldpctl_atom_set(port, lldpctl_k_port_med_power,
+                               med_power) == NULL) {
+                               log_warnx("lldpctl", "unable to set LLDP MED power on %s. %s.",
+                                   name, lldpctl_last_strerror(conn));
+                       } else
+                               log_info("lldpctl", "LLDP-MED power has been set for port %s",
+                                   name);
+               }
+
+       end:
+               lldpctl_atom_dec_ref(med_power);
+               lldpctl_atom_dec_ref(port);
+       }
+       return 1;
+}
+
+static int
+cmd_store_powerpairs_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *value)
+{
+       return cmd_store_something_env_value_and_pop2("powerpairs", env, value);
+}
+static int
+cmd_store_class_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *value)
+{
+       return cmd_store_something_env_value_and_pop2("class", env, value);
+}
+static int
+cmd_store_prio_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *value)
+{
+       return cmd_store_something_env_value_and_pop2("priority", env, value);
+}
+
+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;
+}
+
+static int
+cmd_check_type_but_no(struct cmd_env *env, void *arg)
+{
+       const char *what = arg;
+       if (!cmdenv_get(env, "device-type")) return 0;
+       if (cmdenv_get(env, what)) return 0;
+       return 1;
+}
+static int
+cmd_check_typeat_but_no(struct cmd_env *env, void *arg)
+{
+       const char *what = arg;
+       if (!cmdenv_get(env, "typeat")) return 0;
+       if (cmdenv_get(env, what)) return 0;
+       return 1;
+}
+static int
+cmd_check_type(struct cmd_env *env, const char *type)
+{
+       const char *etype = cmdenv_get(env, "device-type");
+       if (!etype) return 0;
+       return (!strcmp(type, etype));
+}
+static int
+cmd_check_pse(struct cmd_env *env, void *arg)
+{
+       return cmd_check_type(env, "pse");
+}
+static int
+cmd_check_pd(struct cmd_env *env, void *arg)
+{
+       return cmd_check_type(env, "pd");
+}
+
+static void
+register_commands_pow_source(struct cmd_node *source)
+{
+       commands_new(source,
+           "unknown", "Unknown power source",
+           NULL, cmd_store_env_value_and_pop2, "source");
+       commands_new(source,
+           "primary", "Primary power source",
+           cmd_check_pse, cmd_store_env_value_and_pop2, "source");
+       commands_new(source,
+           "backup", "Backup power source",
+           cmd_check_pse, cmd_store_env_value_and_pop2, "source");
+       commands_new(source,
+           "pse", "Power source is PSE",
+           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
+       commands_new(source,
+           "local", "Local power source",
+           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
+       commands_new(source,
+           "both", "Both PSE and local source available",
+           cmd_check_pd, cmd_store_env_value_and_pop2, "source");
+}
+
+static void
+register_commands_pow_priority(struct cmd_node *priority, int key)
+{
+       for (lldpctl_map_t *prio_map =
+                lldpctl_key_get_map(key);
+            prio_map->string;
+            prio_map++) {
+               char *tag = strdup(totag(prio_map->string)); /* TODO: memory leak, happens once */
+               commands_new(
+                       priority,
+                       tag,
+                       prio_map->string,
+                       NULL, cmd_store_prio_env_value_and_pop2, prio_map->string);
+       }
+}
+
+/**
+ * Register `configure med power` commands.
+ */
+void
+register_commands_medpow(struct cmd_node *configure_med)
+{
+       struct cmd_node *configure_medpower = commands_new(
+               configure_med,
+               "power", "MED power configuration",
+               NULL, NULL, NULL);
+
+       commands_new(
+               configure_medpower,
+               NEWLINE, "Apply new MED power configuration",
+               cmd_check_env, cmd_medpower, "device-type,source,priority,value");
+
+       /* Type: PSE or PD */
+       commands_new(
+               configure_medpower,
+               "pd", "MED power consumer",
+               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
+       commands_new(
+               configure_medpower,
+               "pse", "MED power provider",
+               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
+
+       /* Source */
+       struct cmd_node *source = commands_new(
+               configure_medpower,
+               "source", "MED power source",
+               cmd_check_type_but_no, NULL, "source");
+       register_commands_pow_source(source);
+
+       /* Priority */
+       struct cmd_node *priority = commands_new(
+               configure_medpower,
+               "priority", "MED power priority",
+               cmd_check_type_but_no, NULL, "priority");
+       register_commands_pow_priority(priority, lldpctl_k_med_power_priority);
+
+       /* Value */
+       commands_new(
+               commands_new(configure_medpower,
+                   "value", "MED power value",
+                   cmd_check_type_but_no, NULL, "value"),
+               NULL, "MED power value in milliwatts",
+               NULL, cmd_store_env_value_and_pop2, "value");
+}
+
+static int
+cmd_check_env_power(struct cmd_env *env, void *nothing)
+{
+       /* We need type and powerpair but if we have typeat, we also request
+        * source, priority, requested and allocated. */
+       if (!cmdenv_get(env, "device-type")) return 0;
+       if (!cmdenv_get(env, "powerpairs")) return 0;
+       if (cmdenv_get(env, "typeat")) {
+               return (!!cmdenv_get(env, "source") &&
+                   !!cmdenv_get(env, "priority") &&
+                   !!cmdenv_get(env, "requested") &&
+                   !!cmdenv_get(env, "allocated"));
+       }
+       return 1;
+}
+
+/**
+ * Register `configure med dot3` commands.
+ */
+void
+register_commands_dot3pow(struct cmd_node *configure_dot3)
+{
+       struct cmd_node *configure_dot3power = commands_new(
+               configure_dot3,
+               "power", "Dot3 power configuration",
+               NULL, NULL, NULL);
+
+       commands_new(
+               configure_dot3power,
+               NEWLINE, "Apply new Dot3 power configuration",
+               cmd_check_env_power, cmd_dot3power, NULL);
+
+       /* Type: PSE or PD */
+       commands_new(
+               configure_dot3power,
+               "pd", "Dot3 power consumer",
+               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
+       commands_new(
+               configure_dot3power,
+               "pse", "Dot3 power provider",
+               cmd_check_no_env, cmd_store_env_value_and_pop, "device-type");
+
+       /* Flags */
+       commands_new(
+               configure_dot3power,
+               "supported", "MDI power support present",
+               cmd_check_type_but_no, cmd_store_env_and_pop, "supported");
+       commands_new(
+               configure_dot3power,
+               "enabled", "MDI power support enabled",
+               cmd_check_type_but_no, cmd_store_env_and_pop, "enabled");
+       commands_new(
+               configure_dot3power,
+               "paircontrol", "MDI power pair can be selected",
+               cmd_check_type_but_no, cmd_store_env_and_pop, "paircontrol");
+
+       /* Power pairs */
+       struct cmd_node *powerpairs = commands_new(
+               configure_dot3power,
+               "powerpairs", "Which pairs are currently used for power (mandatory)",
+               cmd_check_type_but_no, NULL, "powerpairs");
+       for (lldpctl_map_t *pp_map =
+                lldpctl_key_get_map(lldpctl_k_dot3_power_pairs);
+            pp_map->string;
+            pp_map++) {
+               commands_new(
+                       powerpairs,
+                       pp_map->string,
+                       pp_map->string,
+                       NULL, cmd_store_powerpairs_env_value_and_pop2, pp_map->string);
+       }
+
+       /* Class */
+       struct cmd_node *class = commands_new(
+               configure_dot3power,
+               "class", "Power class",
+               cmd_check_type_but_no, NULL, "class");
+       for (lldpctl_map_t *class_map =
+                lldpctl_key_get_map(lldpctl_k_dot3_power_class);
+            class_map->string;
+            class_map++) {
+               const char *tag = strdup(totag(class_map->string));
+               commands_new(
+                       class,
+                       tag,
+                       class_map->string,
+                       NULL, cmd_store_class_env_value_and_pop2, class_map->string);
+       }
+
+       /* 802.3at type */
+       struct cmd_node *typeat = commands_new(
+               configure_dot3power,
+               "type", "802.3at device type",
+               cmd_check_type_but_no, NULL, "typeat");
+       commands_new(typeat,
+           "1", "802.3at type 1",
+           NULL, cmd_store_env_value_and_pop2, "typeat");
+       commands_new(typeat,
+           "2", "802.3at type 2",
+           NULL, cmd_store_env_value_and_pop2, "typeat");
+
+       /* Source */
+       struct cmd_node *source = commands_new(
+               configure_dot3power,
+               "source", "802.3at dot3 power source (mandatory)",
+               cmd_check_typeat_but_no, NULL, "source");
+       register_commands_pow_source(source);
+
+       /* Priority */
+       struct cmd_node *priority = commands_new(
+               configure_dot3power,
+               "priority", "802.3at dot3 power priority (mandatory)",
+               cmd_check_typeat_but_no, NULL, "priority");
+       register_commands_pow_priority(priority, lldpctl_k_dot3_power_priority);
+
+       /* Values */
+       commands_new(
+               commands_new(configure_dot3power,
+                   "requested", "802.3at dot3 power value requested (mandatory)",
+                   cmd_check_typeat_but_no, NULL, "requested"),
+               NULL, "802.3at power value requested in milliwatts",
+               NULL, cmd_store_env_value_and_pop2, "requested");
+       commands_new(
+               commands_new(configure_dot3power,
+                   "allocated", "802.3at dot3 power value allocated (mandatory)",
+                   cmd_check_typeat_but_no, NULL, "allocated"),
+               NULL, "802.3at power value allocated in milliwatts",
+               NULL, cmd_store_env_value_and_pop2, "allocated");
+}
diff --git a/src/client/conf.c b/src/client/conf.c
new file mode 100644 (file)
index 0000000..3a9b8df
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- mode: c; c-file-style: "openbsd" -*- */
+/*
+ * Copyright (c) 2013 Vincent Bernat <bernat@luffy.cx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <string.h>
+
+#include "client.h"
+#include "../log.h"
+
+
+/**
+ * Register `configure` and `no configure` commands.
+ */
+void
+register_commands_configure(struct cmd_node *root)
+{
+       int has_med  = (lldpctl_key_get_map(
+                   lldpctl_k_med_policy_type)[0].string != NULL);
+       int has_dot3 = (lldpctl_key_get_map(
+                   lldpctl_k_dot3_power_class)[0].string != NULL);
+       if (!has_med && !has_dot3) return;
+
+       struct cmd_node *configure = commands_new(
+               root,
+               "configure",
+               "Change system settings",
+               NULL, NULL, NULL);
+       cmd_restrict_ports(configure);
+
+       if (has_med) register_commands_configure_med(configure);
+       if (has_dot3) register_commands_configure_dot3(configure);
+}