Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
a62a8c85
Commit
a62a8c85
authored
Jul 04, 2017
by
Adam Wujek
💬
Committed by
Grzegorz Daniluk
Dec 01, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lib/lldp: try to change some fields and make it more dynamic
Signed-off-by:
Adam Wujek
<
adam.wujek@cern.ch
>
parent
c9c30aab
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
173 additions
and
92 deletions
+173
-92
lldp.c
lib/lldp.c
+141
-64
lldp.h
lib/lldp.h
+32
-28
No files found.
lib/lldp.c
View file @
a62a8c85
...
...
@@ -2,7 +2,10 @@
* This work is part of the White Rabbit project
*
* Copyright (C) 2011 GSI (www.gsi.de)
* Copyright (C) 2017 CERN
*
* Author: Cesar Prados <c.prados@gsi.de>
* Author: Adam Wujek <adam.wujek@cern.ch>
*
* LLDP transmit-only station
*
...
...
@@ -17,9 +20,10 @@
#include "endpoint.h"
#include "ipv4.h"
#include "shell.h"
#include "syscon.h"
#include <wrpc.h>
/*needed for htons()*/
static
char
lldpdu
[
LLDP
_PKT_LEN
];
static
uint8_t
lldpdu
[
LLDP_MAX
_PKT_LEN
];
static
uint16_t
lldpdu_len
;
/* tx-only socket */
...
...
@@ -31,105 +35,165 @@ static struct wrpc_socket __static_lldp_socket = {
static
struct
wrpc_socket
*
lldp_socket
;
static
struct
wr_sockaddr
addr
;
static
void
lldp_header_tlv
(
int
tlv_type
)
{
extern
char
wrc_hw_name
[
HW_NAME_LENGTH
];
//lldpdu_len = tlv_offset[tlv_type];
static
void
lldp_header_tlv
(
uint8_t
tlv_type
,
uint8_t
tlv_len
)
{
lldpdu
[
lldpdu_len
]
=
tlv_type
<<
1
;
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
]
=
tlv_type_len
[
tlv_type
];
lldpdu_len
+=
2
;
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
]
=
tlv_len
;
lldpdu_len
+=
LLDP_HEADER
;
}
static
void
fill_mac
(
uint8_t
*
tlv
,
uint8_t
type
)
{
*
tlv
=
type
;
/* write MAC after subtype byte */
get_mac_addr
(
tlv
+
LLDP_SUBTYPE
);
}
static
void
lldp_add_tlv
(
int
tlv_type
)
{
u
nsigned
char
mac
[
6
];
u
int8_t
mac
[
6
];
unsigned
char
ipWR
[
4
];
int
tlv_len
=
0
;
switch
(
tlv_type
)
{
switch
(
tlv_type
)
{
case
END_LLDP
:
/* End TLV */
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* End TLV */
memcpy
(
lldpdu
+
lldpdu_len
,
0x0
,
tlv_type_len
[
tlv_type
]);
break
;
case
CHASSIS_ID
:
tlv_len
=
CHASSIS_ID_TLV_LEN
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Chassis Component */
lldpdu
[
lldpdu_len
]
=
4
;
get_mac_addr
(
mac
);
memcpy
(
lldpdu
+
(
lldpdu_len
+
LLDP_SUBTYPE
),
mac
,
6
);
fill_mac
(
&
lldpdu
[
lldpdu_len
],
CHASSIS_ID_TYPE_MAC
);
break
;
case
PORT_ID
:
tlv_len
=
PORT_ID_TLV_LEN
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Interce Alias */
lldpdu
[
lldpdu_len
]
=
LLDP_ID_SUBTYPE_MAC
;
get_mac_addr
(
mac
);
memcpy
(
lldpdu
+
(
lldpdu_len
+
LLDP_SUBTYPE
),
mac
,
6
);
/* TLV portID */
fill_mac
(
&
lldpdu
[
lldpdu_len
],
PORT_ID_SUBTYPE_MAC
);
break
;
case
TTL
:
tlv_len
=
TTL_ID_TLV_LEN
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Time to Live */
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
]
=
0x20
;
/* sec */
/* use LLDP_TX_TICK_INTERVAL in seconds times 4 */
lldpdu
[
lldpdu_len
+
TTL_BYTE_MSB
]
=
(((
LLDP_TX_TICK_INTERVAL
/
1000
)
*
4
)
>>
8
)
&
0xff
;
lldpdu
[
lldpdu_len
+
TTL_BYTE_LSB
]
=
((
LLDP_TX_TICK_INTERVAL
/
1000
)
*
4
)
&
0xff
;
break
;
case
PORT
:
tlv_len
=
strlen
(
PORT_NAME
)
+
1
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Info srting */
if
(
HAS_IP
)
{
getIP
(
ipWR
);
char
buf
[
32
];
format_ip
(
buf
,
ipWR
);
strcpy
(
lldpdu
+
lldpdu_len
,
buf
);
}
strcpy
((
char
*
)
lldpdu
+
lldpdu_len
,
PORT_NAME
);
break
;
case
SYS_NAME
:
{
/* TODO get host system name from wr-core outer world */
/* NOTE: according to 802.1AB-2005 9.5.6.2 and then
* IETF RFC 3418:
* "If the name is unknown, the value is
* the zero-length string."
* However, we put the IP, if not set MAC to be able to
* identify a system */
char
buf
[
32
];
getIP
(
ipWR
);
if
(
HAS_IP
&&
memcmp
(
ipWR
,
"
\0\0\0\0
"
,
4
))
{
/* NOTE: no subtype */
format_ip
(
buf
,
ipWR
);
tlv_len
=
strlen
((
char
*
)
buf
);
strcpy
((
char
*
)(
lldpdu
+
lldpdu_len
+
LLDP_HEADER
),
(
char
*
)
buf
);
}
else
{
/* NOTE: no subtype */
get_mac_addr
(
mac
);
pp_sprintf
(
buf
,
"%02x:%02x:%02x:%02x:%02x:%02x"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
],
mac
[
4
],
mac
[
5
]);
tlv_len
=
17
;
strncpy
((
char
*
)(
lldpdu
+
lldpdu_len
+
LLDP_HEADER
),
(
char
*
)
buf
,
tlv_len
);
}
/* header */
lldp_header_tlv
(
tlv_type
);
/* TLV Info srting */
/* TODO get host system name from wr-core outer world */
strcpy
(
lldpdu
+
lldpdu_len
,
"WR PTP Core"
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
break
;
}
case
SYS_DESCR
:
/* header */
lldp_header_tlv
(
tlv_type
);
tlv_len
=
0
;
/* will be calculated later */
uint8_t
*
pdu_p
;
/* set the pointer after TLV's header */
pdu_p
=
&
lldpdu
[
lldpdu_len
+
LLDP_HEADER
];
/* TLV Info srting */
strcpy
(
lldpdu
+
lldpdu_len
,
build_revision
);
strncpy
((
char
*
)(
pdu_p
),
wrc_hw_name
,
HW_NAME_LENGTH
-
1
);
pdu_p
+=
strnlen
(
wrc_hw_name
,
HW_NAME_LENGTH
-
1
);
strcpy
((
char
*
)(
pdu_p
),
": "
);
pdu_p
+=
2
;
/* length of ": " */
strncpy
((
char
*
)(
pdu_p
),
build_revision
,
32
);
pdu_p
+=
strnlen
(
build_revision
,
32
);
tlv_len
=
(
uint8_t
)(
pdu_p
-
&
lldpdu
[
lldpdu_len
+
LLDP_HEADER
]);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
break
;
case
SYS_CAPLTY
:
/* don't implement this, this TLV is optional */
break
;
tlv_len
=
4
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Info string */
memset
(
lldpdu
+
lldpdu_len
,
0x0
,
4
);
memset
(
lldpdu
+
lldpdu_len
,
0x0
,
tlv_len
);
break
;
case
MNG_ADD
:
/* TODO: fill with MAC if no IP present */
if
(
!
HAS_IP
||
!
memcmp
(
ipWR
,
"
\0\0\0\0
"
,
4
))
{
/* if no IP present skip this field */
break
;
}
/* TODO: dynamic len */
tlv_len
=
0xc
;
/* header */
lldp_header_tlv
(
tlv_type
);
lldp_header_tlv
(
tlv_type
,
tlv_len
);
/* TLV Info string */
/* TODO get host system name from wr-core outer world */
lldpdu
[
lldpdu_len
]
=
0x5
;
/* len */
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
]
=
0x1
;
/* mngt add subtype */
lldpdu
[
lldpdu_len
+
IF_SUBTYPE
]
=
0x1
;
/* if subtype */
lldpdu
[
lldpdu_len
+
IF_NUM
]
=
0x1
;
/* if number */
lldpdu
[
lldpdu_len
]
=
MNG_ADDR_LEN
;
/* len */
/* mngt add subtype */
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
]
=
MNG_ADDR_SUBTYPE_IPv4
;
/* if subtype (ifIndex)*/
lldpdu
[
lldpdu_len
+
MNT_IF_SUBTYPE
]
=
MNG_IF_NUM_SUBTYPE_IFINDEX
;
/* if number */
lldpdu
[
lldpdu_len
+
MNT_IF_NUM
]
=
0x1
;
/* TLV Info srting */
if
(
HAS_IP
)
{
getIP
(
ipWR
);
if
(
HAS_IP
)
{
getIP
(
ipWR
);
char
buf
[
32
];
format_ip
(
buf
,
ipWR
);
memcpy
(
&
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
+
1
],
ipWR
,
4
);
}
format_ip
(
buf
,
ipWR
);
memcpy
(
&
lldpdu
[
lldpdu_len
+
LLDP_SUBTYPE
+
1
],
ipWR
,
4
);
}
/* TODO: add info about VLAN 9.5.9.9g */
break
;
case
USER_DEF
:
/* TODO define WR TLV */
...
...
@@ -139,22 +203,21 @@ static void lldp_add_tlv(int tlv_type) {
return
;
break
;
}
lldpdu_len
+=
tlv_
type_len
[
tlv_type
]
;
lldpdu_len
+=
tlv_
len
;
}
static
void
lldp_update
(
void
)
{
int
i
;
int
i
;
/* add mandatory LLDP TLVs */
memset
(
lldpdu
,
0x0
,
LLDP_PKT_LEN
);
memset
(
lldpdu
,
0x0
,
LLDP_
MAX_
PKT_LEN
);
lldpdu_len
=
0
;
for
(
i
=
CHASSIS_ID
;
i
<=
SYS_CAPLTY
;
i
++
)
pp_printf
(
"lldp update
\n
"
);
/* add all TLV's */
for
(
i
=
CHASSIS_ID
;
i
<=
MNG_ADD
;
i
++
)
lldp_add_tlv
(
i
);
/* add optional TLVs */
lldp_add_tlv
(
MNG_ADD
);
/* end TLVs */
lldp_add_tlv
(
END_LLDP
);
}
...
...
@@ -178,19 +241,33 @@ static void lldp_init(void)
static
int
lldp_poll
(
void
)
{
static
int
ticks
;
static
int
ticks
;
unsigned
char
new_ipWR
;
static
unsigned
char
old_ipWR
;
uint8_t
new_mac
[
ETH_ALEN
];
static
uint8_t
old_mac
[
ETH_ALEN
];
/* periodic tasks */
if
(
ticks
>
LLDP_TX_FQ
)
{
if
(
ticks
>
LLDP_TX_TICK_INTERVAL
)
{
get_mac_addr
(
new_mac
);
if
(
HAS_IP
)
{
getIP
(
&
new_ipWR
);
}
if
(
HAS_IP
&&
(
ip_status
!=
IP_TRAINING
))
{
//lldp_add_tlv(PORT);
lldp_add_tlv
(
MNG_ADD
);
/* Update only when IP or MAC changed */
/* TODO: or VLAN changed */
if
(
memcmp
(
&
new_mac
,
&
old_mac
,
ETH_ALEN
)
||
(
HAS_IP
&&
(
ip_status
!=
IP_TRAINING
)
&&
memcmp
(
&
new_ipWR
,
&
old_ipWR
,
IPLEN
))
)
{
/* update LLDP info */
lldp_update
();
/* update other dynamic TLVs */
/* copy new MAC nad IP */
memcpy
(
&
old_mac
,
&
new_mac
,
ETH_ALEN
);
memcpy
(
&
old_ipWR
,
&
new_ipWR
,
IPLEN
);
}
ptpd_netif_sendto
(
lldp_socket
,
&
addr
,
lldpdu
,
LLDP_PKT_LEN
,
0
);
ptpd_netif_sendto
(
lldp_socket
,
&
addr
,
lldpdu
,
lldpdu_len
,
0
);
ticks
=
0
;
return
1
;
...
...
lib/lldp.h
View file @
a62a8c85
...
...
@@ -11,26 +11,41 @@
#ifndef __LLDP_H
#define __LLDP_H
#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 0xA
#define LLDP_HEADER 0x2
#define LLDP_SUBTYPE 0x1
#define IF_SUBTYPE 0x6
#define IF_NUM 0x10
#define LLDP_ID_SUBTYPE_MAC 3
#define LLDP_TX_FQ 1000
enum
TLV_TYPE
{
END_LLDP
=
0
,
/* mandatory TLVs */
#include "minic.h"
#define LLDP_MCAST_MAC "\x01\x80\xC2\x00\x00\x0E"
/* 802.1AB-2005,
Table 8-1 */
#define LLDP_ETH_TYP 0x88CC
/* 802.1AB-2005, Table 8-2 */
#define LLDP_MAX_PKT_LEN 0x9E
/* 158 bytes */
#define TLV_MAX 0xA
#define LLDP_HEADER 0x2
#define LLDP_SUBTYPE 0x1
#define MNT_IF_SUBTYPE 0x6
#define MNT_IF_NUM 10
#define LLDP_TX_TICK_INTERVAL 1000
#define CHASSIS_ID_TLV_LEN (1 + ETH_ALEN)
/* chassis ID subtype byte
* + MAC Len */
#define CHASSIS_ID_TYPE_MAC 4
/* 802.1AB-2005, table 9-2 */
#define PORT_ID_TLV_LEN (1 + ETH_ALEN)
/* port ID subtype byte
* + MAC Len */
#define PORT_ID_SUBTYPE_MAC 3
/* 802.1AB-2005, table 9-3 */
#define TTL_ID_TLV_LEN 2
/* 802.1AB-2005, Figure 9-6 */
#define TTL_BYTE_MSB 0
#define TTL_BYTE_LSB 1
#define PORT_NAME "wr0"
#define IPLEN 4
/* len of IP address in bytes */
#define MNG_ADDR_LEN (1 + IPLEN)
/* MNT addr subtype + IPLEN */
#define MNG_ADDR_SUBTYPE_IPv4 1
/* ianaAddressFamilyNumbers MIB */
#define MNG_ADDR_SUBTYPE_MAC 6
/* ianaAddressFamilyNumbers MIB */
#define MNG_IF_NUM_SUBTYPE_IFINDEX 2
/* 802.1AB-2005, 9.5.9.5 */
enum
TLV_TYPE
{
END_LLDP
=
0
,
/* mandatory TLVs */
CHASSIS_ID
,
PORT_ID
,
TTL
,
PORT
,
/* optional TLVs */
PORT
,
/* optional TLVs */
SYS_NAME
,
SYS_DESCR
,
SYS_CAPLTY
,
...
...
@@ -38,15 +53,4 @@ enum TLV_TYPE { END_LLDP = 0, /* mandatory TLVs */
USER_DEF
};
uint16_t
tlv_type_len
[
TLV_MAX
]
=
{
0x0
,
/* LEN_LLDP_END */
0x7
,
/* LEN_CHASSIS_ID */
0x7
,
/* LEN_PORT_ID */
0x2
,
/* LEN_TTL */
0x14
,
/* LEN_PORT */
0x14
,
/* LEN_SYS_NAME */
0x14
,
/* LEN_SYS_DESCR */
0x4
,
/* LEN_SYS_CAPLTY */
0xC
/* LEN_MNG_ADD */
};
#endif
/* __LLDP_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment