The previous section described at a high level how the config_db.json file is loaded into the Redis CONFIG_DB database in the Database container. Next we look at the topic in slightly more detail. First, we examine how physical port information, such as the port's default speed and lane configuration, is processed during the initial boot before it is programmed into the switch ASIC.
Step 1: Creating a Config_db.json and Updating CONFIG_DB by Sonic-cogent
Figure
4-2 illustrates how platform-specific port information becomes the PORT and
BREAKOUT_CFG entries stored in the Redis CONFIG_DB database. During the image
initialization process, sonic-cfggen uses the platform-specific port_config.ini
file (1) together with other platform configuration files and templates to
generate the port-related entries in the config_db.json file (2). The
port_config.ini file defines the logical, expected physical characteristics of
the switch ports, including the front-panel alias names, lane mappings, index
values, subport values, and default port speeds. After the config_db.json file
has been generated, its contents are loaded into the Redis CONFIG_DB database
during the SONiC boot process (3).
Figure
4-2 also shows the DEVICE_METADATA table, which contains platform-specific
information such as the base MAC address, switch_type, buffer_model, and hwsku
(hardware stock keeping unit identifier). During the initial boot process, the
portmgrd daemon uses the selected HwSKU together with platform-specific
configuration information to validate the port configuration before publishing
it to the APPL_DB database. The validation verifies that parameters such as the
configured port speed, lane mapping, and breakout mode are supported by the
selected hardware platform.
Figure 4-2: Creating/Updating
a CONFIG_DB based on the Config_db.json.
A
SONiC distribution may support several hardware platforms. In our example, we
are using the SONiC Virtual Switch image. To locate the appropriate
port_config.ini file, we first need to determine the platform and HwSKU used by
the virtual switch. This information is displayed by the show platform
summary command, shown in Example 4-3. The output
identifies the platform as x86_64-kvm_x86_64-r0 and the HwSKU as Force10-S6000.
root@leaf-1:/# show platform
summary
/bin/sh: 1: sudo: not found
Platform:
x86_64-kvm_x86_64-r0
HwSKU:
Force10-S6000
ASIC: vs
ASIC Count: 1
Serial Number: N/A
Model Number: N/A
Hardware Revision: N/A
Switch Type: switch
Example 4-3:
Platform Summary.
Next, we verify that the corresponding port_config.ini
file exists by using the Linux command:
ls -l /usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000
The output in Example
4-4 lists the platform-specific files in specified directory. Besides port_config.ini,
the directory contains numerous other files used to describe platform-specific
settings such as buffer management, and QoS policies.
root@leaf-1:/# ls -l
/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000
total 92
drwxr-xr-x 2 root root 4096 Apr 24 14:34 BALANCED
drwxr-xr-x 2 root root 4096 Apr 24 14:34 RDMA-CENTRIC
drwxr-xr-x 2 root root 4096 Apr 24 14:34 TCP-CENTRIC
-rw-r--r-- 1 root root 221 Feb 20
2017 buffer_ports_t0.j2
-rw-r--r-- 1 root root 221 Feb 20
2017 buffer_ports_t1.j2
-rw-r--r-- 1 root root 66 Feb 20
2017 buffers.json.j2
-rw-r--r-- 1 root root 1069 Feb 20
2017 buffers_defaults_t0.j2
-rw-r--r-- 1 root root 1070 Feb 20
2017 buffers_defaults_t1.j2
-rw-r--r-- 1 root root 174 Feb 20
2017 fabriclanemap.ini
-rw-r--r-- 1 root root 799 Feb 20
2017 lanemap.ini
-rw-r--r-- 1 root root 223 Feb 20
2017 pai.profile
-rw-r--r-- 1 root root 812 Feb 20
2017 pg_profile_lookup.ini
-rw-r--r--
1 root root 3953 Feb 20 2017 port_config.ini
-rw-r--r-- 1 root root 775 Feb 20
2017 qos.json.j2
-rw-r--r-- 1 root root 302 Feb 20
2017 sai.profile
-rw-r--r-- 1 root root 728 Feb 20
2017 sai.profile.j2
-rw-r--r-- 1 root root 302 Feb 20
2017 sai_mlnx.profile
-rw-r--r-- 1 root root 10607 Feb
20 2017 th-s6100-64x40G-t0.config.bcm
-rw-r--r-- 1 root root 10607 Feb
20 2017 th-s6100-64x40G-t1.config.bcm
Example 4-4:
Files in Force10-S6100 directory.
We
can examine the contents of the port_config.ini file by using the command:
cat
/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/port_config.ini
Example
4-5 shows two interfaces, Ethernet0 and Ethernet4, with their lane mappings,
front-panel alias names, index values, and default speeds. Although Ethernet4
appears first in this excerpt, Ethernet0 has index value 0, while Ethernet4 has
index value 1.
Note: SONiC derives logical Ethernet interface
numbering from the physical lane mapping. Since Ethernet0 occupies four
physical lanes (25-28), the next interface begins at lane 29 and is therefore
named Ethernet4.
root@leaf-1:/# cat
/usr/share/sonic/device/x86_64-kvm_x86_64-r0/Force10-S6000/port_config.ini
# name lanes alias index speed
Ethernet4 29,30,31,32 fortyGigE0/4 1 40000
Ethernet0 25,26,27,28 fortyGigE0/0 0 40000
Example 4-5:
The Content of the Port_config.ini File.
The resulting
configuration generated by sonic-cfggen can be viewed by using the command:
cat /etc/sonic/config_db.json
file.
Example 4-6 shows the
DEVICE_METADATA table together with the PORT entry for Ethernet0. The values in
the PORT table are derived from the platform-specific configuration, while the
DEVICE_METADATA table contains information describing the hardware platform.
root@leaf-1:/# cat
/etc/sonic/config_db.json
{
"DEVICE_METADATA": {
"localhost": {
"mac": "6e:fc:2e:c2:81:22",
"switch_type":
"switch",
"buffer_model":
"traditional",
"hwsku":
"Force10-S6000"
}
"PORT": {
"Ethernet0": {
"alias":
"fortyGigE0/0",
"lanes":
"25,26,27,28",
"speed": "40000",
"index": "0",
"subport": "0"
},
Example 4-6:
The Content of the Config_db.json File.
Example
4-7 shows the corresponding entries stored in the Redis CONFIG_DB database by
using the command:
sonic-db-dump -n CONFIG_DB --pretty.
The
database is organized into tables, where each table represents a particular
configuration category. Each table contains one or more keys, and every key
consists of a set of field/value pairs. In this example, the PORT table
contains the key PORT|Ethernet0, while the BREAKOUT_CFG and DEVICE_METADATA
tables contain the keys BREAKOUT_CFG|Ethernet0 and DEVICE_METADATA|localhost,
respectively.
root@leaf-1:/# sonic-db-dump
-n CONFIG_DB --pretty
{
"BREAKOUT_CFG|Ethernet0": {
"expireat": 1784018980.3639462,
"ttl": -0.001,
"type": "hash",
"value": {
"brkout_mode": "1x40G"
}
},
"PORT|Ethernet0": {
"expireat": 1784019105.4230292,
"ttl": -0.001,
"type": "hash",
"value": {
"alias":
"fortyGigE0/0",
"index": "0",
"lanes":
"25,26,27,28",
"speed": "40000",
"subport": "0"
}
},
"DEVICE_METADATA|localhost": {
"expireat": 1784019105.448699,
"ttl": -0.001,
"type": "hash",
"value": {
"buffer_model":
"traditional",
"hwsku":
"Force10-S6000",
"mac": "6e:fc:2e:c2:81:22",
"switch_type":
"switch"
}
},
Example 4-7:
CONFIG_DB – Ethernet0 Field/Value Pairs#1.
The previous example
displays the complete contents of the CONFIG_DB database. If you want to
display only the field/value pairs associated with Ethernet0 in the PORT table,
you can use the Redis command:
redis-cli -n 4 HGETALL
"PORT|Ethernet0".
root@leaf-1:/# redis-cli
-n 4 HGETALL "PORT|Ethernet0"
1) "alias"
2) "fortyGigE0/0"
3) "index"
4) "0"
5) "lanes"
6) "25,26,27,28"
7) "speed"
8) "400000"
9) "subport"
10)
"0"
11)
"admin_status"
12)
"up"
Example 4-8:
CONFIG_DB – Ethernet0 Field/Value Pairs#2.
Note:
The admin_status field is not defined in the port_config.ini file because that
file describes only the platform's physical port characteristics. The
administrative state is applied later as part of the interface configuration.
If config_db.json does not explicitly configure the administrative state, SONiC
keeps the interface administratively down by default. Consequently, the
contents of the PORT entry in CONFIG_DB may change after the initial
configuration has been loaded.
Step 2: Updating APPL_DB by Portmgrd
The portmgrd
daemon running in the SWSS container is responsible for translating the port
configuration stored in CONFIG_DB into application-level objects stored in
APPL_DB. Figure 4-3 depicts this process. When the PORT table in CONFIG_DB is
updated, Redis notifies the SWSS database framework that the corresponding key
has changed (4). Rather than periodically polling the database for changes,
portmgrd reacts to these notifications, allowing the updated port configuration
to be processed immediately after it is written to CONFIG_DB. The portmgrd
daemon then retrieves the complete set of field/value pairs associated with the
modified port (5). Then it validates the configuration using the selected HwSKU
together with platform-specific configuration information, and resolves any
configuration dependencies (6). During this process, portmgrd also adds default
attributes required by the SONiC application layer, such as the interface MTU
and administrative state. After the validation is completed successfully,
portmgrd publishes the resulting port object to the PORT_TABLE in APPL_DB (7).
Figure 4-3: Information
Flow from CONFIG_DB to APPL_DB.
Example 4-9 shows the PORT_TABLE:Ethernet0
entry printed by using the command:
sonic-db-dump -n APPL_DB --pretty.
Similar to CONFIG_DB,
the APPL_DB database is organized into tables, where each key contains a
collection of field/value pairs describing the corresponding object. Compared
to the PORT entry in CONFIG_DB, the PORT_TABLE entry contains additional
attributes such as admin_status, oper_status, mtu, and flap_count, which are
required by other SONiC components during the hardware programming process.
root@leaf-1:/# sonic-db-dump
-n APPL_DB –pretty
<snipped for brevity>
"PORT_TABLE:Ethernet0":
{
"expireat": 1784020527.8656764,
"ttl": -0.001,
"type": "hash",
"value": {
"admin_status":
"down",
"alias":
"fortyGigE0/0",
"flap_count": "0",
"index": "0",
"lanes":
"25,26,27,28",
"mtu": "9100",
"oper_status":
"down",
"speed": "40000",
"subport": "0"
}
},
<snipped for brevity>
Example 4-9:
APPL_DB – Ethernet0 Field/Value Pairs#1.
To display only the
field/value pairs associated with Ethernet0, use the Redis command:
redis-cli -n 0 HGETALL
"PORT_TABLE:Ethernet0".
root@leaf-1:/# redis-cli -n 0
HGETALL "PORT_TABLE:Ethernet0"
1) "alias"
2) "fortyGigE0/0"
3) "index"
4) "0"
5) "lanes"
6) "25,26,27,28"
7) "speed"
8) "40000"
9) "subport"
10) "0"
11) "oper_status"
12) "down"
13) "flap_count"
14) "0"
15) "mtu"
16) "9100"
17) "admin_status"
18) "up"
Example 4-10:
APPL_DB – Ethernet0 Field/Value Pairs#2.
Note: As mentioned before, the PORT_TABLE
entry in APPL_DB is not a direct copy of the PORT entry in CONFIG_DB. Besides
the configuration parameters retrieved from CONFIG_DB, portmgrd adds default
values and application-specific attributes during the validation process. Some
fields, such as oper_status, are updated later as the switch learns the actual
operational state of the interface. This illustrates an important architectural
principle of SONiC: CONFIG_DB stores the desired configuration, whereas
APPL_DB stores the application's runtime view of the configured object.
Step 3: Discovering ASIC Port Information
At this point both
CONFIG_DB and APPL_DB have been updated, and the port configuration is ready to
be translated into SAI objects. After PortMgrd updates the PORT_TABLE in
APPL_DB, Redis sends a notification to Orchagent in the SWSS container (8).
Orchagent dispatches the notification to the PortOrch orchestrator (9), which
is responsible for keeping the port information synchronized with the ASIC.
PortOrch then retrieves the updated keys from APPL_DB (10).
Figure 4-4: Updating
ASIC_DB by PortOrch.
Note: A log output at the end of this section
can be used to correlate the initialization sequence with the text and figures.
During
the initialization process, the syncd daemon in the Syncd container receives a
Linux rtnetlink message from the Linux kernel (11). The message type is
RTM_NEWLINK (message type 16), which carries information about the interface,
including the interface name, interface flags (ifflags), interface index
(ifindex), master interface, and interface type. The value master:0 indicates
that the interface is a standalone port and is not a member of another
interface or networking construct such as a VRF, team interface, or bond (Link
Aggregation). The value type:tun is specific to SONiC-VS. It indicates that the
interface is created using the Linux TUN/TAP driver. In SONiC-VS, this
interface carries Layer 2 Ethernet frames and is used for communication between
the virtual switch ASIC and the Linux networking stack.
Note: Both the syncd and portsyncd daemons
subscribe to Linux rtnetlink notifications. In the log output, the syncd
netlink callback is shown as asyncOnLinkMsg, while the portsyncd callback is
shown as onMsg. Both syncd and portsyncd receive the same RTM_NEWLINK
notification. The daemons interpret and log different subsets of the message.
For example, portsyncd derives the administrative (admin) and operational
(oper) states from the interface flags and operational-state attributes rather
than receiving explicit admin and oper fields from the Linux kernel.
The
syncd daemon communicates with the ASIC through the Vendor SAI implementation
(12). During switch initialization, the Vendor SAI implementation retrieves the
physical port objects and their attributes, including the hardware lane
mapping, from the ASIC and returns them to the syncd daemon (13). Figure 4-5
shows how the hardware lane mapping is stored in the SAI_PORT_ATTR_HW_LANE_LIST
attribute of the SAI port object associated with Ethernet0 (OID
0x1000000000002). After receiving the port information, the syncd daemon synchronizes
the SAI port objects and their attributes with ASIC_DB through its Redis
communication layer (14), which generates a Redis notification to orchagent in
the SWSS container (15). orchagent dispatches the notification to the PortOrch
orchestrator (16), which retrieves the corresponding SAI port Object (17).
PortOrch
has already learned the configured lane mapping for interface Ethernet0 from
APPL_DB. It compares this lane mapping with the hardware lane mapping
associated with each SAI port object (18) to identify the correct object
identifier (OID) for Ethernet0. Since SAI port objects do not contain the SONiC
logical port names, the lane mapping is used to establish the association
between the logical port and its corresponding SAI port object. This validation
step ensures that the lane mapping configured by SONiC matches the hardware
lane mapping obtained from the ASIC. After the association has been
established, After the association has been established, PortOrch uses this OID
whenever it issues SAI API requests to configure or update the corresponding
physical port.
Figure 4-5: Information
Flow from CONFIG_DB to APPL_DB.
Step 4: Programming the ASIC
After
PortOrch has associated the logical port Ethernet0 with the correct SAI port
object, it uses the corresponding object identifier (OID) when issuing SAI API
requests. The request is delivered to the syncd daemon through SONiC's
Redis-based communication mechanism (19). The syncd daemon translates the
generic SAI request into calls to the Vendor SAI implementation (20), which
invokes the vendor SDK to program the corresponding hardware resources in the
ASIC (21).
After
the ASIC has been successfully programmed, syncd synchronizes the updated SAI
object state with ASIC_DB. The update generates a Redis notification that can
be consumed by SONiC components monitoring changes to the ASIC state. From this
point onward, PortOrch no longer identifies the physical port by its logical
name (Ethernet0). Instead, all subsequent port operations, such as changing the
administrative state, MTU, speed, Forward Error Correction (FEC), or other SAI
port attributes, are performed using the associated SAI port object identifier
(OID).
Note: ASIC_DB is a mirror of the ASIC
state, not a command database. During normal SONiC operation, syncd is
responsible for synchronizing SAI objects and their attributes with ASIC_DB. Orchagent
does not program the ASIC directly by writing to ASIC_DB. Instead, it issues
SAI API requests that are delivered to syncd through SONiC's Redis-based SAI
communication channel. After the requested operation has been performed, syncd
updates ASIC_DB to reflect the resulting ASIC state.
Figure
4-6: Updating the ASIC.
ASIC_DB: Resolving OID-to-PORT mapping
The ASIC uses object
identifiers (OIDs) to identify hardware objects. For example, SONiC identifies
the first physical port as Ethernet0, while the ASIC refers to the same port by
its OID. To inspect the port information stored in ASIC_DB, we must first determine
which OID corresponds to Ethernet0.
Example 4-11 lists all
keys in the ASIC_STATE table related to SAI_OBJECT_TYPE_PORT and
SAI_OBJECT_TYPE_PORT_SERDES. Our goal is to identify the OID associated with
Ethernet0.
root@leaf-1:/# redis-cli -n 1
KEYS "ASIC_STATE:SAI_OBJECT_TYPE_PORT*"
1)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000371"
2)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000569"
3)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008f"
4)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000024b"
5)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000004c1"
6)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000092"
7)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009f"
8)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008b"
9)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008c"
10)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000000d1"
11)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000004eb"
12)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000053f"
13)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000039b"
14)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000031d"
15)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000001f7"
16)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000029f"
17)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000003c5"
18)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a1"
19)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008e"
20)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a7"
21)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000125"
22)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000091"
23)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a2"
24)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000096"
25)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a0"
26)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000099"
27)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000098"
28)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000275"
29)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009e"
30)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000003ef"
31)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000347"
32)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009d"
33)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000002f3"
34)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000003"
35)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000497"
36)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a5"
37)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000090"
38)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000419"
39)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000094"
40)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008d"
41)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000082"
42)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000000fb"
43)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a6"
44)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009a"
45)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000001a3"
46)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000081"
47)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000014f"
48)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000093"
49)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a4"
50)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000001cd"
51)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009c"
52)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000179"
53)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000515"
54)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000001"
55)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000002"
56)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000443"
57)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000000a3"
58)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x5700000000046d"
59)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000095"
60)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000221"
61)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x57000000000593"
62)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT_SERDES:oid:0x570000000002c9"
63)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000008a"
64)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x100000000009b"
65)
"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000097"
Example 4-11:
ASIC_DB – ASIC_STATE:SAI_OBJECT_TYPE_PORT.
There are several ways
to resolve the OID-to-port mapping. One of the simplest methods is shown in
Example 4-12 by using the command:
redis-cli -n 2 HGETALL
COUNTERS_PORT_NAME_MAP.
This command retrieves
the contents of the COUNTERS_PORT_NAME_MAP table in COUNTERS_DB, where each
entry maps a SONiC port name to its corresponding OID.
root@leaf-1:/# redis-cli -n 2
HGETALL COUNTERS_PORT_NAME_MAP
1) "Ethernet0"
2)
"oid:0x1000000000002"
3) "Ethernet4"
4)
"oid:0x1000000000003"
Example 4-12:
COUNTERS_DB – Port:SAI_OBJECT_TYPE_PORT mapping.
After identifying the
OID, we can inspect the corresponding port object stored in ASIC_DB by using
the following command:
redis-cli -n 1 HGETALL ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000002"
The exact contents of a
SAI_OBJECT_TYPE_PORT object depend on the SAI implementation and the underlying
hardware platform. Example 4-13 shows a typical set of attributes associated
with the Ethernet0 port object.
root@leaf-1:/# redis-cli -n 1
HGETALL ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x1000000000002"
1) "NULL"
2) "NULL"
3)
"SAI_PORT_ATTR_HW_LANE_LIST"
4)
"4:25,26,27,28"
5)
"SAI_PORT_ATTR_SPEED"
6) "40000"
7)
"SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE"
8) "false"
9)
"SAI_PORT_ATTR_ADMIN_STATE"
10) "false"
11) "SAI_PORT_ATTR_MTU"
12) "9100"
Example 4-13:
ASIC_DB – Updated SAI_OBJECT_TYPE_PORT Field/Values.
Step 5: Updating STATE_DB
The
syncd daemon is not the only subscriber to Linux rtnetlink notifications. The
portsyncd daemon in the SWSS container also subscribes to these notifications
and receives RTM_NEWLINK (message type 16) messages from the Linux kernel (A).
Although both daemons receive the same notifications, they perform different
tasks. In SONiC-VS, syncd uses the notifications as part of the virtual switch
implementation, while portsyncd monitors Linux interface state changes and
publishes the relevant interface status to STATE_DB.
The
RTM_NEWLINK message carries interface flags and operational state information.
portsyncd interprets this information and updates the corresponding
administrative and operational status in STATE_DB (B). At this stage, interface
Ethernet0 has not yet been enabled, so both the administrative and operational
states remain down. Although the RTM_NEWLINK message also carries the interface
MAC address, portsyncd does not store it in STATE_DB, because STATE_DB contains
only the interface state information required by SONiC components.
In
the next chapter, we enable interface Ethernet0 and examine how portsyncd
updates STATE_DB in response to the resulting RTM_NEWLINK notification. We then
follow how the updated interface state is propagated through the SONiC software
stack.
Note: The absence of the IFF_UP (0x0001) flag
indicates that the interface is administratively down, which is why portsyncd
reports admin:0.
Log Output
root@leaf-1:/#
grep -i Ethernet0 /var/log/syslog | tail -50 | sed -E
's/^[A-Z][a-z]{2} [ 0-9]{2} [0-9:.]+ //'
#orchagent: :- initializePort: Initializing port
alias:Ethernet0 pid:1000000000002
#orchagent: :- initializePortBufferMaximumParameters: Unable
to get the maximum headroom for port
Ethernet0
rv:-15, ignored
#syncd: :- asyncOnLinkMsg: received RTM_NEWLINK ifname: Ethernet0, ifflags:
0x1002, ifindex: 3
#portsyncd: :- onMsg: nlmsg type:16 key:Ethernet0 admin:0
oper:0 addr:06:d2:f3:62:33:ec ifindex:3
master:0
type:tun
#syncd: :- asyncOnLinkMsg: received RTM_NEWLINK ifname: Ethernet0, ifflags:
0x1002, ifindex: 3
#portsyncd: :- onMsg: Publish Ethernet0(ok:down) to state db
#portsyncd: :- onMsg: nlmsg type:16 key:Ethernet0 admin:0
oper:0 addr:92:d6:c0:5f:d3:01 ifindex:3
master:0
type:tun
#portsyncd: :- onMsg: Publish Ethernet0(ok:down) to state db
#orchagent: :- addHostIntfs: Create host interface for port
Ethernet0
#orchagent: :- setHostTxReady: Setting host_tx_ready status =
true, alias = Ethernet0,
port_id
= 0x1000000000002
#orchagent: :- setHostIntfsOperStatus: Set operation status
DOWN to host interface Ethernet0
#orchagent: :- publish: EVENT_PUBLISHED:
{"sonic-events-swss:if-state":
{"ifname":"Ethernet0","status":"down","timestamp":"2026-07-24T10:21:09.351690Z"}}
#orchagent: :- initPort: Initialized port Ethernet0
#orchagent: :- getPortSupportedSpeeds: Unable to validate
speed for port
Ethernet0
id=1000000000002. Not supported by platform
#syncd: :- asyncOnLinkMsg: received RTM_NEWLINK ifname: Ethernet0, ifflags:
0x1002, ifindex: 3
#portsyncd: :- onMsg: nlmsg type:16 key:Ethernet0 admin:0
oper:0 addr:92:d6:c0:5f:d3:01 ifindex:3
master:0
type:tun
#portsyncd: :- onMsg: Publish Ethernet0(ok:down) to state db
#portmgrd: :- doTask: Configure Ethernet0 MTU to 9100
#portmgrd: :- doTask: Configure Ethernet0 admin status to
down
#buffermgrd: :- doSpeedUpdateTask: Not creating/updating PG
profile for port Ethernet0.
Cable
length is set to 0m
Example
4-14: Log Output about Ethernet0 Processing by
Orchagent, Syncd, and Portmgrd.
Summary
The previous examples
focused on port initialization to illustrate how SONiC programs hardware
through the Redis databases, Orchagent, and Syncd. Although only the basic port
configuration was used as an example, the same programming model is used throughout
SONiC. Additional port-related settings, such as breakout configuration, buffer
allocation, queue and priority settings, flow control, and many other port
attributes, follow the same sequence. The configuration is first written into
CONFIG_DB, processed by the corresponding manager daemon into APPL_DB,
translated into SAI objects by Orchagent, and finally programmed into the ASIC
by Syncd through the Vendor SDK implementation.
PortOrch is only one of
several orchestrators running under the Orchagent process. Each orchestrator is
responsible for translating a specific type of configuration into SAI objects.
For example, IntfOrch programs Layer 3 interfaces, VlanOrch manages VLANs,
RouteOrch programs routing entries, NeighborOrch resolves neighbor information,
and BufferOrch manages buffer-related resources. Together, these orchestrators
ensure that the configuration stored in Redis databases is consistently
translated into the hardware-specific objects required by the ASIC.
Understanding this
programming pipeline is essential for understanding how SONiC operates.
Regardless of whether the configuration relates to ports, VLANs, routing, QoS,
or another feature, the same overall workflow is followed: the configuration is
stored in Redis, processed by the appropriate manager daemon and orchestrator,
translated into SAI objects, and finally programmed into the ASIC.
Looking Ahead
This chapter concludes
the discussion of the SONiC boot and initialization process. Starting from the
Linux boot sequence in Chapter 3, we have followed the complete path of the
initial switch configuration from the config_db.json file into CONFIG_DB, through
the SWSS container, and finally into the ASIC. Understanding this process
provides a solid foundation for the remaining chapters, where the switch is
configured to perform actual networking functions.
The next part of the
book shifts from the startup process to building a complete Clos fabric by
using SONiC. We begin by configuring the inter-switch links, continue by
enabling the IP underlay, and finally build a BGP EVPN overlay with VXLAN data
plane. Rather than focusing only on the SONiC CLI configuration, each phase
also explains what happens internally. You will see how the configuration is
written into the Redis databases, which manager daemons and orchestrators
process the changes, how the different containers cooperate, and how the
resulting configuration is translated into SAI objects before being programmed
into the ASIC.
By examining both the
configuration steps and the internal processing pipeline, you will gain a
deeper understanding of how SONiC implements modern data center networking.
This approach not only explains how to configure SONiC, but also why the
configuration works the way it does.