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 @@
#include <string.h>
#include "endpoint.h"
#include "ipv4.h"
#include "revision.h"
#include "ptpd_netif.h"
#include "lldp.h"
#ifndef htons
#define htons(x) x
#endif
#include "endpoint.h"
#include "ipv4.h"
static char lldpdu[LLDP_PKT_LEN];
static uint16_t lldpdu_len;
/* LLDPC: a tx-only socket */
/* tx-only socket */
static struct wrpc_socket __static_lldp_socket = {
.queue.buff = NULL,
.queue.size = 0,
};
static struct wrpc_socket *lldp_socket;
static struct wr_sockaddr addr;
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) {
unsigned char mac[6];
uint8_t myIP[4];
switch(tlv_type) {
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;
case CHASSIS_ID:
/* header */
lldp_header_tlv(tlv_type);
/* TLV Info srting */
lldpdu[lldpdu_len] = 1; /* Chassis Component */
strcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), "WR Timing Receiver");
/* TLV Chassis Component */
lldpdu[lldpdu_len] = 4;
get_mac_addr(mac);
memcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), mac, 6);
lldpdu_len += tlv_type_len[tlv_type];
break;
......@@ -58,17 +71,17 @@ static void lldp_add_tlv(int tlv_type) {
/* header */
lldp_header_tlv(tlv_type);
/* TLV Info string */
lldpdu[lldpdu_len] = 3; /* Interface Alias */
memcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), LLDP_MCAST_MAC, 6);
/* TLV Interce Alias */
lldpdu[lldpdu_len] = 7;
strcpy(lldpdu+(lldpdu_len + LLDP_SUBTYPE), "WR Timing Receiver");
lldpdu_len += tlv_type_len[tlv_type];
break;
case TTL:
/* header */
lldp_header_tlv(tlv_type);
/* TLV Info srting */
lldpdu[lldpdu_len] = 0x30; /* Interface Alias */
/* TLV Time to Live */
lldpdu[lldpdu_len + 1] = 0xFF; /* sec */
lldpdu_len += tlv_type_len[tlv_type];
break;
case PORT:
......@@ -76,7 +89,8 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type);
/* TLV Info srting */
strcpy(lldpdu+lldpdu_len, "wr0");
getIP(myIP);
memcpy(lldpdu + lldpdu_len, myIP, 4);
lldpdu_len += tlv_type_len[tlv_type];
break;
case SYS_NAME:
......@@ -84,7 +98,8 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type);
/* 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];
break;
case SYS_DESCR:
......@@ -92,7 +107,7 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type);
/* TLV Info srting */
strcpy(lldpdu+lldpdu_len, "Firmware Commit/Version");
strcpy(lldpdu+lldpdu_len, build_revision);
lldpdu_len += tlv_type_len[tlv_type];
break;
case SYS_CAPLTY:
......@@ -100,11 +115,23 @@ static void lldp_add_tlv(int tlv_type) {
lldp_header_tlv(tlv_type);
/* TLV Info string */
lldpdu[lldpdu_len] = 7; /* Station Only */
memset(lldpdu + lldpdu_len, 0x0, 4);
lldpdu_len += tlv_type_len[tlv_type];
break;
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 */
break;
default:
......@@ -118,37 +145,39 @@ static void lldp_init(void)
int i;
/* LLDP: raw ethernet*/
memset(&saddr, 0, sizeof(saddr));
saddr.ethertype = htons(0x88CC);
memset(&saddr, 0x0, sizeof(saddr));
saddr.ethertype = htons(LLDP_ETH_TYP);
lldp_socket = ptpd_netif_create_socket(&__static_lldp_socket, &saddr,
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;
/* Create LLDP TLVs */
for (i=CHASSIS_ID; i <= SYS_CAPLTY; 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)
{
uint8_t buf[LLDP_PKT_LEN];
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);
static int ticks;
if (tick > 10000) { /* to be fixed, waiting for periodic tasks */
ptpd_netif_sendto(lldp_socket, &addr, buf, LLDP_PKT_LEN, 0);
tick = 0;
/* fix me, waiting for periodic tasks */
if (ticks > LLDP_TX_FQ) {
ptpd_netif_sendto(lldp_socket, &addr, lldpdu, LLDP_PKT_LEN, 0);
ticks = 0;
}
else
tick += 1;
ticks += 1;
}
DEFINE_WRC_TASK(lldp) = {
......
......@@ -12,11 +12,19 @@
#ifndef __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 TLV_MAX 0x9
#define TLV_MAX 0xA
#define LLDP_HEADER 0x2
#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 */
CHASSIS_ID,
......@@ -26,18 +34,19 @@ enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */
SYS_NAME,
SYS_DESCR,
SYS_CAPLTY,
MNG_ADD
MNG_ADD,
USER_DEF
};
uint16_t tlv_type_len[TLV_MAX] = { 0x0, /* LEN_LLDP_END */
0x14, /* LEN_CHASSIS_ID */
0x7, /* LEN_CHASSIS_ID */
0x14, /* LEN_PORT_ID */
0x2, /* LEN_TTL */
0x14, /* LEN_PORT */
0x14, /* LEN_SYS_NAME */
0x14, /* LEN_SYS_DESCR */
0x4, /* LEN_SYS_CAPLTY */
0x1E /* LEN_MNG_ADD */
0xC /* LEN_MNG_ADD */
};
#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