]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
snmp: implement lldpRemOrgDefInfoTable for remote custom TLVs
authorVincent Bernat <vincent@bernat.ch>
Wed, 29 May 2019 16:58:09 +0000 (18:58 +0200)
committerVincent Bernat <vincent@bernat.ch>
Mon, 3 Jun 2019 16:11:08 +0000 (18:11 +0200)
As a simplification, lldpRemOrgDefInfoIndex is 1 for the first custom
TLV of a given port and is increased by 1 for each new TLV. This is
not what is encouraged in the MIB:

> An agent is encouraged to assign monotonically increasing index
> values to new entries, starting with one, after each reboot. It is
> considered unlikely that the lldpRemOrgDefInfoIndex will wrap
> between reboots.

However, it is simpler to implement it this way as we don't need to
record the index inside the `lldpd_custom` structure. Also, the index
will increase even for a different OUI or subtype as we do not want to
sort the custom TLVs.

Fix #330.

NEWS
src/daemon/agent.c
tests/check_snmp.c

diff --git a/NEWS b/NEWS
index bf8f0aa6a0671b00cea6805741a639dd656bf6f4..608188e885ec45baf9d973b288dcc338d34a9070 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ lldpd (1.0.4)
   * Changes:
     + Add "configure system max-neighbors XX" command to modify maximum
       of neighbors accepted per port.
+    + Implement lldpRemOrgDefInfoTable table for custom TLVs.
   * Fix:
     + Better compliance for statsTLVsUnrecognizedTotal and
       statsAgeoutsTotal counters.
index dd36d9430fe0d21f27512aae63b53ab937dde471..cd33c78ec2bf89fcedcc56842a523691a589941d 100644 (file)
@@ -295,6 +295,40 @@ header_tpripindexed_table(struct variable *vp, oid *name, size_t *length,
        return header_index_best();
 }
 
+#ifdef ENABLE_CUSTOM
+static struct lldpd_custom*
+header_tprcustomindexed_table(struct variable *vp, oid *name, size_t *length,
+    int exact, size_t *var_len, WriteMethod **write_method)
+{
+       struct lldpd_hardware *hardware;
+       struct lldpd_port *port;
+       struct lldpd_custom *custom;
+       oid index[8];
+       oid idx;
+
+       if (!header_index_init(vp, name, length, exact, var_len, write_method)) return NULL;
+       TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
+               TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
+                       if (SMART_HIDDEN(port)) continue;
+                       idx = 1;
+                       TAILQ_FOREACH(custom, &port->p_custom_list, next) {
+                               index[0] = lastchange(port);
+                               index[1] = hardware->h_ifindex;
+                               index[2] = port->p_chassis->c_index;
+                               index[3] = custom->oui[0];
+                               index[4] = custom->oui[1];
+                               index[5] = custom->oui[2];
+                               index[6] = custom->subtype;
+                               index[7] = idx++;
+                               if (header_index_add(index, 8, custom))
+                                       return custom;
+                       }
+               }
+       }
+       return header_index_best();
+}
+#endif
+
 #ifdef ENABLE_LLDPMED
 #define TPR_VARIANT_MED_POLICY 2
 #define TPR_VARIANT_MED_LOCATION 3
@@ -552,6 +586,8 @@ header_tprpiindexed_table(struct variable *vp, oid *name, size_t *length,
 #define LLDP_SNMP_ADDR_IFSUBTYPE 2
 #define LLDP_SNMP_ADDR_IFID 3
 #define LLDP_SNMP_ADDR_OID 4
+/* Custom TLVs */
+#define LLDP_SNMP_ORG_DEF_INFO 1
 /* LLDP-MED */
 #define LLDP_SNMP_MED_CAP_AVAILABLE 1
 #define LLDP_SNMP_MED_CAP_ENABLED 2
@@ -1407,6 +1443,33 @@ agent_h_remote_management(struct variable *vp, oid *name, size_t *length,
         return agent_v_management(vp, var_len, mgmt);
 }
 
+#ifdef ENABLE_CUSTOM
+static u_char*
+agent_v_custom(struct variable *vp, size_t *var_len, struct lldpd_custom *custom)
+{
+       switch (vp->magic) {
+        case LLDP_SNMP_ORG_DEF_INFO:
+               *var_len = custom->oui_info_len;
+               return (u_char *)custom->oui_info;
+       default:
+               break;
+        }
+        return NULL;
+}
+static u_char*
+agent_h_remote_custom(struct variable *vp, oid *name, size_t *length,
+    int exact, size_t *var_len, WriteMethod **write_method)
+{
+       struct lldpd_custom *custom;
+
+       if ((custom = header_tprcustomindexed_table(vp, name, length,
+                   exact, var_len, write_method)) == NULL)
+               return NULL;
+
+        return agent_v_custom(vp, var_len, custom);
+}
+#endif
+
 /*
   Here is how it works: a agent_h_*() function will handle incoming
   requests. It will use an appropriate header_*indexed_table()
@@ -1477,8 +1540,13 @@ struct variable8 agent_lldp_vars[] = {
          {1, 4, 2, 1, 4}},
         {LLDP_SNMP_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_remote_management, 5,
          {1, 4, 2, 1, 5}},
-       /* Dot3, local ports */
+#ifdef ENABLE_CUSTOM
+       /* Custom TLVs */
+       {LLDP_SNMP_ORG_DEF_INFO, ASN_OCTET_STR, RONLY, agent_h_remote_custom, 5,
+        {1, 4, 4, 1, 4}},
+#endif
 #ifdef ENABLE_DOT3
+       /* Dot3, local ports */
         {LLDP_SNMP_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8,
          {1, 5, 4623, 1, 2, 1, 1, 1}},
         {LLDP_SNMP_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
index 742c5bf8cb8b998fe0c54820e8b32e7ff6621bdd..24b3077a0546a788f95b03f2deb5acb2353d53ff 100644 (file)
@@ -246,10 +246,38 @@ struct lldpd_hardware hardware2 = {
                                .data_len = 15,
                        }, { .format = 0 }, { .format = 0 },
                },
-#endif         
+#endif
        }
 };
 
+#ifdef ENABLE_CUSTOM
+struct lldpd_custom custom1 = {
+       .oui = { 33, 44, 55 },
+       .subtype = 44,
+       .oui_info = (u_int8_t*)"OUI content",
+};
+struct lldpd_custom custom2 = {
+       .oui = { 33, 44, 55 },
+       .subtype = 44,
+       .oui_info = (u_int8_t*)"More content",
+};
+struct lldpd_custom custom3 = {
+       .oui = { 33, 44, 55 },
+       .subtype = 45,
+       .oui_info = (u_int8_t*)"More more content",
+};
+struct lldpd_custom custom4 = {
+       .oui = { 33, 44, 56 },
+       .subtype = 44,
+       .oui_info = (u_int8_t*)"Even more content",
+};
+struct lldpd_custom custom5 = {
+       .oui = { 33, 44, 55 },
+       .subtype = 44,
+       .oui_info = (u_int8_t*)"Still more content",
+};
+#endif
+
 #ifdef ENABLE_DOT1
 struct lldpd_vlan vlan47 = {
        .v_name = "VLAN #47",
@@ -308,6 +336,21 @@ snmp_config()
        TAILQ_INIT(&test_cfg.g_hardware);
        TAILQ_INSERT_TAIL(&test_cfg.g_hardware, &hardware1, h_entries);
        TAILQ_INSERT_TAIL(&test_cfg.g_hardware, &hardware2, h_entries);
+#ifdef ENABLE_CUSTOM
+       custom1.oui_info_len = strlen((char*)custom1.oui_info);
+       custom2.oui_info_len = strlen((char*)custom2.oui_info);
+       custom3.oui_info_len = strlen((char*)custom3.oui_info);
+       custom4.oui_info_len = strlen((char*)custom4.oui_info);
+       custom5.oui_info_len = strlen((char*)custom5.oui_info);
+       TAILQ_INIT(&hardware1.h_lport.p_custom_list);
+       TAILQ_INIT(&hardware2.h_lport.p_custom_list);
+       TAILQ_INIT(&port2.p_custom_list);
+       TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom1, next);
+       TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom2, next);
+       TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom3, next);
+       TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom4, next);
+       TAILQ_INSERT_TAIL(&hardware1.h_lport.p_custom_list, &custom5, next);
+#endif
 #ifdef ENABLE_DOT1
        TAILQ_INIT(&hardware1.h_lport.p_vlans);
        TAILQ_INSERT_TAIL(&hardware1.h_lport.p_vlans, &vlan47, v_entries);
@@ -525,6 +568,20 @@ struct tree_node snmp_tree[] = {
          { .string = { .octet = (char *)zeroDotZero,
                        .len = sizeof(zeroDotZero) }} },
 
+#ifdef ENABLE_CUSTOM
+       /* lldpRemOrgDefInfo */
+       { {1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 44, 1 }, 13, ASN_OCTET_STR,
+         { .string = { .octet = "OUI content", .len = 11 }} },
+       { {1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 44, 2 }, 13, ASN_OCTET_STR,
+         { .string = { .octet = "More content", .len = 12 }} },
+       { {1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 45, 3 }, 13, ASN_OCTET_STR,
+         { .string = { .octet = "More more content", .len = 17 }} },
+       { {1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 56, 44, 4 }, 13, ASN_OCTET_STR,
+         { .string = { .octet = "Even more content", .len = 17 }} },
+       { {1, 4, 4, 1, 4, 10000, 4, 1, 33, 44, 55, 44, 1 }, 13, ASN_OCTET_STR,
+         { .string = { .octet = "Still more content", .len = 18 }} },
+#endif
+
 #ifdef ENABLE_DOT3
        /* lldpXdot3LocPortAutoNegSupported */
        { {1, 5, 4623, 1, 2, 1, 1, 1, 3 }, 9, ASN_INTEGER, { .integer = 1 }},