]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Support for multiple IPv4/IPv6 management addresses.
authorJoão Valverde <joao.valverde@ist.utl.pt>
Tue, 6 Mar 2012 14:08:59 +0000 (14:08 +0000)
committerVincent Bernat <bernat@luffy.cx>
Thu, 15 Mar 2012 19:41:10 +0000 (20:41 +0100)
This patch introduces a new 'struct lldpd_mgmt' to store IPv4/IPv6
management addresses. These addresses are stored in a tail queue.
For the local chassis we currently only use one IPv4 and one IPv6 address.

Options for IPv6 addresses are the same as IPv4 (use -6).

TODO: Fix SNMP agent.

15 files changed:
src/agent.c
src/cdp.c
src/display.c
src/edp.c
src/interfaces.c
src/lldp.c
src/lldp.h
src/lldpd.c
src/lldpd.h
src/sonmp.c
tests/check_cdp.c
tests/check_edp.c
tests/check_lldp.c
tests/check_snmp.c
tests/check_sonmp.c

index 3b96ca46624269f9203748ffb50875e13e22ce8e..5cef0c79efc77075326ddf12fc2f988efda52c00 100644 (file)
@@ -228,19 +228,23 @@ header_ipindexed_table(struct variable *vp, oid *name, size_t *length,
     int exact, size_t *var_len, WriteMethod **write_method)
 {
        struct lldpd_chassis *chassis = LOCAL_CHASSIS(scfg);
+       struct lldpd_mgmt *mgmt;
 
        if (!header_index_init(vp, name, length, exact, var_len, write_method)) return NULL;
-       oid index[6] = {
-               1, 4,
-               ((u_int8_t*)&chassis->c_mgmt.s_addr)[0],
-               ((u_int8_t*)&chassis->c_mgmt.s_addr)[1],
-               ((u_int8_t*)&chassis->c_mgmt.s_addr)[2],
-               ((u_int8_t*)&chassis->c_mgmt.s_addr)[3] };
-       if (header_index_add(index, 6,
-                            chassis) || header_index_best() != NULL)
-               return chassis;
+       TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+               if (mgmt->m_family != LLDPD_AF_IPV4)
+                               continue;
+               oid index[6] = {
+                       1, 4,
+                       mgmt->m_addr.octets[0],
+                       mgmt->m_addr.octets[1],
+                       mgmt->m_addr.octets[2],
+                       mgmt->m_addr.octets[3] };
+               if (header_index_add(index, 6, chassis))
+                       return chassis;
+       }
 
-       return NULL;
+       return header_index_best();
 }
 
 static struct lldpd_chassis*
@@ -249,24 +253,27 @@ header_tpripindexed_table(struct variable *vp, oid *name, size_t *length,
 {
        struct lldpd_hardware *hardware;
        struct lldpd_port *port;
+       struct lldpd_mgmt *mgmt;
 
        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;
-                       if (port->p_chassis->c_mgmt.s_addr == INADDR_ANY)
-                               continue;
-                       oid index[9] = { lastchange(port),
-                                        hardware->h_ifindex,
-                                        port->p_chassis->c_index,
-                                        1, 4,
-                                        ((u_int8_t*)&port->p_chassis->c_mgmt.s_addr)[0],
-                                        ((u_int8_t*)&port->p_chassis->c_mgmt.s_addr)[1],
-                                        ((u_int8_t*)&port->p_chassis->c_mgmt.s_addr)[2],
-                                        ((u_int8_t*)&port->p_chassis->c_mgmt.s_addr)[3] };
-                       if (header_index_add(index, 9,
-                                            port->p_chassis))
-                               return port->p_chassis;
+                       TAILQ_FOREACH(mgmt, &port->p_chassis->c_mgmt, m_entries) {
+                               if (mgmt->m_family != LLDPD_AF_IPV4)
+                                       continue;
+                               oid index[9] = { lastchange(port),
+                                                hardware->h_ifindex,
+                                                port->p_chassis->c_index,
+                                                1, 4,
+                                                mgmt->m_addr.octets[0],
+                                                mgmt->m_addr.octets[1],
+                                                mgmt->m_addr.octets[2],
+                                                mgmt->m_addr.octets[3] };
+                               if (header_index_add(index, 9,
+                                                        port->p_chassis))
+                                       return port->p_chassis;
+                       }
                }
        }
        return header_index_best();
@@ -1328,15 +1335,18 @@ agent_v_management(struct variable *vp, size_t *var_len, struct lldpd_chassis *c
         case LLDP_SNMP_ADDR_LEN:
                 long_ret = 5;
                 return (u_char*)&long_ret;
+/* FIXME */
+/*
         case LLDP_SNMP_ADDR_IFSUBTYPE:
-                if (chassis->c_mgmt_if != 0)
+                if (chassis->c_mgmt4.iface != 0)
                         long_ret = LLDP_MGMT_IFACE_IFINDEX;
                 else
                         long_ret = 1;
                 return (u_char*)&long_ret;
         case LLDP_SNMP_ADDR_IFID:
-                long_ret = chassis->c_mgmt_if;
+                long_ret = chassis->c_mgmt4.iface;
                 return (u_char*)&long_ret;
+*/
         case LLDP_SNMP_ADDR_OID:
                 *var_len = sizeof(zeroDotZero);
                 return (u_char*)zeroDotZero;
index 609773b8d4814bc26ec85b3f3e3ab66b5053fbe1..b66b8ba5afa66cab0616e4365870129cea77f5e7 100644 (file)
--- a/src/cdp.c
+++ b/src/cdp.c
 #include <unistd.h>
 #include <errno.h>
 #include <arpa/inet.h>
+#include <assert.h>
 
 static int
 cdp_send(struct lldpd *global,
         struct lldpd_hardware *hardware, int version)
 {
        struct lldpd_chassis *chassis;
+       struct lldpd_mgmt *mgmt;
        u_int8_t mcastaddr[] = CDP_MULTICAST_ADDR;
        u_int8_t llcorg[] = LLC_ORG_CISCO;
 #ifdef ENABLE_FDP
@@ -94,16 +96,22 @@ cdp_send(struct lldpd *global,
                goto toobig;
 
        /* Adresses */
-       if (!(
-             POKE_START_CDP_TLV(CDP_TLV_ADDRESSES) &&
-             POKE_UINT32(1) && /* We ship only one address */
-             POKE_UINT8(1) &&  /* Type: NLPID */
-             POKE_UINT8(1) &&  /* Length: 1 */
-             POKE_UINT8(CDP_ADDRESS_PROTO_IP) && /* IP */
-             POKE_UINT16(sizeof(struct in_addr)) && /* Address length */
-             POKE_BYTES(&chassis->c_mgmt, sizeof(struct in_addr)) &&
-             POKE_END_CDP_TLV))
-               goto toobig;
+       TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+               if (mgmt->m_family == LLDPD_AF_IPV4) {
+                       if (!(
+                               POKE_START_CDP_TLV(CDP_TLV_ADDRESSES) &&
+                               POKE_UINT32(1) &&       /* We ship only one address */
+                               POKE_UINT8(1) &&        /* Type: NLPID */
+                               POKE_UINT8(1) &&  /* Length: 1 */
+                               POKE_UINT8(CDP_ADDRESS_PROTO_IP) && /* IP */
+                               POKE_UINT16(sizeof(struct in_addr)) && /* Address length */
+                               POKE_BYTES(&mgmt->m_addr, sizeof(struct in_addr)) &&
+                               POKE_END_CDP_TLV)) {
+                               goto toobig;
+                       }
+               break;
+               }
+       }
 
        /* Port ID */
        if (!(
@@ -211,6 +219,8 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
 {
        struct lldpd_chassis *chassis;
        struct lldpd_port *port;
+       struct lldpd_mgmt *mgmt;
+       struct in_addr addr;
 #if 0
        u_int16_t cksum;
 #endif
@@ -231,6 +241,7 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
                LLOG_WARN("failed to allocate remote chassis");
                return -1;
        }
+       TAILQ_INIT(&chassis->c_mgmt);
        if ((port = calloc(1, sizeof(struct lldpd_port))) == NULL) {
                LLOG_WARN("failed to allocate remote port");
                free(chassis);
@@ -379,10 +390,17 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
                                PEEK_RESTORE(pos_address);
                                if ((PEEK_UINT8 == 1) && (PEEK_UINT8 == 1) &&
                                    (PEEK_UINT8 == CDP_ADDRESS_PROTO_IP) &&
-                                   (PEEK_UINT16 == sizeof(struct in_addr)) &&
-                                   (chassis->c_mgmt.s_addr == INADDR_ANY))
-                                       PEEK_BYTES(&chassis->c_mgmt,
-                                                  sizeof(struct in_addr));
+                                   (PEEK_UINT16 == sizeof(struct in_addr))) {
+                                               PEEK_BYTES(&addr, sizeof(struct in_addr));
+                                               mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr, 
+                                                                       sizeof(struct in_addr), 0);
+                                               if (mgmt == NULL) {
+                                                       assert(errno == ENOMEM);
+                                                       LLOG_WARN("unable to allocate memory for management address");
+                                                       goto malformed;
+                                               }
+                                               TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
+                               }
                                /* Go to the end of the address */
                                PEEK_RESTORE(pos_next_address);
                        }
index 480381c80558c59e4621a1598f7b9fce468ca13f..14b34f715f6fd5a35b824fbf864340a308e08e1e 100644 (file)
@@ -643,6 +643,8 @@ display_chassis(struct writer * w, struct lldpd_chassis *chassis)
 {
        char *cid;
        struct in_addr ip;
+       struct lldpd_mgmt *mgmt;
+       char addrbuf[INET6_ADDRSTRLEN];
 
        if ((cid = (char *)malloc(chassis->c_id_len + 1)) == NULL)
                fatal(NULL);
@@ -679,8 +681,18 @@ display_chassis(struct writer * w, struct lldpd_chassis *chassis)
        tag_datatag(w, "name", "SysName", chassis->c_name);
        tag_datatag(w, "descr", "SysDescr", chassis->c_descr);
 
-       if (chassis->c_mgmt.s_addr != INADDR_ANY)
-               tag_datatag(w, "mgmt-ip", "MgmtIP", inet_ntoa(chassis->c_mgmt));
+       TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+               memset(addrbuf, 0, sizeof(addrbuf));
+               inet_ntop(lldpd_af(mgmt->m_family), &mgmt->m_addr, addrbuf, sizeof(addrbuf));
+               switch (mgmt->m_family) {
+               case LLDPD_AF_IPV4:
+                       tag_datatag(w, "mgmt-ip", "MgmtIP", addrbuf);
+                       break;
+               case LLDPD_AF_IPV6:
+                       tag_datatag(w, "mgmt-ip6", "MgmtIPv6", addrbuf);
+                       break;
+               }
+       }
 
        display_cap(w, chassis, LLDP_CAP_OTHER, "Other");
        display_cap(w, chassis, LLDP_CAP_REPEATER, "Repeater");
index ee210065c074b45452ea0b2c21a5c1e14e4efc63..a0d980dfac3ae7c78615f389ca2d5bff852dcdb6 100644 (file)
--- a/src/edp.c
+++ b/src/edp.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <arpa/inet.h>
 #include <fnmatch.h>
+#include <assert.h>
 
 static int seq = 0;
 
@@ -229,6 +230,7 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
 {
        struct lldpd_chassis *chassis;
        struct lldpd_port *port;
+       struct lldpd_mgmt *mgmt, *m;
 #ifdef ENABLE_DOT1
        struct lldpd_vlan *lvlan = NULL, *lvlan_next;
 #endif
@@ -246,6 +248,7 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
                LLOG_WARN("failed to allocate remote chassis");
                return -1;
        }
+       TAILQ_INIT(&chassis->c_mgmt);
        if ((port = calloc(1, sizeof(struct lldpd_port))) == NULL) {
                LLOG_WARN("failed to allocate remote port");
                free(chassis);
@@ -410,18 +413,14 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
                        PEEK_BYTES(lvlan->v_name, tlv_len - 12);
 
                        if (address.s_addr != INADDR_ANY) {
-                               if (chassis->c_mgmt.s_addr == INADDR_ANY)
-                                       chassis->c_mgmt.s_addr = address.s_addr;
-                               else
-                                       /* We need to guess the good one */
-                                       if (cfg->g_mgmt_pattern != NULL) {
-                                               /* We can try to use this to prefer an address */
-                                               char *ip;
-                                               ip = inet_ntoa(address);
-                                               if (fnmatch(cfg->g_mgmt_pattern,
-                                                       ip, 0) == 0)
-                                                       chassis->c_mgmt.s_addr = address.s_addr;
-                                       }
+                               mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &address, 
+                                                       sizeof(struct in_addr), 0);
+                               if (mgmt == NULL) {
+                                       assert(errno == ENOMEM);
+                                       LLOG_WARN("Out of memory");
+                                       goto malformed;
+                               }
+                               TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
                        }
                        TAILQ_INSERT_TAIL(&port->p_vlans,
                            lvlan, v_entries);
@@ -464,9 +463,16 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
                                            lvlan, v_entries);
                                }
                                /* And the IP address */
-                               oport->p_chassis->c_mgmt.s_addr =
-                                   chassis->c_mgmt.s_addr;
-                               break;
+                               TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+                                       m = lldpd_alloc_mgmt(mgmt->m_family,
+                                                       &mgmt->m_addr, mgmt->m_addrsize, mgmt->m_iface);
+                                       if (m == NULL) {
+                                               assert(errno == ENOMEM);
+                                               LLOG_WARN("Out of memory");
+                                               goto malformed;
+                                       }
+                                       TAILQ_INSERT_TAIL(&oport->p_chassis->c_mgmt, m, m_entries);
+                               }
                        }
                        /* We discard the remaining frame */
                        goto malformed;
index 781784b363d417b04c7008b3f49040a40d48bce9..ce91f5dcc1666298f07b7ea6a27b9df8c92b5729 100644 (file)
@@ -21,6 +21,7 @@
 #include <stddef.h>
 #include <unistd.h>
 #include <errno.h>
+#include <assert.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1042,6 +1043,17 @@ lldpd_ifh_vlan(struct lldpd *cfg, struct ifaddrs *ifap)
 }
 #endif
 
+#ifndef IN_IS_ADDR_LOOPBACK
+#define IN_IS_ADDR_LOOPBACK(a) ((a)->s_addr == htonl(INADDR_LOOPBACK))
+#endif
+#ifndef IN_IS_ADDR_GLOBAL
+#define IN_IS_ADDR_GLOBAL(a) (!IN_IS_ADDR_LOOPBACK(a))
+#endif
+#ifndef IN6_IS_ADDR_GLOBAL
+#define IN6_IS_ADDR_GLOBAL(a) (!IN6_IS_ADDR_LOOPBACK(a) && \
+                                                               !IN6_IS_ADDR_LINKLOCAL(a))
+#endif
+
 /* Find a management address in all available interfaces, even those that were
    already handled. This is a special interface handler because it does not
    really handle interface related information (management address is attached
@@ -1050,38 +1062,64 @@ void
 lldpd_ifh_mgmt(struct lldpd *cfg, struct ifaddrs *ifap)
 {
        struct ifaddrs *ifa;
-       struct sockaddr_in sa;
-
-       if (LOCAL_CHASSIS(cfg)->c_mgmt.s_addr != INADDR_ANY)
-               return;         /* We already have one */
+       char addrstrbuf[INET6_ADDRSTRLEN];
+       struct lldpd_mgmt *mgmt, *mgmt_next;
+       void *sin_addr_ptr;
+       size_t sin_addr_size;
+       char *mgmt_pattern_ptr;
+       int af;
+
+       for (mgmt = TAILQ_FIRST(&LOCAL_CHASSIS(cfg)->c_mgmt); mgmt;
+                       mgmt = mgmt_next) {
+               mgmt_next = TAILQ_NEXT(mgmt, m_entries);
+               TAILQ_REMOVE(&LOCAL_CHASSIS(cfg)->c_mgmt, mgmt, m_entries);
+               free(mgmt);
+       }
 
-       for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-               if ((ifa->ifa_addr != NULL) &&
-                   (ifa->ifa_addr->sa_family == AF_INET)) {
-                       /* We have an IPv4 address (IPv6 not handled yet) */
-                       memcpy(&sa, ifa->ifa_addr, sizeof(struct sockaddr_in));
-                       if ((ntohl(*(u_int32_t*)&sa.sin_addr) != INADDR_LOOPBACK) &&
-                           (cfg->g_mgmt_pattern == NULL)) {
-                               memcpy(&LOCAL_CHASSIS(cfg)->c_mgmt,
-                                   &sa.sin_addr,
-                                   sizeof(struct in_addr));
-                               LOCAL_CHASSIS(cfg)->c_mgmt_if = if_nametoindex(ifa->ifa_name);
-                       } else if (cfg->g_mgmt_pattern != NULL) {
-                               char *ip;
-                               ip = inet_ntoa(sa.sin_addr);
-                               if (fnmatch(cfg->g_mgmt_pattern,
-                                       ip, 0) == 0) {
-                                       memcpy(&LOCAL_CHASSIS(cfg)->c_mgmt,
-                                           &sa.sin_addr,
-                                           sizeof(struct in_addr));
-                                       LOCAL_CHASSIS(cfg)->c_mgmt_if =
-                                           if_nametoindex(ifa->ifa_name);
+       /* Find management addresses */
+       for (af = LLDPD_AF_UNSPEC + 1; af != LLDPD_AF_LAST; af++) {
+               /* We only take one of each address family */
+               mgmt = NULL;
+               for (ifa = ifap; ifa != NULL && mgmt == NULL; ifa = ifa->ifa_next) {
+                       if (ifa->ifa_addr == NULL)
+                               continue;
+                       if (ifa->ifa_addr->sa_family != lldpd_af(af))
+                               continue;
+                       switch (af) {
+                       case LLDPD_AF_IPV4:
+                               sin_addr_ptr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
+                               sin_addr_size = sizeof(struct in_addr);
+                               if (!IN_IS_ADDR_GLOBAL((struct in_addr *)sin_addr_ptr))
+                                       continue;
+                               mgmt_pattern_ptr = cfg->g_mgmt_pattern;
+                               break;
+                       case LLDPD_AF_IPV6:
+                               sin_addr_ptr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
+                               sin_addr_size = sizeof(struct in6_addr);
+                               if (!IN6_IS_ADDR_GLOBAL((struct in6_addr *)sin_addr_ptr))
+                                       continue;
+                               mgmt_pattern_ptr = cfg->g_mgmt_pattern6;
+                               break;
+                       default:
+                               assert(0);
+                       }
+                       inet_ntop(lldpd_af(af), sin_addr_ptr, addrstrbuf, sizeof(addrstrbuf));
+                       if (mgmt_pattern_ptr == NULL || 
+                                       fnmatch(mgmt_pattern_ptr, addrstrbuf, 0) == 0) {
+                               mgmt = lldpd_alloc_mgmt(af, sin_addr_ptr, sin_addr_size,
+                                                       if_nametoindex(ifa->ifa_name));
+                               if (mgmt == NULL) {
+                                       assert(errno == ENOMEM); /* anything else is a bug */
+                                       LLOG_WARN("out of memory error");
+                                       return;
                                }
+                               TAILQ_INSERT_TAIL(&LOCAL_CHASSIS(cfg)->c_mgmt, mgmt, m_entries);
                        }
                }
        }
 }
 
+
 /* Fill out chassis ID if not already done. This handler is special
    because we will only handle interfaces that are already handled. */
 void
index 31c6de46e253ca68877b6a36ff85e3a7509940f4..c58f0d855d7d34deba23e9123dad2a5b9e9d761a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <unistd.h>
 #include <errno.h>
+#include <assert.h>
 #include <time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netpacket/packet.h>
 #include <linux/sockios.h>
 
+inline static int
+lldpd_af_to_lldp_proto(int af)
+{
+       switch (af) {
+       case LLDPD_AF_IPV4:
+               return LLDP_MGMT_ADDR_IP4;
+       case LLDPD_AF_IPV6:
+               return LLDP_MGMT_ADDR_IP6;
+       default:
+               return LLDP_MGMT_ADDR_NONE;
+       }
+}
+
+inline static int
+lldpd_af_from_lldp_proto(int proto)
+{
+       switch (proto) {
+       case LLDP_MGMT_ADDR_IP4:
+               return LLDPD_AF_IPV4;
+       case LLDP_MGMT_ADDR_IP6:
+               return LLDPD_AF_IPV6;
+       default:
+               return LLDPD_AF_UNSPEC;
+       }
+}
+
 int
 lldp_send(struct lldpd *global,
          struct lldpd_hardware *hardware)
@@ -35,6 +62,8 @@ lldp_send(struct lldpd *global,
        struct lldpd_frame *frame;
        int length;
        u_int8_t *packet, *pos, *tlv;
+       struct lldpd_mgmt *mgmt;
+       int proto;
 
        u_int8_t mcastaddr[] = LLDP_MULTICAST_ADDR;
 #ifdef ENABLE_DOT1
@@ -114,35 +143,36 @@ lldp_send(struct lldpd *global,
              POKE_END_LLDP_TLV))
                goto toobig;
 
-       if (chassis->c_mgmt.s_addr != INADDR_ANY) {
-               /* Management address */
+       /* Management addresses */
+       TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+               proto = lldpd_af_to_lldp_proto(mgmt->m_family);
+               assert(proto != LLDP_MGMT_ADDR_NONE);
                if (!(
-                     POKE_START_LLDP_TLV(LLDP_TLV_MGMT_ADDR) &&
-                     /* Size of the address, including its type */
-                     POKE_UINT8(sizeof(struct in_addr) + 1) &&
-                     /* Address is IPv4 */
-                     POKE_UINT8(LLDP_MGMT_ADDR_IP4) &&
-                     POKE_BYTES(&chassis->c_mgmt, sizeof(struct in_addr))))
+                         POKE_START_LLDP_TLV(LLDP_TLV_MGMT_ADDR) &&
+                         /* Size of the address, including its type */
+                         POKE_UINT8(mgmt->m_addrsize + 1) &&
+                         POKE_UINT8(proto) &&
+                         POKE_BYTES(&mgmt->m_addr, mgmt->m_addrsize)))
                        goto toobig;
 
                /* Interface port type, OID */
-               if (chassis->c_mgmt_if == 0) {
+               if (mgmt->m_iface == 0) {
                        if (!(
-                             /* We don't know the management interface */
-                             POKE_UINT8(LLDP_MGMT_IFACE_UNKNOWN) &&
-                             POKE_UINT32(0)))
+                                 /* We don't know the management interface */
+                                 POKE_UINT8(LLDP_MGMT_IFACE_UNKNOWN) &&
+                                 POKE_UINT32(0)))
                                goto toobig;
                } else {
                        if (!(
-                             /* We have the index of the management interface */
-                             POKE_UINT8(LLDP_MGMT_IFACE_IFINDEX) &&
-                             POKE_UINT32(chassis->c_mgmt_if)))
+                                 /* We have the index of the management interface */
+                                 POKE_UINT8(LLDP_MGMT_IFACE_IFINDEX) &&
+                                 POKE_UINT32(mgmt->m_iface)))
                                goto toobig;
                }
                if (!(
-                     /* We don't provide an OID for management */
-                     POKE_UINT8(0) &&
-                     POKE_END_LLDP_TLV))
+                         /* We don't provide an OID for management */
+                         POKE_UINT8(0) &&
+                         POKE_END_LLDP_TLV))
                        goto toobig;
        }
 
@@ -456,11 +486,17 @@ lldp_decode(struct lldpd *cfg, char *frame, int s,
        struct lldpd_ppvid *ppvid;
        struct lldpd_pi *pi;
 #endif
+       struct lldpd_mgmt *mgmt;
+       int af;
+       u_int8_t addr_str_length, addr_str_buffer[32];
+       u_int8_t addr_family, addr_length, *addr_ptr, iface_subtype;
+       u_int32_t iface_number, iface;
 
        if ((chassis = calloc(1, sizeof(struct lldpd_chassis))) == NULL) {
                LLOG_WARN("failed to allocate remote chassis");
                return -1;
        }
+       TAILQ_INIT(&chassis->c_mgmt);
        if ((port = calloc(1, sizeof(struct lldpd_port))) == NULL) {
                LLOG_WARN("failed to allocate remote port");
                free(chassis);
@@ -575,17 +611,32 @@ lldp_decode(struct lldpd *cfg, char *frame, int s,
                        chassis->c_cap_enabled = PEEK_UINT16;
                        break;
                case LLDP_TLV_MGMT_ADDR:
-                       CHECK_TLV_SIZE(11, "Management address");
-                       if ((chassis->c_mgmt.s_addr == INADDR_ANY) &&
-                           (PEEK_UINT8 == 1+sizeof(struct in_addr)) &&
-                           (PEEK_UINT8 == LLDP_MGMT_ADDR_IP4)) {
-                               /* We have an IPv4 address, we ignore anything else */
-                               PEEK_BYTES(&chassis->c_mgmt, sizeof(struct in_addr));
-                               chassis->c_mgmt_if = 0;
-                               /* We only handle ifIndex subtype */
-                               if (PEEK_UINT8 == LLDP_MGMT_IFACE_IFINDEX)
-                                       chassis->c_mgmt_if = PEEK_UINT32;
+                       CHECK_TLV_SIZE(1, "Management address");
+                       addr_str_length = PEEK_UINT8;
+                       CHECK_TLV_SIZE(addr_str_length, "Management address");
+                       PEEK_BYTES(addr_str_buffer, addr_str_length);
+                       addr_length = addr_str_length - 1;
+                       addr_family = addr_str_buffer[0];
+                       addr_ptr = &addr_str_buffer[1];
+                       CHECK_TLV_SIZE(5, "Management address");
+                       iface_subtype = PEEK_UINT8;
+                       iface_number = PEEK_UINT32;
+                       
+                       af = lldpd_af_from_lldp_proto(addr_family);
+                       if (af == LLDPD_AF_UNSPEC)
+                               break;
+                       if (iface_subtype == LLDP_MGMT_IFACE_IFINDEX)
+                               iface = iface_number;
+                       else
+                               iface = 0;
+                       mgmt = lldpd_alloc_mgmt(af, addr_ptr, addr_length, iface);
+                       if (mgmt == NULL) {
+                               assert(errno == ENOMEM);
+                               LLOG_WARN("unable to allocate memory "
+                                                       "for management address");
+                                               goto malformed;
                        }
+                       TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
                        break;
                case LLDP_TLV_ORG:
                        CHECK_TLV_SIZE(4, "Organisational");
index 7f7fc723ee813cb6467f64b7e8a30bf9123677aa..738b4cebb51acb58449b802bc9730ac409374b82 100644 (file)
@@ -174,6 +174,7 @@ enum {
 
 /* see http://www.iana.org/assignments/address-family-numbers */
 enum {
+       LLDP_MGMT_ADDR_NONE     = 0,
        LLDP_MGMT_ADDR_IP4      = 1,
        LLDP_MGMT_ADDR_IP6      = 2
 };
index 5f4b1cdfd80f68e19ce2b546f115d2c53b334e0f..1ae7149e8bec3ac6c78252000c61cbe80446437e 100644 (file)
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 #include <time.h>
 #include <libgen.h>
+#include <assert.h>
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -94,7 +95,9 @@ usage(void)
        fprintf(stderr, "-k       Disable advertising of kernel release, version, machine.\n");
        fprintf(stderr, "-S descr Override the default system description.\n");
        fprintf(stderr, "-P name  Override the default hardware platform.\n");
-       fprintf(stderr, "-m IP    Specify the management address of this system.\n");
+       fprintf(stderr, "-4 IP    Specify the IPv4 management address of this system.\n");
+       fprintf(stderr, "-m IP    Same as '-4', for backward compatibility.\n");
+       fprintf(stderr, "-6 IP    Specify the IPv6 management address of this system.\n");
        fprintf(stderr, "-H mode  Specify the behaviour when detecting multiple neighbors.\n");
        fprintf(stderr, "-I iface Limit interfaces to use.\n");
 #ifdef ENABLE_LLDPMED
@@ -243,6 +246,32 @@ lldpd_port_cleanup(struct lldpd *cfg, struct lldpd_port *port, int all)
        }
 }
 
+struct lldpd_mgmt *
+lldpd_alloc_mgmt(int family, void *addrptr, size_t addrsize, u_int32_t iface)
+{
+       struct lldpd_mgmt *mgmt;
+       
+       if (family <= LLDPD_AF_UNSPEC || family >= LLDPD_AF_LAST) {
+               errno = EAFNOSUPPORT;
+               return NULL;
+       }
+       if (addrsize > LLDPD_MGMT_MAXADDRSIZE) {
+               errno = EOVERFLOW;
+               return NULL;
+       }
+       mgmt = calloc(1, sizeof(struct lldpd_mgmt));
+       if (mgmt == NULL) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       mgmt->m_family = family;
+       assert(addrsize <= LLDPD_MGMT_MAXADDRSIZE);
+       memcpy(&mgmt->m_addr, addrptr, addrsize);
+       mgmt->m_addrsize = addrsize;
+       mgmt->m_iface = iface;
+       return mgmt;
+}
+
 void
 lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all)
 {
@@ -1011,7 +1040,6 @@ lldpd_update_localports(struct lldpd *cfg)
        TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries)
            hardware->h_flags = 0;
 
-       LOCAL_CHASSIS(cfg)->c_mgmt.s_addr = INADDR_ANY;
        if (getifaddrs(&ifap) != 0)
                fatal("lldpd_update_localports: failed to get interface list");
 
@@ -1121,11 +1149,11 @@ lldpd_main(int argc, char *argv[])
        int snmp = 0;
        char *agentx = NULL;    /* AgentX socket */
 #endif
-       char *mgmtp = NULL;
+       char *mgmtp = NULL, *mgmtp6 = NULL;
        char *cidp = NULL;
        char *interfaces = NULL;
        char *popt, opts[] = 
-               "H:hkrdxX:m:I:C:p:M:P:S:i@                    ";
+               "H:hkrdxX:m:4:6:I:C:p:M:P:S:i@                    ";
        int i, found, advertise_version = 1;
 #ifdef ENABLE_LLDPMED
        int lldpmed = 0, noinventory = 0;
@@ -1156,9 +1184,12 @@ lldpd_main(int argc, char *argv[])
                case 'r':
                        receiveonly = 1;
                        break;
-               case 'm':
+               case 'm': /* fall through */
+               case '4':
                        mgmtp = optarg;
                        break;
+               case '6':
+                       mgmtp6 = optarg;
                case 'I':
                        interfaces = optarg;
                        break;
@@ -1269,6 +1300,7 @@ lldpd_main(int argc, char *argv[])
                fatal(NULL);
 
        cfg->g_mgmt_pattern = mgmtp;
+       cfg->g_mgmt_pattern6 = mgmtp6;
        cfg->g_cid_pattern = cidp;
        cfg->g_interfaces = interfaces;
        cfg->g_smart = smart;
@@ -1296,6 +1328,7 @@ lldpd_main(int argc, char *argv[])
                fatal(NULL);
        lchassis->c_cap_available = LLDP_CAP_BRIDGE | LLDP_CAP_WLAN |
            LLDP_CAP_ROUTER;
+       TAILQ_INIT(&lchassis->c_mgmt);
 #ifdef ENABLE_LLDPMED
        if (lldpmed > 0) {
                if (lldpmed == LLDPMED_CLASS_III)
index 696c710fb2fec9dec4cbd0c8c492554d320f620c..9773e1211b020ab0f04b24515cdef29aca897a4f 100644 (file)
 #define LLDPD_PPVID_CAP_SUPPORTED              (1 << 1)
 #define LLDPD_PPVID_CAP_ENABLED                        (1 << 2)
 
+enum {
+       LLDPD_AF_UNSPEC = 0,
+       LLDPD_AF_IPV4,
+       LLDPD_AF_IPV6,
+       LLDPD_AF_LAST
+};
+
+inline static int
+lldpd_af(int af)
+{
+       switch (af) {
+       case LLDPD_AF_IPV4:
+               return AF_INET;
+       case LLDPD_AF_IPV6:
+               return AF_INET6;
+       case LLDPD_AF_LAST:
+               return AF_MAX;
+       default:
+               return AF_UNSPEC;
+       }
+}
+
 struct lldpd_ppvid {
        TAILQ_ENTRY(lldpd_ppvid) p_entries;
        u_int8_t                p_cap_status;
@@ -156,6 +178,22 @@ struct lldpd_dot3_power {
 MARSHAL(lldpd_dot3_power);
 #endif
 
+#define LLDPD_MGMT_MAXADDRSIZE 16 /* sizeof(struct in6_addr) */
+struct lldpd_mgmt {
+       TAILQ_ENTRY(lldpd_mgmt) m_entries;
+       int                             m_family;
+       union {
+               struct in_addr          inet;
+               struct in6_addr         inet6;
+               u_int8_t                        octets[LLDPD_MGMT_MAXADDRSIZE];
+       } m_addr;
+       size_t                  m_addrsize;
+       u_int32_t               m_iface;
+};
+MARSHAL_BEGIN(lldpd_mgmt)
+MARSHAL_TQE(lldpd_mgmt, m_entries)
+MARSHAL_END;
+
 struct lldpd_chassis {
        TAILQ_ENTRY(lldpd_chassis) c_entries;
        u_int16_t                c_refcount; /* Reference count by ports */
@@ -172,8 +210,7 @@ struct lldpd_chassis {
 
        u_int16_t                c_ttl;
 
-       struct in_addr           c_mgmt;
-       u_int32_t                c_mgmt_if;
+       TAILQ_HEAD(, lldpd_mgmt) c_mgmt;
 
 #ifdef ENABLE_LLDPMED
        u_int16_t                c_med_cap_available;
@@ -193,6 +230,7 @@ MARSHAL_TQE(lldpd_chassis, c_entries)
 MARSHAL_FSTR(lldpd_chassis, c_id, c_id_len)
 MARSHAL_STR(lldpd_chassis, c_name)
 MARSHAL_STR(lldpd_chassis, c_descr)
+MARSHAL_SUBTQ(lldpd_chassis, lldpd_mgmt, c_mgmt)
 #ifdef ENABLE_LLDPMED
 MARSHAL_STR(lldpd_chassis, c_med_hw)
 MARSHAL_STR(lldpd_chassis, c_med_fw)
@@ -414,7 +452,7 @@ struct lldpd {
 
        TAILQ_HEAD(, lldpd_callback) g_callbacks;
 
-       char                    *g_mgmt_pattern;
+       char                    *g_mgmt_pattern, *g_mgmt_pattern6;
        char                    *g_cid_pattern;
        char                    *g_interfaces;
 
@@ -452,6 +490,7 @@ void         lldpd_pi_cleanup(struct lldpd_port *);
 #endif
 void    lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
 void    lldpd_port_cleanup(struct lldpd*, struct lldpd_port *, int);
+struct lldpd_mgmt *lldpd_alloc_mgmt(int family, void *addr, size_t addrsize, u_int32_t iface);
 void    lldpd_chassis_cleanup(struct lldpd_chassis *, int);
 int     lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
 void    lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));
index a7a8f13e0c7c9069ad86918d1f18ca7a92e51750..ba905d9300bd9f5e047a241a1555122b100d183e 100644 (file)
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <arpa/inet.h>
+#include <assert.h>
 
 static struct sonmp_chassis sonmp_chassis_types[] = {
        {1, "unknown (via SONMP)"},
@@ -186,8 +187,10 @@ sonmp_send(struct lldpd *global,
        const u_int8_t mcastaddr[] = SONMP_MULTICAST_ADDR;
        const u_int8_t llcorg[] = LLC_ORG_NORTEL;
        struct lldpd_chassis *chassis;
+       struct lldpd_mgmt *mgmt;
        u_int8_t *packet, *pos, *pos_pid, *end;
        int length;
+       struct in_addr address;
 
        chassis = hardware->h_lport.p_chassis;
        length = hardware->h_mtu;
@@ -219,21 +222,30 @@ sonmp_send(struct lldpd *global,
              POKE_UINT16(LLC_PID_SONMP_HELLO)))
                goto toobig;
 
+
+       address.s_addr = htonl(INADDR_ANY);
+       TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
+               if (mgmt->m_family == LLDPD_AF_IPV4) {
+                       address.s_addr = mgmt->m_addr.inet.s_addr;
+               }
+               break;
+       }
+
        /* SONMP */
        if (!(
-             /* Our IP address */
-             POKE_BYTES(&chassis->c_mgmt, sizeof(struct in_addr)) &&
-             /* Segment on three bytes, we don't have slots, so we
+                 /* Our IP address */
+                 POKE_BYTES(&address, sizeof(struct in_addr)) &&
+                 /* Segment on three bytes, we don't have slots, so we
                 skip the first two bytes */
-             POKE_UINT16(0) &&
-             POKE_UINT8(hardware->h_ifindex) &&
-             POKE_UINT8(1) &&  /* Chassis: Other */
-             POKE_UINT8(12) && /* Back: Ethernet, Fast Ethernet and Gigabit */
-             POKE_UINT8(SONMP_TOPOLOGY_NEW) && /* Should work. We have no state */
-             POKE_UINT8(1) &&  /* Links: Dunno what it is */
-             POKE_SAVE(end)))
+                 POKE_UINT16(0) &&
+                 POKE_UINT8(hardware->h_ifindex) &&
+                 POKE_UINT8(1) &&  /* Chassis: Other */
+                 POKE_UINT8(12) &&     /* Back: Ethernet, Fast Ethernet and Gigabit */
+                 POKE_UINT8(SONMP_TOPOLOGY_NEW) && /* Should work. We have no state */
+                 POKE_UINT8(1) &&      /* Links: Dunno what it is */
+                 POKE_SAVE(end)))
                goto toobig;
-
+                               
        if (hardware->h_ops->send(global, hardware,
                (char *)packet, end - packet) == -1) {
                LLOG_WARN("unable to send packet on real device for %s",
@@ -272,6 +284,7 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
        const u_int8_t mcastaddr[] = SONMP_MULTICAST_ADDR;
        struct lldpd_chassis *chassis;
        struct lldpd_port *port;
+       struct lldpd_mgmt *mgmt;
        int length, i;
        u_int8_t *pos;
        u_int8_t seg[3], rchassis;
@@ -281,6 +294,7 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
                LLOG_WARN("failed to allocate remote chassis");
                return -1;
        }
+       TAILQ_INIT(&chassis->c_mgmt);
        if ((port = calloc(1, sizeof(struct lldpd_port))) == NULL) {
                LLOG_WARN("failed to allocate remote port");
                free(chassis);
@@ -336,7 +350,13 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
                    hardware->h_ifname);
                goto malformed;
        }
-       memcpy(&chassis->c_mgmt, &address, sizeof(struct in_addr));
+       mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &address, sizeof(struct in_addr), 0);
+       if (mgmt == NULL) {
+               assert(errno == ENOMEM);
+               LLOG_WARN("unable to allocate memory for management address");
+               goto malformed;
+       }
+       TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
        chassis->c_ttl = LLDPD_TTL;
 
        port->p_id_subtype = LLDP_PORTID_SUBTYPE_LOCAL;
index f83117bad2070b9cbd207607ff8200450e806ea4..4a6c2c8945af79b90b5e049539eab116f0d7989c 100644 (file)
@@ -102,7 +102,13 @@ Cisco Discovery Protocol
        chassis.c_name = "First chassis";
        chassis.c_descr = "Chassis description";
        chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER;
-       chassis.c_mgmt.s_addr = inet_addr("172.17.142.37");
+       TAILQ_INIT(&chassis.c_mgmt);
+       in_addr_t addr = inet_addr("172.17.142.37");
+       struct lldpd_mgmt *mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, 
+                                       &addr, sizeof(in_addr_t), 0);
+       if (mgmt == NULL)
+               ck_abort();
+       TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries);
 
        /* Build packet */
        n = cdpv1_send(NULL, &hardware);
@@ -215,7 +221,13 @@ Cisco Discovery Protocol
        chassis.c_descr = "Chassis description";
        chassis.c_cap_available = chassis.c_cap_enabled =
          LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE;
-       chassis.c_mgmt.s_addr = inet_addr("172.17.142.36");
+       TAILQ_INIT(&chassis.c_mgmt);
+       in_addr_t addr = inet_addr("172.17.142.36");
+       struct lldpd_mgmt *mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, 
+                                       &addr, sizeof(in_addr_t), 0);
+       if (mgmt == NULL)
+               ck_abort();
+       TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries);
 
        /* Build packet */
        n = cdpv2_send(NULL, &hardware);
@@ -352,9 +364,9 @@ Cisco Discovery Protocol
        ck_assert_int_eq(nchassis->c_id_len, 2);
        fail_unless(memcmp(nchassis->c_id, "R1", 2) == 0);
        ck_assert_str_eq(nchassis->c_name, "R1");
-       ck_assert_int_eq(nchassis->c_mgmt.s_addr,
+       ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr,
            (u_int32_t)inet_addr("192.168.10.1"));
-       ck_assert_int_eq(nchassis->c_mgmt_if, 0);
+       ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 0);
        ck_assert_int_eq(nport->p_id_subtype,
            LLDP_PORTID_SUBTYPE_IFNAME);
        ck_assert_int_eq(nport->p_id_len, strlen("Ethernet0"));
@@ -496,9 +508,9 @@ Cisco Discovery Protocol
        fail_unless(memcmp(nchassis->c_id,
                "rtbg6test01", strlen("rtbg6test01")) == 0);
        ck_assert_str_eq(nchassis->c_name, "rtbg6test01");
-       ck_assert_int_eq(nchassis->c_mgmt.s_addr,
+       ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr,
            (u_int32_t)inet_addr("172.66.55.3"));
-       ck_assert_int_eq(nchassis->c_mgmt_if, 0);
+       ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0);
        ck_assert_int_eq(nport->p_id_subtype,
            LLDP_PORTID_SUBTYPE_IFNAME);
        ck_assert_int_eq(nport->p_id_len, strlen("FastEthernet0/0"));
index e2e5aa42f65d43d509173174384a187fd02f11f1..8fc65333de5932f940249daac5a293b901d77959 100644 (file)
@@ -536,7 +536,7 @@ Extreme Discovery Protocol
                fail("unable to find our previous port?");
                return;
        }
-       ck_assert_int_eq(nport->p_chassis->c_mgmt.s_addr,
+       ck_assert_int_eq(TAILQ_FIRST(&nport->p_chassis->c_mgmt)->m_addr.inet.s_addr,
            (u_int32_t)inet_addr("10.50.0.63"));
        if (TAILQ_EMPTY(&nport->p_vlans)) {
                fail("no VLAN");
index c8693dd975fc7823437acf12e0f7a3b131210f1f..8672e3fb7d9877c80b529d96cdcca5e8127f07f8 100644 (file)
@@ -703,9 +703,9 @@ Link Layer Discovery Protocol
            LLDP_CAP_WLAN | LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
        ck_assert_int_eq(nchassis->c_cap_enabled,
            LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE);
-       ck_assert_int_eq(nchassis->c_mgmt.s_addr,
+       ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr,
            (u_int32_t)inet_addr("10.238.80.75"));
-       ck_assert_int_eq(nchassis->c_mgmt_if, 3);
+       ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 3);
 #ifdef ENABLE_DOT3
        ck_assert_int_eq(nport->p_aggregid, 0);
        ck_assert_int_eq(nport->p_macphy.autoneg_enabled, 1);
index b420e3667c951096fedd1cae4466d3285d8665f3..b7871b4436ea5bc9bea781af63d1997c24c74e7b 100644 (file)
@@ -32,8 +32,12 @@ struct lldpd_chassis chassis1 = {
        .c_cap_available = LLDP_CAP_BRIDGE | LLDP_CAP_WLAN | LLDP_CAP_ROUTER,
        .c_cap_enabled   = LLDP_CAP_ROUTER,
        .c_ttl           = 60,
-       .c_mgmt          = { .s_addr = 251789504 }, /* 192.0.2.15 */
-       .c_mgmt_if       = 3,
+       .c_mgmt4          = {
+               .family = AF_INET,
+               .address = { .inet = { 251789504 } }, /* 192.0.2.15 */
+               .addrsize = sizeof(struct in_addr),
+               .iface = 3
+       },
 #ifdef ENABLE_LLDPMED
        .c_med_cap_available = LLDPMED_CAP_CAP | LLDPMED_CAP_IV | \
                LLDPMED_CAP_LOCATION |  LLDPMED_CAP_POLICY | \
@@ -60,8 +64,12 @@ struct lldpd_chassis chassis2 = {
        .c_cap_available = LLDP_CAP_ROUTER,
        .c_cap_enabled   = LLDP_CAP_ROUTER,
        .c_ttl           = 60,
-       .c_mgmt          = { .s_addr = 285343936 }, /* 192.0.2.17 */
-       .c_mgmt_if       = 5,
+       .c_mgmt4          = {
+               .family = AF_INET,
+               .address = { .inet = { 285343936 } }, /* 192.0.2.17 */
+               .addrsize = sizeof(struct in_addr),
+               .iface = 5
+       },
 #ifdef ENABLE_LLDPMED
        .c_med_hw     = "Hardware 2",
        /* We skip c_med_fw */
index 9f17dd95b668349a9e9cead2e4828bade598a61d..b6175e2c0bce54a0c81d3d495793ce9b70f70d14 100644 (file)
@@ -80,7 +80,13 @@ Nortel Networks / SynOptics Network Management Protocol
        chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
        chassis.c_id = macaddress;
        chassis.c_id_len = ETH_ALEN;
-       chassis.c_mgmt.s_addr = inet_addr("172.17.142.37");
+       TAILQ_INIT(&chassis.c_mgmt);
+       in_addr_t addr = inet_addr("172.17.142.37");
+       struct lldpd_mgmt *mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, 
+                                       &addr, sizeof(in_addr_t), 0);
+       if (mgmt == NULL)
+               ck_abort();
+       TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries);
 
        /* Build packet */
        n = sonmp_send(NULL, &hardware);
@@ -161,9 +167,9 @@ Nortel Networks / SynOptics Network Management Protocol
        fail_unless(memcmp(nchassis->c_id, cid, 5) == 0);
        ck_assert_str_eq(nchassis->c_name, "172.16.101.168");
        ck_assert_str_eq(nchassis->c_descr, "Nortel Ethernet Routing 8610 L3 Switch");
-       ck_assert_int_eq(nchassis->c_mgmt.s_addr,
+       ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr,
            (u_int32_t)inet_addr("172.16.101.168"));
-       ck_assert_int_eq(nchassis->c_mgmt_if, 0);
+       ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0);
        ck_assert_str_eq(nport->p_descr, "port 2/8");
        ck_assert_int_eq(nport->p_id_subtype,
            LLDP_PORTID_SUBTYPE_LOCAL);