Commit aa28585c authored by Cesar Prados's avatar Cesar Prados Committed by Grzegorz Daniluk

lldp: add all LLDP TLVs to the LLDPDU

The optional TLV of LLDP has been added, leaving
two of them still as *todo* since there is not hw
support yet for getting info from the wr-core outer world.
parent ca16dbfb
...@@ -11,25 +11,23 @@ ...@@ -11,25 +11,23 @@
#include <string.h> #include <string.h>
#include "endpoint.h" #include "revision.h"
#include "ipv4.h"
#include "ptpd_netif.h" #include "ptpd_netif.h"
#include "lldp.h" #include "lldp.h"
#include "endpoint.h"
#ifndef htons #include "ipv4.h"
#define htons(x) x
#endif
static char lldpdu[LLDP_PKT_LEN]; static char lldpdu[LLDP_PKT_LEN];
static uint16_t lldpdu_len; static uint16_t lldpdu_len;
/* LLDPC: a tx-only socket */ /* tx-only socket */
static struct wrpc_socket __static_lldp_socket = { static struct wrpc_socket __static_lldp_socket = {
.queue.buff = NULL, .queue.buff = NULL,
.queue.size = 0, .queue.size = 0,
}; };
static struct wrpc_socket *lldp_socket; static struct wrpc_socket *lldp_socket;
static struct wr_sockaddr addr;
static void lldp_header_tlv(int tlv_type) { static void lldp_header_tlv(int tlv_type) {
...@@ -39,18 +37,33 @@ static void lldp_header_tlv(int tlv_type) { ...@@ -39,18 +37,33 @@ static void lldp_header_tlv(int tlv_type) {
} }
#ifndef htons
#define htons(x) x
#endif
static void lldp_add_tlv(int tlv_type) { static void lldp_add_tlv(int tlv_type) {
unsigned char mac[6];
uint8_t myIP[4];
switch(tlv_type) { switch(tlv_type) {
case END_LLDP: case END_LLDP:
/* header */
lldp_header_tlv(tlv_type);
/* End TLV */
memcpy(lldpdu+(lldpdu_len), 0x0, tlv_type_len[tlv_type]);
lldpdu_len += tlv_type_len[tlv_type];
break; break;
case CHASSIS_ID: case CHASSIS_ID:
/* header */ /* header */
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info srting */ /* TLV Chassis Component */
lldpdu[lldpdu_len] = 1; /* Chassis Component */ lldpdu[lldpdu_len] = 4;
strcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), "WR Timing Receiver"); get_mac_addr(mac);
memcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), mac, 6);
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
...@@ -58,17 +71,17 @@ static void lldp_add_tlv(int tlv_type) { ...@@ -58,17 +71,17 @@ static void lldp_add_tlv(int tlv_type) {
/* header */ /* header */
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info string */ /* TLV Interce Alias */
lldpdu[lldpdu_len] = 3; /* Interface Alias */ lldpdu[lldpdu_len] = 7;
memcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), LLDP_MCAST_MAC, 6); strcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), "WR Timing Receiver");
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case TTL: case TTL:
/* header */ /* header */
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info srting */ /* TLV Time to Live */
lldpdu[lldpdu_len] = 0x30; /* Interface Alias */ lldpdu[lldpdu_len + 1] = 0xFF; /* sec */
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case PORT: case PORT:
...@@ -76,7 +89,8 @@ static void lldp_add_tlv(int tlv_type) { ...@@ -76,7 +89,8 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info srting */ /* TLV Info srting */
strcpy(lldpdu+lldpdu_len, "wr0"); getIP(myIP);
memcpy(lldpdu + lldpdu_len, myIP, 4);
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case SYS_NAME: case SYS_NAME:
...@@ -84,7 +98,8 @@ static void lldp_add_tlv(int tlv_type) { ...@@ -84,7 +98,8 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info srting */ /* TLV Info srting */
strcpy(lldpdu+lldpdu_len, "WR Timing Receiver"); /* fixme, define how to get formfactor name */
//strcpy(lldpdu+lldpdu_len, form_factor);
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case SYS_DESCR: case SYS_DESCR:
...@@ -92,7 +107,7 @@ static void lldp_add_tlv(int tlv_type) { ...@@ -92,7 +107,7 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info srting */ /* TLV Info srting */
strcpy(lldpdu+lldpdu_len, "Firmware Commit/Version"); strcpy(lldpdu+lldpdu_len, build_revision);
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case SYS_CAPLTY: case SYS_CAPLTY:
...@@ -100,11 +115,23 @@ static void lldp_add_tlv(int tlv_type) { ...@@ -100,11 +115,23 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type); lldp_header_tlv(tlv_type);
/* TLV Info string */ /* TLV Info string */
lldpdu[lldpdu_len] = 7; /* Station Only */ memset(lldpdu + lldpdu_len, 0x0, 4);
lldpdu_len += tlv_type_len[tlv_type]; lldpdu_len += tlv_type_len[tlv_type];
break; break;
case MNG_ADD: case MNG_ADD:
/* header */
lldp_header_tlv(tlv_type);
/* TLV Info string */
lldpdu[lldpdu_len] = 0x5; /* len */
lldpdu[lldpdu_len + LLDP_SUBTYPE] = 0x1; /* mngt add subtype */
/* fixme, defien how to get the mngt IP from the host */
//memcpy(lldpdu + (lldpdu_len + 2), MNG_IP , 4); /* mngt IP */
lldpdu[lldpdu_len + IF_SUBTYPE] = 0x1; /* if subtype */
lldpdu[lldpdu_len + IF_NUM] = 0x1; /* if number */
lldpdu_len += tlv_type_len[tlv_type];
break;
case USER_DEF:
/* to be added */ /* to be added */
break; break;
default: default:
...@@ -118,37 +145,39 @@ static void lldp_init(void) ...@@ -118,37 +145,39 @@ static void lldp_init(void)
int i; int i;
/* LLDP: raw ethernet*/ /* LLDP: raw ethernet*/
memset(&saddr, 0, sizeof(saddr)); memset(&saddr, 0x0, sizeof(saddr));
saddr.ethertype = htons(0x88CC); saddr.ethertype = htons(LLDP_ETH_TYP);
lldp_socket = ptpd_netif_create_socket(&__static_lldp_socket, &saddr, lldp_socket = ptpd_netif_create_socket(&__static_lldp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0); PTPD_SOCK_RAW_ETHERNET, 0);
memset(lldpdu,0x0,500);
memset(&addr, 0x0, sizeof(struct wr_sockaddr));
memcpy(addr.mac, LLDP_MCAST_MAC, 6);
/* add mandatory LLDP TLVs */
memset(lldpdu, 0x0, LLDP_PKT_LEN);
lldpdu_len = 0; lldpdu_len = 0;
/* Create LLDP TLVs */
for (i=CHASSIS_ID; i <= SYS_CAPLTY; i++) for (i=CHASSIS_ID; i <= SYS_CAPLTY; i++)
lldp_add_tlv(i); lldp_add_tlv(i);
/* add optional and end TLVs */
lldp_add_tlv(MNG_ADD);
lldp_add_tlv(END_LLDP);
} }
static void lldp_poll(void) static void lldp_poll(void)
{ {
uint8_t buf[LLDP_PKT_LEN]; static int ticks;
struct wr_sockaddr addr;
static int tick;
memset(&addr, 0x0, sizeof(struct wr_sockaddr));
memcpy(addr.mac, LLDP_MCAST_MAC, 6);
memset(buf, 0x0, LLDP_PKT_LEN);
memcpy(buf, lldpdu, LLDP_PKT_LEN);
if (tick > 10000) { /* to be fixed, waiting for periodic tasks */ /* fix me, waiting for periodic tasks */
ptpd_netif_sendto(lldp_socket, &addr, buf, LLDP_PKT_LEN, 0); if (ticks > LLDP_TX_FQ) {
tick = 0; ptpd_netif_sendto(lldp_socket, &addr, lldpdu, LLDP_PKT_LEN, 0);
ticks = 0;
} }
else else
tick += 1; ticks += 1;
} }
DEFINE_WRC_TASK(lldp) = { DEFINE_WRC_TASK(lldp) = {
......
...@@ -12,11 +12,19 @@ ...@@ -12,11 +12,19 @@
#ifndef __LLDP_H #ifndef __LLDP_H
#define __LLDP_H #define __LLDP_H
#define LLDP_MCAST_MAC "\x01\x80\xC2\x00\x00\x0E" #define LLDP_MCAST_MAC "\x01\x80\xC2\x00\x00\x0E"
#define LLDP_ETH_TYP 0x88CC
#define LLDP_PKT_LEN 0x9E /* 158 bytes */ #define LLDP_PKT_LEN 0x9E /* 158 bytes */
#define TLV_MAX 0x9 #define TLV_MAX 0xA
#define LLDP_HEADER 0x2 #define LLDP_HEADER 0x2
#define LLDP_SUBTYPE 0x1 #define LLDP_SUBTYPE 0x1
#define MASK_CAPLTY 0x2
#define EO_CAPLTY 0x3
#define IF_SUBTYPE 0x6
#define IF_NUM 0x10
#define LLDP_TX_FQ 10000
enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */ enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */
CHASSIS_ID, CHASSIS_ID,
...@@ -26,18 +34,19 @@ enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */ ...@@ -26,18 +34,19 @@ enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */
SYS_NAME, SYS_NAME,
SYS_DESCR, SYS_DESCR,
SYS_CAPLTY, SYS_CAPLTY,
MNG_ADD MNG_ADD,
USER_DEF
}; };
uint16_t tlv_type_len[TLV_MAX] = { 0x0, /* LEN_LLDP_END */ uint16_t tlv_type_len[TLV_MAX] = { 0x0, /* LEN_LLDP_END */
0x14, /* LEN_CHASSIS_ID */ 0x7, /* LEN_CHASSIS_ID */
0x14, /* LEN_PORT_ID */ 0x14, /* LEN_PORT_ID */
0x2, /* LEN_TTL */ 0x2, /* LEN_TTL */
0x14, /* LEN_PORT */ 0x14, /* LEN_PORT */
0x14, /* LEN_SYS_NAME */ 0x14, /* LEN_SYS_NAME */
0x14, /* LEN_SYS_DESCR */ 0x14, /* LEN_SYS_DESCR */
0x4, /* LEN_SYS_CAPLTY */ 0x4, /* LEN_SYS_CAPLTY */
0x1E /* LEN_MNG_ADD */ 0xC /* LEN_MNG_ADD */
}; };
#endif /* __LLDP_H */ #endif /* __LLDP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment