diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:02:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:02:34 +0000 |
commit | fadeddfbb2aa38a980dd959b5ec1ffba7afd43cb (patch) | |
tree | a7bde6111c84ea64619656a38fba50909fa0bf60 /src/lib/atoms/port.c | |
parent | Initial commit. (diff) | |
download | lldpd-fadeddfbb2aa38a980dd959b5ec1ffba7afd43cb.tar.xz lldpd-fadeddfbb2aa38a980dd959b5ec1ffba7afd43cb.zip |
Adding upstream version 1.0.18.upstream/1.0.18upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/atoms/port.c')
-rw-r--r-- | src/lib/atoms/port.c | 862 |
1 files changed, 862 insertions, 0 deletions
diff --git a/src/lib/atoms/port.c b/src/lib/atoms/port.c new file mode 100644 index 0000000..f99e18b --- /dev/null +++ b/src/lib/atoms/port.c @@ -0,0 +1,862 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <vincent@bernat.im> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <arpa/inet.h> + +#include "../lldpctl.h" +#include "../../log.h" +#include "../atom.h" +#include "../helpers.h" + +static struct atom_map lldpd_protocol_map = { .key = lldpctl_k_port_protocol, + .map = { + { LLDPD_MODE_LLDP, "LLDP" }, + { LLDPD_MODE_CDPV1, "CDPv1" }, + { LLDPD_MODE_CDPV2, "CDPv2" }, + { LLDPD_MODE_EDP, "EDP" }, + { LLDPD_MODE_FDP, "FDP" }, + { LLDPD_MODE_SONMP, "SONMP" }, + { 0, NULL }, + } }; + +ATOM_MAP_REGISTER(lldpd_protocol_map, 3); + +static lldpctl_map_t port_id_subtype_map[] = { + { LLDP_PORTID_SUBTYPE_IFNAME, "ifname" }, + { LLDP_PORTID_SUBTYPE_IFALIAS, "ifalias" }, + { LLDP_PORTID_SUBTYPE_LOCAL, "local" }, + { LLDP_PORTID_SUBTYPE_LLADDR, "mac" }, + { LLDP_PORTID_SUBTYPE_ADDR, "ip" }, + { LLDP_PORTID_SUBTYPE_PORT, "unhandled" }, + { LLDP_PORTID_SUBTYPE_AGENTCID, "unhandled" }, + { 0, NULL }, +}; + +static struct atom_map port_status_map = { .key = lldpctl_k_port_status, + .map = { + { LLDPD_RXTX_TXONLY, "TX only" }, + { LLDPD_RXTX_RXONLY, "RX only" }, + { LLDPD_RXTX_DISABLED, "disabled" }, + { LLDPD_RXTX_BOTH, "RX and TX" }, + { 0, NULL }, + } }; + +ATOM_MAP_REGISTER(port_status_map, 3); + +#ifdef ENABLE_DOT3 +static lldpctl_map_t operational_mau_type_values[] = { + { LLDP_DOT3_MAU_AUI, "AUI - No internal MAU, view from AUI" }, + { LLDP_DOT3_MAU_10BASE5, "10Base5 - Thick coax MAU" }, + { LLDP_DOT3_MAU_FOIRL, "Foirl - FOIRL MAU" }, + { LLDP_DOT3_MAU_10BASE2, "10Base2 - Thin coax MAU" }, + { LLDP_DOT3_MAU_10BASET, "10BaseT - UTP MAU" }, + { LLDP_DOT3_MAU_10BASEFP, "10BaseFP - Passive fiber MAU" }, + { LLDP_DOT3_MAU_10BASEFB, "10BaseFB - Sync fiber MAU" }, + { LLDP_DOT3_MAU_10BASEFL, "10BaseFL - Async fiber MAU" }, + { LLDP_DOT3_MAU_10BROAD36, "10Broad36 - Broadband DTE MAU" }, + { LLDP_DOT3_MAU_10BASETHD, "10BaseTHD - UTP MAU, half duplex mode" }, + { LLDP_DOT3_MAU_10BASETFD, "10BaseTFD - UTP MAU, full duplex mode" }, + { LLDP_DOT3_MAU_10BASEFLHD, "10BaseFLHD - Async fiber MAU, half duplex mode" }, + { LLDP_DOT3_MAU_10BASEFLFD, "10BaseFLDF - Async fiber MAU, full duplex mode" }, + { LLDP_DOT3_MAU_100BASET4, "100BaseT4 - 4 pair category 3 UTP" }, + { LLDP_DOT3_MAU_100BASETXHD, + "100BaseTXHD - 2 pair category 5 UTP, half duplex mode" }, + { LLDP_DOT3_MAU_100BASETXFD, + "100BaseTXFD - 2 pair category 5 UTP, full duplex mode" }, + { LLDP_DOT3_MAU_100BASEFXHD, + "100BaseFXHD - X fiber over PMT, half duplex mode" }, + { LLDP_DOT3_MAU_100BASEFXFD, + "100BaseFXFD - X fiber over PMT, full duplex mode" }, + { LLDP_DOT3_MAU_100BASET2HD, + "100BaseT2HD - 2 pair category 3 UTP, half duplex mode" }, + { LLDP_DOT3_MAU_100BASET2FD, + "100BaseT2FD - 2 pair category 3 UTP, full duplex mode" }, + { LLDP_DOT3_MAU_1000BASEXHD, + "1000BaseXHD - PCS/PMA, unknown PMD, half duplex mode" }, + { LLDP_DOT3_MAU_1000BASEXFD, + "1000BaseXFD - PCS/PMA, unknown PMD, full duplex mode" }, + { LLDP_DOT3_MAU_1000BASELXHD, + "1000BaseLXHD - Fiber over long-wavelength laser, half duplex mode" }, + { LLDP_DOT3_MAU_1000BASELXFD, + "1000BaseLXFD - Fiber over long-wavelength laser, full duplex mode" }, + { LLDP_DOT3_MAU_1000BASESXHD, + "1000BaseSXHD - Fiber over short-wavelength laser, half duplex mode" }, + { LLDP_DOT3_MAU_1000BASESXFD, + "1000BaseSXFD - Fiber over short-wavelength laser, full duplex mode" }, + { LLDP_DOT3_MAU_1000BASECXHD, + "1000BaseCXHD - Copper over 150-Ohm balanced cable, half duplex mode" }, + { LLDP_DOT3_MAU_1000BASECXFD, + "1000BaseCXFD - Copper over 150-Ohm balanced cable, full duplex mode" }, + { LLDP_DOT3_MAU_1000BASETHD, + "1000BaseTHD - Four-pair Category 5 UTP, half duplex mode" }, + { LLDP_DOT3_MAU_1000BASETFD, + "1000BaseTFD - Four-pair Category 5 UTP, full duplex mode" }, + { LLDP_DOT3_MAU_10GIGBASEX, "10GigBaseX - X PCS/PMA, unknown PMD." }, + { LLDP_DOT3_MAU_10GIGBASELX4, "10GigBaseLX4 - X fiber over WWDM optics" }, + { LLDP_DOT3_MAU_10GIGBASER, "10GigBaseR - R PCS/PMA, unknown PMD." }, + { LLDP_DOT3_MAU_10GIGBASEER, "10GigBaseER - R fiber over 1550 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASELR, "10GigBaseLR - R fiber over 1310 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASESR, "10GigBaseSR - R fiber over 850 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASEW, "10GigBaseW - W PCS/PMA, unknown PMD." }, + { LLDP_DOT3_MAU_10GIGBASEEW, "10GigBaseEW - W fiber over 1550 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASELW, "10GigBaseLW - W fiber over 1310 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASESW, "10GigBaseSW - W fiber over 850 nm optics" }, + { LLDP_DOT3_MAU_10GIGBASECX4, + "10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable" }, + { LLDP_DOT3_MAU_2BASETL, + "2BaseTL - Voice grade UTP copper, up to 2700m, optional PAF" }, + { LLDP_DOT3_MAU_10PASSTS, + "10PassTS - Voice grade UTP copper, up to 750m, optional PAF" }, + { LLDP_DOT3_MAU_100BASEBX10D, + "100BaseBX10D - One single-mode fiber OLT, long wavelength, 10km" }, + { LLDP_DOT3_MAU_100BASEBX10U, + "100BaseBX10U - One single-mode fiber ONU, long wavelength, 10km" }, + { LLDP_DOT3_MAU_100BASELX10, + "100BaseLX10 - Two single-mode fibers, long wavelength, 10km" }, + { LLDP_DOT3_MAU_1000BASEBX10D, + "1000BaseBX10D - One single-mode fiber OLT, long wavelength, 10km" }, + { LLDP_DOT3_MAU_1000BASEBX10U, + "1000BaseBX10U - One single-mode fiber ONU, long wavelength, 10km" }, + { LLDP_DOT3_MAU_1000BASELX10, + "1000BaseLX10 - Two sigle-mode fiber, long wavelength, 10km" }, + { LLDP_DOT3_MAU_1000BASEPX10D, + "1000BasePX10D - One single-mode fiber EPON OLT, 10km" }, + { LLDP_DOT3_MAU_1000BASEPX10U, + "1000BasePX10U - One single-mode fiber EPON ONU, 10km" }, + { LLDP_DOT3_MAU_1000BASEPX20D, + "1000BasePX20D - One single-mode fiber EPON OLT, 20km" }, + { LLDP_DOT3_MAU_1000BASEPX20U, + "1000BasePX20U - One single-mode fiber EPON ONU, 20km" }, + { LLDP_DOT3_MAU_10GBASET, + "10GbaseT - Four-pair Category 6A or better, full duplex mode only" }, + { LLDP_DOT3_MAU_10GBASELRM, + "10GbaseLRM - R multimode fiber over 1310 nm optics" }, + { LLDP_DOT3_MAU_1000BASEKX, "1000baseKX - X backplane, full duplex mode only" }, + { LLDP_DOT3_MAU_10GBASEKX4, + "10GbaseKX4 - 4 lane X backplane, full duplex mode only" }, + { LLDP_DOT3_MAU_10GBASEKR, "10GbaseKR - R backplane, full duplex mode only" }, + { LLDP_DOT3_MAU_10G1GBASEPRXD1, + "10G1GbasePRXD1 - One single-mode fiber asymmetric-rate EPON OLT, low power budget (PRX10)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXD2, + "10G1GbasePRXD2 - One single-mode fiber asymmetric-rate EPON OLT, medium power budget (PRX20)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXD3, + "10G1GbasePRXD3 - One single-mode fiber asymmetric-rate EPON OLT, high power budget (PRX30)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXU1, + "10G1GbasePRXU1 - One single-mode fiber asymmetric-rate EPON ONU, low power budget (PRX10)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXU2, + "10G1GbasePRXU2 - One single-mode fiber asymmetric-rate EPON ONU, medium power budget (PRX20)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXU3, + "10G1GbasePRXU3 - One single-mode fiber asymmetric-rate EPON ONU, high power budget (PRX30)" }, + { LLDP_DOT3_MAU_10GBASEPRD1, + "10GbasePRD1 - One single-mode fiber symmetric-rate EPON OLT, low power budget (PR10)" }, + { LLDP_DOT3_MAU_10GBASEPRD2, + "10GbasePRD2 - One single-mode fiber symmetric-rate EPON OLT, medium power budget (PR20)" }, + { LLDP_DOT3_MAU_10GBASEPRD3, + "10GbasePRD3 - One single-mode fiber symmetric-rate EPON OLT, high power budget (PR30)" }, + { LLDP_DOT3_MAU_10GBASEPRU1, + "10GbasePRU1 - One single-mode fiber symmetric-rate EPON ONU, low and medium power budget" }, + { LLDP_DOT3_MAU_10GBASEPRU3, + "10GbasePRU3 - One single-mode fiber symmetric-rate EPON ONU, high power budget (PR30)" }, + { LLDP_DOT3_MAU_40GBASEKR4, + "40GbaseKR4 - 40GBASE-R PCS/PMA over an electrical backplane" }, + { LLDP_DOT3_MAU_40GBASECR4, + "40GbaseCR4 - 40GBASE-R PCS/PMA over 4 lane shielded copper balanced cable" }, + { LLDP_DOT3_MAU_40GBASESR4, + "40GbaseSR4 - 40GBASE-R PCS/PMA over 4 lane multimode fiber" }, + { LLDP_DOT3_MAU_40GBASEFR, + "40GbaseFR - 40GBASE-R PCS/PMA over single mode fiber" }, + { LLDP_DOT3_MAU_40GBASELR4, + "40GbaseLR4 - 40GBASE-R PCS/PMA over 4 WDM lane single mode fiber" }, + { LLDP_DOT3_MAU_100GBASECR10, + "100GbaseCR10 - 100GBASE-R PCS/PMA over 10 lane shielded copper balanced cable" }, + { LLDP_DOT3_MAU_100GBASESR10, + "100GbaseSR10 - 100GBASE-R PCS/PMA over 10 lane multimode fiber" }, + { LLDP_DOT3_MAU_100GBASELR4, + "100GbaseLR4 - 100GBASE-R PCS/PMA over 4 WDM lane single mode fiber, long reach" }, + { LLDP_DOT3_MAU_100GBASEER4, + "100GbaseER4 - 100GBASE-R PCS/PMA over 4 WDM lane single mode fiber PMD, extended reach" }, + { LLDP_DOT3_MAU_1000BASET1, + "1000baseT1 - 1000BASE-T1 single balanced twisted-pair copper cabling PHY" }, + { LLDP_DOT3_MAU_1000BASEPX30D, + "1000basePX30D - One single-mode fiber EPON OLT, 20km, 1:32 split ratio" }, + { LLDP_DOT3_MAU_1000BASEPX30U, + "1000basePX30U - One single-mode fiber EPON ONU, 20km, 1:32 split ratio" }, + { LLDP_DOT3_MAU_1000BASEPX40D, + "1000basePX40D - One single-mode fiber EPON OLT, 20km, 1:64 split ratio" }, + { LLDP_DOT3_MAU_1000BASEPX40U, + "1000basePX40U - One single-mode fiber EPON ONU, 20km, 1:64 split ratio" }, + { LLDP_DOT3_MAU_10G1GBASEPRXD4, + "10G1GbasePRXD4 - One single-mode fiber asymmetric-rate EPON OLT, supporting extended power budget (PRX40)" }, + { LLDP_DOT3_MAU_10G1GBASEPRXU4, + "10G1GbasePRXU4 - One single-mode fiber asymmetric-rate EPON ONU, supporting extended power budget (PRX40)" }, + { LLDP_DOT3_MAU_10GBASEPRD4, + "10GbasePRD4 - One single-mode fiber symmetric-rate EPON OLT, supporting extended power budget (PR40)" }, + { LLDP_DOT3_MAU_10GBASEPRU4, + "10GbasePRU4 - One single-mode fiber symmetric-rate EPON ONU, supporting extended power budget (PR40)" }, + { LLDP_DOT3_MAU_25GBASECR, + "25GbaseCR - 25GBASE-R PCS/PMA over shielded balanced copper cable" }, + { LLDP_DOT3_MAU_25GBASECRS, + "25GbaseCRS - 25GBASE-R PCS/PMA over shielded balanced copper cable without RS-FEC" }, + { LLDP_DOT3_MAU_25GBASEKR, + "25GbaseKR - 25GBASE-R PCS/PMA over an electrical backplane" }, + { LLDP_DOT3_MAU_25GBASEKRS, + "25GbaseKRS - 25GBASE-R PCS/PMA over an electrical backplane without RS-FEC" }, + { LLDP_DOT3_MAU_25GBASER, "25GbaseR - 25GBASE-R PCS/PMA over undefined PMD" }, + { LLDP_DOT3_MAU_25GBASESR, + "25GbaseSR - 25GBASE-R PCS/PMA over multimode fiber" }, + { LLDP_DOT3_MAU_25GBASET, + "25GbaseT - Four-pair twisted-pair balanced copper cabling" }, + { LLDP_DOT3_MAU_40GBASEER4, + "40GbaseER4 - 40GBASE-R PCS/PMA over 4 WDM lane single mode fiber" }, + { LLDP_DOT3_MAU_40GBASER, + "40GbaseR - 40GBASE-R PCS as over undefined PMA/PMD" }, + { LLDP_DOT3_MAU_40GBASET, + "40GbaseT - Four-pair twisted-pair balanced copper cabling" }, + { LLDP_DOT3_MAU_100GBASECR4, + "100GbaseCR4 - 100GBASE-R PCS/PMA over 4 lane shielded copper balanced cable" }, + { LLDP_DOT3_MAU_100GBASEKR4, + "100GbaseKR4 - 100GBASE-R PCS/PMA over an electrical backplane" }, + { LLDP_DOT3_MAU_100GBASEKP4, + "100GbaseKP4 - 100GBASE-P PCS/PMA over an electrical backplane PMD" }, + { LLDP_DOT3_MAU_100GBASER, + "100GbaseR - 100GBASE-R Multi-lane PCS over undefined PMA/PMD" }, + { LLDP_DOT3_MAU_100GBASESR4, + "100GbaseSR4 - 100GBASE-R PCS/PMA over 4 lane multimode fiber" }, + { LLDP_DOT3_MAU_2P5GIGT, + "2p5GigT - 2.5GBASE-T Four-pair twisted-pair balanced copper cabling PHY" }, + { LLDP_DOT3_MAU_5GIGT, + "5GigT - 5GBASE-T Four-pair twisted-pair balanced copper cabling PHY" }, + { LLDP_DOT3_MAU_100BASET1, + "100baseT1 - 100BASE-T1 Single balanced twisted-pair copper cabling PHY" }, + { LLDP_DOT3_MAU_1000BASERHA, + "1000baseRHA - 1000BASE-RHA Plastic optical fiber PHY" }, + { LLDP_DOT3_MAU_1000BASERHB, + "1000baseRHB - 1000BASE-RHB Plastic optical fiber PHY" }, + { LLDP_DOT3_MAU_1000BASERHC, + "1000baseRHC - 1000BASE-RHC Plastic optical fiber PHY" }, + { LLDP_DOT3_MAU_2P5GBASEKX, + "2p5GbaseKX - 2.5GBASE-X PMD over an electrical backplane" }, + { LLDP_DOT3_MAU_2P5GBASEX, + "2p5GbaseX - 2.5GBASE-X PCS/PMA over undefined PMD" }, + { LLDP_DOT3_MAU_5GBASEKR, + "5GbaseKR - 5GBASE-KR PMD over an electrical backplane" }, + { LLDP_DOT3_MAU_5GBASER, "5GbaseR - 5GBASE-R PCS/PMA over undefined PMD" }, + { LLDP_DOT3_MAU_10GPASSXR, + "10GpassXR - Coax cable distribution network PHY continuous downstream/burst mode upstream PHY" }, + { LLDP_DOT3_MAU_25GBASELR, + "25GbaseLR - 25GBASE-R PCS/PMA over single-mode fiber PMD, with long reach" }, + { LLDP_DOT3_MAU_25GBASEER, + "25GbaseER - 25GBASE-R PCS/PMA over single-mode fiber PMD, with extended reach" }, + { LLDP_DOT3_MAU_50GBASER, + "50GbaseR - 50GBASE-R Multi-lane PCS over undefined PMA/PMD" }, + { LLDP_DOT3_MAU_50GBASECR, + "50GbaseCR - 50GBASE-R PCS/PMA over shielded copper balanced cable PMD" }, + { LLDP_DOT3_MAU_50GBASEKR, + "50GbaseKR - 50GBASE-R PCS/PMA over an electrical backplane PMD" }, + { LLDP_DOT3_MAU_50GBASESR, + "50GbaseSR - 50GBASE-R PCS/PMA over multimode fiber PMD" }, + { LLDP_DOT3_MAU_50GBASEFR, + "50GbaseFR - 50GBASE-R PCS/PMA over single mode fiber PMD with reach up to at least 2 km" }, + { LLDP_DOT3_MAU_50GBASELR, + "50GbaseLR - 50GBASE-R PCS/PMA over single mode fiber PMD with reach up to at least 10 km" }, + { LLDP_DOT3_MAU_50GBASEER, + "50GbaseER - 50GBASE-R PCS/PMA over single-mode fiber PMD with reach up to at least 40 km" }, + { LLDP_DOT3_MAU_100GBASECR2, + "100GbaseCR2 - 100GBASE-R PCS/PMA over 2 lane shielded copper balanced cable PMD" }, + { LLDP_DOT3_MAU_100GBASEKR2, + "100GbaseKR2 - 100GBASE-R PCS/PMA over an electrical backplane PMD" }, + { LLDP_DOT3_MAU_100GBASESR2, + "100GbaseSR2 - 100GBASE-R PCS/PMA over 2 lane multimode fiber PMD" }, + { LLDP_DOT3_MAU_100GBASEDR, + "100GbaseDR - 100GBASE-R PCS/PMA over single mode fiber PMD" }, + { LLDP_DOT3_MAU_200GBASER, + "200GbaseR - 200GBASE-R Multi-lane PCS over undefined PMA/PMD" }, + { LLDP_DOT3_MAU_200GBASEDR4, + "200GbaseDR4 - 200GBASE-R PCS/PMA over 4-lane single-mode fiber PMD" }, + { LLDP_DOT3_MAU_200GBASEFR4, + "200GbaseFR4 - 200GBASE-R PCS/PMA over 4 WDM lane single-mode fiber PMD with reach up to at least 2 km" }, + { LLDP_DOT3_MAU_200GBASELR4, + "200GbaseLR4 - 200GBASE-R PCS/PMA over 4 WDM lane single-mode fiber PMD with reach up to at least 10 km" }, + { LLDP_DOT3_MAU_200GBASECR4, + "200GbaseCR4 - 200GBASE-R PCS/PMA over 4 lane shielded copper balanced cable PMD" }, + { LLDP_DOT3_MAU_200GBASEKR4, + "200GbaseKR4 - 200GBASE-R PCS/PMA over an electrical backplane PMD" }, + { LLDP_DOT3_MAU_200GBASESR4, + "200GbaseSR4 - 200GBASE-R PCS/PMA over 4 lane multimode fiber PMD" }, + { LLDP_DOT3_MAU_200GBASEER4, + "200GbaseER4 - 200GBASE-R PCS/PMA over 4 WDM lane single-mode fiber PMD with reach up to at least 40 km" }, + { LLDP_DOT3_MAU_400GBASER, + "400GbaseR - 400GBASE-R Multi-lane PCS over undefined PMA/PMD" }, + { LLDP_DOT3_MAU_400GBASESR16, + "400GbaseSR16 - 400GBASE-R PCS/PMA over 16-lane multimode fiber PMD" }, + { LLDP_DOT3_MAU_400GBASEDR4, + "400GbaseDR4 - 400GBASE-R PCS/PMA over 4-lane single-mode fiber PMD" }, + { LLDP_DOT3_MAU_400GBASEFR8, + "400GbaseFR8 - 400GBASE-R PCS/PMA over 8 WDM lane single-mode fiber PMD with reach up to at least 2 km" }, + { LLDP_DOT3_MAU_400GBASELR8, + "400GbaseLR8 - 400GBASE-R PCS/PMA over 8 WDM lane single-mode fiber PMD with reach up to at least 10 km" }, + { LLDP_DOT3_MAU_400GBASEER8, + "400GbaseER8 - 400GBASE-R PCS/PMA over 8 WDM lane single-mode fiber PMD with reach up to at least 40 km" }, + { LLDP_DOT3_MAU_10BASET1L, "10baseT1L - 10BASE-T1L Single balanced pair PHY" }, + { LLDP_DOT3_MAU_10BASET1SHD, + "10baseT1SHD - 10BASE-T1S Single balanced pair PHY, half duplex mode" }, + { LLDP_DOT3_MAU_10BASET1SMD, + "10baseT1SMD - 10BASE-T1S Single balanced pair PHY, multidrop mode" }, + { LLDP_DOT3_MAU_10BASET1SFD, + "10baseT1SFD - 10BASE-T1S Single balanced pair PHY, full duplex mode" }, + { 0, NULL } +}; +#endif + +static lldpctl_atom_iter_t * +_lldpctl_atom_iter_ports_list(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_any_list_t *plist = + (struct _lldpctl_atom_any_list_t *)atom; + return (lldpctl_atom_iter_t *)TAILQ_FIRST(&plist->parent->hardware->h_rports); +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_next_ports_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct lldpd_port *port = (struct lldpd_port *)iter; + return (lldpctl_atom_iter_t *)TAILQ_NEXT(port, p_entries); +} + +static lldpctl_atom_t * +_lldpctl_atom_value_ports_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct lldpd_port *port = (struct lldpd_port *)iter; + return _lldpctl_new_atom(atom->conn, atom_port, 0, NULL, port, + ((struct _lldpctl_atom_any_list_t *)atom)->parent); +} + +static int +_lldpctl_atom_new_port(lldpctl_atom_t *atom, va_list ap) +{ + struct _lldpctl_atom_port_t *port = (struct _lldpctl_atom_port_t *)atom; + port->local = va_arg(ap, int); + port->hardware = va_arg(ap, struct lldpd_hardware *); + port->port = va_arg(ap, struct lldpd_port *); + port->parent = va_arg(ap, struct _lldpctl_atom_port_t *); + if (port->parent) lldpctl_atom_inc_ref((lldpctl_atom_t *)port->parent); + + if (port->port) { + /* Internal atom. We are the parent, but our reference count is + * not incremented. */ + port->chassis = _lldpctl_new_atom(atom->conn, atom_chassis, + port->port->p_chassis, port, 1); + } + return 1; +} + +TAILQ_HEAD(chassis_list, lldpd_chassis); + +static void +add_chassis(struct chassis_list *chassis_list, struct lldpd_chassis *chassis) +{ + struct lldpd_chassis *one_chassis; + TAILQ_FOREACH (one_chassis, chassis_list, c_entries) { + if (one_chassis == chassis) return; + } + TAILQ_INSERT_TAIL(chassis_list, chassis, c_entries); +} + +static void +_lldpctl_atom_free_port(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_port_t *port = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_hardware *hardware = port->hardware; + struct lldpd_chassis *one_chassis, *one_chassis_next; + struct lldpd_port *one_port; + + /* Free internal chassis atom. Should be freed immediately since we + * should have the only reference. */ + lldpctl_atom_dec_ref((lldpctl_atom_t *)port->chassis); + + /* We need to free the whole struct lldpd_hardware: local port, local + * chassis and remote ports... The same chassis may be present several + * times. We build a list of chassis (we don't use reference count). */ + struct chassis_list chassis_list; + TAILQ_INIT(&chassis_list); + + if (port->parent) + lldpctl_atom_dec_ref((lldpctl_atom_t *)port->parent); + else if (!hardware && port->port) { + /* No parent, no hardware, we assume a single neighbor: one + * port, one chassis. */ + if (port->port->p_chassis) { + lldpd_chassis_cleanup(port->port->p_chassis, 1); + port->port->p_chassis = NULL; + } + lldpd_port_cleanup(port->port, 1); + free(port->port); + } + if (!hardware) return; + + add_chassis(&chassis_list, port->port->p_chassis); + TAILQ_FOREACH (one_port, &hardware->h_rports, p_entries) + add_chassis(&chassis_list, one_port->p_chassis); + + /* Free hardware port */ + lldpd_remote_cleanup(hardware, NULL, 1); + lldpd_port_cleanup(port->port, 1); + free(port->hardware); + + /* Free list of chassis */ + for (one_chassis = TAILQ_FIRST(&chassis_list); one_chassis != NULL; + one_chassis = one_chassis_next) { + one_chassis_next = TAILQ_NEXT(one_chassis, c_entries); + lldpd_chassis_cleanup(one_chassis, 1); + } +} + +static lldpctl_atom_t * +_lldpctl_atom_get_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + struct lldpd_hardware *hardware = p->hardware; + + /* Local port only */ + if (hardware != NULL) { + switch (key) { + case lldpctl_k_port_neighbors: + return _lldpctl_new_atom(atom->conn, atom_ports_list, p); + default: + break; + } + } + + /* Local and remote port */ + switch (key) { + case lldpctl_k_port_chassis: + if (port->p_chassis) { + return _lldpctl_new_atom(atom->conn, atom_chassis, + port->p_chassis, p, 0); + } + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; +#ifdef ENABLE_DOT3 + case lldpctl_k_port_dot3_power: + return _lldpctl_new_atom(atom->conn, atom_dot3_power, p); +#endif +#ifdef ENABLE_DOT1 + case lldpctl_k_port_vlans: + return _lldpctl_new_atom(atom->conn, atom_vlans_list, p); + case lldpctl_k_port_ppvids: + return _lldpctl_new_atom(atom->conn, atom_ppvids_list, p); + case lldpctl_k_port_pis: + return _lldpctl_new_atom(atom->conn, atom_pis_list, p); +#endif +#ifdef ENABLE_LLDPMED + case lldpctl_k_port_med_policies: + return _lldpctl_new_atom(atom->conn, atom_med_policies_list, p); + case lldpctl_k_port_med_locations: + return _lldpctl_new_atom(atom->conn, atom_med_locations_list, p); + case lldpctl_k_port_med_power: + return _lldpctl_new_atom(atom->conn, atom_med_power, p); +#endif +#ifdef ENABLE_CUSTOM + case lldpctl_k_custom_tlvs: + return _lldpctl_new_atom(atom->conn, atom_custom_list, p); +#endif + default: + /* Compatibility: query the associated chassis too */ + if (port->p_chassis) return lldpctl_atom_get(p->chassis, key); + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } +} + +static lldpctl_atom_t * +_lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, + lldpctl_atom_t *value) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_hardware *hardware = p->hardware; + struct lldpd_port_set set = {}; + int rc; + char *canary = NULL; + +#ifdef ENABLE_DOT3 + struct _lldpctl_atom_dot3_power_t *dpow; +#endif +#ifdef ENABLE_LLDPMED + struct _lldpctl_atom_med_power_t *mpow; + struct _lldpctl_atom_med_policy_t *mpol; + struct _lldpctl_atom_med_location_t *mloc; +#endif +#ifdef ENABLE_CUSTOM + struct _lldpctl_atom_custom_t *custom; +#endif + + /* Local and default port only */ + if (!p->local) { + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + + set.vlan_tx_enabled = -1; + + switch (key) { + case lldpctl_k_port_id: + set.local_id = p->port->p_id; + break; + case lldpctl_k_port_descr: + set.local_descr = p->port->p_descr; + break; + case lldpctl_k_port_status: + set.rxtx = LLDPD_RXTX_FROM_PORT(p->port); + break; + case lldpctl_k_port_vlan_tx: + set.vlan_tx_tag = p->port->p_vlan_tx_tag; + set.vlan_tx_enabled = p->port->p_vlan_tx_enabled; + break; +#ifdef ENABLE_DOT3 + case lldpctl_k_port_dot3_power: + if (value->type != atom_dot3_power) { + SET_ERROR(atom->conn, LLDPCTL_ERR_INCORRECT_ATOM_TYPE); + return NULL; + } + + dpow = (struct _lldpctl_atom_dot3_power_t *)value; + set.dot3_power = &dpow->parent->port->p_power; + break; +#endif +#ifdef ENABLE_LLDPMED + case lldpctl_k_port_med_power: + if (value->type != atom_med_power) { + SET_ERROR(atom->conn, LLDPCTL_ERR_INCORRECT_ATOM_TYPE); + return NULL; + } + + mpow = (struct _lldpctl_atom_med_power_t *)value; + set.med_power = &mpow->parent->port->p_med_power; + break; + case lldpctl_k_port_med_policies: + if (value->type != atom_med_policy) { + SET_ERROR(atom->conn, LLDPCTL_ERR_INCORRECT_ATOM_TYPE); + return NULL; + } + mpol = (struct _lldpctl_atom_med_policy_t *)value; + set.med_policy = mpol->policy; + break; + case lldpctl_k_port_med_locations: + if (value->type != atom_med_location) { + SET_ERROR(atom->conn, LLDPCTL_ERR_INCORRECT_ATOM_TYPE); + return NULL; + } + mloc = (struct _lldpctl_atom_med_location_t *)value; + set.med_location = mloc->location; + break; +#endif +#ifdef ENABLE_CUSTOM + case lldpctl_k_custom_tlvs_clear: + set.custom_list_clear = 1; + break; + case lldpctl_k_custom_tlv: + if (value->type != atom_custom) { + SET_ERROR(atom->conn, LLDPCTL_ERR_INCORRECT_ATOM_TYPE); + return NULL; + } + custom = (struct _lldpctl_atom_custom_t *)value; + set.custom = custom->tlv; + set.custom_tlv_op = custom->op; + break; +#endif + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + + char empty_str[] = ""; + set.ifname = hardware ? hardware->h_ifname : empty_str; + + if (asprintf(&canary, "%d%p%s", key, value, set.ifname) == -1) { + SET_ERROR(atom->conn, LLDPCTL_ERR_NOMEM); + return NULL; + } + rc = _lldpctl_do_something(atom->conn, CONN_STATE_SET_PORT_SEND, + CONN_STATE_SET_PORT_RECV, canary, SET_PORT, &set, + &MARSHAL_INFO(lldpd_port_set), NULL, NULL); + free(canary); + if (rc == 0) return atom; + return NULL; +} + +static const char * +_lldpctl_atom_get_str_port(lldpctl_atom_t *atom, lldpctl_key_t key) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + struct lldpd_hardware *hardware = p->hardware; + char *ipaddress = NULL; + size_t len; + + /* Local port only */ + switch (key) { + case lldpctl_k_port_name: + if (hardware != NULL) return hardware->h_ifname; + break; + case lldpctl_k_port_status: + if (p->local) + return map_lookup(port_status_map.map, + LLDPD_RXTX_FROM_PORT(port)); + break; + default: + break; + } + + if (!port) return NULL; + + /* Local and remote port */ + switch (key) { + case lldpctl_k_port_protocol: + return map_lookup(lldpd_protocol_map.map, port->p_protocol); + case lldpctl_k_port_id_subtype: + return map_lookup(port_id_subtype_map, port->p_id_subtype); + case lldpctl_k_port_id: + switch (port->p_id_subtype) { + case LLDP_PORTID_SUBTYPE_IFNAME: + case LLDP_PORTID_SUBTYPE_IFALIAS: + case LLDP_PORTID_SUBTYPE_LOCAL: + return port->p_id; + case LLDP_PORTID_SUBTYPE_LLADDR: + return _lldpctl_dump_in_atom(atom, (uint8_t *)port->p_id, + port->p_id_len, ':', 0); + case LLDP_PORTID_SUBTYPE_ADDR: + switch (port->p_id[0]) { + case LLDP_MGMT_ADDR_IP4: + len = INET_ADDRSTRLEN + 1; + break; + case LLDP_MGMT_ADDR_IP6: + len = INET6_ADDRSTRLEN + 1; + break; + default: + len = 0; + } + if (len > 0) { + ipaddress = _lldpctl_alloc_in_atom(atom, len); + if (!ipaddress) return NULL; + if (inet_ntop((port->p_id[0] == LLDP_MGMT_ADDR_IP4) ? + AF_INET : + AF_INET6, + &port->p_id[1], ipaddress, len) == NULL) + break; + return ipaddress; + } + break; + } + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + case lldpctl_k_port_descr: + return port->p_descr; + +#ifdef ENABLE_DOT3 + case lldpctl_k_port_dot3_mautype: + return map_lookup(operational_mau_type_values, port->p_macphy.mau_type); +#endif + + default: + /* Compatibility: query the associated chassis too */ + return lldpctl_atom_get_str(p->chassis, key); + } +} + +static lldpctl_atom_t * +_lldpctl_atom_set_int_port(lldpctl_atom_t *atom, lldpctl_key_t key, long int value) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + + if (p->local) { + switch (key) { + case lldpctl_k_port_status: + port->p_disable_rx = !LLDPD_RXTX_RXENABLED(value); + port->p_disable_tx = !LLDPD_RXTX_TXENABLED(value); + break; + case lldpctl_k_port_vlan_tx: + if (value > -1) { + port->p_vlan_tx_tag = value; + port->p_vlan_tx_enabled = 1; + } else + port->p_vlan_tx_enabled = 0; + break; + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + } else { + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + + return _lldpctl_atom_set_atom_port(atom, key, NULL); +} + +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; + + if (p->local) { + switch (key) { + case lldpctl_k_port_status: + return _lldpctl_atom_set_int_port(atom, key, + map_reverse_lookup(port_status_map.map, value)); + default: + break; + } + } + + switch (key) { + case lldpctl_k_port_id: + free(port->p_id); + port->p_id = strdup(value); + port->p_id_len = strlen(value); + break; + case lldpctl_k_port_descr: + free(port->p_descr); + port->p_descr = strdup(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) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + struct lldpd_hardware *hardware = p->hardware; + + /* Local port only */ + if (hardware != NULL) { + switch (key) { + case lldpctl_k_port_index: + return hardware->h_ifindex; + case lldpctl_k_tx_cnt: + return hardware->h_tx_cnt; + case lldpctl_k_rx_cnt: + return hardware->h_rx_cnt; + case lldpctl_k_rx_discarded_cnt: + return hardware->h_rx_discarded_cnt; + case lldpctl_k_rx_unrecognized_cnt: + return hardware->h_rx_unrecognized_cnt; + case lldpctl_k_ageout_cnt: + return hardware->h_ageout_cnt; + case lldpctl_k_insert_cnt: + return hardware->h_insert_cnt; + case lldpctl_k_delete_cnt: + return hardware->h_delete_cnt; + default: + break; + } + } + if (p->local) { + switch (key) { + case lldpctl_k_port_status: + return LLDPD_RXTX_FROM_PORT(port); + default: + break; + } + } + if (!port) return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + + /* Local and remote port */ + switch (key) { + case lldpctl_k_port_protocol: + return port->p_protocol; + case lldpctl_k_port_age: + return port->p_lastchange; + case lldpctl_k_port_ttl: + return port->p_ttl; + case lldpctl_k_port_id_subtype: + return port->p_id_subtype; + case lldpctl_k_port_hidden: + return port->p_hidden_in; + case lldpctl_k_port_vlan_tx: + return port->p_vlan_tx_enabled ? port->p_vlan_tx_tag : -1; +#ifdef ENABLE_DOT3 + case lldpctl_k_port_dot3_mfs: + if (port->p_mfs > 0) return port->p_mfs; + break; + case lldpctl_k_port_dot3_aggregid: + if (port->p_aggregid > 0) return port->p_aggregid; + break; + case lldpctl_k_port_dot3_autoneg_support: + return port->p_macphy.autoneg_support; + case lldpctl_k_port_dot3_autoneg_enabled: + return port->p_macphy.autoneg_enabled; + case lldpctl_k_port_dot3_autoneg_advertised: + return port->p_macphy.autoneg_advertised; + case lldpctl_k_port_dot3_mautype: + return port->p_macphy.mau_type; +#endif +#ifdef ENABLE_DOT1 + case lldpctl_k_port_vlan_pvid: + return port->p_pvid; +#endif + default: + /* Compatibility: query the associated chassis too */ + return lldpctl_atom_get_int(p->chassis, key); + } + return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); +} + +static const uint8_t * +_lldpctl_atom_get_buf_port(lldpctl_atom_t *atom, lldpctl_key_t key, size_t *n) +{ + struct _lldpctl_atom_port_t *p = (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + + switch (key) { + case lldpctl_k_port_id: + *n = port->p_id_len; + return (uint8_t *)port->p_id; + default: + /* Compatibility: query the associated chassis too */ + return lldpctl_atom_get_buffer(p->chassis, key, n); + } +} + +static struct atom_builder ports_list = { atom_ports_list, + sizeof(struct _lldpctl_atom_any_list_t), .init = _lldpctl_atom_new_any_list, + .free = _lldpctl_atom_free_any_list, .iter = _lldpctl_atom_iter_ports_list, + .next = _lldpctl_atom_next_ports_list, + .value = _lldpctl_atom_value_ports_list }; + +static struct atom_builder port = { atom_port, sizeof(struct _lldpctl_atom_port_t), + .init = _lldpctl_atom_new_port, .free = _lldpctl_atom_free_port, + .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, .set_int = _lldpctl_atom_set_int_port, + .get_buffer = _lldpctl_atom_get_buf_port }; + +ATOM_BUILDER_REGISTER(ports_list, 4); +ATOM_BUILDER_REGISTER(port, 5); |