xref: /openbmc/google-misc/acpi-power-state-daemon/subprojects/ncsid/doc/ncsid_internals.md (revision 7d6fa42fd19cf708de1257414bb375d5a552b722)
1*# NC-SId Internals
2*
3*__NOTE__: This documents describes the internal architecture of NC-SId daemon.
4*However, it is meant to be used as a guide for understanding the code, not on
5*its own. Some details are intentionally omitted.
6*
7*![Internals Diagram](ncsid_arch.png)
8*
9*In the diagram above the components are split into four groups:
10*
11** __NC-SId Core__. These are new components implemented in NC-SId.
12*
13** __Hardware__. External hardware components, in this case, the NIC.
14*
15** __EC__. This is the code borrowed from EC. The three state machines are
16*  pretty much copied from EC code.
17*
18** __External Components__. These are external services/daemons NC-SIs interacts
19*  with.
20*
21*Let's look into their details.
22*
23*## NIC
24*
25*In the NIC — NC-SId interactions, NIC acts as a server, replying to NC-SId
26*requests and NC-SId itself acts as a client, sending those requests.  Thus,
27*there is no state in NIC (server), but there is a state in NC-SId (client).
28*
29*## EC State Machines
30*
31*NC-SId reuses the state machines from EC. They are treated like black boxes.
32*They are C functions with simple interface: the state machine is given incoming
33*NC-SI command buffer (reply from the NIC) and returns the buffer that needs to
34*be sent to the NIC (the next command).
35*
36*### L2 FSM
37*
38*This state machine performs basic configuration of the NC-SI comm channel and
39*also reads the MAC Address of the NIC.
40*
41*### L3/4 FSM
42*
43*Once BMC's network is configured, this state machine sets up filters in the NIC.
44*
45*### Test FSM
46*
47*This state machine periodically tests NC-SI connection with the NIC, verifies
48*filters and queries the NIC state (hostless or host-based). If it ever fails,
49*all state machines restart, which means that NC-SI in the NIC is also reset and
50*reconfigured.
51*
52*---
53*
54*In addition to the buffer there are parameters that provide information which is
55*not a part of EC state machines' state:
56*
57** State Parameters. These structures are allocated outside of EC State Machines,
58*  but their content is fully managed by EC State Machines.
59** MAC Address. For L2 FSM this parameter is _OUT_.
60** IP Address (only for L3/4 FSM and Test FSM) for setting up and verifying
61*  filteres. If set to zero, the NIC filter won't check for IP address.
62** TCP Port (only for L3/4 FSM and Test FSM) for setting up and verifying
63*  filters.
64*
65*In the initial state the command buffer (reply from the NIC) is empty. When
66*there is nothing more to send to the NIC, i.e. that particular state machine is
67*done, it returns empty buffer.
68*
69*## External Components
70*
71*NC-SId uses `phosphord-networkd` to configure the BMC's network (MAC Address).
72*In turn, `phosphord-networkd` uses `systemd`. Their interactions go through
73*`DBus`.
74*
75*## NC-SId Core
76*
77*### ncsi::StateMachine
78*
79*This component coordinates the interaction between EC State Machines and is also
80*heavily based on EC code. It uses `net::SockIO` interface to interact with the
81*NIC and `net::ConfigBase` interface to set/query MAC Address.
82*
83*### net::PhosphorConfig
84*
85*Implements `net::ConfigBase` and makes calls to `phosphord-networkd` via `DBus`
86*to get/set MAC Address.
87*
88*### ncsi::SockIO
89*
90*Implements `net::SockIO` and sends NC-SI commands to the NIC through raw Unix
91*socket. That socket is configured using `net::IFace` component, which represents
92*the network interface (think ethX). To simplify testing, the abstract
93*`net::IFaceBase` interface is introduced.
94*
95*---
96*
97*## Unit Testing
98*
99*![Test infrastructure](ncsid_test_arch.png)
100*
101*To allow some fairly sophisticated unit-tests, EC State Machines as well as
102*`ncsi::StateMachine` component only interact with the outside world using
103*`net::SockIO` and `net::ConfigBase` interfaces. This makes it easy to mock them.
104*
105*The most complicated part of these tests is `mock::NIC`, which acts as a NC-SI
106*server, replying to NC-SI requests coming from NC-SI State Machines.
107*