Skip to content

Commit d5da645

Browse files
committed
PNAC parsing
Signed-off-by: Milan Lenco <milan@zededa.com>
1 parent 18bfbee commit d5da645

File tree

3 files changed

+185
-11
lines changed

3 files changed

+185
-11
lines changed

pkg/pillar/cmd/zedagent/handleconfig.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ type getconfigContext struct {
121121
pubAppInstanceConfig pubsub.Publication
122122
bootOrderUpdateMx sync.Mutex
123123

124+
// parsed PNAC configurations
125+
pnacs map[string]*types.PNACConfig // key: logical label
126+
124127
// parsed L2 adapters
125128
vlans []L2Adapter
126129
bonds []L2Adapter

pkg/pillar/cmd/zedagent/parseconfig.go

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,19 @@ func parseConfig(getconfigCtx *getconfigContext, config *zconfig.EdgeDevConfig,
148148
// DeviceIoList has some defaults for Usage and UsagePolicy
149149
// used by systemAdapters
150150
physioChanged := parseDeviceIoListConfig(getconfigCtx, config)
151+
pnacChanged := parsePNACConfig(getconfigCtx, config)
151152
// It is important to parse Bonds before VLANs.
152153
bondsChanged := parseBonds(getconfigCtx, config)
153154
vlansChanged := parseVlans(getconfigCtx, config)
154155
// Network objects are used for systemAdapters
155156
networksChanged := parseNetworkXObjectConfig(getconfigCtx, config)
156157
sourceChanged := getconfigCtx.lastConfigSource != source
157158
// system adapter configuration that we publish, depends
158-
// on Physio, VLAN, Bond and Networks configuration.
159+
// on Physio, PNAC, VLAN, Bond and Networks configuration.
159160
// If any of these change, we should re-parse system adapters and
160161
// publish updated configuration.
161162
forceSystemAdaptersParse := physioChanged || networksChanged || vlansChanged ||
162-
bondsChanged || sourceChanged
163+
bondsChanged || sourceChanged || pnacChanged
163164
parseSystemAdapterConfig(getconfigCtx, config, source, forceSystemAdaptersParse)
164165

165166
if source != fromBootstrap {
@@ -1239,7 +1240,8 @@ func propagateError(higherLayerPort, lowerLayerPort *types.NetworkPortConfig) {
12391240
}
12401241
}
12411242

1242-
func propagatePhyioAttrsToPort(port *types.NetworkPortConfig, phyio *types.PhysicalIOAdapter) {
1243+
func propagatePhyioAttrsToPort(getconfigCtx *getconfigContext,
1244+
port *types.NetworkPortConfig, phyio *types.PhysicalIOAdapter) {
12431245
port.Phylabel = phyio.Phylabel
12441246
port.IfName = phyio.Phyaddr.Ifname
12451247
port.USBAddr = phyio.Phyaddr.UsbAddr
@@ -1270,6 +1272,9 @@ func propagatePhyioAttrsToPort(port *types.NetworkPortConfig, phyio *types.Physi
12701272
handleMissingIfname(port, phyio)
12711273
}
12721274
}
1275+
if pnac := getconfigCtx.pnacs[phyio.Logicallabel]; pnac != nil {
1276+
port.PNAC = *pnac
1277+
}
12731278
}
12741279

12751280
func handleMissingIfname(port *types.NetworkPortConfig, phyio *types.PhysicalIOAdapter) {
@@ -1285,9 +1290,10 @@ func handleMissingIfname(port *types.NetworkPortConfig, phyio *types.PhysicalIOA
12851290

12861291
// Make NetworkPortConfig entry for PhysicalIO which is below an L2 port.
12871292
// The port configuration will contain only labels and the interface name.
1288-
func makeL2PhyioPort(phyio *types.PhysicalIOAdapter) *types.NetworkPortConfig {
1293+
func makeL2PhyioPort(getconfigCtx *getconfigContext,
1294+
phyio *types.PhysicalIOAdapter) *types.NetworkPortConfig {
12891295
phyioPort := &types.NetworkPortConfig{Logicallabel: phyio.Logicallabel}
1290-
propagatePhyioAttrsToPort(phyioPort, phyio)
1296+
propagatePhyioAttrsToPort(getconfigCtx, phyioPort, phyio)
12911297
return phyioPort
12921298
}
12931299

@@ -1296,7 +1302,8 @@ func makeL2PhyioPort(phyio *types.PhysicalIOAdapter) *types.NetworkPortConfig {
12961302
// Recursively adds port entries for all adapter below this one.
12971303
// The port configuration will contain only labels, the interface name
12981304
// and L2 configuration.
1299-
func makeL2Port(l2Adapter *L2Adapter) (ports []*types.NetworkPortConfig) {
1305+
func makeL2Port(getconfigCtx *getconfigContext,
1306+
l2Adapter *L2Adapter) (ports []*types.NetworkPortConfig) {
13001307
ports = append(ports, &types.NetworkPortConfig{
13011308
IfName: l2Adapter.config.IfName,
13021309
Phylabel: l2Adapter.config.Phylabel,
@@ -1306,10 +1313,10 @@ func makeL2Port(l2Adapter *L2Adapter) (ports []*types.NetworkPortConfig) {
13061313
TestResults: l2Adapter.config.TestResults,
13071314
})
13081315
for _, phyio := range l2Adapter.lowerPhysPorts {
1309-
ports = append(ports, makeL2PhyioPort(phyio))
1316+
ports = append(ports, makeL2PhyioPort(getconfigCtx, phyio))
13101317
}
13111318
for _, lowerL2 := range l2Adapter.lowerL2Ports {
1312-
ports = append(ports, makeL2Port(lowerL2)...)
1319+
ports = append(ports, makeL2Port(getconfigCtx, lowerL2)...)
13131320
}
13141321
return ports
13151322
}
@@ -1388,7 +1395,7 @@ func parseOneSystemAdapterConfig(getconfigCtx *getconfigContext,
13881395
phyioFreeUplink = phyio.UsagePolicy.FreeUplink
13891396
log.Functionf("Found phyio for %s: free %t, oldController: %t",
13901397
sysAdapter.Name, phyioFreeUplink, oldController)
1391-
propagatePhyioAttrsToPort(port, phyio)
1398+
propagatePhyioAttrsToPort(getconfigCtx, port, phyio)
13921399
} else {
13931400
// Note that if controller sends VLAN or bond config,
13941401
// it means that it is new enough to not use FreeUplink anymore.
@@ -1397,10 +1404,10 @@ func parseOneSystemAdapterConfig(getconfigCtx *getconfigContext,
13971404
propagateError(port, l2Adapter.config)
13981405
// Add NetworkPortConfig entries for lower-layer adapters.
13991406
for _, phyio := range l2Adapter.lowerPhysPorts {
1400-
ports = append(ports, makeL2PhyioPort(phyio))
1407+
ports = append(ports, makeL2PhyioPort(getconfigCtx, phyio))
14011408
}
14021409
for _, lowerL2 := range l2Adapter.lowerL2Ports {
1403-
ports = append(ports, makeL2Port(lowerL2)...)
1410+
ports = append(ports, makeL2Port(getconfigCtx, lowerL2)...)
14041411
}
14051412
}
14061413

@@ -1684,6 +1691,58 @@ func parseDeviceIoListConfig(getconfigCtx *getconfigContext,
16841691
return true
16851692
}
16861693

1694+
var pnacPrevConfigHash []byte
1695+
1696+
func parsePNACConfig(getconfigCtx *getconfigContext, config *zconfig.EdgeDevConfig) bool {
1697+
pnacs := config.GetPnacs()
1698+
h := sha256.New()
1699+
for _, pnac := range pnacs {
1700+
computeConfigElementSha(h, pnac)
1701+
}
1702+
configHash := h.Sum(nil)
1703+
same := bytes.Equal(configHash, pnacPrevConfigHash)
1704+
if same {
1705+
return false
1706+
}
1707+
pnacPrevConfigHash = configHash
1708+
1709+
getconfigCtx.pnacs = make(map[string]*types.PNACConfig)
1710+
for _, pnac := range config.GetPnacs() {
1711+
if pnac.GetLogicallabel() == "" {
1712+
errStr := fmt.Sprintf("PNAC entry missing logical label; "+
1713+
"ignoring config: %+v", pnac)
1714+
log.Errorf("parsePNACConfig: %s", errStr)
1715+
continue
1716+
}
1717+
1718+
// Check that the referenced physical IO exists and is Ethernet NIC.
1719+
physIO := lookupDeviceIoLogicallabel(getconfigCtx, pnac.GetLogicallabel())
1720+
if physIO == nil {
1721+
errStr := fmt.Sprintf(
1722+
"PNAC logical label %q references a non-existent physical IO; "+
1723+
"ignoring config", pnac.GetLogicallabel())
1724+
log.Errorf("parsePNACConfig: %s", errStr)
1725+
continue
1726+
}
1727+
1728+
physIOType := types.IoType(physIO.Ptype)
1729+
if physIOType != types.IoNetEth && physIOType != types.IoNetEthPF {
1730+
errStr := fmt.Sprintf(
1731+
"PNAC logical label %q references non-Ethernet physical IO (type: %v); "+
1732+
"ignoring config", pnac.GetLogicallabel(), physIOType)
1733+
log.Errorf("parsePNACConfig: %s", errStr)
1734+
continue
1735+
}
1736+
getconfigCtx.pnacs[pnac.GetLogicallabel()] = &types.PNACConfig{
1737+
Enabled: true,
1738+
EAPIdentity: pnac.GetEapIdentity(),
1739+
EAPMethod: pnac.GetEapMethod(),
1740+
CertEnrollmentProfileName: pnac.GetCertEnrollmentProfileName(),
1741+
}
1742+
}
1743+
return true
1744+
}
1745+
16871746
var bondsPrevConfigHash []byte
16881747

16891748
func parseBonds(getconfigCtx *getconfigContext, config *zconfig.EdgeDevConfig) bool {

pkg/pillar/cmd/zedagent/parseconfig_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,3 +1841,115 @@ func TestParseIpspec_GatewayVersionMismatch(t *testing.T) {
18411841
g.Expect(err).To(HaveOccurred())
18421842
g.Expect(err.Error()).To(ContainSubstring("IP version mismatch"))
18431843
}
1844+
1845+
func TestParsePNAC(t *testing.T) {
1846+
g := NewGomegaWithT(t)
1847+
getconfigCtx := initGetConfigCtx(g)
1848+
1849+
const networkUUID = "572cd3bc-ade6-42ad-97a0-22cd24fed1a0"
1850+
config := &zconfig.EdgeDevConfig{
1851+
Networks: []*zconfig.NetworkConfig{
1852+
{
1853+
Id: networkUUID,
1854+
Type: zcommon.NetworkType_V4,
1855+
Ip: &zcommon.Ipspec{
1856+
Dhcp: zcommon.DHCPType_Client,
1857+
},
1858+
},
1859+
},
1860+
DeviceIoList: []*zconfig.PhysicalIO{
1861+
{
1862+
Ptype: zcommon.PhyIoType_PhyIoNetEth,
1863+
Phylabel: "eth0",
1864+
Logicallabel: "ethernet0",
1865+
Assigngrp: "eth-grp-1",
1866+
Phyaddrs: map[string]string{
1867+
"ifname": "eth0",
1868+
"pcilong": "0000:04:00.0",
1869+
},
1870+
Usage: zcommon.PhyIoMemberUsage_PhyIoUsageMgmtAndApps,
1871+
},
1872+
{
1873+
Ptype: zcommon.PhyIoType_PhyIoNetEth,
1874+
Phylabel: "eth1",
1875+
Logicallabel: "ethernet1",
1876+
Assigngrp: "eth-grp-1",
1877+
Phyaddrs: map[string]string{
1878+
"ifname": "eth1",
1879+
"pcilong": "0000:05:00.0",
1880+
},
1881+
Usage: zcommon.PhyIoMemberUsage_PhyIoUsageMgmtAndApps,
1882+
},
1883+
},
1884+
SystemAdapterList: []*zconfig.SystemAdapter{
1885+
{
1886+
Name: "adapter-ethernet0",
1887+
Uplink: true,
1888+
NetworkUUID: networkUUID,
1889+
Alias: "ethernet0-alias",
1890+
LowerLayerName: "ethernet0",
1891+
Cost: 0,
1892+
},
1893+
{
1894+
Name: "adapter-ethernet1",
1895+
Uplink: true,
1896+
NetworkUUID: networkUUID,
1897+
Alias: "ethernet1-alias",
1898+
LowerLayerName: "ethernet1",
1899+
Cost: 10,
1900+
},
1901+
},
1902+
Pnacs: []*zconfig.PNAC{
1903+
{
1904+
Logicallabel: "ethernet0",
1905+
EapIdentity: "123456789",
1906+
EapMethod: zconfig.EAPMethod_EAP_METHOD_TLS,
1907+
CertEnrollmentProfileName: "scep-profile1",
1908+
},
1909+
},
1910+
ScepProfiles: []*zconfig.SCEPProfile{
1911+
{
1912+
ProfileName: "scep-profile1",
1913+
ScepUrl: "https://ca.example.com/scep",
1914+
UseControllerProxy: true,
1915+
CsrProfile: &zconfig.CSRProfile{
1916+
CommonName: "123456789",
1917+
Organization: "Test Organization",
1918+
OrganizationalUnit: "Unit Test",
1919+
Country: "US",
1920+
State: "TestState",
1921+
Locality: "TestCity",
1922+
SanUri: []string{"urn:test:device:123456789"},
1923+
RenewPeriodPercent: 60,
1924+
KeyType: zconfig.KeyType_KEY_TYPE_RSA_4096,
1925+
HashAlgorithm: zconfig.HashAlgorithm_HASH_ALGORITHM_SHA256,
1926+
},
1927+
},
1928+
},
1929+
}
1930+
1931+
parseDeviceIoListConfig(getconfigCtx, config)
1932+
// TODO : parse SCEP profiles
1933+
parsePNACConfig(getconfigCtx, config)
1934+
parseNetworkXObjectConfig(getconfigCtx, config)
1935+
parseSystemAdapterConfig(getconfigCtx, config, fromController, true)
1936+
1937+
portConfig, err := getconfigCtx.pubDevicePortConfig.Get("zedagent")
1938+
g.Expect(err).To(BeNil())
1939+
dpc := portConfig.(types.DevicePortConfig)
1940+
g.Expect(dpc.Version).To(Equal(types.DPCIsMgmt))
1941+
g.Expect(dpc.HasError()).To(BeFalse())
1942+
g.Expect(dpc.Ports).To(HaveLen(2))
1943+
port0 := dpc.Ports[0]
1944+
g.Expect(port0.Logicallabel).To(Equal("adapter-ethernet0"))
1945+
g.Expect(port0.PNAC.Enabled).To(BeTrue())
1946+
g.Expect(port0.PNAC.CertEnrollmentProfileName).To(Equal("scep-profile1"))
1947+
g.Expect(port0.PNAC.EAPMethod).To(Equal(zconfig.EAPMethod_EAP_METHOD_TLS))
1948+
g.Expect(port0.PNAC.EAPIdentity).To(Equal("123456789"))
1949+
port1 := dpc.Ports[0]
1950+
g.Expect(port1.Logicallabel).To(Equal("adapter-ethernet1"))
1951+
g.Expect(port1.PNAC.Enabled).To(BeFalse())
1952+
g.Expect(port1.PNAC.CertEnrollmentProfileName).To(BeEmpty())
1953+
g.Expect(port1.PNAC.EAPMethod).To(Equal(zconfig.EAPMethod_EAP_METHOD_UNSPECIFIED))
1954+
g.Expect(port1.PNAC.EAPIdentity).To(BeEmpty())
1955+
}

0 commit comments

Comments
 (0)