diff --git a/cmd_parser.c b/cmd_parser.c index cf45684c..9fe92879 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -945,6 +945,8 @@ void parse_port(void) print_string("\"\n"); } else if (cmd_compare(2, "lldp")) { if (cmd_compare(3, "block")){ + if (lldp_enabled) + lldp_shutdown((uint16_t)1 << phy_settings.port); lldp_logical_port_status &= ~((uint16_t)1 << phy_settings.port); } else if (cmd_compare(3, "permit")) { lldp_logical_port_status |= (uint16_t)1 << phy_settings.port; @@ -2089,6 +2091,8 @@ void cmd_parser(void) __banked trap_rma_set(RTL837X_RMA0E_CONF, RTL837X_RMA_ACT_TRAP); } else { print_string("LLDP disabled\n"); + if (lldp_enabled) + lldp_shutdown(lldp_logical_port_status); lldp_enabled = 0; trap_rma_set(RTL837X_RMA0E_CONF, RTL837X_RMA_ACT_FORWARD); } diff --git a/rtl837x_lldp.c b/rtl837x_lldp.c index 922c16a6..d4e3a2db 100644 --- a/rtl837x_lldp.c +++ b/rtl837x_lldp.c @@ -47,7 +47,7 @@ struct lldp_pkt { struct rtl_tag rtl_tag; uint16_t ether_type; - uint8_t payload[64]; + uint8_t payload[LLDP_MAX_PAYLOAD]; }; #define LLDP_O ((__xdata struct lldp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE]) @@ -59,7 +59,7 @@ struct lldp_pkt { // the length at any point #define LLDP_TYPE(value) (value << 1) -void lldp_send(void) __banked __reentrant +static void lldp_send_ports(uint16_t ttl, uint16_t ports) __reentrant { __xdata uint8_t *p; uint8_t port_position; @@ -81,18 +81,44 @@ void lldp_send(void) __banked __reentrant *p++ = LLDP_TYPE(LLDP_PORT_ID_TLV_TYPE); *p++ = LLDP_PORT_ID_TLV_LENGTH; *p++ = LLDP_PORT_ID_TLV_SUBTYPE; + memcpyc(p, LLDP_PORT_ID_PREFIX, LLDP_PORT_ID_PREFIX_LENGTH); + p += LLDP_PORT_ID_PREFIX_LENGTH; port_position = (p-LLDP_O->payload); *p++ = '0'; // filled in per port below //TTL *p++ = LLDP_TYPE(LLDP_TTL_TLV_TYPE); *p++ = LLDP_TTL_TLV_LENGTH; - *p++ = 0x00; //padding - *p++ = LLDP_TTL_TTL_SECONDS; + *p++ = ttl >> 8; + *p++ = ttl & 0xff; p += lldp_sysname(p); p += lldp_sysdesc(p); + //System Capabilities: supported, enabled + *p++ = LLDP_TYPE(LLDP_CAPABILITIES_TLV_TYPE); + *p++ = LLDP_CAPABILITIES_TLV_LENGTH; + *p++ = LLDP_CAPABILITY_BRIDGE >> 8; + *p++ = LLDP_CAPABILITY_BRIDGE & 0xff; + *p++ = LLDP_CAPABILITY_BRIDGE >> 8; + *p++ = LLDP_CAPABILITY_BRIDGE & 0xff; + + //Management Address: IPv4 + if (uip_hostaddr[0] | uip_hostaddr[1]) { + *p++ = LLDP_TYPE(LLDP_MGMT_ADDR_TLV_TYPE); + *p++ = LLDP_MGMT_ADDR_TLV_LENGTH; + *p++ = LLDP_MGMT_ADDR_STR_LENGTH; + *p++ = LLDP_MGMT_ADDR_SUBTYPE_IPV4; + memcpy(p, (__xdata uint8_t *)uip_hostaddr, sizeof(uip_ipaddr_t)); + p += sizeof(uip_ipaddr_t); + *p++ = LLDP_MGMT_IF_NUMBERING_UNKNOWN; + *p++ = 0; //interface number + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; //OID length + } + // End of LLDPDU TLV *p++ = 0x00; //padding *p++ = 0x00; //padding @@ -115,7 +141,7 @@ void lldp_send(void) __banked __reentrant for (uint8_t port = MACHINE_MIN_PORT; port <= MACHINE_MAX_PORT; port++) { - if ((1 << port) & lldp_logical_port_status) { + if ((1 << port) & ports) { LLDP_O->payload[port_position] = '0' + machine.log_to_phys_port[port]; LLDP_O->rtl_tag.pmask = HTONS((uint16_t)1 << port); @@ -124,6 +150,16 @@ void lldp_send(void) __banked __reentrant } } +void lldp_send(void) __banked __reentrant +{ + lldp_send_ports(LLDP_TTL_TTL_SECONDS, lldp_logical_port_status); +} + +void lldp_shutdown(uint16_t ports) __banked __reentrant +{ + lldp_send_ports(0, ports); +} + void lldp_set_addresses(void) __banked { // LLDP destination multicast addr: 01:80:c2:00:00:0e memcpyc(LLDP_O->dst.addr, "\x01\x80\xc2\x00\x00\x0e", MAC_ADDR_LEN); diff --git a/rtl837x_lldp.h b/rtl837x_lldp.h index fd2c5aa3..e79143c3 100644 --- a/rtl837x_lldp.h +++ b/rtl837x_lldp.h @@ -11,8 +11,10 @@ #define LLDP_HOLD_MULTIPLIER 4 #define LLDP_PORT_ID_TLV_TYPE 2 -#define LLDP_PORT_ID_TLV_LENGTH 0x02 -#define LLDP_PORT_ID_TLV_SUBTYPE 0x07 +#define LLDP_PORT_ID_PREFIX "Port " +#define LLDP_PORT_ID_PREFIX_LENGTH 5 +#define LLDP_PORT_ID_TLV_LENGTH (1 + LLDP_PORT_ID_PREFIX_LENGTH + 1) +#define LLDP_PORT_ID_TLV_SUBTYPE 0x05 #define LLDP_TTL_TLV_TYPE 3 #define LLDP_TTL_TLV_LENGTH 2 @@ -25,9 +27,22 @@ #define LLDP_SYSNAME_TLV_TYPE 5 #define LLDP_SYSDESC_TLV_TYPE 6 +#define LLDP_CAPABILITIES_TLV_TYPE 7 +#define LLDP_CAPABILITIES_TLV_LENGTH 4 +#define LLDP_CAPABILITY_BRIDGE 0x0004 + +#define LLDP_MGMT_ADDR_TLV_TYPE 8 +#define LLDP_MGMT_ADDR_TLV_LENGTH 12 +#define LLDP_MGMT_ADDR_STR_LENGTH 5 +#define LLDP_MGMT_ADDR_SUBTYPE_IPV4 1 +#define LLDP_MGMT_IF_NUMBERING_UNKNOWN 1 + +#define LLDP_MAX_PAYLOAD 128 + void lldp_init(void) __banked; void lldp_tick(void) __banked; void lldp_send(void) __banked; +void lldp_shutdown(uint16_t ports) __banked; void lldp_set_addresses(void) __banked; void lldp_set_rtl_wrapper(void) __banked; uint8_t lldp_sysname(__xdata uint8_t *p) __banked;