@@ -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
12751280func 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+
16871746var bondsPrevConfigHash []byte
16881747
16891748func parseBonds (getconfigCtx * getconfigContext , config * zconfig.EdgeDevConfig ) bool {
0 commit comments