chiark / gitweb /
Remove src/libsystemd-network
[elogind.git] / src / libsystemd-network / lldp-internal.c
diff --git a/src/libsystemd-network/lldp-internal.c b/src/libsystemd-network/lldp-internal.c
deleted file mode 100644 (file)
index 0f35446..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2014 Tom Gundersen
-  Copyright (C) 2014 Susant Sahani
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "lldp-internal.h"
-
-/* We store maximum 1K chassis entries */
-#define LLDP_MIB_MAX_CHASSIS 1024
-
-/* Maximum Ports can be attached to any chassis */
-#define LLDP_MIB_MAX_PORT_PER_CHASSIS 32
-
-int lldp_read_chassis_id(tlv_packet *tlv,
-                         uint8_t *type,
-                         uint16_t *length,
-                         uint8_t **data) {
-        uint8_t subtype;
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID);
-        if (r < 0)
-                goto out2;
-
-        r = tlv_packet_read_u8(tlv, &subtype);
-        if (r < 0)
-                goto out1;
-
-        switch (subtype) {
-        case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
-
-                r = tlv_packet_read_bytes(tlv, data, length);
-                if (r < 0)
-                        goto out1;
-
-                break;
-        default:
-                r = -EOPNOTSUPP;
-                break;
-        }
-
-        *type = subtype;
-
- out1:
-        (void) lldp_tlv_packet_exit_container(tlv);
-
- out2:
-        return r;
-}
-
-int lldp_read_port_id(tlv_packet *tlv,
-                      uint8_t *type,
-                      uint16_t *length,
-                      uint8_t **data) {
-        uint8_t subtype;
-        char *s;
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID);
-        if (r < 0)
-                goto out2;
-
-        r = tlv_packet_read_u8(tlv, &subtype);
-        if (r < 0)
-                goto out1;
-
-        switch (subtype) {
-        case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
-        case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
-        case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
-        case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
-
-                r = tlv_packet_read_string(tlv, &s, length);
-                if (r < 0)
-                        goto out1;
-
-                *data = (uint8_t *) s;
-
-                break;
-        case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
-
-                r = tlv_packet_read_bytes(tlv, data, length);
-                if (r < 0)
-                        goto out1;
-
-                break;
-        default:
-                r = -EOPNOTSUPP;
-                break;
-        }
-
-        *type = subtype;
-
- out1:
-        (void) lldp_tlv_packet_exit_container(tlv);
-
- out2:
-        return r;
-}
-
-int lldp_read_ttl(tlv_packet *tlv, uint16_t *ttl) {
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_TTL);
-        if (r < 0)
-                goto out;
-
-        r = tlv_packet_read_u16(tlv, ttl);
-
-        (void) lldp_tlv_packet_exit_container(tlv);
-
- out:
-        return r;
-}
-
-int lldp_read_system_name(tlv_packet *tlv,
-                          uint16_t *length,
-                          char **data) {
-        char *s;
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_NAME);
-        if (r < 0)
-                return r;
-
-        r = tlv_packet_read_string(tlv, &s, length);
-        if (r < 0)
-                goto out;
-
-        *data = (char *) s;
-
- out:
-        (void) lldp_tlv_packet_exit_container(tlv);
-
-        return r;
-}
-
-int lldp_read_system_description(tlv_packet *tlv,
-                                 uint16_t *length,
-                                 char **data) {
-        char *s;
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION);
-        if (r < 0)
-                return r;
-
-        r = tlv_packet_read_string(tlv, &s, length);
-        if (r < 0)
-                goto out;
-
-        *data = (char *) s;
-
- out:
-        (void) lldp_tlv_packet_exit_container(tlv);
-
-        return r;
-}
-
-int lldp_read_port_description(tlv_packet *tlv,
-                               uint16_t *length,
-                               char **data) {
-        char *s;
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_DESCRIPTION);
-        if (r < 0)
-                return r;
-
-        r = tlv_packet_read_string(tlv, &s, length);
-        if (r < 0)
-                goto out;
-
-        *data = (char *) s;
-
- out:
-        (void) lldp_tlv_packet_exit_container(tlv);
-
-        return r;
-}
-
-int lldp_read_system_capability(tlv_packet *tlv, uint16_t *data) {
-        int r;
-
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES);
-        if (r < 0)
-                return r;
-
-        r = tlv_packet_read_u16(tlv, data);
-        if (r < 0)
-                goto out;
-
-        return 0;
- out:
-
-        (void) lldp_tlv_packet_exit_container(tlv);
-
-        return r;
-}
-
-/* 10.5.5.2.2 mibUpdateObjects ()
- * The mibUpdateObjects () procedure updates the MIB objects corresponding to
- * the TLVs contained in the received LLDPDU for the LLDP remote system
- * indicated by the LLDP remote systems update process defined in 10.3.5 */
-
-int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv) {
-        lldp_neighbour_port *p;
-        uint16_t length, ttl;
-        uint8_t *data;
-        uint8_t type;
-        int r;
-
-        assert_return(c, -EINVAL);
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_read_port_id(tlv, &type, &length, &data);
-        if (r < 0)
-                return r;
-
-        /* Update the packet if we already have */
-        LIST_FOREACH(port, p, c->ports) {
-
-                if ((p->type == type && p->length == length && !memcmp(p->data, data, p->length))) {
-
-                        r = lldp_read_ttl(tlv, &ttl);
-                        if (r < 0)
-                                return r;
-
-                        p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
-                        tlv_packet_free(p->packet);
-                        p->packet = tlv;
-
-                        prioq_reshuffle(p->c->by_expiry, p, &p->prioq_idx);
-
-                        return 0;
-                }
-        }
-
-        return -1;
-}
-
-int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv) {
-        lldp_neighbour_port *p, *q;
-        uint8_t *data;
-        uint16_t length;
-        uint8_t type;
-        int r;
-
-        assert_return(c, -EINVAL);
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_read_port_id(tlv, &type, &length, &data);
-        if (r < 0)
-                return r;
-
-        LIST_FOREACH_SAFE(port, p, q, c->ports) {
-
-                /* Find the port */
-                if (p->type == type && p->length == length && !memcmp(p->data, data, p->length)) {
-                        lldp_neighbour_port_remove_and_free(p);
-                        break;
-                }
-        }
-
-        return 0;
-}
-
-int lldp_mib_add_objects(Prioq *by_expiry,
-                         Hashmap *neighbour_mib,
-                         tlv_packet *tlv) {
-        _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
-        _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
-        lldp_chassis_id chassis_id;
-        bool new_chassis = false;
-        uint8_t subtype, *data;
-        uint16_t ttl, length;
-        int r;
-
-        assert_return(by_expiry, -EINVAL);
-        assert_return(neighbour_mib, -EINVAL);
-        assert_return(tlv, -EINVAL);
-
-        r = lldp_read_chassis_id(tlv, &subtype, &length, &data);
-        if (r < 0)
-                goto drop;
-
-        r = lldp_read_ttl(tlv, &ttl);
-        if (r < 0)
-                goto drop;
-
-        /* Make hash key */
-        chassis_id.type = subtype;
-        chassis_id.length = length;
-        chassis_id.data = data;
-
-        /* Try to find the Chassis */
-        c = hashmap_get(neighbour_mib, &chassis_id);
-        if (!c) {
-
-                /* Don't create chassis if ttl 0 is received . Silently drop it */
-                if (ttl == 0) {
-                        log_lldp("TTL value 0 received. Skiping Chassis creation.");
-                        goto drop;
-                }
-
-                /* Admission Control: Can we store this packet ? */
-                if (hashmap_size(neighbour_mib) >= LLDP_MIB_MAX_CHASSIS) {
-
-                        log_lldp("Exceeding number of chassie: %d. Dropping ...",
-                                 hashmap_size(neighbour_mib));
-                        goto drop;
-                }
-
-                r = lldp_chassis_new(tlv, by_expiry, neighbour_mib, &c);
-                if (r < 0)
-                        goto drop;
-
-                new_chassis = true;
-
-                r = hashmap_put(neighbour_mib, &c->chassis_id, c);
-                if (r < 0)
-                        goto drop;
-
-        } else {
-
-                /* When the TTL field is set to zero, the receiving LLDP agent is notified all
-                 * system information associated with the LLDP agent/port is to be deleted */
-                if (ttl == 0) {
-                        log_lldp("TTL value 0 received . Deleting associated Port ...");
-
-                        lldp_mib_remove_objects(c, tlv);
-
-                        c = NULL;
-                        goto drop;
-                }
-
-                /* if we already have this port just update it */
-                r = lldp_mib_update_objects(c, tlv);
-                if (r >= 0) {
-                        c = NULL;
-                        return r;
-                }
-
-                /* Admission Control: Can this port attached to the existing chassis ? */
-                if (REFCNT_GET(c->n_ref) >= LLDP_MIB_MAX_PORT_PER_CHASSIS) {
-                        log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...",
-                                 REFCNT_GET(c->n_ref));
-
-                        c = NULL;
-                        goto drop;
-                }
-        }
-
-        /* This is a new port */
-        r = lldp_neighbour_port_new(c, tlv, &p);
-        if (r < 0)
-                goto drop;
-
-        r = prioq_put(c->by_expiry, p, &p->prioq_idx);
-        if (r < 0)
-                goto drop;
-
-        /* Attach new port to chassis */
-        LIST_PREPEND(port, c->ports, p);
-        REFCNT_INC(c->n_ref);
-
-        p = NULL;
-        c = NULL;
-
-        return 0;
-
- drop:
-        tlv_packet_free(tlv);
-
-        if (new_chassis)
-                hashmap_remove(neighbour_mib, &c->chassis_id);
-
-        return r;
-}
-
-void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p) {
-        lldp_chassis *c;
-
-        assert(p);
-        assert(p->c);
-
-        c = p->c;
-
-        prioq_remove(c->by_expiry, p, &p->prioq_idx);
-
-        LIST_REMOVE(port, c->ports, p);
-        lldp_neighbour_port_free(p);
-
-        /* Drop the Chassis if no port is attached  */
-        if (REFCNT_DEC(c->n_ref) <= 1) {
-                hashmap_remove(c->neighbour_mib, &c->chassis_id);
-                lldp_chassis_free(c);
-        }
-}
-
-void lldp_neighbour_port_free(lldp_neighbour_port *p) {
-
-        if(!p)
-                return;
-
-        tlv_packet_free(p->packet);
-
-        free(p->data);
-        free(p);
-}
-
-int lldp_neighbour_port_new(lldp_chassis *c,
-                            tlv_packet *tlv,
-                            lldp_neighbour_port **ret) {
-        _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
-        uint16_t length, ttl;
-        uint8_t *data;
-        uint8_t type;
-        int r;
-
-        assert(tlv);
-
-        r = lldp_read_port_id(tlv, &type, &length, &data);
-        if (r < 0)
-                return r;
-
-        r = lldp_read_ttl(tlv, &ttl);
-        if (r < 0)
-                return r;
-
-        p = new0(lldp_neighbour_port, 1);
-        if (!p)
-                return -ENOMEM;
-
-        p->c = c;
-        p->type = type;
-        p->length = length;
-        p->packet = tlv;
-        p->prioq_idx = PRIOQ_IDX_NULL;
-        p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
-        p->data = memdup(data, length);
-        if (!p->data)
-                return -ENOMEM;
-
-        *ret = p;
-        p = NULL;
-
-        return 0;
-}
-
-void lldp_chassis_free(lldp_chassis *c) {
-
-        if (!c)
-                return;
-
-        if (REFCNT_GET(c->n_ref) > 1)
-                return;
-
-        free(c->chassis_id.data);
-        free(c);
-}
-
-int lldp_chassis_new(tlv_packet *tlv,
-                     Prioq *by_expiry,
-                     Hashmap *neighbour_mib,
-                     lldp_chassis **ret) {
-        _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
-        uint16_t length;
-        uint8_t *data;
-        uint8_t type;
-        int r;
-
-        assert(tlv);
-
-        r = lldp_read_chassis_id(tlv, &type, &length, &data);
-        if (r < 0)
-                return r;
-
-        c = new0(lldp_chassis, 1);
-        if (!c)
-                return -ENOMEM;
-
-        c->n_ref = REFCNT_INIT;
-        c->chassis_id.type = type;
-        c->chassis_id.length = length;
-
-        c->chassis_id.data = memdup(data, length);
-        if (!c->chassis_id.data)
-                return -ENOMEM;
-
-        LIST_HEAD_INIT(c->ports);
-
-        c->by_expiry = by_expiry;
-        c->neighbour_mib = neighbour_mib;
-
-        *ret = c;
-        c = NULL;
-
-        return 0;
-}