1# NC-SId Internals
2
3__NOTE__: This documents describes the internal architecture of NC-SId daemon.
4However, it is meant to be used as a guide for understanding the code, not on
5its own. Some details are intentionally omitted.
6
7![Internals Diagram](ncsid_arch.png)
8
9In 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
21Let's look into their details.
22
23## NIC
24
25In the NIC — NC-SId interactions, NIC acts as a server, replying to NC-SId
26requests and NC-SId itself acts as a client, sending those requests.  Thus,
27there is no state in NIC (server), but there is a state in NC-SId (client).
28
29## EC State Machines
30
31NC-SId reuses the state machines from EC. They are treated like black boxes.
32They are C functions with simple interface: the state machine is given incoming
33NC-SI command buffer (reply from the NIC) and returns the buffer that needs to
34be sent to the NIC (the next command).
35
36### L2 FSM
37
38This state machine performs basic configuration of the NC-SI comm channel and
39also reads the MAC Address of the NIC.
40
41### L3/4 FSM
42
43Once BMC's network is configured, this state machine sets up filters in the NIC.
44
45### Test FSM
46
47This state machine periodically tests NC-SI connection with the NIC, verifies
48filters and queries the NIC state (hostless or host-based). If it ever fails,
49all state machines restart, which means that NC-SI in the NIC is also reset and
50reconfigured.
51
52---
53
54In addition to the buffer there are parameters that provide information which is
55not 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
65In the initial state the command buffer (reply from the NIC) is empty. When
66there is nothing more to send to the NIC, i.e. that particular state machine is
67done, it returns empty buffer.
68
69## External Components
70
71NC-SId uses `phosphord-networkd` to configure the BMC's network (MAC Address).
72In turn, `phosphord-networkd` uses `systemd`. Their interactions go through
73`DBus`.
74
75## NC-SId Core
76
77### ncsi::StateMachine
78
79This component coordinates the interaction between EC State Machines and is also
80heavily based on EC code. It uses `net::SockIO` interface to interact with the
81NIC and `net::ConfigBase` interface to set/query MAC Address.
82
83### net::PhosphorConfig
84
85Implements `net::ConfigBase` and makes calls to `phosphord-networkd` via `DBus`
86to get/set MAC Address.
87
88### ncsi::SockIO
89
90Implements `net::SockIO` and sends NC-SI commands to the NIC through raw Unix
91socket. That socket is configured using `net::IFace` component, which represents
92the 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
101To 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
105The most complicated part of these tests is `mock::NIC`, which acts as a NC-SI
106server, replying to NC-SI requests coming from NC-SI State Machines.
107