]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Add initial Dot3/802.3at support
authorVincent Bernat <bernat@luffy.cx>
Sat, 8 May 2010 15:25:35 +0000 (17:25 +0200)
committerVincent Bernat <bernat@luffy.cx>
Tue, 26 Apr 2011 05:48:15 +0000 (07:48 +0200)
This includes ability to receive  and store Dot3 MDI power TLV, to
display them with lldpctl and to export them through SNMP agent. There
is no support for 802.3af yet.

src/agent.c
src/display.c
src/lldp.c
src/lldp.h
src/lldpd.h

index 5cfd11f4cccc2bce9c9ac3249291ac7c0d236251..660a27e41295f26ffb55c58392ef497323f1169a 100644 (file)
@@ -419,7 +419,13 @@ header_tprvindexed_table(struct variable *vp, oid *name, size_t *length,
 #define LLDP_SNMP_REMOTE_DOT3_AGG_STATUS 14
 #define LLDP_SNMP_REMOTE_DOT3_AGG_ID 15
 #define LLDP_SNMP_REMOTE_DOT3_MFS 16
-#define LLDP_SNMP_REMOTE_DOT1_PVID 17
+#define LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE 17
+#define LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT 18
+#define LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED 19
+#define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL 20
+#define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS 21
+#define LLDP_SNMP_REMOTE_DOT3_POWER_CLASS 22
+#define LLDP_SNMP_REMOTE_DOT1_PVID 23
 /* Local vlans */
 #define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1
 /* Remote vlans */
@@ -1201,6 +1207,42 @@ agent_h_remote_port(struct variable *vp, oid *name, size_t *length,
         case LLDP_SNMP_REMOTE_DOT3_MFS:
                 long_ret = port->p_mfs;
                 return (u_char *)&long_ret;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE:
+               if (port->p_power.devicetype) {
+                       long_ret = (port->p_power.devicetype == LLDP_DOT3_POWER_PSE)?1:2;
+                       return (u_char *)&long_ret;
+               }
+               break;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT:
+               if (port->p_power.devicetype) {
+                       long_ret = (port->p_power.supported)?1:2;
+                       return (u_char *)&long_ret;
+               }
+               break;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED:
+               if (port->p_power.devicetype) {
+                       long_ret = (port->p_power.enabled)?1:2;
+                       return (u_char *)&long_ret;
+               }
+               break;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL:
+               if (port->p_power.devicetype) {
+                       long_ret = (port->p_power.paircontrol)?1:2;
+                       return (u_char *)&long_ret;
+               }
+               break;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS:
+               if (port->p_power.devicetype) {
+                       long_ret = port->p_power.pairs;
+                       return (u_char *)&long_ret;
+               }
+               break;
+       case LLDP_SNMP_REMOTE_DOT3_POWER_CLASS:
+               if (port->p_power.devicetype && port->p_power.class) {
+                       long_ret = port->p_power.class;
+                       return (u_char *)&long_ret;
+               }
+               break;
 #endif
 #ifdef ENABLE_DOT1
         case LLDP_SNMP_REMOTE_DOT1_PVID:
@@ -1210,7 +1252,10 @@ agent_h_remote_port(struct variable *vp, oid *name, size_t *length,
        default:
                break;
         }
-        return NULL;
+       if (!exact && (name[*length-1] < MAX_SUBID))
+               return agent_h_remote_port(vp, name, length,
+                   exact, var_len, write_method);
+       return NULL;
 }
 
 static u_char*
@@ -1368,6 +1413,18 @@ static struct variable8 lldp_vars[] = {
          {1, 5, 4623, 1, 3, 1, 1, 3}},
         {LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
          {1, 5, 4623, 1, 3, 1, 1, 4}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 1}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 2}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 3}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 4}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 5}},
+       {LLDP_SNMP_REMOTE_DOT3_POWER_CLASS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
+        {1, 5, 4623, 1, 3, 2, 1, 6}},
         {LLDP_SNMP_REMOTE_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
          {1, 5, 4623, 1, 3, 3, 1, 1}},
         {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
index 0010fee148dcc022f06f5d2ff988aa730f43f1e2..e3c1dd4b894c715cca500a2100414c0a032f6725 100644 (file)
@@ -242,6 +242,27 @@ static const struct value_string operational_mau_type_values[] = {
        { 53,   "1000BasePX20U - One single-mode fiber EPON ONU, 20km" },
        { 0, NULL }
 };
+
+static const struct value_string port_dot3_power_devicetype_map[] = {
+       { LLDP_DOT3_POWER_PSE, "PSE" },
+       { LLDP_DOT3_POWER_PD,  "PD" },
+       { 0, NULL }
+};
+
+static const struct value_string port_dot3_power_pairs_map[] = {
+       { LLDP_DOT3_POWERPAIRS_SIGNAL, "signal" },
+       { LLDP_DOT3_POWERPAIRS_SPARE,  "spare" },
+       { 0, NULL }
+};
+
+static const struct value_string port_dot3_power_class_map[] = {
+       { 1, "class 0" },
+       { 2, "class 1" },
+       { 3, "class 2" },
+       { 4, "class 3" },
+       { 5, "class 4" },
+       { 0, NULL }
+};
 #endif
 
 static const struct value_string chassis_capability_map[] = {
@@ -881,6 +902,28 @@ display_port(struct writer * w, struct lldpd_port *port)
                        map_lookup(operational_mau_type_values, port->p_macphy.mau_type));
                tag_end(w);
        }
+       if (port->p_power.devicetype) {
+               tag_start(w, "power", "MDI Power");
+               tag_attr(w, "supported", "supported",
+                   port->p_power.supported?"yes":"no");
+               tag_attr(w, "enabled", "enabled",
+                   port->p_power.enabled?"yes":"no");
+               tag_attr(w, "paircontrol", "pair control",
+                   port->p_power.paircontrol?"yes":"no");
+               tag_start(w, "device-type", "Device type");
+               tag_data(w, map_lookup(port_dot3_power_devicetype_map,
+                       port->p_power.devicetype));
+               tag_end(w);
+               tag_start(w, "pairs", "Power pairs");
+               tag_data(w, map_lookup(port_dot3_power_pairs_map,
+                       port->p_power.pairs));
+               tag_end(w);
+               tag_start(w, "class", "Class");
+               tag_data(w, map_lookup(port_dot3_power_class_map,
+                       port->p_power.class));
+               tag_end(w);
+               tag_end(w);
+       }
 #endif
        tag_end(w);
 }
index 09143f2c0d9d32782a068986b7c13ba93ac9031a..d58f579b5a5981bea64fb1f70edc322e81473961 100644 (file)
@@ -567,9 +567,9 @@ lldp_decode(struct lldpd *cfg, char *frame, int s,
                                        CHECK_TLV_SIZE(9, "MAC/PHY");
                                        port->p_macphy.autoneg_support = PEEK_UINT8;
                                        port->p_macphy.autoneg_enabled =
-                                           port->p_macphy.autoneg_support && 0x2;
+                                           port->p_macphy.autoneg_support & 0x2;
                                        port->p_macphy.autoneg_support =
-                                           port->p_macphy.autoneg_support && 0x1;
+                                           port->p_macphy.autoneg_support & 0x1;
                                        port->p_macphy.autoneg_advertised =
                                            PEEK_UINT16;
                                        port->p_macphy.mau_type = PEEK_UINT16;
@@ -583,6 +583,21 @@ lldp_decode(struct lldpd *cfg, char *frame, int s,
                                        CHECK_TLV_SIZE(6, "MFS");
                                        port->p_mfs = PEEK_UINT16;
                                        break;
+                               case LLDP_TLV_DOT3_POWER:
+                                       CHECK_TLV_SIZE(7, "Power");
+                                       port->p_power.devicetype = PEEK_UINT8;
+                                       port->p_power.supported =
+                                               port->p_power.devicetype & 0x2;
+                                       port->p_power.enabled =
+                                               port->p_power.devicetype & 0x4;
+                                       port->p_power.paircontrol =
+                                               port->p_power.devicetype & 0x8;
+                                       port->p_power.devicetype =
+                                               (port->p_power.devicetype & 0x1)?
+                                               LLDP_DOT3_POWER_PSE:LLDP_DOT3_POWER_PD;
+                                       port->p_power.pairs = PEEK_UINT8;
+                                       port->p_power.class = PEEK_UINT8;
+                                       break;
                                default:
                                        /* Unknown Dot3 TLV, ignore it */
                                        hardware->h_rx_unrecognized_cnt++;
index f1b5f947e2b5688d90653bf1bcf5f3bd2dfbb47e..08f36ffa01eab902121d3098b67160c83d9a54ea 100644 (file)
@@ -119,6 +119,14 @@ enum {
 #define LLDP_DOT3_MAU_10GIGBASELW 39
 #define LLDP_DOT3_MAU_10GIGBASESW 40
 
+/* Dot3 Power Devicetype */
+#define LLDP_DOT3_POWER_PSE 1
+#define LLDP_DOT3_POWER_PD 2
+
+/* Dot3 Power Pairs (RFC 3621) */
+#define LLDP_DOT3_POWERPAIRS_SIGNAL 1
+#define LLDP_DOT3_POWERPAIRS_SPARE 2
+
 /* PMD Auto-Negotiation Advertised Capability field, from RFC 3636 */
 #define LLDP_DOT3_LINK_AUTONEG_OTHER           0x8000
 #define LLDP_DOT3_LINK_AUTONEG_10BASE_T                0x4000
index 89b0d3d2c78312d0c8759a0723fa5b1b5ba4d1cc..f93478e86c7bc4f2d4ddef3f6513e5757200d55b 100644 (file)
@@ -110,6 +110,16 @@ struct lldpd_dot3_macphy {
        u_int16_t                autoneg_advertised;
        u_int16_t                mau_type;
 };
+
+#define STRUCT_LLDPD_DOT3_POWER "(bbbbbb)"
+struct lldpd_dot3_power {
+       u_int8_t                devicetype;
+       u_int8_t                supported;
+       u_int8_t                enabled;
+       u_int8_t                paircontrol;
+       u_int8_t                pairs;
+       u_int8_t                class;
+};
 #endif
 
 struct lldpd_chassis {
@@ -165,10 +175,11 @@ struct lldpd_port {
        u_int8_t                 p_hidden_out:2; /* Considered as hidden for emission */
 
 #ifdef ENABLE_DOT3
-#define STRUCT_LLDPD_PORT_DOT3 "l" STRUCT_LLDPD_DOT3_MACPHY
+#define STRUCT_LLDPD_PORT_DOT3 "l" STRUCT_LLDPD_DOT3_MACPHY STRUCT_LLDPD_DOT3_POWER
        /* Dot3 stuff */
        u_int32_t                p_aggregid;
        struct lldpd_dot3_macphy p_macphy;
+       struct lldpd_dot3_power  p_power;
 #else
 #define STRUCT_LLDPD_PORT_DOT3 ""
 #endif