]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: implement basic support to override port IDs via lldpcli
authorAlexandru Ardelean <ardeleanalex@gmail.com>
Tue, 24 Mar 2015 07:08:33 +0000 (09:08 +0200)
committerAlexandru Ardelean <ardeleanalex@gmail.com>
Tue, 24 Mar 2015 08:54:08 +0000 (10:54 +0200)
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
src/client/conf-lldp.c
src/daemon/client.c
src/daemon/interfaces.c
src/lib/atom-private.c
src/lib/lldpctl.h
src/lldpd-structs.c
src/lldpd-structs.h

index 64553c8092ca732fd621b392d3c1163b56b1bc56..962ce3606e2470356d058c4b6c92878b32cc8766 100644 (file)
@@ -69,6 +69,30 @@ cmd_txhold(struct lldpctl_conn_t *conn, struct writer *w,
        return 1;
 }
 
+static int
+cmd_portid_type_local(struct lldpctl_conn_t *conn, struct writer *w,
+               struct cmd_env *env, void *arg)
+{
+       lldpctl_atom_t *iface;
+       const char *id = cmdenv_get(env, "port-id");
+
+       if (!id || !strlen(id)) {
+               log_warnx("lldpctl", "no id speficied");
+               return 0;
+       }
+
+       while ((iface = cmd_iterate_on_interfaces(conn, env))) {
+               lldpctl_atom_t *port = lldpctl_get_port(iface);
+               if (lldpctl_atom_set_str(port, lldpctl_k_port_id, id) == NULL) {
+                       log_warnx("lldpctl", "unable to set LLDP PortID."
+                         " %s", lldpctl_last_strerror(conn));
+               }
+               lldpctl_atom_dec_ref(port);
+       }
+
+       return 1;
+}
+
 static int
 cmd_portid_type(struct lldpctl_conn_t *conn, struct writer *w,
                struct cmd_env *env, void *arg)
@@ -167,6 +191,17 @@ register_commands_configure_lldp(struct cmd_node *configure)
                                NEWLINE, NULL,
                                NULL, cmd_portid_type,
                                b_map->string);
+               } else if (!strcmp(b_map->string, "local")) {
+                       commands_new(
+                               commands_new(
+                                       commands_new(configure_lldp_portid_type,
+                                                    b_map->string, "Local",
+                                                    NULL, NULL, NULL),
+                                       NULL, "PortID",
+                                       NULL, cmd_store_env_value, "port-id"),
+                               NEWLINE, NULL,
+                               NULL, cmd_portid_type_local,
+                               b_map->string);
                } else if (!strcmp(b_map->string, "macaddress")) {
                        commands_new(
                                commands_new(configure_lldp_portid_type,
index 6e8fdca631b4152fe2eb078d36093dc9ef13c781..7f4b46584e53b8c7191049b0b27f69083a2ffef9 100644 (file)
@@ -293,7 +293,13 @@ client_handle_set_port(struct lldpd *cfg, enum hmsg_type *type,
        TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries)
            if (!strcmp(hardware->h_ifname, set->ifname)) {
                    struct lldpd_port *port = &hardware->h_lport;
-                   (void)port;
+                   if (set->local_id) {
+                           log_debug("rpc", "requested change to Port ID");
+                           free(port->p_id);
+                           port->p_id = strdup(set->local_id);
+                           port->p_id_len = strlen(set->local_id);
+                           port->p_id_subtype = LLDP_PORTID_SUBTYPE_LOCAL;
+                   }
 #ifdef ENABLE_LLDPMED
                    if (set->med_policy && set->med_policy->type > 0) {
                            log_debug("rpc", "requested change to MED policy");
@@ -356,6 +362,7 @@ client_handle_set_port(struct lldpd *cfg, enum hmsg_type *type,
 set_port_finished:
        if (!ret) *type = NONE;
        free(set->ifname);
+       free(set->local_id);
 #ifdef ENABLE_LLDPMED
        free(set->med_policy);
        if (set->med_location) free(set->med_location->data);
index 849ed285b7291e193dc3c7f05faf512b61dbf08d..c43614e724731193aa46fdfc4a160e8e21583f0c 100644 (file)
@@ -465,6 +465,9 @@ interfaces_helper_port_name_desc(struct lldpd *cfg,
 {
        struct lldpd_port *port = &hardware->h_lport;
 
+       if (port->p_id_subtype == LLDP_PORTID_SUBTYPE_LOCAL)
+               goto description;
+
        /* We need to set the portid to what the client configured.
           This can be done from the CLI.
        */
@@ -492,6 +495,7 @@ interfaces_helper_port_name_desc(struct lldpd *cfg,
                port->p_id_len = ETHER_ADDR_LEN;
        }
 
+description:
        if (iface->alias != NULL && strlen(iface->alias) != 0) {
                /* use the actual alias in the port description */
                log_debug("interfaces", "using alias in description for %s",
index 7b43a03af56d597423d1f6f5e842982780d71799..ad725211616fa300a93ff738298d8a2fa79ee589 100644 (file)
@@ -273,6 +273,7 @@ static lldpctl_map_t bond_slave_src_mac_map[] = {
 static lldpctl_map_t lldp_portid_map[] = {
        { LLDP_PORTID_SUBTYPE_IFNAME,   "ifname"},
        { LLDP_PORTID_SUBTYPE_LLADDR,   "macaddress"},
+       { LLDP_PORTID_SUBTYPE_LOCAL,    "local"},
        { LLDP_PORTID_SUBTYPE_UNKNOWN,  NULL},
 };
 
@@ -844,6 +845,9 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato
        }
 
        switch (key) {
+       case lldpctl_k_port_id:
+               set.local_id = p->port->p_id;
+               break;
 #ifdef ENABLE_DOT3
        case lldpctl_k_port_dot3_power:
                if (value->type != atom_dot3_power) {
@@ -1025,6 +1029,31 @@ _lldpctl_atom_get_str_port(lldpctl_atom_t *atom, lldpctl_key_t key)
        }
 }
 
+static lldpctl_atom_t*
+_lldpctl_atom_set_str_port(lldpctl_atom_t *atom, lldpctl_key_t key,
+    const char *value)
+{
+       struct _lldpctl_atom_port_t *p =
+           (struct _lldpctl_atom_port_t *)atom;
+       struct lldpd_port     *port     = p->port;
+
+       if (!value || !strlen(value))
+               return NULL;
+
+       switch (key) {
+       case lldpctl_k_port_id:
+               free(port->p_id);
+               port->p_id = strdup(value);
+               port->p_id_len = strlen(value);
+               break;
+       default:
+               SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
+               return NULL;
+       }
+
+       return _lldpctl_atom_set_atom_port(atom, key, NULL);
+}
+
 static long int
 _lldpctl_atom_get_int_port(lldpctl_atom_t *atom, lldpctl_key_t key)
 {
@@ -2593,6 +2622,7 @@ struct atom_builder builders[] = {
          .get  = _lldpctl_atom_get_atom_port,
          .set  = _lldpctl_atom_set_atom_port,
          .get_str = _lldpctl_atom_get_str_port,
+         .set_str = _lldpctl_atom_set_str_port,
          .get_int = _lldpctl_atom_get_int_port,
          .get_buffer = _lldpctl_atom_get_buf_port },
        { atom_mgmts_list, sizeof(struct _lldpctl_atom_mgmts_list_t),
index e6263be584840de3e7bc6a3e3c492a2bfcdad2bc..d42d5efbcfe075df15b5b1eca57fba906705cafc 100644 (file)
@@ -626,7 +626,7 @@ typedef enum {
        lldpctl_k_port_protocol,   /**< `(IS)` The protocol that was used to retrieve this information. */
        lldpctl_k_port_age,        /**< `(I)`  Age of information, seconds from epoch. */
        lldpctl_k_port_id_subtype, /**< `(IS)` The subtype ID of this port.  */
-       lldpctl_k_port_id,         /**< `(BS)` The ID of this port. */
+       lldpctl_k_port_id,         /**< `(BS,WO)` The ID of this port. */
        lldpctl_k_port_descr,      /**< `(S)` The description of this port. */
        lldpctl_k_port_hidden,     /**< `(I)` Is this port hidden (or should it be displayed?)? */
 
index 094325d7e9806c85cd0c07b584a40510e9df0217..d24f4bf5f9cd893b54e61aa71b11861f0a77ab0c 100644 (file)
@@ -161,11 +161,11 @@ lldpd_port_cleanup(struct lldpd_port *port, int all)
 #endif
        /* will set these to NULL so we don't free wrong memory */
 
-       free(port->p_id);
-       port->p_id = NULL;
        free(port->p_descr);
        port->p_descr = NULL;
        if (all) {
+               free(port->p_id);
+               port->p_id = NULL;
                free(port->p_lastframe);
                if (port->p_chassis) { /* chassis may not have been attributed, yet */
                        port->p_chassis->c_refcount--;
index c2b69d26db30af2ac6639a2c3b8d90347d3ba6ac..5255707369129b836e8ecbb46eec61d6cd78d8bd 100644 (file)
@@ -275,6 +275,7 @@ MARSHAL_END(lldpd_port);
 /* Used to modify some port related settings */
 struct lldpd_port_set {
        char *ifname;
+       char *local_id;
 #ifdef ENABLE_LLDPMED
        struct lldpd_med_policy *med_policy;
        struct lldpd_med_loc    *med_location;
@@ -286,6 +287,7 @@ struct lldpd_port_set {
 };
 MARSHAL_BEGIN(lldpd_port_set)
 MARSHAL_STR(lldpd_port_set, ifname)
+MARSHAL_STR(lldpd_port_set, local_id)
 #ifdef ENABLE_LLDPMED
 MARSHAL_POINTER(lldpd_port_set, lldpd_med_policy, med_policy)
 MARSHAL_POINTER(lldpd_port_set, lldpd_med_loc,    med_location)