Giter VIP home page Giter VIP logo

meraki-builder's People

Contributors

hall avatar halmartin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meraki-builder's Issues

Handle DHCP lease expiration

Currently S10meraki sets the IP address during boot and then it assumes the IP address from DHCP never changes.

This doesn't fit all environments, so it would be better if we initially set the IP address received from DHCP during boot, and then periodically polled to see if the DHCP address has changed, and change the switch IP address accordingly.

Turns out, there's a handy place in click where we can poll for the details of the DHCP lease:

# cat /click/uplinkstate/dhcp_state
vlan added_by active state disc_ago offer_ago req_ago ack_delay renew_at exp_at              ip         gw        bcast             dns mtu
   1      C|T   true bound  1506512   1506511   16010    0.0049     6017  27189 192.168.0.15/22 192.168.0.1 192.168.0.255 0.0.0.0 0.0.0.0   0

renew_at tells us how long to wait before we should poll click for any new IP address received from DHCP.

  1. Check dhcp_state
  2. Sleep for renew_at seconds
  3. Check dhcpc_state_for_brain to see if the IP address has changed

initialize poe before network

The DHCP server on my network is powered by postmerkOS. As it stands, during boot, the switch waits for an address prior to initializing PoE. Thus it will always fail and fallback to the hardcoded address.

As someone with very little knowledge here, is there any reason you're aware of that the order cannot be flipped? I'm happy to test suggested approaches -- just didn't want to break things (on my only device) if it was a lost cause.

Support Meraki MS225 (brumby)?

Summary

Meraki brumby is the codename for the Broadcom Hurricane3 based MS225 (and MS210?) switches.

The MS225 switches use a completely different ASIC (Broadcom BCM56160; ARM Cortex A9 softfloat) to the MS220 series (Vitesse VSC74xx), and as such are completely incompatible with the current firmware.

Background

Broadcom-based switches use two kernel modules to manage the switch ASIC:

  • linux_kernel_bde
  • linux_user_bde

From what I've been able to gather, the OEM is expected to implement the switching engine in userspace, using the OpenNSA API. Don't let the name fool you though, while there is "open" in the name, API documentation appears to only be available under NDA from Broadcom.

On the MS225, the switching engine is implemented via /usr/lib/bcm_click.uo however I don't currently understand how this is invoked by the Meraki firmware. Here's the Meraki firmware output on the console during/after the Broadcom kernel modules are loaded:

[   17.224289] boot 26 build switch-12-202008242327-G4db7ce45-rel-zoology board switch-arm mac 0C:8D:DB:XX:XX:XX
[   17.591853] Module: amc6821  .text=0x3f020000 .data=0x3f021644 .bss=0x3f021b50
[   17.591853] Module: linux_kernel_bde  .text=0x3f026000 .data=0x3f02cb70 .bss=0x3f02fa2c
[   17.591853] Module: linux_user_bde  .text=0x3f039000 .data=0x3f03d47c .bss=0x3f03d740
[   17.813024] RUNIT: not installed
[   20.975146] OK
[   20.977529] Starting ciscotamservices
[   38.704173] !!!!! {/usr/bin/switch_brain} opening /click/sw0_ctrl/mac_temp failed: No such file or directory
[   38.730404] !!!!! {/usr/bin/switch_brain} opening /click/sw0_ctrl/mac_temp failed: No such file or directory
[   38.751169] !!!!! {/usr/bin/switch_brain} opening /click/switch_port_table/dump_stack_info_and_reset_stack_change failed: No such file or directory
[   40.953426] DMA pool size: 33554432
[   42.260552] AXI unit 0: Dev 0xb160, Rev 0x11, Chip BCM56160_B0, Driver BCM56160_A0
[   42.280076] PCI unit 1: Dev 0xb160, Rev 0x11, Chip BCM56160_B0, Driver BCM56160_A0
[   42.320164] SOC unit 0 attached to PCI device BCM56160_B0
[   46.844638] Firmware download success
[   46.930777] Error Gp3:0 app:8805--:40
[   47.018989] Error Gp3:8885 app:8805--:41
[   47.600162] SOC unit 1 attached to PCI device BCM56160_B0
[   50.507499] Broadcom Command Monitor: Copyright (c) 1998-2020 Broadcom
[   50.520408] Release: sdk-6.5.12 built 20200825 (Tue Aug 25 01:53:37 2020)
[   50.533465] From [email protected]:/mnt/jenkins/workspace/router/prod-signing/switch-12-4/base/build_switch-arm/bcm-switch
[   50.557298] Platform: MERAKI_SWITCH_ARM
[   50.570308] OS: Unix (Posix)
[   51.140154] Stacking initialized
[   51.820205] Stack attach callback
[   51.823954] Unit 0 (attaching) is: 0C:8D:DB:XX:XX:XX
[   51.828910] Stack attach callback
[   51.840110] Unit 1 (attaching) is: 0C:8D:DB:XX:XX:XX
[   51.845103] STACK: master on c:8d:db:xx:xx:xx (1 cpu, 2 units)
[   51.860077] STACK: attach 2 units on 1 cpu
[   52.191668] sw0_ctrl :: BroadcomSwitchController Stack topology changed but list of stack members didn't.

Current status

The u-boot configuration has been modified to allow for interrupting default the boot sequence and booting via tftp.

A minimal buildroot firmware exists, however the device is not functional as a switch as the userspace switching engine initialization method is unknown, bcm_click.uo in the Meraki firmware is dynamically linked to other libraries, and there is no public documentation available from Broadcom on the OpenNSA API.

tl;dr the MS225 boots but is useless as a switch as the ASIC is unmanaged 😒

Hardware info

/ # cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 2498.56
Features        : half thumb fastmult edsp tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x4
CPU part        : 0xc09
CPU revision    : 1

Hardware        : BRUMBY
Revision        : 0000
Serial          : 0000000000000000

/ # cat /proc/mtd
dev:    size   erasesize  name
mtd0: 10000000 00020000 "ubi"
mtd1: 00100000 00010000 "uboot"
mtd2: 00700000 00010000 "bootkernel1"
mtd3: 00000000 00000000 "bootkernel2"
mtd4: 0192e000 0001f000 "part.old"
mtd5: 01943000 0001f000 "part.safe"
mtd6: 0801e000 0001f000 "storage"

/ # lspci
00:00.0 PCI bridge: Broadcom Inc. and subsidiaries Device b160 (rev 11)
01:00.0 Ethernet controller: Broadcom Inc. and subsidiaries Device b160 (rev 11)
01:00.1 Ethernet controller: Broadcom Inc. and subsidiaries Device b160 (rev 11)

/ # lspci -vvv
00:00.0 PCI bridge: Broadcom Inc. and subsidiaries Device b160 (rev 11) (prog-if 00 [Normal decode])
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 111
        Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
        I/O behind bridge: 00000000-00000fff [size=4K]
        Memory behind bridge: fff00000-000fffff [disabled]
        Prefetchable memory behind bridge: 0000000020000000-0000000020bfffff [size=12M]
        Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
        BridgeCtl: Parity+ SERR- NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
                PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
        Capabilities: [48] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
        Capabilities: [ac] Express (v2) Root Port (Slot-), MSI 00
                DevCap: MaxPayload 128 bytes, PhantFunc 0
                        ExtTag- RBE+
                DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
                        RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
                        MaxPayload 128 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <2us
                        ClockPM+ Surprise- LLActRep- BwNot+ ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 5GT/s (ok), Width x1 (ok)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt+ ABWMgmt-
                RootCap: CRSVisible+
                RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible+
                RootSta: PME ReqID 0000, PMEStatus- PMEPending-
                DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
                         10BitTagComp- 10BitTagReq- OBFF Via WAKE#, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- LN System CLS Not Supported, TPHComp- ExtTPHComp- ARIFwd-
                         AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LTR- OBFF Disabled, ARIFwd-
                         AtomicOpsCtl: ReqEn- EgressBlck-
                LnkCap2: Supported Link Speeds: 2.5-5GT/s, Crosslink- Retimer- 2Retimers- DRS-
                LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
                         EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: unsupported
        Capabilities: [100 v1] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
                AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
                RootCmd: CERptEn+ NFERptEn+ FERptEn+
                RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
                         FirstFatal- NonFatalMsg- FatalMsg- IntMsg 0
                ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
        Capabilities: [180 v1] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
        Capabilities: [240 v1] L1 PM Substates
                L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
                          PortCommonModeRestoreTime=8us PortTPowerOnTime=10us
                L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
                           T_CommonMode=1us LTR1.2_Threshold=0ns
                L1SubCtl2: T_PwrOn=10us
        Kernel driver in use: pcieport

01:00.0 Ethernet controller: Broadcom Inc. and subsidiaries Device b160 (rev 11)
        Subsystem: Broadcom Inc. and subsidiaries Device b160
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 111
        Region 0: Memory at 20800000 (64-bit, prefetchable) [size=32K]
        Region 2: Memory at 20000000 (64-bit, prefetchable) [size=8M]
        Capabilities: [48] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
        Capabilities: [50] Vital Product Data
pcilib: sysfs_read_vpd: read failed: Connection timed out
                Not readable
        Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
                Address: 0000000000000000  Data: 0000
        Capabilities: [a0] MSI-X: Enable- Count=1 Masked-
                Vector table: BAR=0 offset=00000000
                PBA: BAR=0 offset=00000000
        Capabilities: [ac] Express (v2) Endpoint, MSI 00
                DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
                        ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000W
                DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
                       RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop+
                        MaxPayload 128 bytes, MaxReadReq 128 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <2us
                        ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 5GT/s (ok), Width x1 (ok)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
                         10BitTagComp- 10BitTagReq- OBFF Via WAKE#, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- TPHComp- ExtTPHComp-
                         AtomicOpsCap: 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LTR- OBFF Disabled,
                         AtomicOpsCtl: ReqEn-
                LnkCap2: Supported Link Speeds: 2.5-5GT/s, Crosslink- Retimer- 2Retimers- DRS-
                LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete- EqualizationPhase1-
                         EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: unsupported
        Capabilities: [100 v1] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
                AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
        Capabilities: [13c v1] Device Serial Number 00-00-00-00-00-00-00-00
        Capabilities: [150 v1] Power Budgeting <?>
        Capabilities: [160 v1] Virtual Channel
                Caps:   LPEVC=0 RefClk=100ns PATEntryBits=1
                Arb:    Fixed- WRR32- WRR64- WRR128-
                Ctrl:   ArbSelect=Fixed
                Status: InProgress-
                VC0:    Caps:   PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
                        Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
                        Ctrl:   Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
                        Status: NegoPending- InProgress-
        Capabilities: [180 v1] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
        Capabilities: [1b0 v1] Latency Tolerance Reporting
                Max snoop latency: 0ns
                Max no snoop latency: 0ns
        Kernel driver in use: linux-kernel-bde

01:00.1 Ethernet controller: Broadcom Inc. and subsidiaries Device b160 (rev 11)
        Subsystem: Broadcom Inc. and subsidiaries Device b160
        Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin B routed to IRQ 111
        Region 0: Memory at 20808000 (64-bit, prefetchable) [disabled] [size=32K]
        Capabilities: [48] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
        Capabilities: [50] Vital Product Data
pcilib: sysfs_read_vpd: read failed: Connection timed out
                Not readable
        Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
                Address: 0000000000000000  Data: 0000
        Capabilities: [a0] MSI-X: Enable- Count=1 Masked-
                Vector table: BAR=0 offset=00000000
                PBA: BAR=0 offset=00000000
        Capabilities: [ac] Express (v2) Endpoint, MSI 00
                DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
                        ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000W
                DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
                        RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
                        MaxPayload 128 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <2us
                        ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 5GT/s (ok), Width x1 (ok)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
                         10BitTagComp- 10BitTagReq- OBFF Via WAKE#, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- TPHComp- ExtTPHComp-
                         AtomicOpsCap: 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LTR- OBFF Disabled,
                         AtomicOpsCtl: ReqEn-
                LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete- EqualizationPhase1-
                         EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: unsupported
        Capabilities: [100 v1] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
                AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
        Capabilities: [13c v1] Device Serial Number 00-00-00-00-00-00-00-00
        Capabilities: [150 v1] Power Budgeting <?>
        Capabilities: [160 v1] Virtual Channel
                Caps:   LPEVC=0 RefClk=100ns PATEntryBits=1
                Arb:    Fixed- WRR32- WRR64- WRR128-
                Ctrl:   ArbSelect=Fixed
                Status: InProgress-
                VC0:    Caps:   PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
                        Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
                        Ctrl:   Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
                        Status: NegoPending- InProgress-
        Capabilities: [180 v1] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
        Kernel driver in use: linux-kernel-bde

Related hardware

The Brocade ICX7150 appears to be based on the same ASIC, however they have not yet released the GPL source code for this model (a request has been sent).

Unrelated hardware

The Ubiquiti Switch Pro Aggregation is based on the Broadcom 56170. The GPL source code can be found in the usw-pro-aggregation repository.

Generate flashable image using buildroot

The current build instructions involve multiple stages, including building the "OpenWrt" toolchain provided in the GPL archive from Meraki. This is cumbersome and inefficient.

It would be much simpler and more efficient to use the buildroot toolchain to build the kernel and assemble the flashable firmware image.

PD690xx PoE daemon

The init script S03gpio currently auto-configures the PD690xx for PoE. This allows for "plug-and-play" PoE functionality on the switch (at least on the MS220-8P; I don't have other Meraki PoE enabled hardware to test).

However, more advanced functionality which is present in the original Meraki firmware is not possible, this includes:

  • querying the PoE power budget
  • disabling PoE on a port (e.g. to power cycle a PoE device)
  • configuring 802.3at/af on a port

And probably more things I don't know about since I don't have much experience with PoE.

Resources:

MS42 not correctly detected

The MS42 has the following output during boot, and is not correctly detected:

Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
cat: read error: Connection timed out
[    8.743000] random: nonblocking pool is initialized
[   21.965000] vtss_core: module license '(c) Vitesse Semiconductor Inc.' taints kernel.
[   21.973000] Disabling lock debugging due to kernel taint
[   22.432000] switch: 'Meraki MS220-48' board detected
Loaded 'jaguar_dual/vtss_core.ko board_desc=MERAKI_BOARD_MS220_48'
Loaded 'proclikefs.ko'
[   39.937000] click: starting router thread pid 397 (87b67600)
Loaded 'merakiclick.ko'
Loaded 'elts_meraki.ko'
Loaded 'jaguar_dual/vc_click.ko'
cat: read error: Connection timed out
sh: -c requires an argument
sh: -c requires an argument
[   82.655000] click-config/switch/io-real/vitesse.click:10: While configuring 'from_arping :: FromHost':
[   82.665000]   PREFIX: parse error
[   82.678000] click-config/switch.template:74: While configuring 'switch_intf_table :: SwitchIntfTable':
[   82.688000]   MAC: required argument missing
[   82.693000]   too many arguments
[   82.697000] click-config/switch.template:166: While configuring 'wan0_ndsolicit :: IP6NDSolicitor':
[   82.706000]   ETH: required argument missing
[   82.711000]   too many arguments
[   82.715000] click-config/switch.template:202: While configuring 'client_ip_table :: ClientIPTable':
[   82.724000]   too many arguments
...(unhappiness continues)

Web UI for switch management

There is no UI in the firmware to configure the switch. Users are required to use SSH if they want to make changes to the switch configuration. This is not a great user experience, as even simple layer 2 switches include web management (though often not SSH).

Please see #2 for my thoughts on how switch configuration could work on the backend, and how it might make development of a management UI simpler.

I am not good at front-end development, nor do I have time/desire to write a Web UI for the firmware. This issue is a placeholder for anyone else who is interested in writing a management UI.

Build Documentation

Whilst the current build documentation provides a good high level overview of the build process, there would be some benefit to expanding on it to encourage community uptake in the project.

Detailing prerequisites and procedures for building the following:

  • Buildroot
  • Building OpenWRT
  • Stage 1/2 make scripts

It would be helpful to highlight what each phase produces, and how the output is then used in the next phase in a step-by-step manner.

Happy to do this, and expand on the current build scripts to automate the process further where possible also.

DHCP Broadcast not passed through

Whilst I've not fully tested this yet, I seem to see a weird behaviour when following these steps:

  1. Connect DHCP Server and upstream network to Port 1.
  2. Boot up MS220-8P
  3. Connect POE powered device (MR-18 flashed with OpenWRT) to Port 2.
  4. Device on port 2 does not acquire an IP address.

I suspect that either the switch is not passing on DHCP packets or probably more likely isn't forwarding broadcast packets?

I'll continue to investigate with some wireshark etc.

Couldn't determine board model, THINGS WILL BE BROKEN on postmerkOS-20220204

First up, a massive thanks for working on this project :)
I successfully flashed an earlier .bin to a MS220-8P last year, but thought I'd revisit with your 2022-02-04 build.
Flashed just fine with a raspberry pi on spi bus.
I don't get any network connectivity and boot log looks like something has gone wrong.
I'll have a go at compiling but not overly sure what I'm doing there..

LinuxLoader built Nov 12 2002 18:01:50
init_pll ok
init_spi ok
init_memctl ok
wait_memctl ok
Training DRAM ok
init_irq ok
init_dram_uncached ok
init_icache ok
init_dcache ok
enable_caches ok
init_board ok
Low level initialization complete, exiting boot mode
[    0.000000] Linux version 3.18.123-meraki-elemental (hmartin@alp) (gcc version 5.4.0 (GCC) ) #10 Sat Jul 18 17:06:37 UTC 2020
[    0.000000] CPU0 revision is: 02019654 (MIPS 24KEc)
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 00477000 @ 00100000 (usable)
[    0.000000]  memory: 00049000 @ 00577000 (usable after init)
[    0.000000] User-defined physical RAM map:
[    0.000000]  memory: 07ff0000 @ 00000000 (usable)
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]
[    0.000000] Reserving 0MB of memory at 0MB for crashkernel
[    0.000000] Kernel command line: console=ttyS0,115200 mtdparts=m25p80:0x40000(redboot),0x2c0000(kernel),0x800000(squashfs),0x500000(overlay) root=/dev/mtdblock3 ubi.mtd=gen_nand.0 mem=134152192
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Writing ErrCtl register=80005024
[    0.000000] Readback ErrCtl register=80005024
[    0.000000] Cache parity protection enabled
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:66
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns
[    0.001000] Calibrating delay loop... 275.45 BogoMIPS (lpj=137728)
[    0.010000] pid_max: default: 32768 minimum: 301
[    0.010000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.010000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.012000] ftrace: allocating 11994 entries in 24 pages
[    0.039000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)
[    0.045000] devtmpfs: initialized
[    0.051000] NET: Registered protocol family 16
[    0.112000] Switched to clocksource MIPS
[    0.139000] NET: Registered protocol family 2
[    0.141000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.141000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.141000] TCP: Hash tables configured (established 1024 bind 1024)
[    0.142000] TCP: reno registered
[    0.142000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.142000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.142000] NET: Registered protocol family 1
[    0.147000] VCORE-III Watchdog Timer enabled (30 seconds).  Prev boot was not caused by WDT reset.
[    0.149000] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.178000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.178000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    0.180000] msgmni has been set to 241
[    0.208000] io scheduler noop registered
[    0.208000] io scheduler deadline registered (default)
[    0.210000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[    0.211000] console [ttyS0] disabled
[    0.212000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A
[    0.512000] console [ttyS0] enabled
[    0.521000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    0.527000] nand: Micron MT29F1G08ABADAWP
[    0.531000] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[    0.543000] Scanning device for bad blocks
[    0.658000] m25p80 spi0.1: found mx25l12805d, expected m25p80
[    0.664000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)
[    0.669000] 4 cmdlinepart partitions found on MTD device m25p80
[    0.675000] Creating 4 MTD partitions on "m25p80":
[    0.680000] 0x000000000000-0x000000040000 : "redboot"
[    0.695000] 0x000000040000-0x000000300000 : "kernel"
[    0.704000] 0x000000300000-0x000000b00000 : "squashfs"
[    0.716000] 0x000000b00000-0x000001000000 : "overlay"
[    0.728000] tun: Universal TUN/TAP device driver, 1.6
[    0.733000] tun: (C) 1999-2004 Max Krasnyansky <[email protected]>
[    0.740000] i2c /dev entries driver
[    0.746000] TCP: cubic registered
[    0.750000] Initializing XFRM netlink socket
[    0.757000] NET: Registered protocol family 10
[    0.772000] NET: Registered protocol family 17
[    0.777000] NET: Registered protocol family 15
[    0.782000] 8021q: 802.1Q VLAN Support v1.8
[    0.786000] Meraki MS220-8 board detected
[    0.797000] i2c-gpio i2c-gpio.1: using pins 6 (SDA) and 5 (SCL)
[    0.814000] UBI: attaching mtd0 to ubi0
[    1.604000] UBI: scanning is finished
[    1.642000] UBI: attached mtd0 (name "gen_nand.0", size 128 MiB) to ubi0
[    1.649000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[    1.656000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[    1.663000] UBI: VID header offset: 512 (aligned 512), data offset: 2048
[    1.670000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0
[    1.676000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128
[    1.683000] UBI: max/mean erase counter: 658/365, WL threshold: 4096, image sequence number: 1363641321
[    1.693000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20
[    1.703000] UBI: background thread "ubi_bgt0d" started, PID 247
[    1.785000] devtmpfs: mounted
[    1.818000] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[    1.849000] devtmpfs: mounted
[    1.857000] Freeing unused kernel memory: 292K
[    5.729000] devpts: called with bogus options
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
!!! IMPORTANT !!!
Couldn't determine board model, THINGS WILL BE BROKEN. model=, product= please open an issue on github.com/halmartin/meraki-builder
!!! IMPORTANT !!!
insmod: ERROR: could not load module /lib/modules//vtss_core.ko: No such file or directory
Loaded 'proclikefs.ko'
[   39.384000] random: nonblocking pool is initialized
Loaded 'merakiclick.ko'
[   43.212000] click: starting router thread pid 372 (87a81700)
[   53.919000] elts_meraki: module license 'unspecified' taints kernel.
[   53.925000] Disabling lock debugging due to kernel taint
Loaded 'elts_meraki.ko'
insmod: ERROR: could not load module /lib/modules//vc_click.ko: No such file or directory
[   55.893000] unsatisfied requirement 'vc_click'
[   55.898000] click-config/switch/io-real/vitesse.click:26: unknown element class 'ToVitesse'
[   55.907000] click-config/switch/io-real/vitesse.click:31: unknown element class 'FromVitesse'
[   55.917000] click-config/switch/io-real/vitesse.click:59: unknown element class 'VitesseController'
[   56.210000] click-config/switch.template:74: While configuring 'switch_intf_table :: SwitchIntfTable':
[   56.220000]   SWITCH_HARDWARE: element type mismatch, expected SwitchHardwareIntf
[   56.230000] click-config/switch.template:1045: While configuring 'switch_port_table :: SwitchPortTable':
[   56.240000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.263000] click-config/switch.template:58: While configuring 'l3_update_hardware :: UpdateHardwareTable':
[   56.273000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.289000] click-config/switch.template:383: While configuring 'switch_rpc_server :: SwitchRPCServer':
[   56.299000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.308000] click-config/switch.template:566: While configuring 'CheckStackMaster@187 :: CheckStackMaster':
[   56.318000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.326000] click-config/switch.template:602: While configuring 'CheckStackMaster@235 :: CheckStackMaster':
[   56.336000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.344000] click-config/switch.template:633: While configuring 'switch_mrt :: MulticastRoutingTable':
[   56.354000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.365000] click-config/switch.template:655: While configuring 'ospf_hello_inspector :: OspfHelloInspector':
[   56.375000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.403000] click-config/switch.template:875: While configuring 'msstp_encap_inst :: MSSTPEncap':
[   56.412000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.423000] click-config/switch.template:930: While configuring 'IntraStackResolver@527 :: IntraStackResolver':
[   56.433000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.444000] click-config/switch.template:1072: While configuring 'igmp_table :: IGMPSnoopTable':
[   56.453000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.462000] click-config/switch.template:1093: While configuring 'mld_table :: MLDSnoopTable':
[   56.471000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   56.482000] click-config/switch.template:1125: While configuring 'msstp_decap :: MSSTPDecap':
[   56.490000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.502000] click-config/switch.template:1187: While configuring 'CheckStackMaster@664 :: CheckStackMaster':
[   56.512000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.519000] click-config/switch.template:1189: While configuring 'CheckStackMaster@669 :: CheckStackMaster':
[   56.530000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.537000] click-config/switch.template:1199: While configuring 'CheckStackMaster@680 :: CheckStackMaster':
[   56.547000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.554000] click-config/switch.template:1212: While configuring 'CheckStackMaster@693 :: CheckStackMaster':
[   56.564000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.573000] click-config/switch.template:1238: While configuring 'CheckStackMaster@726 :: CheckStackMaster':
[   56.583000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.594000] click-config/switch.template:1307: While configuring 'stp_check_master :: CheckStackMaster':
[   56.604000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.611000] click-config/switch.template:1320: While configuring 'lacp_check_master :: CheckStackMaster':
[   56.621000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.629000] click-config/switch.template:1409: While configuring 'udld :: UDLD':
[   56.637000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.646000] click-config/switch.template:1459: While configuring 'CheckStackMaster@861 :: CheckStackMaster':
[   56.656000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   56.731000] Router could not be initialized!
Default port count: 10
net.ipv4.ip_local_reserved_ports = 50000-50127
vc_click isn't loaded; aborting!
/etc/init.d/S11leds: line 8: can't create /click/sw0_ctrl/power_led_orange: nonexistent directory
/etc/init.d/S11leds: line 9: can't create /click/sw0_ctrl/power_led_green: nonexistent directory
Saving random seed: SKIP (read-only file system detected)
Starting network: OK
Starting chrony: Could not open /etc/chrony.conf : No such file or directory
FAIL
Starting dropbear sshd: OK

MS120-24P support

Hi,

It seems like there is not yet any support for MS120-24P.

I have one of those switches available. Can i assist in getting it supported?

/David

Switch detection for MS220-24/48 broken

Meraki left the switch model of both the MS220-24 and MS220-48 as meraki_elemental in the board-config MTD.

Therefore, the board detection in S08kmods is wrong.

The check should be changed to something like this:

    elif [ $(echo $model | grep -c MS220-24) -eq 1 ]; || ( [ $(echo $model | grep -c meraki_elemental) -eq 1 ] && [ $(cat /proc/cpuinfo | grep -c VSC7427) -eq 1] ) then
        mod_dir=luton26
        switch_board=MERAKI_BOARD_MS220_24
        echo 24 > /tmp/NUM_PORTS
    elif [ $(echo $model | grep -c MS220-48) -eq 1 ] || ( [ $(echo $model | grep -c meraki_elemental) -eq 1 ] && [ $(cat /proc/cpuinfo | grep -c VSC7434) -eq 1] ); then
        mod_dir=jaguar_dual
        switch_board=MERAKI_BOARD_MS220_48
        echo 52 > /tmp/NUM_PORTS

Alternatively, just handle the case of meraki_elemental here.

Mainline u-boot support

As mentioned in #4, it is possible to build and boot u-boot on the MS220-8P:

U-Boot 2019.10 (Apr 04 2020 - 09:26:23 +0000)

MSCC VCore-III MIPS 24Kec
Model: Luton26 PCB090 Reference Board
DRAM:  128 MiB
Loading Environment from SPI Flash... SF: Detected mx25l12805d with page size 256 Bytes, erase size 64 KiB, total 16 MiB

OK
In:    serial@10100000
Out:   serial@10100000
Err:   serial@10100000
Net:   Could not get PHY for miim-bus1: addr 0
Could not get PHY for miim-bus1: addr 1
Could not get PHY for miim-bus1: addr 2
Could not get PHY for miim-bus1: addr 3
Could not get PHY for miim-bus1: addr 4
Could not get PHY for miim-bus1: addr 5
Could not get PHY for miim-bus1: addr 6
Could not get PHY for miim-bus1: addr 7
Could not get PHY for miim-bus1: addr 8
Could not get PHY for miim-bus1: addr 9
Could not get PHY for miim-bus1: addr 10
Could not get PHY for miim-bus1: addr 11

Warning: switch@1010000 (eth0) using random MAC address - ee:6a:6f:da:b9:7a
eth0: switch@1010000
Hit any key to stop autoboot:  0 
luton # dhcp
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
BOOTP broadcast 4
BOOTP broadcast 5
BOOTP broadcast 6
BOOTP broadcast 7
BOOTP broadcast 8
BOOTP broadcast 9
BOOTP broadcast 10
BOOTP broadcast 11
BOOTP broadcast 12
BOOTP broadcast 13
DHCP client bound to address 192.168.0.51 (20779 ms)

There are however, some issues as the pcb090 reference implementation in u-boot does not match the hardware configuration of the MS220-8P:

u-boot brings some really nice benefits to the switch:

  • change the kernel command line without recompiling
  • tftp boot the kernel without flashing
  • supported/expected by other firmwares (e.g. OpenWrt)

Mainline Linux support for vcoreiii ASIC

u-boot has basic support for the luton26, including networking support.

It is possible to build and boot u-boot on the MS220-8P with functional networking:

U-Boot 2019.10 (Apr 04 2020 - 09:26:23 +0000)

MSCC VCore-III MIPS 24Kec
Model: Luton26 PCB090 Reference Board
DRAM:  128 MiB
Loading Environment from SPI Flash... SF: Detected mx25l12805d with page size 256 Bytes, erase size 64 KiB, total 16 MiB

OK
In:    serial@10100000
Out:   serial@10100000
Err:   serial@10100000
Net:   Could not get PHY for miim-bus1: addr 0
Could not get PHY for miim-bus1: addr 1
Could not get PHY for miim-bus1: addr 2
Could not get PHY for miim-bus1: addr 3
Could not get PHY for miim-bus1: addr 4
Could not get PHY for miim-bus1: addr 5
Could not get PHY for miim-bus1: addr 6
Could not get PHY for miim-bus1: addr 7
Could not get PHY for miim-bus1: addr 8
Could not get PHY for miim-bus1: addr 9
Could not get PHY for miim-bus1: addr 10
Could not get PHY for miim-bus1: addr 11

Warning: switch@1010000 (eth0) using random MAC address - ee:6a:6f:da:b9:7a
eth0: switch@1010000
Hit any key to stop autoboot:  0 
luton # dhcp
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
BOOTP broadcast 4
BOOTP broadcast 5
BOOTP broadcast 6
BOOTP broadcast 7
BOOTP broadcast 8
BOOTP broadcast 9
BOOTP broadcast 10
BOOTP broadcast 11
BOOTP broadcast 12
BOOTP broadcast 13
DHCP client bound to address 192.168.0.51 (20779 ms)

The Luton26 PCB090 Reference Board does not correspond exactly to the MS220-8P (nor, I suspect, to the MS220-24). This is the cause of the miim-bus1 errors above, incorrect system LED output, and may be related to the MS220-8P losing uart output after userspace starts.

Support for Jaguar1 (MS42, MS220-48, MS320-48) does not yet exist in u-boot.

The ultimate stretch goal would be upstream support in the kernel for the Vitesse ASICs used in Meraki switches, as this would allow newer kernels and support for other operating systems like OpenWrt on the hardware.

MS320-48 fails on first boot "failed back to cpuinfo board detection" Does not detect model number

Hey, just tried to drop the firmware on one of my MS320-48's and the system was unable to fully boot. It appears to me that it was unable to read the model number from the system.

Is there anything that I can try to get auto detection to work? If not I might try to see if I can roll my own version that bypasses the detection and just jumps past with the proper values.

Boot log is as follows.

⸮LinuxLoader built Nov 12 2020 18:01:50
init_pll ok
init_spi ok
init_memctl ok
wait_memctl ok
Training DRAM ok
init_irq ok
init_dram_uncached ok
init_icache ok
init_dcache ok
enable_caches ok
init_pi ok
init_board ok
Low level initialization complete, exiting boot mode
[    0.000000] Linux version 3.18.123-meraki-elemental (hmartin@alp) (gcc version 5.4.0 (GCC) ) #10 Sat Jul 18 17:06:37 UTC 2020
[    0.000000] CPU0 revision is: 01019654 (MIPS 24KEc)
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 00477000 @ 00100000 (usable)
[    0.000000]  memory: 00049000 @ 00577000 (usable after init)
[    0.000000] User-defined physical RAM map:
[    0.000000]  memory: 07ff0000 @ 00000000 (usable)
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]
[    0.000000] Reserving 0MB of memory at 0MB for crashkernel
[    0.000000] Kernel command line: console=ttyS0,115200 mtdparts=m25p80:0x40000(redboot),0x2c0000(kernel),0x800000(squashfs),0x500000(overlay) root=/dev/mtdblock3 ubi.mtd=gen_nand.0 mem=134152192
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Writing ErrCtl register=8006e000
[    0.000000] Readback ErrCtl register=8006e000
[    0.000000] Cache parity protection enabled
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:66
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns
[    0.002000] VCore-III slave device ID 7460 found
[    0.002000] Calibrating delay loop... 275.45 BogoMIPS (lpj=137728)
[    0.011000] pid_max: default: 32768 minimum: 301
[    0.011000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.011000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.013000] ftrace: allocating 11994 entries in 24 pages
[    0.041000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)
[    0.048000] devtmpfs: initialized
[    0.055000] NET: Registered protocol family 16
[    0.094000] Switched to clocksource MIPS
[    0.124000] NET: Registered protocol family 2
[    0.127000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.128000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.128000] TCP: Hash tables configured (established 1024 bind 1024)
[    0.128000] TCP: reno registered
[    0.128000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.128000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.129000] NET: Registered protocol family 1
[    0.133000] VCORE-III Watchdog Timer enabled (30 seconds).  Prev boot was not caused by WDT reset.
[    0.158000] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.195000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.195000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    0.198000] msgmni has been set to 241
[    0.226000] io scheduler noop registered
[    0.226000] io scheduler deadline registered (default)
[    0.228000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[    0.230000] console [ttyS0] disabled
[    0.231000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A
[    0.612000] console [ttyS0] enabled
[    0.622000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    0.628000] nand: Micron MT29F1G08ABADAWP
[    0.632000] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[    0.644000] Scanning device for bad blocks
[    0.670000] Bad eraseblock 211 at 0x000001a60000
[    0.768000] m25p80 spi0.1: found mx25l12805d, expected m25p80
[    0.774000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)
[    0.779000] 4 cmdlinepart partitions found on MTD device m25p80
[    0.785000] Creating 4 MTD partitions on "m25p80":
[    0.790000] 0x000000000000-0x000000040000 : "redboot"
[    0.810000] 0x000000040000-0x000000300000 : "kernel"
[    0.820000] 0x000000300000-0x000000b00000 : "squashfs"
[    0.835000] 0x000000b00000-0x000001000000 : "overlay"
[    0.849000] tun: Universal TUN/TAP device driver, 1.6
[    0.855000] tun: (C) 1999-2004 Max Krasnyansky <[email protected]>
[    0.864000] i2c /dev entries driver
[    0.871000] TCP: cubic registered
[    0.874000] Initializing XFRM netlink socket
[    0.882000] NET: Registered protocol family 10
[    0.891000] NET: Registered protocol family 17
[    0.896000] NET: Registered protocol family 15
[    0.900000] 8021q: 802.1Q VLAN Support v1.8
[    0.911000] i2c-gpio i2c-gpio.1: using pins 15 (SDA) and 14 (SCL)
[    0.917000] at24 1-0051: 1024 byte 24c08 EEPROM, writable, 8 bytes/write
[    0.926000] meraki-config meraki-config: Meraki config device loaded
[    1.063000] i2c-gpio i2c-gpio.2: using pins 708 (SDA) and 709 (SCL)
[    1.118000] i2c-gpio i2c-gpio.3: using pins 714 (SDA) and 715 (SCL)
[    1.174000] i2c-gpio i2c-gpio.4: using pins 720 (SDA) and 721 (SCL)
[    1.231000] i2c-gpio i2c-gpio.5: using pins 726 (SDA) and 727 (SCL)
[    1.248000] tmp401 6-004c: Detected TI TMP411 chip
[    1.258000] i2c-gpio i2c-gpio.6: using pins 47 (SDA) and 46 (SCL)
[    1.276000] i2c-gpio i2c-gpio.7: using pins 51 (SDA) and 50 (SCL)
[    1.291000] i2c-gpio i2c-gpio.8: using pins 53 (SDA) and 52 (SCL)
[    1.300000] at24 2-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[    1.307000] at24 3-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[    1.314000] at24 4-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[    1.322000] at24 5-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[    1.335000] pca953x 6-0022: interrupt support not compiled in
[    1.352000] UBI: attaching mtd0 to ubi0
[    2.162000] UBI: scanning is finished
[    2.204000] UBI: attached mtd0 (name "gen_nand.0", size 128 MiB) to ubi0
[    2.211000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[    2.218000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[    2.225000] UBI: VID header offset: 512 (aligned 512), data offset: 2048
[    2.231000] UBI: good PEBs: 1023, bad PEBs: 1, corrupted PEBs: 0
[    2.237000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128
[    2.245000] UBI: max/mean erase counter: 2902/2040, WL threshold: 4096, image sequence number: 2124770675
[    2.255000] UBI: available PEBs: 407, total reserved PEBs: 616, PEBs reserved for bad PEB handling: 19
[    2.265000] UBI: background thread "ubi_bgt0d" started, PID 297
[    2.385000] devtmpfs: mounted
[    2.418000] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[    2.456000] devtmpfs: mounted
[    2.465000] Freeing unused kernel memory: 292K
[    6.415000] devpts: called with bogus options
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
!!! IMPORTANT !!!
Falling back to cpuinfo board detection, your board model is: , please open an issue on github.com/halmartin/meraki-builder
!!! IMPORTANT !!!
[    8.792000] random: nonblocking pool is initialized
insmod: ERROR: could not load module /lib/modules//vtss_core.ko: No such file or directory
Loaded 'proclikefs.ko'
[   15.030000] click: starting router thread pid 471 (87b62900)
Loaded 'merakiclick.ko'
[   26.171000] elts_meraki: module license 'unspecified' taints kernel.
[   26.178000] Disabling lock debugging due to kernel taint
Loaded 'elts_meraki.ko'
insmod: ERROR: could not load module /lib/modules//vc_click.ko: No such file or directory
[   28.401000] unsatisfied requirement 'vc_click'
[   28.407000] click-config/switch/io-real/vitesse.click:26: unknown element class 'ToVitesse'
[   28.416000] click-config/switch/io-real/vitesse.click:31: unknown element class 'FromVitesse'
[   28.426000] click-config/switch/io-real/vitesse.click:59: unknown element class 'VitesseController'
[   28.753000] click-config/switch.template:74: While configuring 'switch_intf_table :: SwitchIntfTable':
[   28.763000]   SWITCH_HARDWARE: element type mismatch, expected SwitchHardwareIntf
[   28.774000] click-config/switch.template:1045: While configuring 'switch_port_table :: SwitchPortTable':
[   28.783000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   28.815000] click-config/switch.template:58: While configuring 'l3_update_hardware :: UpdateHardwareTable':
[   28.825000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   28.843000] click-config/switch.template:383: While configuring 'switch_rpc_server :: SwitchRPCServer':
[   28.853000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   28.863000] click-config/switch.template:566: While configuring 'CheckStackMaster@187 :: CheckStackMaster':
[   28.873000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   28.881000] click-config/switch.template:602: While configuring 'CheckStackMaster@235 :: CheckStackMaster':
[   28.891000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   28.900000] click-config/switch.template:633: While configuring 'switch_mrt :: MulticastRoutingTable':
[   28.909000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   28.920000] click-config/switch.template:655: While configuring 'ospf_hello_inspector :: OspfHelloInspector':
[   28.931000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   28.963000] click-config/switch.template:875: While configuring 'msstp_encap_inst :: MSSTPEncap':
[   28.972000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   28.984000] click-config/switch.template:930: While configuring 'IntraStackResolver@527 :: IntraStackResolver':
[   28.994000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.006000] click-config/switch.template:1072: While configuring 'igmp_table :: IGMPSnoopTable':
[   29.015000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   29.024000] click-config/switch.template:1093: While configuring 'mld_table :: MLDSnoopTable':
[   29.033000]   SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[   29.044000] click-config/switch.template:1125: While configuring 'msstp_decap :: MSSTPDecap':
[   29.053000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.066000] click-config/switch.template:1187: While configuring 'CheckStackMaster@664 :: CheckStackMaster':
[   29.076000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.083000] click-config/switch.template:1189: While configuring 'CheckStackMaster@669 :: CheckStackMaster':
[   29.093000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.101000] click-config/switch.template:1199: While configuring 'CheckStackMaster@680 :: CheckStackMaster':
[   29.111000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.118000] click-config/switch.template:1212: While configuring 'CheckStackMaster@693 :: CheckStackMaster':
[   29.128000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.138000] click-config/switch.template:1238: While configuring 'CheckStackMaster@726 :: CheckStackMaster':
[   29.148000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.159000] click-config/switch.template:1307: While configuring 'stp_check_master :: CheckStackMaster':
[   29.169000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.177000] click-config/switch.template:1320: While configuring 'lacp_check_master :: CheckStackMaster':
[   29.187000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.195000] click-config/switch.template:1409: While configuring 'udld :: UDLD':
[   29.203000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.213000] click-config/switch.template:1459: While configuring 'CheckStackMaster@861 :: CheckStackMaster':
[   29.223000]   HW_INTF: element type mismatch, expected SwitchHardwareIntf
[   29.311000] Router could not be initialized!
Default port count: 10
net.ipv4.ip_local_reserved_ports = 50000-50127
vc_click isn't loaded; aborting!
/etc/init.d/S11leds: line 8: can't create /click/sw0_ctrl/power_led_orange: nonexistent directory
/etc/init.d/S11leds: line 9: can't create /click/sw0_ctrl/power_led_green: nonexistent directory
Saving random seed: SKIP (read-only file system detected)
Starting network: OK
Starting chrony: Could not open configuration file /etc/chrony.conf : No such file or directory
FAIL
Starting dropbear sshd: OK

/ # 

pd690xx output contains errors on MS220-48LP

The port status output from pd690xx is nonsensical on the MS220-48 switch:

~ # pd690xx -l
Port    Status          Type    Priority        Power
1       Enabled         at      Critical        0.0
2       Enabled         at      Critical        0.0
3       Enabled         at      Critical        0.0
4       Enabled         at      Critical        0.0
5       Enabled         at      Critical        0.0
6       Enabled         at      Critical        0.0
7       Enabled         at      Critical        0.0
8       Enabled         at      Critical        0.0
9       Enabled         at      Critical        0.0
10      Enabled         at      Critical        0.0
11      Enabled         at      Critical        0.0
12      Enabled         at      Critical        0.0
13      Disabled        af      Critical        0.0
14      Disabled        af      Unknown 0.0
15      Disabled        af      Unknown 0.0
16      Disabled        af      Unknown 0.0
17      Disabled        af      Unknown 0.0
18      Disabled        af      Unknown 0.0
19      Disabled        af      Unknown 0.0
20      Disabled        af      Unknown 0.0
21      Disabled        af      Unknown 0.0
22      Disabled        af      Unknown 0.0
23      Disabled        af      Unknown 0.0
24      Disabled        af      Unknown 0.0
25      Disabled        af      Unknown 0.0
26      Disabled        af      Critical        0.0
27      Disabled        af      Critical        0.0
28      Disabled        af      Critical        0.0
29      Disabled        af      Critical        0.0
30      Disabled        af      Critical        0.0
31      Disabled        af      Critical        0.0
32      Disabled        af      Critical        0.0
33      Disabled        af      Critical        0.0
34      Disabled        af      Critical        0.0
35      Disabled        af      Critical        0.0
36      Disabled        af      Critical        0.0
37      Disabled        af      Critical        0.0
38      Disabled        af      Critical        95.6
39      Disabled        af      Critical        78.7
40      Disabled        af      Critical        68.8
41      Disabled        af      Unknown 1.6
42      Disabled        Unknown Critical        16.9
43      Forced          Unknown Unknown 50.6
44      Forced          Unknown Critical        57.0
45      Disabled        Unknown Unknown 38.8
46      Unknown Unknown Unknown 38.8
47      Disabled        Unknown Critical        3.8

The switch has no PoE devices attached, so absent a serious hardware fault, there should be no power consumption on any ports (especially on ports which are supposedly disabled).

UART pinout for MS22P?

I opened up my MS22P switch yesterday, and am trying to figure out the jumper layout for it. I suspect J3 is the UART pins, but looking for confirmation as I didn't get any serial response from it.

Read board-config from AT24 EEPROM not NAND

Previous releases of postmerkOS have relied on the board-config mtd on NAND to provide the board model and product number. This have proven to be very unreliable, because different switch models identify as meraki_elemental, necessitating the use of other methods like cpuinfo to determine the switch model.

Falsely assuming the switch is a different model causes problems on the MS220-48, as this switch uses the "Jaguar Dual" platform, but lacks the 10G PHY that the MS320-48 contains:

[   50.492000] switch: 'Meraki MS320-48' board detected
Loaded 'jaguar_dual/vtss_core.ko board_desc=MERAKI_BOARD_MS320_48'
Loaded 'proclikefs.ko'
[   69.335000] click: starting router thread pid 439 (87a97c00)
Loaded 'merakiclick.ko'
Loaded 'elts_meraki.ko'
Loaded 'jaguar_dual/vc_click.ko'
[  117.537000] jr_mmd_read:209 jr_mmd_read failed, miim_controller:1 miim_addr:1e, mmd:1e, addr:0
[  117.546000] chatter: vtss_phy_10g_mode_get failed, port 48
[  117.552000] chatter: phy_10g_speed_setup_failed, port_no: 48
[  117.595000] jr_mmd_read:209 jr_mmd_read failed, miim_controller:1 miim_addr:1f, mmd:1e, addr:0
[  117.604000] chatter: vtss_phy_10g_mode_get failed, port 49
[  117.610000] chatter: phy_10g_speed_setup_failed, port_no: 49
[  117.653000] jr_mmd_read:209 jr_mmd_read failed, miim_controller:1 miim_addr:1e, mmd:1e, addr:0
[  117.662000] chatter: vtss_phy_10g_mode_get failed, port 50
[  117.668000] chatter: phy_10g_speed_setup_failed, port_no: 50
[  117.711000] jr_mmd_read:209 jr_mmd_read failed, miim_controller:1 miim_addr:1f, mmd:1e, addr:0
[  117.720000] chatter: vtss_phy_10g_mode_get failed, port 51
[  117.726000] chatter: phy_10g_speed_setup_failed, port_no: 51
[  117.893000] chatter: [sw0_ctrl :: VitesseController] Failed to set 10G PHY GPIO (48,0) config
[  117.902000] chatter: [sw0_ctrl :: VitesseController] Failed to set 10G PHY GPIO (48,9) config
[  117.911000] chatter: [sw0_ctrl :: VitesseController] Failed to set 10G PHY GPIO (50,0) config
[  117.919000] chatter: [sw0_ctrl :: VitesseController] Failed to set 10G PHY GPIO (50,9) config

The main issue with board detection has been that numerous different models identified themselves as meraki_elemental (see #15, #17, and #24) making reliable detection difficult.

It turns out that the board-config mtd on NAND is simply static data which is never updated:

~ # cat /dev/mtdblock5 | strings
5311
meraki_elemental 000000000
Q2XXXXXXXXXV

MS220 switches have an AT24 EEPROM (/sys/devices/platform/i2c-gpio.1/i2c-1/1-0051/eeprom) which is programmed with the relevant information at manufacture time.

We should switch to using the EEPROM data instead of board-config as it resolves all issues with board detection (since the correct data is actually present).

Make MAC address permanent

Currently the MAC address is dynamically generated on boot, resulting in a constantly changing (or incrementing) IP address when using DHCP. It also means DHCP address associations are not possible in router configs etc.

It should be possible to set the MAC address on initial boot after flash, rather than dynamically generating each boot.

Please assign this to me.

Centralized layer-2 switch configuration

Currently, the switch boots to a default configuration of VLAN 1 untagged on every port.

While this is useful for the initial configuration, it has the potential to expose connected devices to incorrect VLANs and is generally not a configuration that people are likely to want from a managed switch in their home network. The more predictable behaviour would be that the initial boot of the switch has this configuration and subsequent boots use the user-defined configuration (basically how every other vendor of managed switches behaves).

Centralizing the layer 2 configuration of the switch and applying the user-defined configuration on boot would allow users to configure the switch to their individual needs starting from the second boot (or first, if you generate the JFFS2 filesystem yourself before flashing).

While maybe not very "unix-like" I was thinking of a single configuration file that configures each port, so that backing up and restoring the configuration is simple.

JSON may be a good choice as it could also make development of a web UI simpler as instead of having to provide an API on the switch to configure ports, the web UI could manipulate the configuration JSON in the browser, and then simply POST the modified configuration file back to the switch to save the changes. It would also simplify applying the configuration as no complicated shell (e.g. Cisco/HPE switch commands) needs to be implemented.

By abstracting the configuration away from Click syntax, users don't need to understand Click to write a configuration, and it allows us to migrate from Click later (e.g. if mainline support for vcoreiii is realized)

My initial concept for the configuration file would be to have something like the following in /etc/switch.json:

{
	"ports": {
		"1": {
			"pvid": 1,
			"vlans": [1, 10],
			"tagged": true,
			"stp": true,
			"lacp": false,
			"poe": {
				"enabled": true,
				"mode": "802.3af"
			}
		},
		"2": {
			"pvid": 1,
			"vlans": [10],
			"tagged": true,
			"stp": true,
			"lacp": false,
			"poe": {
				"enabled": true,
				"mode": "802.3af"
			}
		}
	}
}

Persistant VLAN configuration

Hi,

I would like to start writing a CLI for this switch, do you have more info on how VLAN configuration works within click ?
Some basic features would be nice: port pvid, allowed vlans, etc ...

I believe storing the configuration under /etc would make it persistent correct ?

Thanks!

postmerkOS software upgrade script

Disclaimer: The following proposal is regarding upgrading the alternative firmware on the switch and does not apply to the initial flashing to replace the Meraki firmware. There is currently no known RCE in the Meraki firmware, so a software-only method to initially install the firmware is impossible.


Since constantly having access to a hardware flashing device is annoying, it would be nice to have a method to upgrade the software on the switch without requiring disassembly and external flashing.

I have been experimenting with this over the past few days, and it seems reasonably stable.

cp /bin/busybox /tmp/
cp /usr/sbin/flash_erase /tmp/
killall chrony
killall syslogd
killall klogd
killall uhttpd
cd /tmp/
./flash_erase /dev/mtd3 0 0
./busybox dd if=rootfs.squashfs of=/dev/mtdblock3 bs=65535 conv=fsync
echo b > /proc/sysrq-trigger

I get rootfs.squashfs from buildroot, but of course you can just carve it out of the standard postmerkOS-YYYYMMDD.bin file as follows:

./busybox dd if=postmerkOS-YYYYMMDD.bin bs=1M skip=3 count=8 | ./busybox dd of=/dev/mtdblock3 bs=65535 conv=fsync

Putting these steps into an upgrade script (if it can be made reasonably reliable) would give people an easy route to upgrading the postmerkOS release on their unit.

PoE not Working on MS220-48LP

Having gone through testing with the MS220-48LP although the PD690xx daemon reports PoE ports 1-12 as being enabled (postmerkOS only supports one PD690xx at this point as I understand it). However even though they report as enabled and diagnostics (voltage, temperature) are sent back from the PoE controller, when PoE appliances are plugged into the ports, they are not powered. Tested with a OLIMEX ESP32-POE and a Meraki MR18.
Things to investigate:

  • strace on poe_server again to try and get successful result
  • dump NAND flash and explore

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.