mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
16 files changed
+342
-6
No files matched your search
@@ -84,6 +84,7 @@ SRCS += \
|
|||||||
rtl837x_pins.c\
|
rtl837x_pins.c\
|
||||||
rtl837x_port.c \
|
rtl837x_port.c \
|
||||||
rtl837x_stp.c \
|
rtl837x_stp.c \
|
||||||
|
rtl837x_lldp.c \
|
||||||
rtl837x_storm.c
|
rtl837x_storm.c
|
||||||
SRCS += \
|
SRCS += \
|
||||||
httpd/httpd.c \
|
httpd/httpd.c \
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
|
#include "rtl837x_lldp.h"
|
||||||
#include "rtl837x_storm.h"
|
#include "rtl837x_storm.h"
|
||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata bool stp_enabled;
|
extern __xdata bool stp_enabled;
|
||||||
extern __code const uint8_t log_to_phys_port[9];
|
extern __code const uint8_t log_to_phys_port[9];
|
||||||
|
extern __xdata bool lldp_enabled;
|
||||||
|
|
||||||
extern volatile __xdata uint32_t ticks;
|
extern volatile __xdata uint32_t ticks;
|
||||||
extern volatile __xdata uint8_t sfr_data[4];
|
extern volatile __xdata uint8_t sfr_data[4];
|
||||||
@@ -880,6 +882,7 @@ void parse_port(void)
|
|||||||
cmd_error("\nUsage:" \
|
cmd_error("\nUsage:" \
|
||||||
"\nport <port> [show|on|off]" \
|
"\nport <port> [show|on|off]" \
|
||||||
"\nport <port> [10m|100m|1g|2g5|duplex] [half|full]" \
|
"\nport <port> [10m|100m|1g|2g5|duplex] [half|full]" \
|
||||||
|
"\nport <port> lldp [block|permit]" \
|
||||||
"\nport <port> name [custom port name]\n");
|
"\nport <port> name [custom port name]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -912,6 +915,14 @@ void parse_port(void)
|
|||||||
print_string("\nName set to: \"");
|
print_string("\nName set to: \"");
|
||||||
print_string_x(port_names[phy_settings.port]);
|
print_string_x(port_names[phy_settings.port]);
|
||||||
print_string("\"\n");
|
print_string("\"\n");
|
||||||
|
} else if (cmd_compare(2, "lldp")) {
|
||||||
|
if (cmd_compare(3, "block")){
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
print_string ("Unknown port <port> lldp [block|permit] command\n");
|
||||||
|
}
|
||||||
} else if (machine.is_sfp[phy_settings.port]) {
|
} else if (machine.is_sfp[phy_settings.port]) {
|
||||||
print_string(" is SFP no PHY information available.\n");
|
print_string(" is SFP no PHY information available.\n");
|
||||||
} else if (cmd_compare(2, "10m")) {
|
} else if (cmd_compare(2, "10m")) {
|
||||||
@@ -2027,6 +2038,14 @@ void cmd_parser(void) __banked
|
|||||||
parse_ingress();
|
parse_ingress();
|
||||||
} else if (cmd_compare(0, "session")) {
|
} else if (cmd_compare(0, "session")) {
|
||||||
parse_session();
|
parse_session();
|
||||||
|
} else if (cmd_compare(0, "lldp")) {
|
||||||
|
if (cmd_compare(1, "on")) {
|
||||||
|
print_string("LLDP enabled\n");
|
||||||
|
lldp_enabled = 1;
|
||||||
|
} else {
|
||||||
|
print_string("LLDP disabled\n");
|
||||||
|
lldp_enabled = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmd_error("Unknown command\n");
|
cmd_error("Unknown command\n");
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern __xdata uint8_t err_status;
|
|||||||
#define HEALTH_PH_STP 4
|
#define HEALTH_PH_STP 4
|
||||||
#define HEALTH_PH_CMD 5
|
#define HEALTH_PH_CMD 5
|
||||||
#define HEALTH_PHASES 6
|
#define HEALTH_PHASES 6
|
||||||
|
#define HEALTH_LLDP 7
|
||||||
|
|
||||||
extern __xdata uint16_t health_rx_frames;
|
extern __xdata uint16_t health_rx_frames;
|
||||||
#define health_rx_frame() health_rx_frames++
|
#define health_rx_frame() health_rx_frames++
|
||||||
|
|||||||
+31
-2
@@ -3,7 +3,7 @@ var LANG={
|
|||||||
en:{
|
en:{
|
||||||
nav_dash:"Dashboard",nav_ports:"Ports",nav_stp:"Spanning tree",nav_stats:"Statistics",
|
nav_dash:"Dashboard",nav_ports:"Ports",nav_stp:"Spanning tree",nav_stats:"Statistics",
|
||||||
nav_vlan:"VLANs",nav_l2:"MAC table",nav_mirror:"Mirroring",nav_isolate:"Isolation",nav_lag:"LAG",nav_eee:"EEE",
|
nav_vlan:"VLANs",nav_l2:"MAC table",nav_mirror:"Mirroring",nav_isolate:"Isolation",nav_lag:"LAG",nav_eee:"EEE",
|
||||||
nav_bw:"Bandwidth",nav_system:"System",nav_fw:"Firmware",
|
nav_bw:"Bandwidth",nav_system:"System",nav_fw:"Firmware",nav_lldp:"LLDP",
|
||||||
hdr_dirty:"unsaved changes",hdr_dirty_t:"Running config differs from startup config",
|
hdr_dirty:"unsaved changes",hdr_dirty_t:"Running config differs from startup config",
|
||||||
hdr_save:"Save to flash",hdr_save_t:"Persist running configuration to flash",
|
hdr_save:"Save to flash",hdr_save_t:"Persist running configuration to flash",
|
||||||
th_auto:"System",th_auto_sel:"System (Selenized)",sy_display:"Display",sy_theme:"Theme",sy_display_note:"Stored in this browser only.",th_light:"Light",th_dark:"Dark",
|
th_auto:"System",th_auto_sel:"System (Selenized)",sy_display:"Display",sy_theme:"Theme",sy_display_note:"Stored in this browser only.",th_light:"Light",th_dark:"Dark",
|
||||||
@@ -40,6 +40,7 @@ stp_en_q:"Enable spanning tree?",
|
|||||||
stp_en_d:"Ports start blocked and take up to twice the forward delay to reach forwarding; edge ports recover immediately.",
|
stp_en_d:"Ports start blocked and take up to twice the forward delay to reach forwarding; edge ports recover immediately.",
|
||||||
stp_dis_q:"Disable spanning tree?",stp_dis_d:"All ports go straight to forwarding; loop protection is lost.",
|
stp_dis_q:"Disable spanning tree?",stp_dis_d:"All ports go straight to forwarding; loop protection is lost.",
|
||||||
stp_cost_err:"Path cost must be 0-200000000",
|
stp_cost_err:"Path cost must be 0-200000000",
|
||||||
|
lldp_enabled: "LLDP Enabled",lldp_title:"Service Status",lldp_portname:"Name",lldp_enable:"Send Frames",
|
||||||
st_title:"Port statistics",st_h:"totals since boot",st_txg:"TX good",st_txb:"TX bad",st_rxg:"RX good",
|
st_title:"Port statistics",st_h:"totals since boot",st_txg:"TX good",st_txb:"TX bad",st_rxg:"RX good",
|
||||||
st_rxb:"RX bad",st_details:"Details",st_counters:"MIB counters",st_nonzero:"non-zero only",
|
st_rxb:"RX bad",st_details:"Details",st_counters:"MIB counters",st_nonzero:"non-zero only",
|
||||||
st_autoref:"auto-refresh",st_counter:"Counter",st_value:"Value",st_fail:"failed to load counters",
|
st_autoref:"auto-refresh",st_counter:"Counter",st_value:"Value",st_fail:"failed to load counters",
|
||||||
@@ -788,6 +789,7 @@ var CONF_CMDS=[
|
|||||||
/^ingress(\s+\d{1,2}[tua])+$/,/^ingress\s+[tua]$/,
|
/^ingress(\s+\d{1,2}[tua])+$/,/^ingress\s+[tua]$/,
|
||||||
/^port\s+\d{1,2}\s+(10m|100m|1g|2g5|5g|10g|auto|on|off)(\s+(half|full))?$/,
|
/^port\s+\d{1,2}\s+(10m|100m|1g|2g5|5g|10g|auto|on|off)(\s+(half|full))?$/,
|
||||||
/^port\s+\d{1,2}\s+name\s+\S+$/,
|
/^port\s+\d{1,2}\s+name\s+\S+$/,
|
||||||
|
/^port\s+\d{1,2}\s+lldp\s+(permit|block)+$/,
|
||||||
/^eee\s+(on|off)(\s+\d{1,2})?(\s+(100m|1g|2g5))?$/,
|
/^eee\s+(on|off)(\s+\d{1,2})?(\s+(100m|1g|2g5))?$/,
|
||||||
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,/^mirror\s+off$/,
|
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,/^mirror\s+off$/,
|
||||||
/^lag\s+[1-4](\s+\d{1,2})+$/,/^lag\s+[1-4]\s+d$/,/^laghash\s+[1-4](\s+\w+)+$/,
|
/^lag\s+[1-4](\s+\d{1,2})+$/,/^lag\s+[1-4]\s+d$/,/^laghash\s+[1-4](\s+\w+)+$/,
|
||||||
@@ -798,7 +800,7 @@ var CONF_CMDS=[
|
|||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+cost\s+\d{1,9}$/,/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+prio\s+\d{1,3}$/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+cost\s+\d{1,9}$/,/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+prio\s+\d{1,3}$/,
|
||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+guard\s+(none|bpdu|root)$/,/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+filter\s+(on|off)$/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+guard\s+(none|bpdu|root)$/,/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+filter\s+(on|off)$/,
|
||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+p2p\s+(auto|on|off)$/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+p2p\s+(auto|on|off)$/,
|
||||||
/^igmp\s+(on|off)$/,/^mtu\s+\d{1,2}\s+\d+$/,
|
/^igmp\s+(on|off)$/,/^mtu\s+\d{1,2}\s+\d+$/,/^lldp\s+(on|off)$/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
||||||
/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\s+(off|\d{1,8}\s+(pps|kbps))$/,
|
/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\s+(off|\d{1,8}\s+(pps|kbps))$/,
|
||||||
];
|
];
|
||||||
@@ -860,6 +862,7 @@ var TABS=[
|
|||||||
{id:"mirror",icon:"M12 3v18M7 8l-4 4 4 4M17 8l4 4-4 4"},
|
{id:"mirror",icon:"M12 3v18M7 8l-4 4 4 4M17 8l4 4-4 4"},
|
||||||
{id:"isolate",icon:"M4 4h6v6H4zM14 14h6v6h-6zM14 4h6v6h-6zM4 14h6v6H4z"},
|
{id:"isolate",icon:"M4 4h6v6H4zM14 14h6v6h-6zM14 4h6v6h-6zM4 14h6v6H4z"},
|
||||||
{id:"lag", icon:"M7 8a4 4 0 100 8h3M17 8a4 4 0 110 8h-3M9 12h6"},
|
{id:"lag", icon:"M7 8a4 4 0 100 8h3M17 8a4 4 0 110 8h-3M9 12h6"},
|
||||||
|
{id:"lldp", icon:"M11 12a1 1 0 002 0 1 1 0 00-2 0M8.5 8.5a5 5 0 000 7M15.5 8.5a5 5 0 010 7M5.6 5.6a9 9 0 000 12.8M18.4 5.6a9 9 0 010 12.8"},
|
||||||
{id:"eee", icon:"M13 2L4 14h6l-1 8 9-12h-6z"},
|
{id:"eee", icon:"M13 2L4 14h6l-1 8 9-12h-6z"},
|
||||||
{id:"bw", icon:"M4 18a8 8 0 0116 0M12 18l4-6"},
|
{id:"bw", icon:"M4 18a8 8 0 0116 0M12 18l4-6"},
|
||||||
{id:"system",icon:"M12 8a4 4 0 100 8 4 4 0 000-8zM4 12h2M18 12h2M12 4v2M12 18v2M6 6l1.5 1.5M16.5 16.5L18 18M18 6l-1.5 1.5M7.5 16.5L6 18"},
|
{id:"system",icon:"M12 8a4 4 0 100 8 4 4 0 000-8zM4 12h2M18 12h2M12 4v2M12 18v2M6 6l1.5 1.5M16.5 16.5L18 18M18 6l-1.5 1.5M7.5 16.5L6 18"},
|
||||||
@@ -1835,6 +1838,32 @@ function lagApply(g){
|
|||||||
}
|
}
|
||||||
tabHooks.lag={enter:function(){needPorts(function(){buildLag();lagLoad().catch(function(){})})}};
|
tabHooks.lag={enter:function(){needPorts(function(){buildLag();lagLoad().catch(function(){})})}};
|
||||||
|
|
||||||
|
|
||||||
|
function lldpLoad(){
|
||||||
|
return getJSON("/lldp.json").then(function(s){
|
||||||
|
$("lldp_en").checked=s.on;
|
||||||
|
var tb=$("lldp_table").tBodies[0];tb.innerHTML="";
|
||||||
|
byPort(s.portStatus).forEach(function(p){
|
||||||
|
var tr=tb.insertRow();
|
||||||
|
tr.insertCell().textContent=p.portNum;
|
||||||
|
tr.insertCell().textContent=p.name;
|
||||||
|
var sw=h("label",{class:"switch"},[
|
||||||
|
h("input",{type:"checkbox",onchange:function(){
|
||||||
|
postCmd("port "+p.portNum+" lldp "+(this.checked?"permit":"block"))
|
||||||
|
.then(function(){setTimeout(lldpLoad,300)}).catch(function(){});
|
||||||
|
}}),h("i")]);
|
||||||
|
sw.firstChild.checked=p.permitted;
|
||||||
|
tr.insertCell().appendChild(sw);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("lldp_en").addEventListener("change",function(){
|
||||||
|
var el=this;
|
||||||
|
postCmd("lldp "+(el.checked?"on":"off")).catch(function(){el.checked=!el.checked});
|
||||||
|
});
|
||||||
|
tabHooks.lldp={enter:lldpLoad};
|
||||||
|
|
||||||
function eeeFlags(bits){
|
function eeeFlags(bits){
|
||||||
var b=parseInt(bits,2);
|
var b=parseInt(bits,2);
|
||||||
return["100M","1G","2.5G"].map(function(s,i){
|
return["100M","1G","2.5G"].map(function(s,i){
|
||||||
|
|||||||
@@ -331,6 +331,17 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="tab" id="tab-lldp">
|
||||||
|
<div class="card"><h2 data-i18n="lldp_title">LLDP</h2>
|
||||||
|
<label class="row"><span class="lb" data-i18n="lldp_enabled">Enabled</span>
|
||||||
|
<span class="switch"><input type="checkbox" id="lldp_en"><i></i></span>
|
||||||
|
</label>
|
||||||
|
<div class="scrollx"><table class="t" id="lldp_table">
|
||||||
|
<thead><tr><th data-i18n="c_port">Port Number</th><th data-i18n="lldp_portname">Name</th><th data-i18n="lldp_enable">Send Frames</th></tr></thead>
|
||||||
|
<tbody></tbody></table></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="tab" id="tab-isolate">
|
<section class="tab" id="tab-isolate">
|
||||||
<div class="card"><h2 data-i18n="iso_title">Port isolation</h2>
|
<div class="card"><h2 data-i18n="iso_title">Port isolation</h2>
|
||||||
<p class="small mut" style="margin-bottom:10px" data-i18n="iso_intro">A frame entering a port may only leave through the ports ticked in its row.</p>
|
<p class="small mut" style="margin-bottom:10px" data-i18n="iso_intro">A frame entering a port may only leave through the ports ticked in its row.</p>
|
||||||
|
|||||||
@@ -1034,6 +1034,8 @@ void httpd_appcall(void)
|
|||||||
send_lag();
|
send_lag();
|
||||||
} else if (is_word(q, "/stp.json")) {
|
} else if (is_word(q, "/stp.json")) {
|
||||||
send_stp();
|
send_stp();
|
||||||
|
} else if (is_word(q, "/lldp.json")) {
|
||||||
|
send_lldp();
|
||||||
} else if (is_word(q, "/vlanlist")) {
|
} else if (is_word(q, "/vlanlist")) {
|
||||||
send_vlanlist();
|
send_vlanlist();
|
||||||
} else if (is_word(q, "/config")) {
|
} else if (is_word(q, "/config")) {
|
||||||
|
|||||||
+32
-1
@@ -49,6 +49,9 @@ extern __xdata char sfp_module_model[2][17];
|
|||||||
extern __xdata char sfp_module_serial[2][17];
|
extern __xdata char sfp_module_serial[2][17];
|
||||||
extern __xdata uint8_t sfp_options[2];
|
extern __xdata uint8_t sfp_options[2];
|
||||||
|
|
||||||
|
extern __xdata uint16_t lldp_logical_port_status;
|
||||||
|
extern __xdata bool lldp_enabled;
|
||||||
|
|
||||||
__code const uint8_t * __code const HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
|
__code const uint8_t * __code const HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
|
||||||
__code const uint8_t * __code const HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
|
__code const uint8_t * __code const HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
|
||||||
|
|
||||||
@@ -619,7 +622,6 @@ static void bridge_to_html(void)
|
|||||||
byte_to_html(pi_mac[i]);
|
byte_to_html(pi_mac[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_stp(void)
|
void send_stp(void)
|
||||||
{
|
{
|
||||||
uint8_t i, j, st, dsg;
|
uint8_t i, j, st, dsg;
|
||||||
@@ -734,8 +736,37 @@ void send_stp(void)
|
|||||||
slen += strtox(outbuf + slen, "]}");
|
slen += strtox(outbuf + slen, "]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_lldp(void)
|
||||||
|
{
|
||||||
|
dbg_string("send_lldp called\n");
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, "{\"on\":");
|
||||||
|
bool_to_html(lldp_enabled);
|
||||||
|
slen += strtox(outbuf + slen, ",\"portStatus\":[");
|
||||||
|
|
||||||
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, ",\"logPort\":");
|
||||||
|
itoa_html(i);
|
||||||
|
slen += strtox(outbuf + slen, ",\"name\":\"");
|
||||||
|
for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) {
|
||||||
|
json_char_to_html(port_names[i][j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, "\",\"permitted\":");
|
||||||
|
bool_to_html(1 & (lldp_logical_port_status >> i));
|
||||||
|
slen += strtox(outbuf + slen, "}");
|
||||||
|
|
||||||
|
if (i < machine.max_port)
|
||||||
|
char_to_html(',');
|
||||||
|
else
|
||||||
|
char_to_html(']');
|
||||||
|
}
|
||||||
|
char_to_html('}');
|
||||||
|
}
|
||||||
|
|
||||||
void send_eee(void)
|
void send_eee(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ void send_config(void);
|
|||||||
void send_cmd_log(void);
|
void send_cmd_log(void);
|
||||||
void send_lag(void);
|
void send_lag(void);
|
||||||
void send_stp(void);
|
void send_stp(void);
|
||||||
|
void send_lldp(void);
|
||||||
void send_vlanlist(void);
|
void send_vlanlist(void);
|
||||||
|
|
||||||
/* Convert only the lower nibble to ascii HEX char.
|
/* Convert only the lower nibble to ascii HEX char.
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ struct flash_region_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
||||||
|
extern __xdata uint16_t lldp_logical_port_status;
|
||||||
|
|
||||||
extern __xdata bool stp_enabled;
|
extern __xdata bool stp_enabled;
|
||||||
|
|
||||||
|
|||||||
+161
@@ -0,0 +1,161 @@
|
|||||||
|
#pragma codeseg BANK3
|
||||||
|
#pragma constseg BANK3
|
||||||
|
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_lldp.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "dhcp.h"
|
||||||
|
#include "uip.h"
|
||||||
|
#include "uip/uip.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
extern __xdata bool lldp_enabled;
|
||||||
|
extern __code const struct machine machine;
|
||||||
|
|
||||||
|
__xdata uint16_t lldp_ticks;
|
||||||
|
__xdata uint16_t lldp_logical_port_status = 0xffff;
|
||||||
|
|
||||||
|
void lldp_init(void) __banked
|
||||||
|
{
|
||||||
|
lldp_ticks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lldp_tick(void) __banked
|
||||||
|
{
|
||||||
|
lldp_ticks++;
|
||||||
|
|
||||||
|
if (lldp_ticks < LLDP_TX_INTERVAL_TICKS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lldp_ticks = 0;
|
||||||
|
|
||||||
|
if(lldp_enabled == 1)
|
||||||
|
lldp_send();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Outgoing LLDP packet.
|
||||||
|
|
||||||
|
struct lldp_pkt {
|
||||||
|
struct uip_eth_addr dst;
|
||||||
|
struct uip_eth_addr src;
|
||||||
|
struct rtl_tag rtl_tag;
|
||||||
|
uint16_t ether_type;
|
||||||
|
|
||||||
|
uint8_t payload[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LLDP_O ((__xdata struct lldp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
||||||
|
|
||||||
|
// The type is 7 bits and the length is 9 bits
|
||||||
|
// we can represent this as the 7 most significant
|
||||||
|
// bits of the type bit and leave the least significant
|
||||||
|
// bit as 0 always as we're not going to need 2^9 for
|
||||||
|
// the length at any point
|
||||||
|
#define LLDP_TYPE(value) (value << 1)
|
||||||
|
|
||||||
|
void lldp_send(void) __banked __reentrant
|
||||||
|
{
|
||||||
|
__xdata uint8_t *p;
|
||||||
|
uint8_t port_position;
|
||||||
|
|
||||||
|
lldp_set_addresses();
|
||||||
|
lldp_set_rtl_wrapper();
|
||||||
|
|
||||||
|
p = LLDP_O->payload;
|
||||||
|
|
||||||
|
//Chassis ID
|
||||||
|
*p++ = LLDP_TYPE(LLDP_CHASSIS_ID_TLV_TYPE);
|
||||||
|
*p++ = LLDP_CHASSIS_ID_TLV_LENGTH;
|
||||||
|
*p++ = LLDP_CHASSIS_ID_TLV_SUBTYPE;
|
||||||
|
|
||||||
|
memcpy(p, uip_ethaddr.addr, MAC_ADDR_LEN);
|
||||||
|
p += MAC_ADDR_LEN;
|
||||||
|
|
||||||
|
//Port ID
|
||||||
|
*p++ = LLDP_TYPE(LLDP_PORT_ID_TLV_TYPE);
|
||||||
|
*p++ = LLDP_PORT_ID_TLV_LENGTH;
|
||||||
|
*p++ = LLDP_PORT_ID_TLV_SUBTYPE;
|
||||||
|
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 += lldp_sysname(p);
|
||||||
|
p += lldp_sysdesc(p);
|
||||||
|
|
||||||
|
// End of LLDPDU TLV
|
||||||
|
*p++ = 0x00; //padding
|
||||||
|
*p++ = 0x00; //padding
|
||||||
|
|
||||||
|
while (p < (LLDP_O->payload + LLDP_MIN_ETHERNET_PAYLOAD_LENGTH))
|
||||||
|
*p++ = 0x00;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uip_len is the Ethernet frame length excluding FCS.
|
||||||
|
*
|
||||||
|
* The frame consists of:
|
||||||
|
*
|
||||||
|
* dst mac
|
||||||
|
* src mac
|
||||||
|
* rtl_tag sizeof(struct rtl_tag)
|
||||||
|
* EtherType (2 bytes)
|
||||||
|
* payload (how far we've moved p pointer)
|
||||||
|
*/
|
||||||
|
uip_len = MAC_ADDR_LEN + MAC_ADDR_LEN + sizeof(struct rtl_tag) + LLDP_ETHERTYPE_LENGTH + (p - LLDP_O->payload);
|
||||||
|
|
||||||
|
for (uint8_t port = machine.min_port; port <= machine.max_port; port++) {
|
||||||
|
|
||||||
|
if ((1 << port) & lldp_logical_port_status) {
|
||||||
|
LLDP_O->payload[port_position] = '0' + machine.log_to_phys_port[port];
|
||||||
|
LLDP_O->rtl_tag.pmask = HTONS((uint16_t)1 << port);
|
||||||
|
|
||||||
|
tcpip_output();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
memcpy(LLDP_O->src.addr, uip_ethaddr.addr, MAC_ADDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lldp_set_rtl_wrapper(void) __banked {
|
||||||
|
/*
|
||||||
|
* This is the RTL CPU tag, not the Ethernet EtherType.
|
||||||
|
* port 0 -> 0x0001
|
||||||
|
* port 1 -> 0x0002
|
||||||
|
* port 2 -> 0x0004
|
||||||
|
*/
|
||||||
|
LLDP_O->rtl_tag.tag = HTONS(RTL_FRAME_TAG_ID);
|
||||||
|
LLDP_O->rtl_tag.version = RTL_FRAME_TAG_VERSION;
|
||||||
|
LLDP_O->rtl_tag.reason = 0x00;
|
||||||
|
LLDP_O->rtl_tag.flags = HTONS(RTL_TAG_LEARN_DIS);
|
||||||
|
|
||||||
|
LLDP_O->ether_type = HTONS(LLDP_ETHERTYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lldp_sysname(__xdata uint8_t *p) __banked
|
||||||
|
{
|
||||||
|
uint8_t hostname_length = strlen_x(hostname);
|
||||||
|
|
||||||
|
*p++ = LLDP_TYPE(LLDP_SYSNAME_TLV_TYPE);
|
||||||
|
*p++ = hostname_length;
|
||||||
|
memcpy(p, hostname, hostname_length);
|
||||||
|
return hostname_length + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lldp_sysdesc(__xdata uint8_t *p) __banked
|
||||||
|
{
|
||||||
|
uint16_t machine_name_length = strlen(machine.machine_name);
|
||||||
|
|
||||||
|
*p++ = LLDP_TYPE(LLDP_SYSDESC_TLV_TYPE);
|
||||||
|
*p++ = machine_name_length;
|
||||||
|
memcpyc(p, machine.machine_name, machine_name_length);
|
||||||
|
return machine_name_length + 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _LLDP_H_
|
||||||
|
#define _LLDP_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LLDP_MIN_ETHERNET_PAYLOAD_LENGTH 46
|
||||||
|
#define LLDP_ETHERTYPE 0x88cc
|
||||||
|
#define LLDP_ETHERTYPE_LENGTH 2
|
||||||
|
#define LLDP_MAX_FRAME 256
|
||||||
|
#define MAC_ADDR_LEN 6
|
||||||
|
#define LLDP_TX_INTERVAL_TICKS 6000
|
||||||
|
|
||||||
|
#define LLDP_PORT_ID_TLV_TYPE 2
|
||||||
|
#define LLDP_PORT_ID_TLV_LENGTH 0x02
|
||||||
|
#define LLDP_PORT_ID_TLV_SUBTYPE 0x07
|
||||||
|
|
||||||
|
#define LLDP_TTL_TLV_TYPE 3
|
||||||
|
#define LLDP_TTL_TLV_LENGTH 2
|
||||||
|
#define LLDP_TTL_TTL_SECONDS 120
|
||||||
|
|
||||||
|
#define LLDP_CHASSIS_ID_TLV_TYPE 1
|
||||||
|
#define LLDP_CHASSIS_ID_TLV_LENGTH 7
|
||||||
|
#define LLDP_CHASSIS_ID_TLV_SUBTYPE 4
|
||||||
|
|
||||||
|
#define LLDP_SYSNAME_TLV_TYPE 5
|
||||||
|
#define LLDP_SYSDESC_TLV_TYPE 6
|
||||||
|
|
||||||
|
void lldp_init(void) __banked;
|
||||||
|
void lldp_tick(void) __banked;
|
||||||
|
void lldp_send(void) __banked;
|
||||||
|
void lldp_set_addresses(void) __banked;
|
||||||
|
void lldp_set_rtl_wrapper(void) __banked;
|
||||||
|
uint8_t lldp_sysname(__xdata uint8_t *p) __banked;
|
||||||
|
uint8_t lldp_sysdesc(__xdata uint8_t *p) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "rtl837x_leds.h"
|
#include "rtl837x_leds.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
#include "rtl837x_init.h"
|
#include "rtl837x_init.h"
|
||||||
|
#include "rtl837x_lldp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "cmd_editor.h"
|
#include "cmd_editor.h"
|
||||||
@@ -127,6 +128,7 @@ __xdata uint8_t tx_seq;
|
|||||||
|
|
||||||
__xdata bool stp_enabled;
|
__xdata bool stp_enabled;
|
||||||
__xdata uint8_t igmpEnabled;
|
__xdata uint8_t igmpEnabled;
|
||||||
|
__xdata bool lldp_enabled;
|
||||||
__xdata char hostname[24]; /* device hostname, default set at boot, see rtl837x_common.h */
|
__xdata char hostname[24]; /* device hostname, default set at boot, see rtl837x_common.h */
|
||||||
|
|
||||||
__code const uint16_t bit_mask[16] = {
|
__code const uint16_t bit_mask[16] = {
|
||||||
@@ -1286,6 +1288,8 @@ static void handle_tick(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
health_phase(HEALTH_PH_STP);
|
health_phase(HEALTH_PH_STP);
|
||||||
|
lldp_tick();
|
||||||
|
health_phase(HEALTH_LLDP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1792,6 +1796,7 @@ void main(void)
|
|||||||
uip_init();
|
uip_init();
|
||||||
uip_arp_init();
|
uip_arp_init();
|
||||||
httpd_init();
|
httpd_init();
|
||||||
|
lldp_init();
|
||||||
|
|
||||||
management_vlan = 1; // Default management VLAN is 1
|
management_vlan = 1; // Default management VLAN is 1
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ char port_names[9][PORT_NAME_SIZE];
|
|||||||
struct flash_region_t flash_region;
|
struct flash_region_t flash_region;
|
||||||
struct syslog_state syslog_state;
|
struct syslog_state syslog_state;
|
||||||
bool stp_enabled;
|
bool stp_enabled;
|
||||||
|
bool lldp_enabled;
|
||||||
|
uint16_t lldp_logical_port_status;
|
||||||
|
|
||||||
|
|
||||||
uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
||||||
struct uip_eth_addr uip_ethaddr = { .addr = { 0x02, 0x11, 0x22, 0x33, 0x44, 0x55 } };
|
struct uip_eth_addr uip_ethaddr = { .addr = { 0x02, 0x11, 0x22, 0x33, 0x44, 0x55 } };
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ void send_lag(void) { }
|
|||||||
void send_stp(void) { }
|
void send_stp(void) { }
|
||||||
void send_stp_counters(void) { }
|
void send_stp_counters(void) { }
|
||||||
void send_vlanlist(void) { }
|
void send_vlanlist(void) { }
|
||||||
|
void send_lldp(void) {}
|
||||||
|
|
||||||
extern uint8_t authenticated;
|
extern uint8_t authenticated;
|
||||||
|
|
||||||
|
|||||||
+36
-2
@@ -447,13 +447,41 @@ void send_mtu(int s)
|
|||||||
json_object_object_add(v, "mtu", json_object_new_string(mtu));
|
json_object_object_add(v, "mtu", json_object_new_string(mtu));
|
||||||
json_object_array_add(mtus, v);
|
json_object_array_add(mtus, v);
|
||||||
}
|
}
|
||||||
write(s, header, strlen(header));
|
write(s, header, strlen(header));
|
||||||
|
|
||||||
jstring = json_object_to_json_string_ext(mtus, JSON_C_TO_STRING_PLAIN);
|
jstring = json_object_to_json_string_ext(mtus, JSON_C_TO_STRING_PLAIN);
|
||||||
write(s, jstring, strlen(jstring));
|
write(s, jstring, strlen(jstring));
|
||||||
json_object_put(mtus);
|
json_object_put(mtus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_lldp(int s)
|
||||||
|
{
|
||||||
|
struct json_object *c, *portStatuses, *p;
|
||||||
|
const char *jstring;
|
||||||
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: application/json; charset=UTF-8\r\n\r\n";
|
||||||
|
|
||||||
|
c = json_object_new_object();
|
||||||
|
json_object_object_add(c, "on", json_object_new_int(1));
|
||||||
|
portStatuses = json_object_new_array_ext(PORTS);
|
||||||
|
|
||||||
|
for (int i = 1; i <= PORTS; i++) {
|
||||||
|
p = json_object_new_object();
|
||||||
|
json_object_object_add(p, "portNum", json_object_new_int(i));
|
||||||
|
json_object_object_add(p, "logPort", json_object_new_int(i-1));
|
||||||
|
json_object_object_add(p, "name", json_object_new_string(""));
|
||||||
|
json_object_object_add(p, "permitted", json_object_new_int(1));
|
||||||
|
json_object_array_add(portStatuses, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_add(c, "portStatus", portStatuses);
|
||||||
|
|
||||||
|
write(s, header, strlen(header));
|
||||||
|
|
||||||
|
jstring = json_object_to_json_string_ext(c, JSON_C_TO_STRING_PLAIN);
|
||||||
|
write(s, jstring, strlen(jstring));
|
||||||
|
json_object_put(c);
|
||||||
|
}
|
||||||
|
|
||||||
void send_cmd_log(int s)
|
void send_cmd_log(int s)
|
||||||
{
|
{
|
||||||
@@ -468,7 +496,6 @@ void send_cmd_log(int s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_config(int s)
|
void send_config(int s)
|
||||||
{
|
{
|
||||||
char *header = "HTTP/1.1 200 OK\r\n"
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
@@ -701,6 +728,13 @@ void launch(struct Server *server)
|
|||||||
else
|
else
|
||||||
send_vlan(new_socket, vlan);
|
send_vlan(new_socket, vlan);
|
||||||
goto done;
|
goto done;
|
||||||
|
} else if (!strncmp(&buffer[4], "/lldp.json", 10)) {
|
||||||
|
printf("LLDP request");
|
||||||
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_lldp(new_socket);
|
||||||
|
goto done;
|
||||||
} else if (!strncmp(&buffer[4], "/cmd_log", 8)) {
|
} else if (!strncmp(&buffer[4], "/cmd_log", 8)) {
|
||||||
printf("Request cmd_log\n");
|
printf("Request cmd_log\n");
|
||||||
if (!authenticated)
|
if (!authenticated)
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE 131072
|
#define BUFFER_SIZE 262144
|
||||||
|
|
||||||
struct Server {
|
struct Server {
|
||||||
int domain;
|
int domain;
|
||||||
|
|||||||
Reference in new issue
Block a user