The port and group of lacp_in(), the member mask passed to
lacp_lag_set() and the compiler temporaries both functions spilled took
six bytes of DSEG, and with them six bytes of stack. The locals and the
mask live in xdata now, the partner fields go through the scratch word,
and lacp_lag_set() records the new group of a port before it releases
the old one. One byte is left: the group number passed in.
lacp_in() always leaves uip_len at 0, so the tcpip_output() after it
never ran. The LAG page names the active members by front-panel port
instead of a logical mask. The partner key is not part of selection;
say so under Known limits.
Listing by next-address also returned the reserved-multicast entries STP
writes, shown as port 1 with a delete button, while l2_delete() still
looks up by next-unicast and so removed the unicast entry after that
index instead. The change was there to show the LACP steering entries;
delivery by trap writes none, so it goes.
Both paths wrote the trunk registers directly and left the protocol
running on the group, so "lag show" said disabled while the partner kept
both links in one aggregate, and re-sending the LACP line did not repair
it because the same-ports shortcut returns early. Each path now releases
the group from LACP first; for a group that never ran LACP that is a
no-op.
The receive machine armed current_while from the partner's TIMEOUT bit,
so against a partner on the slow rate a port whose LACPDUs stopped with
the link still up stayed in the trunk for the long timeout, two minutes.
802.3ad 43.4.12 starts the timer from the actor's own LACP_Timeout, and
we always advertise the short one: the partner sends every second and is
let go after the short timeout.
Sandbox T23 plays a slow-rate partner that goes quiet and fails on the
code before this.
Dynamic link aggregation on top of the static LAGG, for RTL8372/8373:
receive, selection and mux state machines (coupled mux, one aggregator
per group), with "lacp show" to look inside. Each of the four trunk
groups runs its own aggregator on the candidate ports assigned with
"lag <n> lacp <ports>"; the engine starts with the first such group and
stops with the last.
LACPDUs reach the CPU through the reserved-multicast trap, so delivery
needs no L2 entry and nothing written per VLAN or per PVID. The trap
acts on the address before the VLAN lookup and before the ingress
filters, so a LACPDU also arrives on a port that admits tagged frames
only and on a port STP holds in blocking, neither of which a forwarded
one reaches. A trapped frame carries no VLAN tag,
so lacp_in() takes the offset of the PDU body from TRAP_RX_BODY(). The
action is set with trap_rma_set(), which leaves the flags sharing that
register alone, and "lacp off" puts the slow-protocols drop default
back. doc/lacp.md and doc/link_aggregation.md record what was measured,
including why the trap looked like a dead end at first.
The web UI gets a Static/LACP mode per group on the LAG page with live
status, and the startup-config validator knows the per-group syntax. A
host-side sandbox for the state machines runs in the test harness
together with the LAG hash check. It drives both forms of an incoming
LACPDU, so the body offset of a trapped one is covered as well.
The L2 table page iterated with the "next unicast" read method, so
static multicast entries such as an IGMP group were invisible. It now
iterates with "next address", skips L3 entries (their layout carries IP
addresses where a MAC is expected), and reports the lowest member of a
multicast entry's port mask, so such an entry shows up as a static
entry on that port.
A port taken out of LACP forgets its partner, so "lacp show" after
"lacp off" no longer reports one. Applying the same candidate set to a
group again, as the LAG page does on every Apply, leaves the trunk
alone instead of tearing it down for a second or two. lacp_in() checks
the frame length and ethertype before reading a LACPDU, so a runt or a
foreign frame on the slow-protocols address cannot leave stale buffer
bytes as a partner. The sandbox covers these three in T20-T22. On the
LAG page, LACP mode with no ports checked sends "lag N lacp off", and
the startup-config validator wants at least one port after "lacp".
A reserved-multicast trap goes to the port named in EXT_CPU_CTRL, which
names no port out of reset, so trapped frames were dropped at ingress.
trap_init() points it at the CPU port once at startup, and
trap_rma_set() changes only the action field of an RMA register.
A trapped frame arrives without the VLAN tag a forwarded one gets, so
TRAP_RX_BODY() gives the offset of the payload for both forms.
STP now traps its address while it runs instead of steering it with a
static L2 entry per VLAN, so turning it on no longer walks the VLAN
table and a pvid change no longer needs stp off and on. With STP off
the flooding entries are restored as before.
A trapped BPDU passes the tagged-only ingress filter that drops a
forwarded one, so the stp_setup() warning about such ports goes.
Opcode 0x48 outputs 8 dummy clocks between the address and the first data
byte. flash_configure_sio() sets DUMMYCYCLES to 0 and flash_read_security()
never raises it, so the controller captures the dummy slot as the first of
its four data bytes while the address still advances by four. The printed
output therefore shows 0xff in place of every fourth byte and skips one
content byte per transfer. flash_read_uid() already sets DUMMYCYCLES for
opcode 0x4b, which needs the same allowance.
The answer to a lookup arrives after the command has returned, so the
console of the web interface never shows it. Plain "dns" now prints the
name and the address, or whether it is still pending or failed.
Needed to increase buffer size for this to send app.js
The logical port status is what is returned in the array, for
non-sequential systems we need to map through physToLog rather
than just subtracting 1
physToLog is 1 based! not 0; also fixing up typecasts
Reimplementing using an array of objects to represent ports.
The previous approach of a bitmask of logical ports, was just too
simple on devices such as the SWGT024_V2_0_MANAGED which has
gaps in the port assignments.
timing with ticks
Fixing up the log_to_phys_port assignment
2000 is about every 10 seconds, so scaling up to once every 30ish
Removing the attempt to block lldp frames,
This does not work however the hard work has been done for us in
the #514 so we can borrow that work later on
boot_to_html outputs 1 and 0 not true and false, making the sim match
the real implementation.
lldp.json has a hanging , in the array; so overwriting it
Moving the global on/off onto the LLDP page
Building a table of LLDP status from the S ports. Later on, if
we wish to implement an lldp receiver we can display the remote
details here
Adding support to the cmd parser for the lldp commands
to each port once every 30 seconds.
* Additionally fixes the on-ward passing of LLDP frames through
the switch
The ports on the case are marked 1-8 so this should reflect that
rather than being 0-based
We can send the hostname as well, this can be dynamically allocated
Let's send the model as the system description as well