]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
client/conf-power: Add support for 803.2bt parameters.
authorAndreas Hofmann <git@andreas-hofmann.org>
Tue, 18 May 2021 12:39:49 +0000 (14:39 +0200)
committerVincent Bernat <vincent@bernat.ch>
Sun, 15 Oct 2023 17:41:17 +0000 (19:41 +0200)
Signed-off-by: Andreas Hofmann <git@andreas-hofmann.org>
src/client/conf-power.c

index 38f2536148f7ee188af015feaeb0f282bdef0140..a1ca816ce40a8920e3927771fea26a43ce313878 100644 (file)
 #include "client.h"
 #include "../log.h"
 
+static int cmd_check_ext_type(struct cmd_env *env, const char *type);
+static int cmd_check_ext_pse_but_no(struct cmd_env *env, void *arg);
+static int cmd_check_ext_pd_but_no(struct cmd_env *env, void *arg);
+
 static int
 cmd_medpower(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env,
     void *arg)
@@ -89,6 +93,132 @@ cmd_store_prio_env_value_and_pop2(struct lldpctl_conn_t *conn, struct writer *w,
        return cmd_store_something_env_value_and_pop2("priority", env, value);
 }
 
+static int
+cmd_dot3power_conf_at(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, lldpctl_atom_t *dot3_power, const char *name)
+{
+       const char *what = NULL;
+       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));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+cmd_dot3power_conf_bt(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, lldpctl_atom_t *dot3_power, const char *name)
+{
+       const char *what = NULL;
+       int typebt = cmdenv_get(env, "type-ext")[0] - '0';
+       if (typebt != LLDP_DOT3_POWER_8023BT_OFF) {
+               if ((what = "802.3bt class-a",
+                       lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_class_a,
+                           cmdenv_get(env, "class-a"))) == NULL ||
+                   (what = "802.3bt class-b",
+                       lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_class_b,
+                           cmdenv_get(env, "class-b"))) == NULL ||
+                   (what = "802.3bt class-ext",
+                       lldpctl_atom_set_str(dot3_power, lldpctl_k_dot3_power_class_ext,
+                           cmdenv_get(env, "class-ext"))) == NULL) {
+                       log_warnx("lldpctl",
+                           "unable to set LLDP Dot3 power value for %s on %s. %s.",
+                           what, name, lldpctl_last_strerror(conn));
+                       return 1;
+               }
+
+               if ((what = "802.3bt type",
+                       lldpctl_atom_set_int(dot3_power, lldpctl_k_dot3_power_type_ext,
+                           typebt)) == NULL ||
+                   (what = "requested power A",
+                       lldpctl_atom_set_str(dot3_power,
+                           lldpctl_k_dot3_power_requested_a,
+                           cmdenv_get(env, "requested-a"))) == NULL ||
+                   (what = "allocated power A",
+                       lldpctl_atom_set_str(dot3_power,
+                           lldpctl_k_dot3_power_allocated_a,
+                           cmdenv_get(env, "allocated-a"))) == NULL ||
+                   (what = "requested power B",
+                       lldpctl_atom_set_str(dot3_power,
+                           lldpctl_k_dot3_power_requested_b,
+                           cmdenv_get(env, "requested-b"))) == NULL ||
+                   (what = "allocated power B",
+                       lldpctl_atom_set_str(dot3_power,
+                           lldpctl_k_dot3_power_allocated_b,
+                           cmdenv_get(env, "allocated-b"))) == NULL) {
+                       log_warnx("lldpctl",
+                           "unable to set LLDP Dot3 power value for %s on %s. %s.",
+                           what, name, lldpctl_last_strerror(conn));
+                       return 1;
+               }
+
+               if (cmd_check_ext_pse_but_no(env, NULL)) {
+                       if ((what = "PSE status",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pse_status,
+                                   cmdenv_get(env, "pse-status"))) == NULL ||
+                           (what = "PSE pairs",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pse_pairs_ext,
+                                   cmdenv_get(env, "pse-pairs-ext"))) == NULL ||
+                           (what = "PSE max",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pse_max,
+                                   cmdenv_get(env, "pse-max"))) == NULL) {
+                               log_warnx("lldpctl",
+                                   "unable to set LLDP Dot3 power value for %s on %s. %s.",
+                                   what, name, lldpctl_last_strerror(conn));
+                               return 1;
+                       }
+               }
+
+               if (cmd_check_ext_pd_but_no(env, NULL)) {
+                       if ((what = "PD status",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pd_status,
+                                   cmdenv_get(env, "pd-status"))) == NULL ||
+                           (what = "PD 4pid",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pd_4pid,
+                                   cmdenv_get(env, "pd-4pid"))) == NULL ||
+                           (what = "PD load",
+                               lldpctl_atom_set_str(dot3_power,
+                                   lldpctl_k_dot3_power_pd_load,
+                                   cmdenv_get(env, "pd-load"))) == NULL) {
+                               log_warnx("lldpctl",
+                                   "unable to set LLDP Dot3 power value for %s on %s. %s.",
+                                   what, name, lldpctl_last_strerror(conn));
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
 static int
 cmd_dot3power(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env,
     void *arg)
@@ -141,42 +271,16 @@ cmd_dot3power(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env
                            "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;
+               } else {
+                       if (cmdenv_get(env, "typeat")) {
+                               if (cmd_dot3power_conf_at(conn, w, env, dot3_power,
+                                       name))
+                                       ok = 0;
+                       }
+                       if (cmdenv_get(env, "type-ext")) {
+                               if (cmd_dot3power_conf_bt(conn, w, env, dot3_power,
+                                       name))
+                                       ok = 0;
                        }
                }
                if (ok) {
@@ -212,6 +316,14 @@ cmd_check_typeat_but_no(struct cmd_env *env, void *arg)
        return 1;
 }
 static int
+cmd_check_typeext_but_no(struct cmd_env *env, void *arg)
+{
+       const char *what = arg;
+       if (!cmdenv_get(env, "type-ext")) 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");
@@ -228,6 +340,33 @@ cmd_check_pd(struct cmd_env *env, void *arg)
 {
        return cmd_check_type(env, "pd");
 }
+static int
+cmd_check_ext_type(struct cmd_env *env, const char *type)
+{
+       const char *etype = cmdenv_get(env, "type-ext");
+       if (!etype) return 0;
+       return (!strcmp(type, etype));
+}
+static int
+cmd_check_ext_pse_but_no(struct cmd_env *env, void *arg)
+{
+       const char *what = arg;
+       if (what)
+               if (cmdenv_get(env, what)) return 0;
+
+       return !!(cmd_check_ext_type(env, "1") || cmd_check_ext_type(env, "2"));
+}
+static int
+cmd_check_ext_pd_but_no(struct cmd_env *env, void *arg)
+{
+       const char *what = arg;
+
+       if (what)
+               if (cmdenv_get(env, what)) return 0;
+
+       return !!(cmd_check_ext_type(env, "3") || cmd_check_ext_type(env, "4") ||
+           cmd_check_ext_type(env, "5") || cmd_check_ext_type(env, "6"));
+}
 
 static void
 register_commands_pow_source(struct cmd_node *source)
@@ -296,15 +435,33 @@ register_commands_medpow(struct cmd_node *configure_med)
 static int
 cmd_check_env_power(struct cmd_env *env, void *nothing)
 {
+       int ret = 1;
+
        /* 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") &&
+               ret &= (!!cmdenv_get(env, "source") && !!cmdenv_get(env, "priority") &&
                    !!cmdenv_get(env, "requested") && !!cmdenv_get(env, "allocated"));
        }
-       return 1;
+
+       if (cmdenv_get(env, "type-ext")) {
+               int mandatories = (!!cmdenv_get(env, "class-a") &&
+                   !!cmdenv_get(env, "class-b") && !!cmdenv_get(env, "class-ext"));
+
+               if (cmd_check_ext_pd_but_no(env, NULL)) {
+                       ret &= (!!cmdenv_get(env, "pd-status") &&
+                           !!cmdenv_get(env, "pd-4pid") && mandatories);
+               } else if (cmd_check_ext_pse_but_no(env, NULL)) {
+                       ret &= (!!cmdenv_get(env, "pse-status") &&
+                           !!cmdenv_get(env, "pse-pairs-ext") &&
+                           !!cmdenv_get(env, "pse-max") && mandatories);
+               }
+       }
+
+       return ret;
 }
 
 /**
@@ -355,6 +512,114 @@ register_commands_dot3pow(struct cmd_node *configure_dot3)
                    cmd_store_class_env_value_and_pop2, class_map->string);
        }
 
+       struct cmd_node *class_a = commands_new(configure_dot3power, "class-a",
+           "802.3bt power class a (mandatory)", cmd_check_typeext_but_no, NULL,
+           "class-a");
+       commands_new(class_a, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "1", "Class 1", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "2", "Class 2", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "3", "Class 3", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "4", "Class 4", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "5", "Class 5", NULL, cmd_store_env_value_and_pop2,
+           "class-a");
+       commands_new(class_a, "7", "Single-signature PD or 2-pair only PSE", NULL,
+           cmd_store_env_value_and_pop2, "class-a");
+
+       struct cmd_node *class_b = commands_new(configure_dot3power, "class-b",
+           "802.3bt power class b (mandatory)", cmd_check_typeext_but_no, NULL,
+           "class-b");
+       commands_new(class_b, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "1", "Class 1", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "2", "Class 2", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "3", "Class 3", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "4", "Class 4", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "5", "Class 5", NULL, cmd_store_env_value_and_pop2,
+           "class-b");
+       commands_new(class_b, "7", "Single-signature PD or 2-pair only PSE", NULL,
+           cmd_store_env_value_and_pop2, "class-b");
+
+       struct cmd_node *class_ext = commands_new(configure_dot3power, "class-ext",
+           "802.3bt power class ext (mandatory)", cmd_check_typeext_but_no, NULL,
+           "class-ext");
+       commands_new(class_ext, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "1", "Class 1", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "2", "Class 2", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "3", "Class 3", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "4", "Class 4", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "5", "Class 5", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "6", "Class 6", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "7", "Class 7", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "8", "Class 8", NULL, cmd_store_env_value_and_pop2,
+           "class-ext");
+       commands_new(class_ext, "15", "Dual-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "class-ext");
+
+       /* PD status */
+       struct cmd_node *pd_status = commands_new(configure_dot3power, "pd-status",
+           "802.3bt PD status (mandatory)", cmd_check_ext_pd_but_no, NULL,
+           "pd-status");
+       commands_new(pd_status, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "pd-status");
+       commands_new(pd_status, "1", "2-pair powered PD", NULL,
+           cmd_store_env_value_and_pop2, "pd-status");
+       commands_new(pd_status, "2", "4-pair powered dual-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "pd-status");
+       commands_new(pd_status, "3", "4-pair powered single-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "pd-status");
+
+       /* PD 4pid */
+       struct cmd_node *pd_4pid = commands_new(configure_dot3power, "pd-4pid",
+           "802.3bt PD 4pid config (mandatory)", cmd_check_ext_pd_but_no, NULL,
+           "pd-4pid");
+       commands_new(pd_4pid, "0", "PD does not support powering both modes", NULL,
+           cmd_store_env_value_and_pop2, "pd-4pid");
+       commands_new(pd_4pid, "1", "PD supports powering both modes", NULL,
+           cmd_store_env_value_and_pop2, "pd-4pid");
+
+       /* PSE status */
+       struct cmd_node *pse_status = commands_new(configure_dot3power, "pse-status",
+           "802.3bt PSE status (mandatory)", cmd_check_ext_pse_but_no, NULL,
+           "pse-status");
+       commands_new(pse_status, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "pse-status");
+       commands_new(pse_status, "1", "2-pair powering PSE", NULL,
+           cmd_store_env_value_and_pop2, "pse-status");
+       commands_new(pse_status, "2", "4-pair powering dual-signature PSE", NULL,
+           cmd_store_env_value_and_pop2, "pse-status");
+       commands_new(pse_status, "3", "4-pair powering single-signature PSE", NULL,
+           cmd_store_env_value_and_pop2, "pse-status");
+
+       /* PSE pairs */
+       struct cmd_node *pse_pairs = commands_new(configure_dot3power, "pse-pairs-ext",
+           "802.3bt PD pairs (mandatory)", cmd_check_ext_pse_but_no, NULL,
+           "pse-pairs-ext");
+       commands_new(pse_pairs, "0", "Unknown", NULL, cmd_store_env_value_and_pop2,
+           "pse-pairs-ext");
+       commands_new(pse_pairs, "1", "Alternative A", NULL,
+           cmd_store_env_value_and_pop2, "pse-pairs-ext");
+       commands_new(pse_pairs, "2", "Alternative B", NULL,
+           cmd_store_env_value_and_pop2, "pse-pairs-ext");
+       commands_new(pse_pairs, "3", "Both alternatives", NULL,
+           cmd_store_env_value_and_pop2, "pse-pairs-ext");
+
        /* 802.3at type */
        struct cmd_node *typeat = commands_new(configure_dot3power, "type",
            "802.3at device type", cmd_check_type_but_no, NULL, "typeat");
@@ -363,6 +628,24 @@ register_commands_dot3pow(struct cmd_node *configure_dot3)
        commands_new(typeat, "2", "802.3at type 2", NULL, cmd_store_env_value_and_pop2,
            "typeat");
 
+       /* 802.3bt type */
+       struct cmd_node *typeext = commands_new(configure_dot3power, "type-ext",
+           "802.3bt device type", cmd_check_type_but_no, NULL, "type-ext");
+       commands_new(typeext, "0", "802.3bt off", NULL, cmd_store_env_value_and_pop2,
+           "type-ext");
+       commands_new(typeext, "1", "802.3bt type 3 PSE", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+       commands_new(typeext, "2", "802.3bt type 4 PSE", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+       commands_new(typeext, "3", "802.3bt type 3 single-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+       commands_new(typeext, "4", "802.3bt type 3 dual-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+       commands_new(typeext, "5", "802.3bt type 4 single-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+       commands_new(typeext, "6", "802.3bt type 4 dual-signature PD", NULL,
+           cmd_store_env_value_and_pop2, "type-ext");
+
        /* Source */
        struct cmd_node *source = commands_new(configure_dot3power, "source",
            "802.3at dot3 power source (mandatory)", cmd_check_typeat_but_no, NULL,
@@ -386,4 +669,34 @@ register_commands_dot3pow(struct cmd_node *configure_dot3)
                         cmd_check_typeat_but_no, NULL, "allocated"),
            NULL, "802.3at power value allocated in milliwatts", NULL,
            cmd_store_env_value_and_pop2, "allocated");
+       commands_new(commands_new(configure_dot3power, "requested-a",
+                        "802.3bt dot3 class a power value requested (mandatory)",
+                        cmd_check_typeext_but_no, NULL, "requested-a"),
+           NULL, "802.3bt power value requested in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "requested-a");
+       commands_new(commands_new(configure_dot3power, "allocated-a",
+                        "802.3bt dot3 class a power value allocated (mandatory)",
+                        cmd_check_typeext_but_no, NULL, "allocated-a"),
+           NULL, "802.3bt power value allocated in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "allocated-a");
+       commands_new(commands_new(configure_dot3power, "requested-b",
+                        "802.3bt dot3 class b power value requested (mandatory)",
+                        cmd_check_typeext_but_no, NULL, "requested-b"),
+           NULL, "802.3bt power value requested in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "requested-b");
+       commands_new(commands_new(configure_dot3power, "allocated-b",
+                        "802.3bt dot3 class b power value allocated (mandatory)",
+                        cmd_check_typeext_but_no, NULL, "allocated-b"),
+           NULL, "802.3bt power value allocated in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "allocated-b");
+       commands_new(commands_new(configure_dot3power, "pd-load",
+                        "802.3bt dot3 pd power load", cmd_check_ext_pd_but_no, NULL,
+                        "pd-load"),
+           NULL, "802.3bt pd power load value allocated in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "pd-load");
+       commands_new(commands_new(configure_dot3power, "pse-max",
+                        "802.3bt dot3 pse max power load (mandatory)",
+                        cmd_check_ext_pse_but_no, NULL, "pse-max"),
+           NULL, "802.3bt pse max power value allocated in milliwatts", NULL,
+           cmd_store_env_value_and_pop2, "pse-max");
 }