mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
Compare commits
174
Commits
v23.10.0
...
v23.11.0-rc1
@@ -1,9 +1,3 @@
|
||||
# To enable this workflow of your Infix fork, set the repoistory or
|
||||
# organisation variable (not secret):
|
||||
#
|
||||
# LATEST_BUILD = true
|
||||
#
|
||||
# https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository
|
||||
name: Bob the Builder
|
||||
|
||||
on:
|
||||
@@ -14,7 +8,6 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: ${{ vars.LATEST_BUILD == 'true' }}
|
||||
name: Build ${{ matrix.platform }} ${{ matrix.variant }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
PROJECT_NAME: Infix
|
||||
CONTACT_EMAIL: troglobit@gmail.com
|
||||
|
||||
jobs:
|
||||
coverity:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Fetch latest Coverity Scan MD5
|
||||
id: var
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
run: |
|
||||
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
||||
--post-data "token=$TOKEN&project=${PROJECT_NAME}&md5=1" \
|
||||
-O coverity-latest.tar.gz.md5
|
||||
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: coverity-latest.tar.gz
|
||||
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
||||
${{ runner.os }}-coverity-
|
||||
${{ runner.os }}-coverity
|
||||
- name: Download Coverity Scan
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
run: |
|
||||
if [ ! -f coverity-latest.tar.gz ]; then
|
||||
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
||||
--post-data "token=$TOKEN&project=${PROJECT_NAME}" \
|
||||
-O coverity-latest.tar.gz
|
||||
else
|
||||
echo "Latest Coverity Scan available from cache :-)"
|
||||
md5sum coverity-latest.tar.gz
|
||||
fi
|
||||
mkdir coverity
|
||||
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install pkg-config libjansson-dev libev-dev libite-dev \
|
||||
libaugeas-dev libglib2.0-dev libpcre2-dev
|
||||
- name: Build dependencies
|
||||
run: |
|
||||
git clone https://github.com/CESNET/libyang.git
|
||||
mkdir libyang/build
|
||||
(cd libyang/build && cmake .. && make all && sudo make install)
|
||||
git clone https://github.com/sysrepo/sysrepo.git
|
||||
mkdir sysrepo/build
|
||||
(cd sysrepo/build && cmake .. && make all && sudo make install)
|
||||
make dep
|
||||
- name: Check applications
|
||||
run: |
|
||||
export PATH=`pwd`/coverity/bin:$PATH
|
||||
cov-build --dir cov-int make check
|
||||
- name: Submit results to Coverity Scan
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
run: |
|
||||
tar czvf ${PROJECT_NAME}.tgz cov-int
|
||||
curl \
|
||||
--form token=$TOKEN \
|
||||
--form email=${CONTACT_EMAIL} \
|
||||
--form file=@${PROJECT_NAME}.tgz \
|
||||
--form version=$(git rev-parse HEAD) \
|
||||
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
||||
https://scan.coverity.com/builds?project=${PROJECT_NAME}
|
||||
- name: Upload build.log
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverity-build.log
|
||||
path: cov-int/build-log.txt
|
||||
@@ -1,9 +1,3 @@
|
||||
# To enable this workflow of your Infix fork, set the repoistory or
|
||||
# organisation variable (not secret):
|
||||
#
|
||||
# REGRESSION_TEST = true
|
||||
#
|
||||
# https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository
|
||||
name: Reggie Regression
|
||||
|
||||
on:
|
||||
@@ -21,7 +15,6 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: ${{ vars.REGRESSION_TEST == 'true' }}
|
||||
name: Regression Testing
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -11,6 +11,10 @@ bmake = $(MAKE) -C buildroot O=$(O) $1
|
||||
all: $(config) buildroot/Makefile
|
||||
@+$(call bmake,$@)
|
||||
|
||||
check dep:
|
||||
@echo "Starting local check, stage $@ ..."
|
||||
@make -C src $@
|
||||
|
||||
$(config):
|
||||
@+$(call bmake,list-defconfigs)
|
||||
@echo "\e[7mERROR: No configuration selected.\e[0m"
|
||||
@@ -25,4 +29,5 @@ $(config):
|
||||
buildroot/Makefile:
|
||||
@git submodule update --init
|
||||
|
||||
.PHONY: all
|
||||
.PHONY: all check
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<img align="right" src="doc/logo.png" alt="Infix - Linux <3 NETCONF" width=480>
|
||||
[![License Badge][]][License] [![Coverity Status][]][Coverity Scan]
|
||||
<img align="right" src="doc/logo.png" alt="Infix - Linux <3 NETCONF" width=480 border=10>
|
||||
<details><summary><b>Documentation</b></summary>
|
||||
|
||||
- **Infix In-Depth**
|
||||
@@ -19,7 +20,8 @@
|
||||
Infix is a Linux Network Operating System (NOS) based on [Buildroot][1],
|
||||
and [sysrepo][2]. A powerful mix that ease porting to different
|
||||
platforms, simplify long-term maintenance, and provide made-easy
|
||||
management using NETCONF[^1] (remote) or the built-in [CLI][3].
|
||||
management using NETCONF[^1] (remote) or the built-in [command
|
||||
line interface (CLI)][3] (click the foldout for an example).
|
||||
|
||||
<details><summary><b>Example CLI Session</b></summary>
|
||||
|
||||
@@ -29,16 +31,20 @@ is brief example of how to set the IP address of an interface:
|
||||
|
||||
```
|
||||
admin@infix-12-34-56:/> configure
|
||||
admin@infix-12-34-56:/config/> edit interfaces interface eth0
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> set ipv4 <TAB>
|
||||
admin@infix-12-34-56:/config/> edit interface eth0
|
||||
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 <TAB>
|
||||
address autoconf bind-ni-name enabled
|
||||
forwarding mtu neighbor
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> show
|
||||
type ethernetCsmacd;
|
||||
ipv4 address 192.168.2.200 prefix-length 24;
|
||||
ipv6 enabled true;
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> diff
|
||||
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@infix-12-34-56:/config/interface/eth0/> show
|
||||
type ethernet;
|
||||
ipv4 {
|
||||
address 192.168.2.200 {
|
||||
prefix-length 24;
|
||||
}
|
||||
}
|
||||
ipv6
|
||||
admin@infix-12-34-56:/config/interface/eth0/> diff
|
||||
interfaces {
|
||||
interface eth0 {
|
||||
+ ipv4 {
|
||||
@@ -48,13 +54,15 @@ interfaces {
|
||||
+ }
|
||||
}
|
||||
}
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> leave
|
||||
admin@infix-12-34-56:/> show interfaces brief
|
||||
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
|
||||
eth0 UP 52:54:00:12:34:56 <BROADCAST,MULTICAST,UP,LOWER_UP>
|
||||
admin@infix-12-34-56:/> show ip brief
|
||||
lo UNKNOWN 127.0.0.1/8 ::1/128
|
||||
eth0 UP 192.168.2.200/24 fe80::5054:ff:fe12:3456/64
|
||||
admin@infix-12-34-56:/config/interface/eth0/> leave
|
||||
admin@infix-12-34-56:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 52:54:00:12:34:56
|
||||
ipv4 192.168.2.200/24 (static)
|
||||
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@infix-12-34-56:/> copy running-config startup-config
|
||||
```
|
||||
|
||||
@@ -86,3 +94,7 @@ more information, see: [Infix in Virtual Environments](doc/virtual.md).
|
||||
[1]: https://buildroot.org/
|
||||
[2]: https://www.sysrepo.org/
|
||||
[3]: doc/cli/introduction.md
|
||||
[License]: https://en.wikipedia.org/wiki/GPL_license
|
||||
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
|
||||
[Coverity Scan]: https://scan.coverity.com/projects/29393
|
||||
[Coverity Status]: https://scan.coverity.com/projects/29393/badge.svg
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/* mpp21: Unused */
|
||||
/* mpp22: Unused */
|
||||
/* mpp23: Unused */
|
||||
#define SFP9_RX_LOS(X) X("mpp24", cp0_gpio1, 24, GPIO_ACTIVE_HIGH)
|
||||
#define DDR_TEN(X) X("mpp24", cp0_gpio1, 24, GPIO_ACTIVE_HIGH)
|
||||
#define ETH9_RESETn(X) X("mpp25", cp0_gpio1, 25, GPIO_ACTIVE_LOW)
|
||||
#define SW_INTn(X) X("mpp26", cp0_gpio1, 26, IRQ_TYPE_LEVEL_LOW)
|
||||
#define SFP9_RS1(X) X("mpp27", cp0_gpio1, 27, GPIO_ACTIVE_HIGH)
|
||||
@@ -34,7 +34,7 @@
|
||||
#define CP_UA0_TXD(X) X("mpp30", none, 0, 0)
|
||||
#define SFP10_TX_DISABLE(X) X("mpp31", cp0_gpio1, 31, GPIO_ACTIVE_HIGH)
|
||||
#define SFP10_MOD_ABS(X) X("mpp32", cp0_gpio2, 0, GPIO_ACTIVE_LOW)
|
||||
#define I2C_IRQ(X) X("mpp33", cp0_gpio2, 1, GPIO_ACTIVE_HIGH)
|
||||
#define I2C_IRQ(X) X("mpp33", cp0_gpio2, 1, IRQ_TYPE_LEVEL_LOW)
|
||||
#define SFP10_RS0(X) X("mpp34", cp0_gpio2, 2, GPIO_ACTIVE_HIGH)
|
||||
#define CP_I2C1_SDA(X) X("mpp35", none, 0, 0)
|
||||
#define CP_I2C1_SCK(X) X("mpp36", none, 0, 0)
|
||||
@@ -54,7 +54,7 @@
|
||||
#define USB1_VBUS_ENABLE(X) X("mpp50", cp0_gpio2, 18, GPIO_ACTIVE_HIGH)
|
||||
#define USB1_VBUS_ERROR_OC(X) X("mpp51", cp0_gpio2, 19, GPIO_ACTIVE_HIGH)
|
||||
/* mpp52: Unused */
|
||||
/* mpp53: Unused */
|
||||
#define SFP9_RX_LOS(X) X("mpp53", cp0_gpio2, 21, GPIO_ACTIVE_HIGH)
|
||||
/* mpp54: Unused */
|
||||
#define CP_SD_LED(X) X("mpp55", none, 0, 0)
|
||||
#define CP_SD_CLK(X) X("mpp56", none, 0, 0)
|
||||
@@ -63,7 +63,7 @@
|
||||
#define CP_SD_D1(X) X("mpp59", none, 0, 0)
|
||||
#define CP_SD_D2(X) X("mpp60", none, 0, 0)
|
||||
#define CP_SD_D3(X) X("mpp61", none, 0, 0)
|
||||
#define DDR_TEN(X) X("mpp62", cp0_gpio2, 30 GPIO_ACTIVE_HIGH)
|
||||
/* mpp62: Unused */
|
||||
|
||||
/* Macros to extract MPP info in different formats */
|
||||
#define MPP_ID(_mpp, _chip, _no, _flags) _mpp
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
|
||||
infix {
|
||||
vpds = <&vpd_cpu &vpd_product &vpd_power>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
@@ -71,10 +75,13 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp0_i2c0_pins>;
|
||||
|
||||
eeprom@50 {
|
||||
vpd_cpu: eeprom@50 {
|
||||
// AT24C256C-MAHL-T
|
||||
compatible = "atmel,24c256";
|
||||
reg = <0x50>;
|
||||
|
||||
infix,board = "cpu";
|
||||
infix,trusted;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -159,11 +166,12 @@
|
||||
/* System Management */
|
||||
|
||||
&i2c_sysmgmt {
|
||||
eeprom@b {
|
||||
vpd_product: eeprom@b {
|
||||
label = "vpd";
|
||||
reg = <0x0b>;
|
||||
compatible = "atmel,24c02";
|
||||
read-only;
|
||||
|
||||
infix,board = "product";
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "onie,tlv-layout";
|
||||
@@ -302,6 +310,7 @@
|
||||
|
||||
&cp0_utmi1 {
|
||||
status = "okay";
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
&cp0_usb3_1 {
|
||||
@@ -377,42 +386,80 @@
|
||||
};
|
||||
};
|
||||
|
||||
#define SWP(_n, _label, _mac_offs, _phymode, _phy) \
|
||||
port@_n { \
|
||||
#define SWP_COMMON(_n, _label, _mac_offs, _phymode, _phy) \
|
||||
reg = <0x ## _n>; \
|
||||
label = _label; \
|
||||
phy-mode = _phymode; \
|
||||
phy-handle = <&_phy>; \
|
||||
\
|
||||
nvmem-cells = <&base_mac _mac_offs>; \
|
||||
nvmem-cell-names = "mac-address"; \
|
||||
nvmem-cell-names = "mac-address"
|
||||
|
||||
#define XSWP(_n, _label, _mac_offs, _phy) \
|
||||
port@_n { \
|
||||
SWP_COMMON(_n, _label, _mac_offs, "usxgmii", _phy); \
|
||||
}
|
||||
|
||||
SWP(9, "x1", 1, "usxgmii", xphy9);
|
||||
SWP(a, "x2", 2, "usxgmii", xphya);
|
||||
#define GSWP(_n, _label, _mac_offs, _phy) \
|
||||
port@_n { \
|
||||
SWP_COMMON(_n, _label, _mac_offs, "gmii", _phy); \
|
||||
\
|
||||
leds { \
|
||||
#address-cells = <1>; \
|
||||
#size-cells = <0>; \
|
||||
\
|
||||
led@0 { \
|
||||
reg = <0>; \
|
||||
function = "tp"; \
|
||||
color = <LED_COLOR_ID_GREEN>; \
|
||||
default-state = "keep"; \
|
||||
}; \
|
||||
led@1 { \
|
||||
reg = <1>; \
|
||||
function = "tp"; \
|
||||
color = <LED_COLOR_ID_YELLOW>; \
|
||||
default-state = "off"; \
|
||||
}; \
|
||||
}; \
|
||||
}
|
||||
|
||||
SWP(8, "x3", 3, "gmii", swphy8);
|
||||
SWP(7, "x4", 4, "gmii", swphy7);
|
||||
SWP(6, "x5", 5, "gmii", swphy6);
|
||||
SWP(5, "x6", 6, "gmii", swphy5);
|
||||
SWP(4, "x7", 7, "gmii", swphy4);
|
||||
SWP(3, "x8", 8, "gmii", swphy3);
|
||||
SWP(2, "x9", 9, "gmii", swphy2);
|
||||
SWP(1, "x10", 10, "gmii", swphy1);
|
||||
#undef SWP
|
||||
XSWP(9, "x1", 1, xphy9);
|
||||
XSWP(a, "x2", 2, xphya);
|
||||
|
||||
GSWP(8, "x3", 3, swphy8);
|
||||
GSWP(7, "x4", 4, swphy7);
|
||||
GSWP(6, "x5", 5, swphy6);
|
||||
GSWP(5, "x6", 6, swphy5);
|
||||
GSWP(4, "x7", 7, swphy4);
|
||||
GSWP(3, "x8", 8, swphy3);
|
||||
GSWP(2, "x9", 9, swphy2);
|
||||
GSWP(1, "x10", 10, swphy1);
|
||||
#undef GSWP
|
||||
#undef XSWP
|
||||
#undef SWP_COMMON
|
||||
};
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
swphy1: ethernet-phy@1 { reg = <0x1>; };
|
||||
swphy2: ethernet-phy@2 { reg = <0x2>; };
|
||||
swphy3: ethernet-phy@3 { reg = <0x3>; };
|
||||
swphy4: ethernet-phy@4 { reg = <0x4>; };
|
||||
swphy5: ethernet-phy@5 { reg = <0x5>; };
|
||||
swphy6: ethernet-phy@6 { reg = <0x6>; };
|
||||
swphy7: ethernet-phy@7 { reg = <0x7>; };
|
||||
swphy8: ethernet-phy@8 { reg = <0x8>; };
|
||||
|
||||
#define SWPHY(_n) \
|
||||
ethernet-phy@_n { \
|
||||
compatible = "ethernet-phy-ieee802.3-c22"; \
|
||||
reg = <_n>; \
|
||||
eee-broken-100tx; \
|
||||
eee-broken-1000t; \
|
||||
}
|
||||
|
||||
swphy1: SWPHY(1);
|
||||
swphy2: SWPHY(2);
|
||||
swphy3: SWPHY(3);
|
||||
swphy4: SWPHY(4);
|
||||
swphy5: SWPHY(5);
|
||||
swphy6: SWPHY(6);
|
||||
swphy7: SWPHY(7);
|
||||
swphy8: SWPHY(8);
|
||||
#undef SWPHY
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -453,17 +500,59 @@
|
||||
/* 88X3310 specifices 35ns minimum MDC period (28.57 MHz). */
|
||||
clock-frequency = <28571428>;
|
||||
|
||||
xphy9: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
sfp = <&sfp9>;
|
||||
};
|
||||
#define XPHY(_n, _sfp) \
|
||||
ethernet-phy@_n { \
|
||||
compatible = "ethernet-phy-ieee802.3-c45"; \
|
||||
reg = <_n>; \
|
||||
sfp = <&_sfp>; \
|
||||
\
|
||||
leds { \
|
||||
#address-cells = <1>; \
|
||||
#size-cells = <0>; \
|
||||
\
|
||||
led@0 { \
|
||||
reg = <0>; \
|
||||
function = "tp"; \
|
||||
color = <LED_COLOR_ID_YELLOW>; \
|
||||
default-state = "off"; \
|
||||
\
|
||||
marvell,media = "copper"; \
|
||||
marvell,polarity = "active-high"; \
|
||||
}; \
|
||||
led@1 { \
|
||||
reg = <1>; \
|
||||
function = "tp"; \
|
||||
color = <LED_COLOR_ID_GREEN>; \
|
||||
default-state = "keep"; \
|
||||
\
|
||||
marvell,media = "copper"; \
|
||||
marvell,polarity = "active-high"; \
|
||||
}; \
|
||||
\
|
||||
led@2 { \
|
||||
reg = <2>; \
|
||||
function = "sfp"; \
|
||||
color = <LED_COLOR_ID_YELLOW>; \
|
||||
default-state = "off"; \
|
||||
\
|
||||
marvell,media = "fiber"; \
|
||||
marvell,polarity = "active-high"; \
|
||||
}; \
|
||||
led@3 { \
|
||||
reg = <3>; \
|
||||
function = "sfp"; \
|
||||
color = <LED_COLOR_ID_GREEN>; \
|
||||
default-state = "keep"; \
|
||||
\
|
||||
marvell,media = "fiber"; \
|
||||
marvell,polarity = "active-high"; \
|
||||
}; \
|
||||
}; \
|
||||
}
|
||||
|
||||
xphya: ethernet-phy@5 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <5>;
|
||||
sfp = <&sfpa>;
|
||||
};
|
||||
xphy9: XPHY(4, sfp9);
|
||||
xphya: XPHY(5, sfpa);
|
||||
#undef XPHY
|
||||
};
|
||||
|
||||
/ {
|
||||
@@ -495,23 +584,35 @@
|
||||
|
||||
/* Power Board */
|
||||
|
||||
&cp0_pinctrl {
|
||||
cp0_pwr_gpio_pins: cp0-pwr-gpio-0 {
|
||||
marvell,pins = I2C_IRQ(MPP_ID);
|
||||
marvell,function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c_pwr {
|
||||
// Shared IRQ on I2C_IRQ
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp0_pwr_gpio_pins>;
|
||||
|
||||
// 0x26 U13 PCF8574 GPIO I/O
|
||||
gpio_pwr1: gpio@26 {
|
||||
compatible = "nxp,pcf8574a";
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
|
||||
reg = <0x26>;
|
||||
#define GPIO_PWR1_UNUSED0 gpio_pwr1 0 GPIO_ACTIVE_HIGH
|
||||
#define GPIO_PWR1_UNUSED1 gpio_pwr1 1 GPIO_ACTIVE_HIGH
|
||||
#define GPIO_POE_PGOOD gpio_pwr1 2 GPIO_ACTIVE_HIGH
|
||||
#define GPIO_RESET_BUTTON gpio_pwr1 3 GPIO_ACTIVE_LOW
|
||||
#define GPIO_VIN1_PGOOD gpio_pwr1 4 GPIO_ACTIVE_LOW
|
||||
#define GPIO_LED_VIN1_ALERT gpio_pwr1 5 GPIO_ACTIVE_LOW
|
||||
#define GPIO_LED_VIN2_ALERT gpio_pwr1 5 GPIO_ACTIVE_LOW
|
||||
#define GPIO_VIN2_PGOOD gpio_pwr1 6 GPIO_ACTIVE_LOW
|
||||
#define GPIO_LED_VIN2_ALERT gpio_pwr1 7 GPIO_ACTIVE_LOW
|
||||
#define GPIO_LED_VIN1_ALERT gpio_pwr1 7 GPIO_ACTIVE_LOW
|
||||
};
|
||||
|
||||
//0x27 U3 PCF8574 GPIO LED
|
||||
@@ -519,6 +620,9 @@
|
||||
compatible = "nxp,pcf8574a";
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
|
||||
reg = <0x27>;
|
||||
#define GPIO_LED2G gpio_pwr2 0 GPIO_ACTIVE_LOW
|
||||
#define GPIO_LED2R gpio_pwr2 1 GPIO_ACTIVE_LOW
|
||||
@@ -534,10 +638,12 @@
|
||||
//0x30 U5 TPS23861PWR PoE Controller broadcast
|
||||
|
||||
//0x50 U15 AT24C256C EEPROM
|
||||
eeprom@50 {
|
||||
vpd_power: eeprom@50 {
|
||||
// AT24C256C-MAHL-T
|
||||
compatible = "atmel,24c256";
|
||||
reg = <0x50>;
|
||||
|
||||
infix,board = "power";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -545,6 +651,18 @@
|
||||
/* System LEDs */
|
||||
|
||||
/ {
|
||||
power-a {
|
||||
compatible = "gpio-charger";
|
||||
charger-type = "mains";
|
||||
gpios = <&GPIO_VIN1_PGOOD>;
|
||||
};
|
||||
|
||||
power-b {
|
||||
compatible = "gpio-charger";
|
||||
charger-type = "mains";
|
||||
gpios = <&GPIO_VIN2_PGOOD>;
|
||||
};
|
||||
|
||||
leds: leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
@@ -584,28 +702,51 @@
|
||||
gpios = <&GPIO_LED3R>;
|
||||
};
|
||||
|
||||
led-dbgg {
|
||||
function = LED_FUNCTION_DEBUG;
|
||||
led-bootg {
|
||||
function = LED_FUNCTION_BOOT;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
gpios = <&GPIO_LED4G>;
|
||||
};
|
||||
|
||||
led-dbgr {
|
||||
function = LED_FUNCTION_DEBUG;
|
||||
led-bootr {
|
||||
function = LED_FUNCTION_BOOT;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
gpios = <&GPIO_LED4R>;
|
||||
default-state = "on";
|
||||
linux,default-trigger = "timer";
|
||||
};
|
||||
|
||||
led-vin1_alert {
|
||||
function = "power-1";
|
||||
led-vin1-alert {
|
||||
function = "power-a";
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
gpios = <&GPIO_LED_VIN1_ALERT>;
|
||||
};
|
||||
|
||||
led-vin2_alert {
|
||||
function = "power-2";
|
||||
led-vin2-alert {
|
||||
function = "power-b";
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
gpios = <&GPIO_LED_VIN2_ALERT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Watchdog */
|
||||
|
||||
&cp0_pinctrl {
|
||||
watchdog_pins: watchdog-pins {
|
||||
marvell,pins = WDT_TICKLE(MPP_ID);
|
||||
marvell,function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
/ {
|
||||
sysmgmt-watchdog {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&watchdog_pins>;
|
||||
compatible = "linux,wdt-gpio";
|
||||
gpios = WDT_TICKLE(MPP_GPIO_REF);
|
||||
always-running;
|
||||
hw_algo = "toggle";
|
||||
hw_margin_ms = <20000>; /* toggle period must be below 1 minute */
|
||||
};
|
||||
};
|
||||
|
||||
@@ -384,6 +384,7 @@ CONFIG_GPIO_PL061=y
|
||||
CONFIG_GPIO_XGENE=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_PCF857X=y
|
||||
CONFIG_GPIO_MAX77620=y
|
||||
CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
CONFIG_POWER_RESET_XGENE=y
|
||||
@@ -400,6 +401,7 @@ CONFIG_ARMADA_THERMAL=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_SOFT_WATCHDOG=y
|
||||
CONFIG_GPIO_WATCHDOG=y
|
||||
CONFIG_ARMADA_37XX_WATCHDOG=y
|
||||
CONFIG_I6300ESB_WDT=y
|
||||
CONFIG_MFD_MAX77620=y
|
||||
@@ -469,8 +471,10 @@ CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LEDS_SYSCON=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_MAX77686=y
|
||||
CONFIG_RTC_DRV_PCF8523=y
|
||||
|
||||
@@ -23,7 +23,7 @@ config SIGN_KEY
|
||||
menuconfig DISK_IMAGE
|
||||
bool "Disk image"
|
||||
help
|
||||
Compose a full disk image with redundant firmware partitions,
|
||||
Compose a full disk image with redundant Linux OS partitions,
|
||||
configuration partition, etc.
|
||||
|
||||
This is useful when:
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
|
||||
image aux.ext4 {
|
||||
mountpoint = "/aux"
|
||||
temporary = true
|
||||
size = 2M
|
||||
|
||||
ext4 {
|
||||
label = "aux"
|
||||
}
|
||||
}
|
||||
|
||||
image cfg.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 16M
|
||||
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
}
|
||||
}
|
||||
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
# 44M - 24k (GPT backup)
|
||||
size = 45032k
|
||||
|
||||
ext4 {
|
||||
label = "var"
|
||||
}
|
||||
}
|
||||
|
||||
image mmc.img {
|
||||
size = 512M
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition aux {
|
||||
offset = 2M
|
||||
image = "aux.ext4"
|
||||
}
|
||||
|
||||
partition primary {
|
||||
image = "rootfs.squashfs"
|
||||
size = 224M
|
||||
}
|
||||
|
||||
partition secondary {
|
||||
bootable = true
|
||||
image = "rootfs.squashfs"
|
||||
size = 224M
|
||||
}
|
||||
|
||||
partition cfg {
|
||||
image = "cfg.ext4"
|
||||
}
|
||||
|
||||
partition var {
|
||||
image = "var.ext4"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
@@ -7,6 +7,7 @@ image aux.ext4 {
|
||||
|
||||
ext4 {
|
||||
label = "aux"
|
||||
use-mke2fs = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +18,7 @@ image cfg.ext4 {
|
||||
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +29,7 @@ image var.ext4 {
|
||||
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ rm -f "$TARGET_DIR/etc/os-release"
|
||||
{
|
||||
echo "NAME=\"$INFIX_NAME\""
|
||||
echo "ID=$INFIX_ID"
|
||||
echo "PRETTY_NAME=\"$INFIX_TAGLINE\""
|
||||
echo "PRETTY_NAME=\"$INFIX_TAGLINE $VERSION\""
|
||||
echo "ID_LIKE=\"${ID}\""
|
||||
echo "VERSION=\"${VERSION}\""
|
||||
echo "VERSION_ID=${VERSION}"
|
||||
|
||||
@@ -81,6 +81,7 @@ if [ "$BR2_TARGET_ROOTFS_SQUASHFS" = "y" ]; then
|
||||
fi
|
||||
|
||||
# Menuconfig support for modifying Qemu args in release tarballs
|
||||
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/bin/onieprom" "$BINARIES_DIR/"
|
||||
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/qemu.sh" "$BINARIES_DIR/"
|
||||
sed -e "s/@ARCH@/QEMU_$BR2_ARCH/" \
|
||||
-e "s/@DISK_IMG@/$diskimg/" \
|
||||
|
||||
@@ -62,9 +62,24 @@ config QEMU_CONSOLE_SERIAL
|
||||
endchoice
|
||||
|
||||
config QEMU_MACHINE
|
||||
string
|
||||
default "qemu-system-aarch64 -M virt -cpu cortex-a72 -m 256M" if QEMU_aarch64
|
||||
default "qemu-system-x86_64 -M q35,accel=kvm -cpu host -m 256M" if QEMU_x86_64
|
||||
string "Select emulated machine"
|
||||
default "qemu-system-aarch64 -M virt -cpu cortex-a72" if QEMU_aarch64
|
||||
default "qemu-system-x86_64 -M q35,accel=kvm -cpu host" if QEMU_x86_64
|
||||
help
|
||||
You should not have to change this setting, although you may
|
||||
want to tweak it, or change the acceleration.
|
||||
|
||||
The default is based on the Buildroot architecture, selected by
|
||||
the defconfig you started with. Currently Infix supports only
|
||||
aarch64 (ARM64) and x86_64 (AMD64).
|
||||
|
||||
config QEMU_MACHINE_RAM
|
||||
string "RAM size (k/M/G)"
|
||||
default "256M"
|
||||
help
|
||||
The default, 255 MiB, works for most configurations, even less for
|
||||
the Infix Classic builds. However, if you get kernel panic with:
|
||||
"System is deadlocked on memory", try increasing this one.
|
||||
|
||||
config QEMU_KERNEL
|
||||
string
|
||||
@@ -103,6 +118,9 @@ config QEMU_RW_VAR
|
||||
default "var.ext4"
|
||||
endif
|
||||
|
||||
config QEMU_VPD
|
||||
bool "Emulate a Vital Product Data (VPD) Memory"
|
||||
|
||||
config QEMU_HOST
|
||||
string "Export host filesystem path"
|
||||
default "/tmp"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#
|
||||
|
||||
# Local variables
|
||||
imgdir=$(readlink -f $(dirname "$0"))
|
||||
prognm=$(basename "$0")
|
||||
|
||||
usage()
|
||||
@@ -169,7 +170,7 @@ net_dev_args()
|
||||
net_args()
|
||||
{
|
||||
# Infix will pick up this file via fwcfg and install it to /etc
|
||||
mactab=$(dirname "$CONFIG_QEMU_ROOTFS")/mactab
|
||||
mactab=${imgdir}/mactab
|
||||
:> "$mactab"
|
||||
echo -n "-fw_cfg name=opt/mactab,file=$mactab "
|
||||
|
||||
@@ -192,6 +193,34 @@ net_args()
|
||||
fi
|
||||
}
|
||||
|
||||
# Vital Product data
|
||||
vpd_args()
|
||||
{
|
||||
[ "$CONFIG_QEMU_VPD" = "y" ] || return
|
||||
|
||||
vpd_file="${imgdir}/vpd"
|
||||
|
||||
if ! [ -f "$vpd_file" ]; then
|
||||
onieprom="${imgdir}/onieprom"
|
||||
|
||||
# This is you QEMU factory/default password:
|
||||
pwhash=$(echo -n "admin" | mkpasswd -s -m sha256crypt)
|
||||
|
||||
cat <<EOF | "$onieprom" -e >"$vpd_file"
|
||||
{
|
||||
"manufacture-date": "$(date +"%d/%m/%Y %H:%M:%S")",
|
||||
"vendor-extension": [
|
||||
[
|
||||
61046,
|
||||
"{\"pwhash\":\"$pwhash\"}"
|
||||
]
|
||||
]
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
echo -n "-fw_cfg name=opt/vpd,file=$vpd_file"
|
||||
}
|
||||
|
||||
wdt_args()
|
||||
{
|
||||
echo -n "-device i6300esb -rtc clock=host"
|
||||
@@ -201,7 +230,7 @@ run_qemu()
|
||||
{
|
||||
local qemu
|
||||
read qemu <<EOF
|
||||
$CONFIG_QEMU_MACHINE \
|
||||
$CONFIG_QEMU_MACHINE -m $CONFIG_QEMU_MACHINE_RAM \
|
||||
$(loader_args) \
|
||||
$(rootfs_args) \
|
||||
$(serial_args) \
|
||||
@@ -209,6 +238,7 @@ run_qemu()
|
||||
$(host_args) \
|
||||
$(net_args) \
|
||||
$(wdt_args) \
|
||||
$(vpd_args) \
|
||||
$CONFIG_QEMU_EXTRA
|
||||
EOF
|
||||
|
||||
|
||||
Executable
+218
@@ -0,0 +1,218 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import binascii
|
||||
import struct
|
||||
|
||||
HDRMGC = b"TlvInfo"
|
||||
HDRVER = 1
|
||||
HDRFMT = ">7sxBH"
|
||||
HDRLEN = struct.calcsize(HDRFMT)
|
||||
|
||||
CRCFMT = ">BBL"
|
||||
CRCLEN = struct.calcsize(CRCFMT)
|
||||
|
||||
def pack_varstr(s, maxlen=0xff):
|
||||
b = bytes(s, "ascii")
|
||||
assert(len(b) <= maxlen)
|
||||
return b
|
||||
|
||||
def unpack_varstr(b):
|
||||
return b.decode("ascii")
|
||||
|
||||
|
||||
def pack_u8(num):
|
||||
return struct.pack("B", num)
|
||||
|
||||
def unpack_u8(b):
|
||||
return struct.unpack("B", b)[0]
|
||||
|
||||
|
||||
def pack_u16(num):
|
||||
return struct.pack(">H", num)
|
||||
|
||||
def unpack_u16(b):
|
||||
return struct.unpack(">H", b)[0]
|
||||
|
||||
|
||||
def pack_u32(num):
|
||||
return struct.pack(">L", num)
|
||||
|
||||
def unpack_u32(b):
|
||||
return struct.unpack(">L", b)[0]
|
||||
|
||||
|
||||
def pack_date(datestr):
|
||||
assert(len(datestr) == 19)
|
||||
return pack_varstr(datestr, 19)
|
||||
|
||||
def pack_country(cstr):
|
||||
assert(len(cstr) == 2)
|
||||
return pack_varstr(cstr, 2)
|
||||
|
||||
def pack_mac(macstr):
|
||||
return struct.pack("6B", *[int(o, 16) for o in macstr.split(":")])
|
||||
|
||||
def unpack_mac(b):
|
||||
o = struct.unpack("6B", b)
|
||||
return f"{o[0]:02x}:{o[1]:02x}:{o[2]:02x}:{o[3]:02x}:{o[4]:02x}:{o[5]:02x}"
|
||||
|
||||
OPS = {
|
||||
"varstr": (pack_varstr, unpack_varstr),
|
||||
"u8": (pack_u8, unpack_u8),
|
||||
"u16": (pack_u16, unpack_u16),
|
||||
"u32": (pack_u32, unpack_u32),
|
||||
|
||||
"date": (pack_date, unpack_varstr),
|
||||
"country": (pack_country, unpack_varstr),
|
||||
"mac": (pack_mac, unpack_mac),
|
||||
}
|
||||
|
||||
TLV = (
|
||||
{ "type": 0x21, "name": "product-name", "ops": "varstr" },
|
||||
{ "type": 0x22, "name": "part-number", "ops": "varstr" },
|
||||
{ "type": 0x23, "name": "serial-number", "ops": "varstr" },
|
||||
{ "type": 0x24, "name": "mac-address", "ops": "mac" },
|
||||
{ "type": 0x25, "name": "manufacture-date", "ops": "date" },
|
||||
{ "type": 0x26, "name": "device-version", "ops": "u8" },
|
||||
{ "type": 0x27, "name": "label-revision", "ops": "varstr" },
|
||||
{ "type": 0x28, "name": "platform-name", "ops": "varstr" },
|
||||
{ "type": 0x29, "name": "onie-version", "ops": "varstr" },
|
||||
{ "type": 0x2a, "name": "num-macs", "ops": "u16" },
|
||||
{ "type": 0x2b, "name": "manufacturer", "ops": "varstr" },
|
||||
{ "type": 0x2c, "name": "country-code", "ops": "country" },
|
||||
{ "type": 0x2d, "name": "vendor", "ops": "varstr" },
|
||||
{ "type": 0x2e, "name": "diag-version", "ops": "varstr" },
|
||||
{ "type": 0x2f, "name": "service-tag", "ops": "varstr" },
|
||||
)
|
||||
|
||||
TLV_VENDOR_EXTENSION = 0xfd
|
||||
TLV_CRC32 = 0xfe
|
||||
|
||||
def _tlv_by_lambda(fn):
|
||||
info = next(filter(fn, TLV))
|
||||
if "ops" in info:
|
||||
return info, OPS[info["ops"]]
|
||||
else:
|
||||
return info
|
||||
|
||||
def tlv_by_name(name):
|
||||
try:
|
||||
return _tlv_by_lambda(lambda info: info["name"] == name)
|
||||
except StopIteration:
|
||||
raise ValueError(f"Unknown type name \"{name}\"")
|
||||
|
||||
def tlv_by_type(t):
|
||||
try:
|
||||
return _tlv_by_lambda(lambda info: info["type"] == t)
|
||||
except StopIteration:
|
||||
raise ValueError(f"Unknown type id {t}")
|
||||
|
||||
def into_tlv(d):
|
||||
def pack_vendor(exts):
|
||||
out = b""
|
||||
for (iana_pen, val) in exts:
|
||||
b = bytes(val, "utf-8")
|
||||
l = len(b) + struct.calcsize(">L")
|
||||
assert(l <= 0xff)
|
||||
out += struct.pack(">BBL", TLV_VENDOR_EXTENSION, l, iana_pen) + b
|
||||
|
||||
return out
|
||||
|
||||
out = b""
|
||||
|
||||
# Generate all optional data
|
||||
for (k, v) in sorted(d.items()):
|
||||
if k == "vendor-extension":
|
||||
out += pack_vendor(v)
|
||||
else:
|
||||
info, (pack, _) = tlv_by_name(k)
|
||||
val = pack(v)
|
||||
out += struct.pack("BB", info["type"], len(val)) + val
|
||||
|
||||
# Prepend the header now that we know the total length of the
|
||||
# optional fields - make sure sure to include the CRC TLV length,
|
||||
# which is appended in the last step
|
||||
out = struct.pack(HDRFMT, HDRMGC, HDRVER, len(out) + CRCLEN) + out
|
||||
|
||||
out += struct.pack("BB", TLV_CRC32, struct.calcsize(">L"))
|
||||
out += struct.pack(">L", binascii.crc32(out))
|
||||
return out
|
||||
|
||||
def from_tlv(f):
|
||||
d = {}
|
||||
|
||||
def unpack_vendor(ext):
|
||||
head, tail = ext[:4], ext[4:]
|
||||
iana_pen = struct.unpack(">L", head)[0]
|
||||
val = tail.decode("utf-8")
|
||||
|
||||
if "vendor-extension" not in d:
|
||||
d["vendor-extension"] = []
|
||||
|
||||
d["vendor-extension"].append([iana_pen, val])
|
||||
|
||||
head = f.read(HDRLEN)
|
||||
magic, ver, l = struct.unpack(HDRFMT, head)
|
||||
assert(magic == HDRMGC)
|
||||
assert(ver == 1)
|
||||
|
||||
tail = f.read(l)
|
||||
b = head + tail
|
||||
assert(len(b) >= HDRLEN + l)
|
||||
|
||||
crcoffs = HDRLEN + l - CRCLEN
|
||||
t, l, v = struct.unpack(CRCFMT, b[crcoffs:crcoffs+CRCLEN])
|
||||
assert(t == TLV_CRC32)
|
||||
assert(v == binascii.crc32(b[:crcoffs + struct.calcsize("BB")]))
|
||||
|
||||
while len(tail) >= 2:
|
||||
t, l = struct.unpack("BB", tail[:2])
|
||||
v = tail[2:l+2]
|
||||
tail = tail[l+2:]
|
||||
|
||||
if t == TLV_VENDOR_EXTENSION:
|
||||
unpack_vendor(v)
|
||||
continue
|
||||
elif t == TLV_CRC32:
|
||||
break
|
||||
|
||||
info, (_, unpack) = tlv_by_type(t)
|
||||
d[info["name"]] = unpack(v)
|
||||
|
||||
return d
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(prog='onieprom')
|
||||
|
||||
parser.add_argument("infile", nargs="?", default=sys.stdin, type=argparse.FileType("rb", 0))
|
||||
parser.add_argument("outfile", nargs="?", default=sys.stdout, type=argparse.FileType("wb"))
|
||||
|
||||
parser.add_argument("-e", "--encode", default=False, action="store_true",
|
||||
help="Encode JSON input to binary output")
|
||||
|
||||
parser.add_argument("-d", "--decode", default=False, action="store_true",
|
||||
help="Decode binary input to JSON output")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if (not args.encode) and (not args.decode):
|
||||
c = args.infile.read(1)
|
||||
args.infile.seek(0, 0)
|
||||
|
||||
if c == b"{":
|
||||
args.encode = True
|
||||
elif c == b"T":
|
||||
args.decode = True
|
||||
else:
|
||||
sys.stderr.write("Neither encode nor decode specified, and could not infer operation from input")
|
||||
sys.exit(1)
|
||||
|
||||
if args.encode:
|
||||
args.outfile.buffer.write(into_tlv(json.load(args.infile)))
|
||||
else:
|
||||
args.outfile.write(json.dumps(from_tlv(args.infile)))
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/bin/sh
|
||||
Q=$@
|
||||
|
||||
echo "$Q, are you sure? (y/N)"
|
||||
/bin/echo -n "$Q, are you sure (y/N)? "
|
||||
read -n1 yorn
|
||||
echo
|
||||
|
||||
if [ x$yorn != "xy" ]; then
|
||||
echo "Ok, aborting"
|
||||
if [ x$yorn != "xy" ] && [ x$yorn != "xY" ]; then
|
||||
echo "OK, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
run [S] /lib/infix/probe -- Probing system information
|
||||
run [S] log:console /lib/infix/probe -- Probing system information
|
||||
run [S] <pid/syslogd> /lib/infix/sysctl-sync-ip-conf --
|
||||
run [S] <pid/syslogd> /lib/infix/nameif -- Probing network interfaces
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
service [2345789] log:prio:user.notice rauc service -- Software update service
|
||||
set G_MESSAGES_DEBUG=nocolor
|
||||
service [2345789] <service/dbus/running> \
|
||||
env:-/etc/default/rauc log:prio:user.notice \
|
||||
rauc service $RAUC_ARGS -- Software update service
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Override Finit plugin
|
||||
service cgroup.system name:dbus pid:!/run/messagebus.pid <pid/syslogd> \
|
||||
[S123456789] /usr/bin/dbus-daemon --nofork --system --syslog-only \
|
||||
service cgroup.system name:dbus notify:none pid:!/run/messagebus.pid \
|
||||
[S123456789] <pid/syslogd> /usr/bin/dbus-daemon --nofork --system --syslog-only \
|
||||
-- D-Bus message bus daemon
|
||||
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
|
||||
#user nobody;
|
||||
worker_processes 1;
|
||||
|
||||
#error_log logs/error.log;
|
||||
#error_log logs/error.log notice;
|
||||
#error_log logs/error.log info;
|
||||
|
||||
#pid logs/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
# '$status $body_bytes_sent "$http_referer" '
|
||||
# '"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
#access_log logs/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
#keepalive_timeout 0;
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
#charset koi8-r;
|
||||
|
||||
#access_log logs/host.access.log main;
|
||||
|
||||
location / {
|
||||
root html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /restconf/ {
|
||||
fastcgi_pass unix:/var/run/clixon/restconf.sock;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
#
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
|
||||
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
|
||||
#
|
||||
#location ~ \.php$ {
|
||||
# proxy_pass http://127.0.0.1;
|
||||
#}
|
||||
|
||||
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
|
||||
#
|
||||
#location ~ \.php$ {
|
||||
# root html;
|
||||
# fastcgi_pass 127.0.0.1:9000;
|
||||
# fastcgi_index index.php;
|
||||
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
|
||||
# include fastcgi_params;
|
||||
#}
|
||||
|
||||
# deny access to .htaccess files, if Apache's document root
|
||||
# concurs with nginx's one
|
||||
#
|
||||
#location ~ /\.ht {
|
||||
# deny all;
|
||||
#}
|
||||
}
|
||||
|
||||
|
||||
# another virtual host using mix of IP-, name-, and port-based configuration
|
||||
#
|
||||
#server {
|
||||
# listen 8000;
|
||||
# listen somename:8080;
|
||||
# server_name somename alias another.alias;
|
||||
|
||||
# location / {
|
||||
# root html;
|
||||
# index index.html index.htm;
|
||||
# }
|
||||
#}
|
||||
|
||||
|
||||
# HTTPS server
|
||||
#
|
||||
#server {
|
||||
# listen 443 ssl;
|
||||
# server_name localhost;
|
||||
|
||||
# ssl_certificate cert.pem;
|
||||
# ssl_certificate_key cert.key;
|
||||
|
||||
# ssl_session_cache shared:SSL:1m;
|
||||
# ssl_session_timeout 5m;
|
||||
|
||||
# ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
# ssl_prefer_server_ciphers on;
|
||||
|
||||
# location / {
|
||||
# root html;
|
||||
# index index.html index.htm;
|
||||
# }
|
||||
#}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Banner /etc/banner
|
||||
@@ -0,0 +1 @@
|
||||
local0.* -/var/log/upgrade.log
|
||||
@@ -17,10 +17,37 @@
|
||||
|
||||
set -e
|
||||
|
||||
nm=$(basename $0)
|
||||
nm=$(basename "$0")
|
||||
err=0
|
||||
opt="-k"
|
||||
|
||||
# External button or bootloader changed kernel command line
|
||||
check_factory()
|
||||
{
|
||||
if [ -f /mnt/cfg/infix/.reset ]; then
|
||||
return 0;
|
||||
fi
|
||||
|
||||
if grep -q 'finit.cond=factory-reset' /proc/cmdline; then
|
||||
return 0;
|
||||
fi
|
||||
|
||||
# Add to your br2-external to extend factory-reset check
|
||||
if [ ! -x /lib/infix/check-factory ]; then
|
||||
return 1;
|
||||
fi
|
||||
|
||||
/lib/infix/check-factory
|
||||
}
|
||||
|
||||
factory_reset()
|
||||
{
|
||||
# XXX: flash LEDs to confirm factory-reset in progress
|
||||
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
|
||||
rm -rf /mnt/cfg/* /mnt/var/*
|
||||
sync
|
||||
}
|
||||
|
||||
mount_rw()
|
||||
{
|
||||
# If something is already setup, leave it be.
|
||||
@@ -60,6 +87,10 @@ mount_overlay()
|
||||
mkdir -p -m 0755 "$u"
|
||||
mkdir -p -m 0755 "$w"
|
||||
|
||||
# Ensure that all users in wheel can create the .reset file
|
||||
# on /cfg and upload docker images to /var
|
||||
chgrp wheel "$(dirname "$u")"
|
||||
|
||||
mount -t overlay "$tag-overlay" "$dst" \
|
||||
-o lowerdir="$dst",upperdir="$u",workdir="$w"
|
||||
}
|
||||
@@ -78,12 +109,8 @@ varsrc=/mnt/var
|
||||
if ! mount_rw var >/dev/null 2>&1; then
|
||||
logger $opt -p user.warn -t "$nm" \
|
||||
"No persistent storage found for /var, only /var/lib is persisted."
|
||||
varsrc=/mnt/tmp
|
||||
varsrc=/mnt/tmp/infix/var
|
||||
vlibsrc=/mnt/cfg/vlib
|
||||
else
|
||||
mount_bind "$varsrc" /var
|
||||
varsrc=
|
||||
vlibsrc=
|
||||
fi
|
||||
|
||||
cfgsrc=/mnt/cfg
|
||||
@@ -100,35 +127,23 @@ if ! mount_rw cfg >/dev/null 2>&1; then
|
||||
# there's no point in overlaying one ramdisk on top of another.
|
||||
vlibsrc=
|
||||
else
|
||||
# Check for factory reset
|
||||
if [ -f /mnt/cfg/infix/.reset ]; then
|
||||
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
|
||||
rm -rf /mnt/cfg/infix /mnt/var/infix
|
||||
sync
|
||||
fi
|
||||
|
||||
# Check build: NETCONF or Classic
|
||||
# Classic Infix has read-write /etc across boots
|
||||
if [ "$VARIANT_ID" != "netconf" ]; then
|
||||
etcsrc=/mnt/cfg
|
||||
fi
|
||||
|
||||
# Ensure that all users in wheel can create the .reset file
|
||||
mkdir -p /mnt/cfg/infix
|
||||
chgrp wheel /mnt/cfg/infix
|
||||
fi
|
||||
|
||||
mount_overlay cfg $cfgsrc /cfg
|
||||
mount_overlay etc $etcsrc /etc
|
||||
mount_overlay home $cfgsrc /home
|
||||
mount_overlay root $cfgsrc /root
|
||||
if check_factory; then
|
||||
factory_reset
|
||||
fi
|
||||
|
||||
[ "$varsrc" ] && mount_overlay var "$varsrc" /var
|
||||
[ "$vlibsrc" ] && mount_bind "$vlibsrc" /var/lib
|
||||
mount_overlay cfg "$cfgsrc" /cfg
|
||||
mount_overlay etc "$etcsrc" /etc
|
||||
mount_overlay home "$cfgsrc" /home
|
||||
mount_overlay root "$cfgsrc" /root
|
||||
mount_bind "$varsrc" /var
|
||||
|
||||
# Keep transient configs in a ramdisk and symlink out to /cfg for
|
||||
# startup.
|
||||
mkdir -p /mnt/tmp/infix/db
|
||||
ln -s /cfg/startup_db /mnt/tmp/infix/db/startup_db
|
||||
[ "$vlibsrc" ] && mount_bind "$vlibsrc" /var/lib
|
||||
|
||||
for tag in $(ls /sys/bus/virtio/devices/*/mount_tag 2>/dev/null); do
|
||||
if [ "$(cat $tag | tr -d '\0')" = hostfs ]; then
|
||||
|
||||
@@ -1,6 +1,267 @@
|
||||
#!/bin/sh
|
||||
# Probe for various types of harware features
|
||||
#!/usr/bin/env python3
|
||||
|
||||
if dmesg |grep -q QEMU || test -d /sys/module/qemu_fw_cfg; then
|
||||
initctl cond set qemu
|
||||
fi
|
||||
import importlib.machinery
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
onieprom = importlib.machinery.SourceFileLoader("onieprom","/bin/onieprom").load_module()
|
||||
|
||||
KKIT_IANA_PEM = 61046
|
||||
|
||||
class DTSystem:
|
||||
BASE = "/sys/firmware/devicetree/base"
|
||||
INFIX = BASE + "/chosen/infix"
|
||||
|
||||
def __init__(self):
|
||||
self.vpdseq = 0
|
||||
|
||||
dt = {}
|
||||
for root, _, files in os.walk(DTSystem.BASE):
|
||||
if "phandle" not in files:
|
||||
continue
|
||||
|
||||
phandle = os.path.join(root, "phandle")
|
||||
if not os.path.exists(phandle):
|
||||
continue
|
||||
|
||||
ph, = struct.unpack(">L", open(phandle, "rb").read())
|
||||
dt[ph] = root
|
||||
|
||||
sys = {}
|
||||
for root, dirs, _ in os.walk("/sys/devices"):
|
||||
if "of_node" not in dirs:
|
||||
continue
|
||||
|
||||
phandle = os.path.join(root, "of_node", "phandle")
|
||||
if not os.path.exists(phandle):
|
||||
continue
|
||||
|
||||
ph, = struct.unpack(">L", open(phandle, "rb").read())
|
||||
sys[ph] = root
|
||||
|
||||
phs = set(list(dt.keys()) + list(sys.keys()))
|
||||
self.devs = { ph: Device(ph, dt.get(ph), sys.get(ph)) for ph in phs }
|
||||
self.base = Device(0, None, DTSystem.BASE)
|
||||
self.infix = Device(0, None, DTSystem.INFIX)
|
||||
|
||||
def __get_phandle_array(self, name):
|
||||
path = os.path.join(DTSystem.INFIX, name)
|
||||
if not os.path.exists(path):
|
||||
return ()
|
||||
|
||||
data = open(path, "rb").read()
|
||||
elems = len(data) // struct.calcsize(">L")
|
||||
return struct.unpack(">" + elems * "L", data)
|
||||
|
||||
def device_from_ph(self, ph):
|
||||
return self.devs.get(ph)
|
||||
|
||||
def into_vpd(self, dev):
|
||||
def parse():
|
||||
if not dev.available():
|
||||
return {}
|
||||
|
||||
try:
|
||||
data = onieprom.from_tlv(open(dev.attrpath("nvmem"), "rb", 0))
|
||||
except:
|
||||
data = {}
|
||||
|
||||
return data
|
||||
|
||||
self.vpdseq += 1
|
||||
return {
|
||||
"board": dev.dtstr("infix,board", f"UNKNOWN{self.vpdseq}"),
|
||||
"available": dev.available(),
|
||||
"trusted": dev.hasdtattr("infix,trusted"),
|
||||
"data": parse(),
|
||||
}
|
||||
|
||||
def infix_devices(self, kind):
|
||||
phs = self.__get_phandle_array(kind)
|
||||
return [self.device_from_ph(ph) for ph in phs]
|
||||
|
||||
def infix_vpds(self):
|
||||
return [self.into_vpd(dev) for dev in self.infix_devices("vpds")]
|
||||
|
||||
class QEMUSystem:
|
||||
BASE = "/sys/firmware/qemu_fw_cfg"
|
||||
REV = BASE + "/rev"
|
||||
VPD = BASE + "/by_name/opt/vpd/raw"
|
||||
|
||||
def product_vpd(self):
|
||||
data = {}
|
||||
if os.path.exists(QEMUSystem.VPD):
|
||||
try:
|
||||
data = onieprom.from_tlv(open(QEMUSystem.VPD, "rb", 0))
|
||||
except:
|
||||
pass
|
||||
|
||||
return {
|
||||
"board": "product",
|
||||
"available": os.path.exists(QEMUSystem.VPD),
|
||||
"trusted": True,
|
||||
"data": data,
|
||||
}
|
||||
|
||||
def vpds(self):
|
||||
return [self.product_vpd()]
|
||||
|
||||
class Device:
|
||||
def __init__(self, ph, dtpath, syspath):
|
||||
self.ph, self.dtpath, self.syspath = ph, dtpath, syspath
|
||||
|
||||
def available(self):
|
||||
return self.syspath != None
|
||||
|
||||
def __getitem__(self, attr):
|
||||
return self.attr(attr).decode("utf-8").strip("\0")
|
||||
|
||||
def __setitem__(self, attr, value):
|
||||
return self.attr(attr, val=value.encode("utf-8"))
|
||||
|
||||
|
||||
def attrpath(self, attr):
|
||||
return os.path.join(self.syspath, attr)
|
||||
|
||||
def hasattr(self, attr):
|
||||
return os.path.exists(self.attrpath(attr))
|
||||
|
||||
def attr(self, attr, default=None, val=None):
|
||||
if not self.hasattr(attr):
|
||||
return default if val == None else False
|
||||
|
||||
if val:
|
||||
open(self.attrpath(attr), "wb").write(value)
|
||||
return True
|
||||
|
||||
return open(self.attrpath(attr), "rb").read()
|
||||
|
||||
def str(self, attr, default=None):
|
||||
val = self.attr(attr)
|
||||
return val.decode("utf-8").strip("\0") if val else default
|
||||
|
||||
|
||||
def dtattrpath(self, attr):
|
||||
return os.path.join(self.dtpath, attr)
|
||||
|
||||
def hasdtattr(self, attr):
|
||||
return os.path.exists(self.dtattrpath(attr))
|
||||
|
||||
def dtattr(self, attr, default=None):
|
||||
if not self.hasdtattr(attr):
|
||||
return default
|
||||
|
||||
return open(self.dtattrpath(attr), "rb").read()
|
||||
|
||||
def dtstr(self, attr, default=None):
|
||||
val = self.dtattr(attr)
|
||||
return val.decode("utf-8").strip("\0") if val else default
|
||||
|
||||
|
||||
def vpd_get_json_ve(vpd, pem):
|
||||
ves = vpd["data"].get("vendor-extension")
|
||||
if not ves:
|
||||
return {}
|
||||
|
||||
out = {}
|
||||
for ve in filter(lambda ve: ve[0] == pem, ves):
|
||||
out.update(json.loads(ve[1]))
|
||||
|
||||
return out
|
||||
|
||||
def vpd_get_pwhash(vpd):
|
||||
if not vpd.get("trusted"):
|
||||
return None
|
||||
|
||||
kkit = vpd_get_json_ve(vpd, KKIT_IANA_PEM)
|
||||
return kkit.get("pwhash")
|
||||
|
||||
def vpd_inject(out, vpds):
|
||||
out["vpd"] = { vpd["board"]: vpd for vpd in vpds }
|
||||
|
||||
product = out["vpd"].get("product", {}).get("data", {})
|
||||
hoistattrs = ("vendor", "product-name", "part-number", "serial-number", "mac-address")
|
||||
for attr in hoistattrs:
|
||||
if attr in product:
|
||||
out[attr] = product[attr]
|
||||
|
||||
for vpd in vpds:
|
||||
pwhash = vpd_get_pwhash(vpd)
|
||||
if pwhash:
|
||||
out["factory-password-hash"] = pwhash
|
||||
break
|
||||
|
||||
def probe_qemusystem(out):
|
||||
ADMINHASH = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
|
||||
|
||||
qsys = QEMUSystem()
|
||||
vpds = qsys.vpds()
|
||||
vpd_inject(out, vpds)
|
||||
|
||||
for (attr, default) in (
|
||||
("vendor", "QEMU"),
|
||||
("product-name", "VM"),
|
||||
):
|
||||
if not out[attr]:
|
||||
out[attr] = default
|
||||
|
||||
if not out["factory-password-hash"] and \
|
||||
not out["vpd"]["product"]["available"]:
|
||||
# Virtual instance without VPD emulation, fallback to
|
||||
# admin/admin
|
||||
out["factory-password-hash"] = ADMINHASH
|
||||
|
||||
# Let others react to the fact that we are running in QEMU
|
||||
subprocess.run("initctl -nbq cond set qemu".split())
|
||||
return 0
|
||||
|
||||
def probe_dtsystem(out):
|
||||
dtsys = DTSystem()
|
||||
vpds = dtsys.infix_vpds()
|
||||
|
||||
model = dtsys.base.str("model")
|
||||
if model:
|
||||
out["product-name"] = model
|
||||
|
||||
staticpw = dtsys.infix.str("factory-password-hash")
|
||||
if not out["factory-password-hash"]:
|
||||
out["factory-password-hash"] = staticpw
|
||||
|
||||
vpd_inject(out, vpds)
|
||||
return 0
|
||||
|
||||
def main():
|
||||
out = {
|
||||
"vendor": None,
|
||||
"product-name": None,
|
||||
"part-number": None,
|
||||
"serial-number": None,
|
||||
"mac-address": None,
|
||||
"factory-password-hash": None,
|
||||
"vpd": {}
|
||||
}
|
||||
vpds = []
|
||||
|
||||
if os.path.exists(QEMUSystem.REV):
|
||||
err = probe_qemusystem(out)
|
||||
elif os.path.exists(DTSystem.BASE):
|
||||
err = probe_dtsystem(out)
|
||||
else:
|
||||
return 1
|
||||
|
||||
if err:
|
||||
return err
|
||||
|
||||
if not out["factory-password-hash"]:
|
||||
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\nNO FACTORY PASSWORD FOUND\033[0m\n\n")
|
||||
err = 1
|
||||
|
||||
json.dump(out, open("/run/system.json", "w"))
|
||||
os.chmod("/run/system.json", 0o444)
|
||||
return err
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
disk=$1
|
||||
bootoffs=$2
|
||||
|
||||
bootsize=8M
|
||||
auxsize=8M
|
||||
|
||||
total=$(awk -vdisk="$(basename $disk)" '$4 == disk { print($3 / 1024); }' /proc/partitions)
|
||||
if [ "$total" -ge 4096 ]; then
|
||||
imgsize=1024M
|
||||
cfgsize=512M
|
||||
elif [ "$total" -ge 2048 ]; then
|
||||
imgsize=512M
|
||||
cfgsize=256M
|
||||
elif [ "$total" -ge 1024 ]; then
|
||||
imgsize=256M
|
||||
cfgsize=64M
|
||||
elif [ "$total" -ge 512 ]; then
|
||||
imgsize=192M
|
||||
cfgsize=16M
|
||||
else
|
||||
echo "$disk is only ${total}M, at least 512M is required" >2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sgdisk \
|
||||
-o \
|
||||
-n1:${bootoffs}:+${bootsize} -t1:8301 -c1:boot \
|
||||
-n2::+${auxsize} -t2:8301 -c2:aux \
|
||||
-n3::+${imgsize} -t3:8300 -c3:primary \
|
||||
-n4::+${imgsize} -t4:8300 -c4:secondary \
|
||||
-n5::+${cfgsize} -t5:8302 -c5:cfg \
|
||||
-n6:: -t6:8310 -c6:var \
|
||||
-p \
|
||||
$disk
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
progname="$0"
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: ${progname} <url-to-pkg> <block-dev>
|
||||
|
||||
Provision Infix to a system (typically netbooted) with a blank block
|
||||
device
|
||||
|
||||
- Downloads an Infix install bundle, using curl(1)
|
||||
- Creates an Infix compatible partition table on the block device
|
||||
- Initializes auxiliary and configuration filesystems and metadata
|
||||
- Installs Infix to both primary and secondary partitions
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
step()
|
||||
{
|
||||
current="$*"
|
||||
printf "\e[37;44m>>> %-60s\e[0m\n" "${current} ..." >&2
|
||||
}
|
||||
|
||||
ok()
|
||||
{
|
||||
printf "\e[37;42m<<< %-56s OK\e[0m\n\n" "${current}" >&2
|
||||
}
|
||||
|
||||
err()
|
||||
{
|
||||
printf "\e[37;41m!!! %-56s ERR\e[0m\n\n" "${current}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts "h" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
usage && exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage && exit 1
|
||||
fi
|
||||
|
||||
url=$1
|
||||
blk=$2
|
||||
pkg=/tmp/pkg
|
||||
|
||||
|
||||
step "Downloading $url"
|
||||
curl -o $pkg $url || err
|
||||
rauc info $pkg || err
|
||||
ok
|
||||
|
||||
|
||||
step "Formatting $blk"
|
||||
[ -b $blk ] || { echo "$blk is not a block device" >&2; err; }
|
||||
/lib/infix/prod/fdisk $blk || err
|
||||
sleep 1
|
||||
ok
|
||||
|
||||
for part in aux cfg var; do
|
||||
step "Creating $part filesystem"
|
||||
mkfs.ext4 -F -L $part /dev/disk/by-partlabel/$part || err
|
||||
mount /mnt/$part || err
|
||||
ok
|
||||
done
|
||||
|
||||
step "Bootstrapping aux partition"
|
||||
if [ -f /etc/fw_env.config ]; then
|
||||
size_n_file=$(awk '{ print("-s", $3, "-o", $1); }' /etc/fw_env.config)
|
||||
mkenvimage $size_n_file - <<EOF
|
||||
BOOT_ORDER=primary secondary net
|
||||
BOOT_primary_LEFT=1
|
||||
BOOT_secondary_LEFT=1
|
||||
BOOT_net_LEFT=1
|
||||
EOF
|
||||
fi
|
||||
ok
|
||||
|
||||
step "Preparing installation"
|
||||
rm -f /tmp/rauc
|
||||
[ -f /etc/default/rauc ] && cp /etc/default/rauc /tmp/rauc
|
||||
ok
|
||||
|
||||
|
||||
step "Installing to primary partition"
|
||||
echo "RAUC_ARGS=--override-boot-slot=secondary" >/etc/default/rauc
|
||||
initctl -b restart rauc || err
|
||||
rauc install $pkg || err
|
||||
ok
|
||||
|
||||
|
||||
step "Installing to secondary partition"
|
||||
echo "RAUC_ARGS=--override-boot-slot=primary" >/etc/default/rauc
|
||||
initctl -b restart rauc || err
|
||||
rauc install $pkg || err
|
||||
ok
|
||||
|
||||
|
||||
step "Finishing installation"
|
||||
rm /etc/default/rauc
|
||||
[ -f /tmp/rauc ] && cp /tmp/rauc /etc/default/rauc
|
||||
initctl -b restart rauc || err
|
||||
rauc status mark-active rootfs.0
|
||||
rauc status --detailed
|
||||
ok
|
||||
@@ -87,7 +87,7 @@ case "$ACTION" in
|
||||
# format: dest1/mask gw1 ... destn/mask gwn
|
||||
set -- $staticroutes
|
||||
while [ -n "$1" -a -n "$2" ]; do
|
||||
route add -net "$1" gw "$2" dev "$interface"
|
||||
ip route add -net "$1" via "$2" dev "$interface" proto 16
|
||||
shift 2
|
||||
done
|
||||
elif [ -n "$router" ] ; then
|
||||
@@ -97,7 +97,7 @@ case "$ACTION" in
|
||||
done
|
||||
|
||||
for i in $router ; do
|
||||
route add default gw $i dev $interface
|
||||
ip route add default via $i dev $interface proto 16
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../usr/bin/klish
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash -li
|
||||
# Source settings, aliases, and probe terminal size, then hand over to klish
|
||||
exec /usr/bin/klish
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"input": {
|
||||
"path": {
|
||||
"locate": { "path": "/run/led/locate" },
|
||||
|
||||
"status-prime": { "path": "/run/led/status-prime" },
|
||||
"status-ok": { "path": "/run/led/status-ok" },
|
||||
"status-err": { "path": "/run/led/status-err" },
|
||||
"status-crit": { "path": "/run/led/status-crit" },
|
||||
|
||||
"fault-prime": { "path": "/run/led/fault-prime" },
|
||||
"fault-ok": { "path": "/run/led/fault-ok" },
|
||||
"fault-err": { "path": "/run/led/fault-err" },
|
||||
"fault-crit": { "path": "/run/led/fault-crit" },
|
||||
|
||||
"lan-prime": { "path": "/run/led/lan-prime" },
|
||||
"lan-ok": { "path": "/run/led/lan-ok" },
|
||||
"lan-err": { "path": "/run/led/lan-err" },
|
||||
"lan-crit": { "path": "/run/led/lan-crit" },
|
||||
|
||||
"startup": { "path": "/run/finit/cond/run/startup/success" },
|
||||
"fail-safe": { "path": "/run/finit/cond/run/failure/success" },
|
||||
"panic": { "path": "/run/finit/cond/run/failure/failure" }
|
||||
},
|
||||
"udev": {
|
||||
"power-a": { "subsystem": "power_supply" },
|
||||
"power-b": { "subsystem": "power_supply" }
|
||||
}
|
||||
},
|
||||
|
||||
"output": {
|
||||
"led-group": {
|
||||
"port-link-act": {
|
||||
"match": ["*:green:tp", "*:green:sfp", "*:green:port" ],
|
||||
|
||||
"rules": [
|
||||
{ "if": "true", "then": { "trigger": "netdev", "link": 1, "rx": 1, "tx": 1 } }
|
||||
]
|
||||
},
|
||||
"port-alarm": {
|
||||
"match": ["*:yellow:tp", "*:yellow:sfp", "*:yellow:port" ],
|
||||
|
||||
"rules": [
|
||||
]
|
||||
}
|
||||
},
|
||||
"led": {
|
||||
"red:status": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@off" },
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "status-crit", "then": "@blink-1hz" },
|
||||
{ "if": "status-err", "then": "@on" }
|
||||
]
|
||||
},
|
||||
"green:status": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@blink-1hz" },
|
||||
{ "if": "status-prime", "then": "@blink-1hz" },
|
||||
{ "if": "status-ok", "then": "@on" }
|
||||
]
|
||||
},
|
||||
"red:fault": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@off" },
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "fault-crit", "then": "@blink-1hz" },
|
||||
{ "if": "fault-err", "then": "@on" }
|
||||
]
|
||||
},
|
||||
"green:fault": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@blink-1hz" },
|
||||
{ "if": "fault-prime", "then": "@blink-1hz" },
|
||||
{ "if": "fault-ok", "then": "@on" }
|
||||
]
|
||||
},
|
||||
"red:lan": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@off" },
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "lan-crit", "then": "@blink-1hz" },
|
||||
{ "if": "lan-err", "then": "@on" }
|
||||
]
|
||||
},
|
||||
"green:lan": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@blink-1hz" },
|
||||
{ "if": "lan-prime", "then": "@blink-1hz" },
|
||||
{ "if": "lan-ok", "then": "@on" }
|
||||
]
|
||||
},
|
||||
|
||||
"red:boot": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@off" },
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "fail-safe", "then": "@blink-5hz" }
|
||||
]
|
||||
},
|
||||
"green:boot": {
|
||||
"rules": [
|
||||
{ "if": "locate", "then": "@blink-1hz" },
|
||||
{ "if": "panic", "then": "@off" },
|
||||
{ "if": "startup", "then": "@on" },
|
||||
{ "if": "true", "then": "@blink-1hz" }
|
||||
]
|
||||
},
|
||||
|
||||
"red:power-a": {
|
||||
"rules": [
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "!power-a:online", "then": "@blink-1hz" }
|
||||
]
|
||||
},
|
||||
"red:power-b": {
|
||||
"rules": [
|
||||
{ "if": "panic", "then": "@blink-5hz" },
|
||||
{ "if": "!power-b:online", "then": "@blink-1hz" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"aliases": {
|
||||
"on": {
|
||||
"brightness": true
|
||||
},
|
||||
"off": {
|
||||
"brightness": false
|
||||
},
|
||||
"blink-1hz": {
|
||||
"trigger": "timer",
|
||||
"delay_on": 500,
|
||||
"delay_off": 500
|
||||
},
|
||||
"blink-5hz": {
|
||||
"trigger": "timer",
|
||||
"delay_on": 100,
|
||||
"delay_off": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,19 @@ class Pad:
|
||||
state = 12
|
||||
data = 41
|
||||
|
||||
class PadRoute:
|
||||
prefix = 30
|
||||
protocol = 10
|
||||
next_hop = 30
|
||||
metric = 10
|
||||
|
||||
class PadSoftware:
|
||||
name = 10
|
||||
date = 25
|
||||
hash = 64
|
||||
state = 10
|
||||
version = 23
|
||||
|
||||
class Decore():
|
||||
@staticmethod
|
||||
def decorate(sgr, txt, restore="0"):
|
||||
@@ -31,22 +44,86 @@ class Decore():
|
||||
def green(txt):
|
||||
return Decore.decorate("32", txt, "39")
|
||||
|
||||
def get_json_data(default, indata, *args):
|
||||
data = indata
|
||||
for arg in args:
|
||||
if arg in data:
|
||||
data = data.get(arg)
|
||||
else:
|
||||
return default
|
||||
|
||||
return data
|
||||
|
||||
class Route:
|
||||
def __init__(self,data):
|
||||
self.data = data
|
||||
self.prefix = data.get('ietf-ipv4-unicast-routing:destination-prefix', '')
|
||||
self.protocol = data.get('source-protocol','')[14:]
|
||||
self.metric = data.get('route-preference','')
|
||||
|
||||
interface = get_json_data(None, self.data, 'next-hop', 'outgoing-interface')
|
||||
address = get_json_data(None, self.data, 'next-hop', 'ietf-ipv4-unicast-routing:next-hop-address')
|
||||
special = get_json_data(None, self.data, 'next-hop', 'special-next-hop')
|
||||
if interface:
|
||||
self.next_hop = interface
|
||||
elif address:
|
||||
self.next_hop = address
|
||||
elif special:
|
||||
self.next_hop = special
|
||||
else:
|
||||
self.next_hop = "unspecified"
|
||||
|
||||
def print(self):
|
||||
row = f"{self.prefix:<{PadRoute.prefix}}"
|
||||
row += f"{self.next_hop:<{PadRoute.next_hop}}"
|
||||
row += f"{self.metric:<{PadRoute.metric}}"
|
||||
row += f"{self.protocol:<{PadRoute.protocol}}"
|
||||
print(row)
|
||||
|
||||
class Software:
|
||||
"""Software bundle class """
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.name = data.get('bootname', '')
|
||||
self.size = data.get('size', '')
|
||||
self.type = data.get('class', '')
|
||||
self.hash = data.get('sha256', '')
|
||||
self.state = data.get('state', '')
|
||||
self.version = get_json_data(None, self.data, 'bundle', 'version')
|
||||
self.date = get_json_data(None, self.data, 'installed', 'datetime')
|
||||
|
||||
def is_rootfs(self):
|
||||
"""True if bundle type is 'rootfs'"""
|
||||
return self.type == "rootfs"
|
||||
|
||||
def print(self):
|
||||
"""Brief information about one bundle"""
|
||||
row = f"{self.name:<{PadSoftware.name}}"
|
||||
row += f"{self.state:<{PadSoftware.state}}"
|
||||
row += f"{self.version:<{PadSoftware.version}}"
|
||||
row += f"{self.date:<{PadSoftware.date}}"
|
||||
print(row)
|
||||
|
||||
def detail(self):
|
||||
"""Detailed information about one bundle"""
|
||||
print(f"Name : {self.name}")
|
||||
print(f"State : {self.state}")
|
||||
print(f"Version : {self.version}")
|
||||
print(f"Size : {self.size}")
|
||||
print(f"SHA-256 : {self.hash}")
|
||||
print(f"Installed : {self.date}")
|
||||
|
||||
class Iface:
|
||||
def get_json_data(self, default, *args):
|
||||
data = self.data
|
||||
for arg in args:
|
||||
if data.get(arg):
|
||||
data = data.get(arg)
|
||||
else:
|
||||
return default
|
||||
|
||||
return data
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.name = data.get('name', '')
|
||||
self.type = data.get('type', '')
|
||||
self.index = data.get('if-index', '')
|
||||
self.oper_status = data.get('oper-status', '')
|
||||
self.autoneg = get_json_data('unknown', self.data, 'ieee802-ethernet-interface:ethernet',
|
||||
'auto-negotiation', 'enable')
|
||||
self.duplex = get_json_data('', self.data,'ieee802-ethernet-interface:ethernet','duplex')
|
||||
self.speed = get_json_data('', self.data, 'ieee802-ethernet-interface:ethernet', 'speed')
|
||||
self.phys_address = data.get('phys-address', '')
|
||||
|
||||
if data.get('statistics'):
|
||||
@@ -79,10 +156,13 @@ class Iface:
|
||||
self.lower_if = ''
|
||||
|
||||
def is_vlan(self):
|
||||
return self.data['type'] == "infix-if-type:vlan"
|
||||
return self.type == "infix-if-type:vlan"
|
||||
|
||||
def is_bridge(self):
|
||||
return self.data['type'] == "infix-if-type:bridge"
|
||||
return self.type == "infix-if-type:bridge"
|
||||
|
||||
def is_veth(self):
|
||||
return self.data['type'] == "infix-if-type:veth"
|
||||
|
||||
def pr_name(self, pipe=""):
|
||||
print(f"{pipe}{self.name:<{Pad.iface - len(pipe)}}", end="")
|
||||
@@ -110,7 +190,7 @@ class Iface:
|
||||
row = f"{'ethernet':<{Pad.proto}}"
|
||||
dec = Decore.green if self.oper_status == "up" else Decore.red
|
||||
row += dec(f"{self.oper_status.upper():<{Pad.state}}")
|
||||
row += f"{self.data['phys-address']:<{Pad.data}}"
|
||||
row += f"{self.phys_address:<{Pad.data}}"
|
||||
print(row)
|
||||
|
||||
def pr_bridge(self, _ifaces):
|
||||
@@ -135,6 +215,20 @@ class Iface:
|
||||
lower.pr_name(pipe)
|
||||
lower.pr_proto_eth()
|
||||
|
||||
def pr_veth(self, _ifaces):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_eth()
|
||||
|
||||
if self.lower_if:
|
||||
row = f"{'':<{Pad.iface}}"
|
||||
row += f"{'veth':<{Pad.proto}}"
|
||||
row += f"{'':<{Pad.state}}"
|
||||
row += f"peer:{self.lower_if}"
|
||||
print(row)
|
||||
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
def pr_vlan(self, _ifaces):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_eth()
|
||||
@@ -161,6 +255,21 @@ class Iface:
|
||||
print(f"{'mtu':<{20}}: {self.mtu}")
|
||||
if self.oper_status:
|
||||
print(f"{'operational status':<{20}}: {self.oper_status}")
|
||||
|
||||
if self.lower_if:
|
||||
print(f"{'lower-layer-if':<{20}}: {self.lower_if}")
|
||||
|
||||
if self.autoneg != 'unknown':
|
||||
val = "on" if self.autoneg else "off"
|
||||
print(f"{'auto-negotiation':<{20}}: {val}")
|
||||
|
||||
if self.duplex:
|
||||
print(f"{'duplex':<{20}}: {self.duplex}")
|
||||
|
||||
if self.speed:
|
||||
mbs = float(self.speed) * 1000
|
||||
print(f"{'speed':<{20}}: {int(mbs)}")
|
||||
|
||||
if self.phys_address:
|
||||
print(f"{'physical address':<{20}}: {self.phys_address}")
|
||||
|
||||
@@ -194,8 +303,8 @@ class Iface:
|
||||
print(f"{'in-octets':<{20}}: {self.in_octets}")
|
||||
print(f"{'out-octets':<{20}}: {self.out_octets}")
|
||||
|
||||
frame = self.get_json_data([], 'ieee802-ethernet-interface:ethernet',
|
||||
'statistics', 'frame')
|
||||
frame = get_json_data([], self.data,'ieee802-ethernet-interface:ethernet',
|
||||
'statistics', 'frame')
|
||||
if frame:
|
||||
print(f"")
|
||||
for key, val in frame.items():
|
||||
@@ -225,6 +334,10 @@ def pr_interface_list(json):
|
||||
iface.pr_bridge(ifaces)
|
||||
continue
|
||||
|
||||
if iface.is_veth():
|
||||
iface.pr_veth(ifaces)
|
||||
continue
|
||||
|
||||
if iface.is_vlan():
|
||||
iface.pr_vlan(ifaces)
|
||||
continue
|
||||
@@ -241,18 +354,67 @@ def pr_interface_list(json):
|
||||
iface.pr_proto_ipv6()
|
||||
|
||||
def ietf_interfaces(json, name):
|
||||
if not json or not json.get("ietf-interfaces:interfaces"):
|
||||
print(f"Error, top level \"ietf-interfaces:interfaces\" missing")
|
||||
if name:
|
||||
if not json.get("ietf-interfaces:interfaces"):
|
||||
print(f"No interface data found for \"{name}\"")
|
||||
sys.exit(1)
|
||||
iface = find_iface(json["ietf-interfaces:interfaces"]["interface"], name)
|
||||
if not iface:
|
||||
print(f"Interface \"{name}\" not found")
|
||||
sys.exit(1)
|
||||
iface.pr_iface()
|
||||
else:
|
||||
if not json.get("ietf-interfaces:interfaces"):
|
||||
print(f"Error, top level \"ietf-interfaces:interfaces\" missing")
|
||||
sys.exit(1)
|
||||
pr_interface_list(json)
|
||||
|
||||
def ietf_routing(json, protocol="ipv4"):
|
||||
if not json.get("ietf-routing:routing"):
|
||||
print(f"Error, top level \"ietf-routing:routing\" missing")
|
||||
sys.exit(1)
|
||||
routes = get_json_data({}, json, 'ietf-routing:routing','ribs', 'rib')[0]
|
||||
routes = get_json_data(None, routes, "routes", "route")
|
||||
|
||||
hdr = (f"{'PREFIX':<{PadRoute.prefix}}"
|
||||
f"{'NEXT-HOP':<{PadRoute.next_hop}}"
|
||||
f"{'METRIC':<{PadRoute.metric}}"
|
||||
f"{'PROTOCOL':<{PadRoute.protocol}}")
|
||||
|
||||
print(Decore.invert(hdr))
|
||||
|
||||
if routes:
|
||||
for r in routes:
|
||||
route = Route(r)
|
||||
route.print()
|
||||
|
||||
def find_slot(_slots, name):
|
||||
for _slot in [Software(data) for data in _slots]:
|
||||
if _slot.name == name:
|
||||
return _slot
|
||||
|
||||
return False
|
||||
|
||||
def infix_system(json, name):
|
||||
if not json.get("ietf-system:system-state", "infix-system:software"):
|
||||
print("Error, cannot find infix-system:software")
|
||||
sys.exit(1)
|
||||
|
||||
if not name:
|
||||
return pr_interface_list(json)
|
||||
|
||||
iface = find_iface(json["ietf-interfaces:interfaces"]["interface"], name)
|
||||
if not iface:
|
||||
print(f"Interface {name} not found")
|
||||
sys.exit(1)
|
||||
return iface.pr_iface()
|
||||
slots = get_json_data({}, json, 'ietf-system:system-state', 'infix-system:software', 'slot')
|
||||
if name:
|
||||
slot = find_slot(slots, name)
|
||||
if slot:
|
||||
slot.detail()
|
||||
else:
|
||||
hdr = (f"{'NAME':<{PadSoftware.name}}"
|
||||
f"{'STATE':<{PadSoftware.state}}"
|
||||
f"{'VERSION':<{PadSoftware.version}}"
|
||||
f"{'DATE':<{PadSoftware.date}}")
|
||||
print(Decore.invert(hdr))
|
||||
for _s in slots:
|
||||
slot = Software(_s)
|
||||
if slot.is_rootfs():
|
||||
slot.print()
|
||||
|
||||
def main():
|
||||
try:
|
||||
@@ -266,6 +428,10 @@ def main():
|
||||
|
||||
if args.module == "ietf-interfaces":
|
||||
sys.exit(ietf_interfaces(json_data, args.name))
|
||||
if args.module == "ietf-routing":
|
||||
sys.exit(ietf_routing(json_data, args.name))
|
||||
if args.module == "infix-system":
|
||||
sys.exit(infix_system(json_data, args.name))
|
||||
else:
|
||||
print(f"Error, unknown module {args.module}")
|
||||
sys.exit(1)
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
|
||||
def get_ethtool_output(interface):
|
||||
try:
|
||||
output = subprocess.check_output(['ethtool', interface], stderr=subprocess.DEVNULL, text=True)
|
||||
return output.splitlines()
|
||||
except subprocess.CalledProcessError:
|
||||
print("Error: Failed to run ethtool on interface", interface)
|
||||
sys.exit(1)
|
||||
|
||||
def parse_ethtool_output(lines, keys):
|
||||
result = {}
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
key = line.split(':', 1)[0].strip()
|
||||
if key in keys:
|
||||
key, value = line.split(':', 1)
|
||||
result[key.strip()] = value.strip()
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {sys.argv[0]} INTERFACE")
|
||||
sys.exit(1)
|
||||
|
||||
interface = sys.argv[1]
|
||||
keys = ["Duplex", "Auto-negotiation"]
|
||||
|
||||
lines = get_ethtool_output(interface)
|
||||
parsed_data = parse_ethtool_output(lines, keys)
|
||||
|
||||
print(json.dumps(parsed_data, indent=4))
|
||||
Executable
+405
@@ -0,0 +1,405 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys # (built-in module)
|
||||
|
||||
def json_get_yang_type(iface_in):
|
||||
if iface_in['link_type'] == "loopback":
|
||||
return "infix-if-type:loopback"
|
||||
|
||||
if iface_in['link_type'] != "ether":
|
||||
return "infix-if-type:other";
|
||||
|
||||
if not 'linkinfo' in iface_in:
|
||||
return "infix-if-type:ethernet"
|
||||
|
||||
if not 'info_kind' in iface_in['linkinfo']:
|
||||
return "infix-if-type:ethernet";
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] == "veth":
|
||||
return "infix-if-type:veth";
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] == "vlan":
|
||||
return "infix-if-type:vlan";
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] == "bridge":
|
||||
return "infix-if-type:bridge";
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] == "dsa":
|
||||
return "infix-if-type:ethernet";
|
||||
|
||||
# Fallback
|
||||
return "infix-if-type:ethernet";
|
||||
|
||||
def json_get_yang_origin(addr):
|
||||
map = {
|
||||
"kernel_ll": "link-layer",
|
||||
"kernel_ra": "link-layer",
|
||||
"static": "static",
|
||||
"dhcp": "dhcp",
|
||||
"random": "random",
|
||||
}
|
||||
proto = addr['protocol']
|
||||
|
||||
if proto == "kernel_ll" or proto == "kernel_ra":
|
||||
if "stable-privacy" in addr:
|
||||
return "random"
|
||||
|
||||
return map.get(proto, "other")
|
||||
|
||||
def get_proc_value(procfile):
|
||||
try:
|
||||
with open(procfile, 'r') as file:
|
||||
data = file.read().strip()
|
||||
return data
|
||||
except FileNotFoundError:
|
||||
# This is considered OK
|
||||
return None
|
||||
except IOError:
|
||||
print(f"Error: reading from {procfile}", file=sys.stderr)
|
||||
|
||||
# This function returns a value from a nested json dict
|
||||
def lookup(json, *keys):
|
||||
curr = json
|
||||
for key in keys:
|
||||
if isinstance(curr, dict) and key in curr:
|
||||
curr = curr[key]
|
||||
else:
|
||||
return None
|
||||
return curr
|
||||
|
||||
# This function inserts a value into a nested json dict
|
||||
def insert(json, *path_and_value):
|
||||
if len(path_and_value) < 2:
|
||||
raise ValueError("Error: insert() takes at least two args")
|
||||
|
||||
*path, value = path_and_value
|
||||
|
||||
curr = json
|
||||
for key in path[:-1]:
|
||||
if key not in curr or not isinstance(curr[key], dict):
|
||||
curr[key] = {}
|
||||
curr = curr[key]
|
||||
|
||||
curr[path[-1]] = value
|
||||
|
||||
def run_cmd(cmd):
|
||||
try:
|
||||
output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True)
|
||||
return output.splitlines()
|
||||
except subprocess.CalledProcessError:
|
||||
print(f"Error: command returned error", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def run_json_cmd(cmd):
|
||||
try:
|
||||
result = subprocess.run(cmd, check=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, text=True)
|
||||
output = result.stdout
|
||||
data = json.loads(output)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error: unable to get data:", file=sys.stderr)
|
||||
print(f"{e.stderr}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error: parsing JSON output: {e.msg}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
return data
|
||||
|
||||
def iface_is_dsa(iface_in):
|
||||
if not "linkinfo" in iface_in:
|
||||
return False
|
||||
if not "info_kind" in iface_in['linkinfo']:
|
||||
return False
|
||||
if iface_in['linkinfo']['info_kind'] != "dsa":
|
||||
return False
|
||||
return True
|
||||
|
||||
def add_ipv4_route(routes):
|
||||
cmd = ['ip', '-4', '-s', '-d', '-j', 'route']
|
||||
data = run_json_cmd(cmd)
|
||||
out={}
|
||||
out["route"] = []
|
||||
|
||||
for d in data:
|
||||
new = {}
|
||||
next_hop = {}
|
||||
if(d['dst'] == "default"):
|
||||
d['dst'] = "0.0.0.0/0"
|
||||
if(d['dst'].find('/') == -1):
|
||||
d['dst'] = d['dst']+"/32"
|
||||
new['ietf-ipv4-unicast-routing:destination-prefix'] = d['dst']
|
||||
new['source-protocol'] = "infix-routing:"+d['protocol']
|
||||
if d.get("metric"):
|
||||
new['route-preference'] = d['metric']
|
||||
else:
|
||||
new['route-preference'] = 0
|
||||
|
||||
if d['type'] == "blackhole":
|
||||
next_hop['special-next-hop'] = "blackhole"
|
||||
if d['type'] == "unreachable":
|
||||
next_hop['special-next-hop'] = "unreachable"
|
||||
|
||||
if d['type'] == "unicast":
|
||||
if(d.get("gateway")):
|
||||
next_hop['ietf-ipv4-unicast-routing:next-hop-address'] = d['gateway']
|
||||
elif(d.get("dev")):
|
||||
next_hop['outgoing-interface'] = d['dev']
|
||||
|
||||
new['next-hop'] = next_hop
|
||||
|
||||
out['route'].append(new)
|
||||
insert(routes, 'routes', out)
|
||||
|
||||
def add_ip_link(ifname, iface_out):
|
||||
cmd = ['ip', '-s', '-d', '-j', 'link', 'show', 'dev', ifname]
|
||||
|
||||
data = run_json_cmd(cmd)
|
||||
if len(data) != 1:
|
||||
print(f"Error: expected ip link output to be array with length 1", file=sys.stderr)
|
||||
sys,exit(1)
|
||||
|
||||
iface_in = data[0]
|
||||
|
||||
if 'ifname' in iface_in:
|
||||
iface_out['name'] = iface_in['ifname']
|
||||
|
||||
if 'ifindex' in iface_in:
|
||||
iface_out['if-index'] = iface_in['ifindex']
|
||||
|
||||
if 'address' in iface_in:
|
||||
iface_out['phys-address'] = iface_in['address']
|
||||
|
||||
if 'master' in iface_in:
|
||||
insert(iface_out, "infix-interfaces:bridge-port", "bridge", iface_in['master'])
|
||||
|
||||
if 'link' in iface_in and not iface_is_dsa(iface_in):
|
||||
insert(iface_out, "infix-interfaces:vlan", "lower-layer-if", iface_in['link'])
|
||||
|
||||
if 'operstate' in iface_in:
|
||||
map = {
|
||||
"DOWN": "down",
|
||||
"UP": "up",
|
||||
"DORMANT": "dormant",
|
||||
"TESTING": "testing",
|
||||
"LOWERLAYERDOWN": "lower-layer-down",
|
||||
"NOTPRESENT": "not-present"
|
||||
}
|
||||
val = map.get(iface_in['operstate'], "unknown")
|
||||
iface_out['oper-status'] = val
|
||||
|
||||
if 'link_type' in iface_in:
|
||||
val = json_get_yang_type(iface_in)
|
||||
iface_out['type'] = val
|
||||
|
||||
val = lookup(iface_in, "stats64", "rx", "bytes")
|
||||
if val is not None:
|
||||
insert(iface_out, "statistics", "out-octets", str(val))
|
||||
|
||||
val = lookup(iface_in, "stats64", "tx", "bytes")
|
||||
if val is not None:
|
||||
insert(iface_out, "statistics", "in-octets", str(val))
|
||||
|
||||
def add_ip_addr(ifname, iface_out):
|
||||
cmd = ['ip', '-j', 'addr', 'show', 'dev', ifname]
|
||||
|
||||
data = run_json_cmd(cmd)
|
||||
if len(data) != 1:
|
||||
print(f"Error: expected ip addr output to be array with length 1", file=sys.stderr)
|
||||
sys,exit(1)
|
||||
|
||||
iface_in = data[0]
|
||||
|
||||
if 'mtu' in iface_in and ifname != "lo":
|
||||
insert(iface_out, "ietf-ip:ipv4", "mtu", iface_in['mtu'])
|
||||
|
||||
# We avoid importing os to check if the file exists (for performance)
|
||||
val = get_proc_value(f"/proc/sys/net/ipv6/conf/{ifname}/mtu")
|
||||
if val is not None:
|
||||
insert(iface_out, "ietf-ip:ipv6", "mtu", int(val))
|
||||
|
||||
if 'addr_info' in iface_in:
|
||||
inet = []
|
||||
inet6 = []
|
||||
|
||||
for addr in iface_in['addr_info']:
|
||||
new = {}
|
||||
|
||||
if not 'family' in addr:
|
||||
print(f"Error: 'family' missing from 'addr_info'", file=sys.stderr)
|
||||
continue
|
||||
|
||||
if 'local' in addr:
|
||||
new['ip'] = addr['local']
|
||||
if 'prefixlen' in addr:
|
||||
new['prefix-length'] = addr['prefixlen']
|
||||
if 'protocol' in addr:
|
||||
new['origin'] = json_get_yang_origin(addr)
|
||||
|
||||
if addr['family'] == "inet":
|
||||
inet.append(new)
|
||||
elif addr['family'] == "inet6":
|
||||
inet6.append(new)
|
||||
else:
|
||||
print(f"Error: invalid 'family' in 'addr_info'", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
insert(iface_out, "ietf-ip:ipv4", "address", inet)
|
||||
insert(iface_out, "ietf-ip:ipv6", "address", inet6)
|
||||
|
||||
def add_ethtool_groups(ifname, iface_out):
|
||||
cmd = ['ethtool', '--json', '-S', ifname, '--all-groups']
|
||||
|
||||
data = run_json_cmd(cmd)
|
||||
if len(data) != 1:
|
||||
print(f"Error: expected ethtool groups output to be array with length 1", file=sys.stderr)
|
||||
sys,exit(1)
|
||||
|
||||
iface_in = data[0]
|
||||
|
||||
# TODO: room for improvement here, the "frame" creation could be more dynamic.
|
||||
if "eth-mac" in iface_in or "rmon" in iface_in:
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "statistics", "frame", {})
|
||||
frame = iface_out['ieee802-ethernet-interface:ethernet']['statistics']['frame']
|
||||
|
||||
if "eth-mac" in iface_in:
|
||||
mac_in = iface_in['eth-mac']
|
||||
|
||||
if "FramesTransmittedOK" in mac_in:
|
||||
frame['out-frames'] = str(mac_in['FramesTransmittedOK'])
|
||||
if "MulticastFramesXmittedOK" in mac_in:
|
||||
frame['out-multicast-frames'] = str(mac_in['MulticastFramesXmittedOK'])
|
||||
if "BroadcastFramesXmittedOK" in mac_in:
|
||||
frame['out-broadcast-frames'] = str(mac_in['BroadcastFramesXmittedOK'])
|
||||
if "FramesReceivedOK" in mac_in:
|
||||
frame['in-frames'] = str(mac_in['FramesReceivedOK'])
|
||||
if "MulticastFramesReceivedOK" in mac_in:
|
||||
frame['in-multicast-frames'] = str(mac_in['MulticastFramesReceivedOK'])
|
||||
if "BroadcastFramesReceivedOK" in mac_in:
|
||||
frame['in-broadcast-frames'] = str(mac_in['BroadcastFramesReceivedOK'])
|
||||
if "FrameCheckSequenceErrors" in mac_in:
|
||||
frame['in-error-fcs-frames'] = str(mac_in['FrameCheckSequenceErrors'])
|
||||
if "FramesLostDueToIntMACRcvError" in mac_in:
|
||||
frame['in-error-mac-internal-frames'] = str(mac_in['FramesLostDueToIntMACRcvError'])
|
||||
|
||||
tot = 0
|
||||
found = False
|
||||
if "FramesReceivedOK" in mac_in:
|
||||
tot += mac_in['FramesReceivedOK']
|
||||
found = True
|
||||
if "FrameCheckSequenceErrors" in mac_in:
|
||||
tot += mac_in['FrameCheckSequenceErrors']
|
||||
found = True
|
||||
if "FramesLostDueToIntMACRcvError" in mac_in:
|
||||
tot += mac_in['FramesLostDueToIntMACRcvError']
|
||||
found = True
|
||||
if "AlignmentErrors" in mac_in:
|
||||
tot += mac_in['AlignmentErrors']
|
||||
found = True
|
||||
if "etherStatsOversizePkts" in mac_in:
|
||||
tot += mac_in['etherStatsOversizePkts']
|
||||
found = True
|
||||
if "etherStatsJabbers" in mac_in:
|
||||
tot += mac_in['etherStatsJabbers']
|
||||
found = True
|
||||
if found:
|
||||
frame['in-total-frames'] = str(tot)
|
||||
|
||||
if "rmon" in iface_in:
|
||||
rmon_in = iface_in['rmon']
|
||||
|
||||
if "undersize_pkts" in rmon_in:
|
||||
frame['in-error-undersize-frames'] = str(rmon_in['undersize_pkts'])
|
||||
|
||||
tot = 0
|
||||
found = False
|
||||
if "etherStatsJabbers" in rmon_in:
|
||||
tot += rmon_in['etherStatsJabbers']
|
||||
found = True
|
||||
if "etherStatsOversizePkts" in rmon_in:
|
||||
tot += rmon_in['etherStatsOversizePkts']
|
||||
found = True
|
||||
if found:
|
||||
frame['in-error-oversize-frames'] = str(tot)
|
||||
|
||||
def add_ethtool_std(ifname, iface_out):
|
||||
cmd = ['ethtool', ifname]
|
||||
keys = ['Speed', 'Duplex', 'Auto-negotiation']
|
||||
result = {}
|
||||
|
||||
lines = run_cmd(cmd)
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
key = line.split(':', 1)[0].strip()
|
||||
if key in keys:
|
||||
key, value = line.split(':', 1)
|
||||
result[key.strip()] = value.strip()
|
||||
|
||||
if "Auto-negotiation" in result:
|
||||
if result['Auto-negotiation'] == "on":
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "auto-negotiation", "enable", True)
|
||||
else:
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "auto-negotiation", "enable", False)
|
||||
|
||||
if "Duplex" in result:
|
||||
if result['Duplex'] == "Half":
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "duplex", "half")
|
||||
elif result['Duplex'] == "Full":
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "duplex", "full")
|
||||
else:
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "duplex", "unknown")
|
||||
|
||||
if "Speed" in result and result['Speed'] != "Unknown!":
|
||||
# Avoid importing re (performance)
|
||||
num = ''.join(filter(str.isdigit, result['Speed']))
|
||||
if num:
|
||||
num = round((int(num) / 1000), 3)
|
||||
insert(iface_out, "ieee802-ethernet-interface:ethernet", "speed", str(num))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print(f"usage: yanger <model> [params]", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
model = sys.argv[1]
|
||||
if(model == 'ietf-interfaces'):
|
||||
# For now, we handle each interface separately, as this is how it's
|
||||
# currently implemented in sysrepo. I.e sysrepo will subscribe to
|
||||
# each individual interface and query it for YANG data.
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print(f"usage: yanger ietf-interfaces IFNAME", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
yang_data = {
|
||||
"ietf-interfaces:interfaces": {
|
||||
"interface": [{}]
|
||||
}
|
||||
}
|
||||
|
||||
ifname = sys.argv[2]
|
||||
iface_out = yang_data['ietf-interfaces:interfaces']['interface'][0]
|
||||
|
||||
add_ip_link(ifname, iface_out)
|
||||
add_ip_addr(ifname, iface_out)
|
||||
add_ethtool_groups(ifname, iface_out)
|
||||
add_ethtool_std(ifname, iface_out)
|
||||
elif(model == 'ietf-routing'):
|
||||
yang_data = {
|
||||
"ietf-routing:routing": {
|
||||
"ribs": {
|
||||
"rib": [{
|
||||
"name": "ipv4",
|
||||
"address-family": "ipv4",
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipv4routes = yang_data['ietf-routing:routing']['ribs']['rib'][0]
|
||||
add_ipv4_route(ipv4routes);
|
||||
else:
|
||||
print(f"Unsupported model {model}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print(json.dumps(yang_data, indent=2))
|
||||
@@ -1,5 +1,6 @@
|
||||
test-dir := $(BR2_EXTERNAL_INFIX_PATH)/test
|
||||
INFIX_TESTS ?= $(test-dir)/case/all-unit.yaml $(test-dir)/case/all.yaml
|
||||
INFIX_TESTS ?= $(test-dir)/case/all-repo.yaml $(test-dir)/case/all-unit.yaml \
|
||||
$(test-dir)/case/all.yaml
|
||||
|
||||
test-env = $(test-dir)/env \
|
||||
-f $(BINARIES_DIR)/infix-x86_64.img \
|
||||
|
||||
@@ -229,6 +229,13 @@ CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_UHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_ACTIVITY=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
|
||||
@@ -22,7 +22,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
|
||||
@@ -13,6 +13,7 @@ BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
|
||||
BR2_INIT_FINIT=y
|
||||
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
||||
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
|
||||
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
|
||||
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
|
||||
BR2_SYSTEM_DHCP="eth0"
|
||||
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
||||
@@ -23,7 +24,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
@@ -36,17 +37,21 @@ BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
|
||||
BR2_PACKAGE_STRACE=y
|
||||
BR2_PACKAGE_STRESS_NG=y
|
||||
BR2_PACKAGE_JQ=y
|
||||
BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_MDIO_TOOLS=y
|
||||
BR2_PACKAGE_RNG_TOOLS=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
||||
BR2_PACKAGE_PYTHON3=y
|
||||
BR2_PACKAGE_CA_CERTIFICATES=y
|
||||
BR2_PACKAGE_LIBOPENSSL_BIN=y
|
||||
@@ -62,7 +67,9 @@ BR2_PACKAGE_CONNTRACK_TOOLS=y
|
||||
BR2_PACKAGE_DNSMASQ=y
|
||||
BR2_PACKAGE_ETHTOOL=y
|
||||
BR2_PACKAGE_FPING=y
|
||||
BR2_PACKAGE_FRR=y
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
BR2_PACKAGE_IPROUTE2=y
|
||||
BR2_PACKAGE_IPTABLES=y
|
||||
BR2_PACKAGE_IPTABLES_NFTABLES=y
|
||||
BR2_PACKAGE_IPUTILS=y
|
||||
@@ -108,7 +115,7 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
INFIX_VENDOR_HOME="https://github.com/kernelkit"
|
||||
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix"
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_CONFD=y
|
||||
@@ -120,9 +127,9 @@ BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
|
||||
BR2_PACKAGE_IITO=y
|
||||
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
||||
BR2_PACKAGE_LOWDOWN=y
|
||||
BR2_PACKAGE_NET=y
|
||||
BR2_PACKAGE_TETRIS=y
|
||||
BR2_PACKAGE_QUERIERD=y
|
||||
DISK_IMAGE_BOOT_BIN=y
|
||||
|
||||
@@ -21,7 +21,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -12,6 +12,7 @@ BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
|
||||
BR2_INIT_FINIT=y
|
||||
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
||||
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
|
||||
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
|
||||
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
|
||||
BR2_SYSTEM_DHCP="eth0"
|
||||
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
||||
@@ -22,7 +23,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -38,11 +39,14 @@ BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
|
||||
BR2_PACKAGE_GPTFDISK=y
|
||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||
BR2_PACKAGE_RNG_TOOLS=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
||||
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
||||
BR2_PACKAGE_PYTHON3=y
|
||||
BR2_PACKAGE_CA_CERTIFICATES=y
|
||||
BR2_PACKAGE_LIBOPENSSL_BIN=y
|
||||
@@ -58,7 +62,9 @@ BR2_PACKAGE_CONNTRACK_TOOLS=y
|
||||
BR2_PACKAGE_DNSMASQ=y
|
||||
BR2_PACKAGE_ETHTOOL=y
|
||||
BR2_PACKAGE_FPING=y
|
||||
BR2_PACKAGE_FRR=y
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
BR2_PACKAGE_IPROUTE2=y
|
||||
BR2_PACKAGE_IPTABLES=y
|
||||
BR2_PACKAGE_IPTABLES_NFTABLES=y
|
||||
BR2_PACKAGE_IPUTILS=y
|
||||
@@ -124,9 +130,9 @@ BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
|
||||
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
|
||||
BR2_PACKAGE_IITO=y
|
||||
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
||||
BR2_PACKAGE_LOWDOWN=y
|
||||
BR2_PACKAGE_NET=y
|
||||
BR2_PACKAGE_TETRIS=y
|
||||
BR2_PACKAGE_QUERIERD=y
|
||||
GNS3_APPLIANCE_RAM=512
|
||||
|
||||
+146
-16
@@ -4,6 +4,138 @@ Change Log
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
|
||||
[v23.11.0][] - 2023-11-28
|
||||
-------------------------
|
||||
|
||||
> **Note:** this is the first release where the `root` account is disabled in
|
||||
> default builds. Only the `admin` user, generated from `factory-config`, can
|
||||
> log in to the system. This can be changed only in developer builds: `make
|
||||
> menuconfig` -> System configuration -> `[*]Enable root login with password`
|
||||
|
||||
### YANG Status
|
||||
|
||||
- [ieee802-ethernet-interfaces][]: Currently supported (read-only) features:
|
||||
- Status of auto-negotiation, and if enabled.
|
||||
- Current speed and duplex
|
||||
- Frame counters:
|
||||
|
||||
| **YANG** | **Linux / Ethtool** |
|
||||
|-----------------------------|-----------------------------------|
|
||||
| `out-frames` | `FramesTransmittedOK` |
|
||||
| `out-multicast-frames` | `MulticastFramesXmittedOK` |
|
||||
| `out-broadcast-frames` | `BroadcastFramesXmittedOK` |
|
||||
| `in-total-octets` | `FramesReceivedOK` |
|
||||
| | + `FrameCheckSequenceErrors` |
|
||||
| | + `FramesLostDueToIntMACRcvError` |
|
||||
| | + `AlignmentErrors` |
|
||||
| | + `etherStatsOversizePkts` |
|
||||
| | + `etherStatsJabbers` |
|
||||
| `in-frames` | `FramesReceivedOK` |
|
||||
| `in-multicast-frames` | `MulticastFramesReceivedOK` |
|
||||
| `in-broadcast-frames` | `BroadcastFramesReceivedOK` |
|
||||
| `in-error-undersize-frames` | `undersize_pkts` |
|
||||
| `in-error-fcs-frames` | `FrameCheckSequenceErrors` |
|
||||
|
||||
- [ietf-system][]:
|
||||
- **augments:**
|
||||
- MotD (Message of the Day)
|
||||
- User login shell, default: `/bin/false` (no SSH or console login)
|
||||
- State information for remotely querying firmware version information
|
||||
- **deviations:**
|
||||
- timezone-name, using IANA timezones instead of plain string
|
||||
- UTC offset, only support per-hour offsets with [tzdata][]
|
||||
- Usernames, clarifying Linux restrictions
|
||||
- Unsupported features marked as deviations, e.g. RADIUS
|
||||
- [infix-system-software][]: firmware upgrade with `install-bundle` RPC
|
||||
- [ietf-interfaces][]:
|
||||
- deviation to allow read-write `if:phys-address` for custom MAC address
|
||||
- [ietf-ip][]: augments
|
||||
- IPv4LL similar to standardized IPv6LL
|
||||
- [ietf-ip][]: deviations (`not-supported`) added for IPv4 and IPv6:
|
||||
- `/if:interfaces/if:interface/ip:ipv4/ip:address/ip:subnet/ip:netmask`
|
||||
- `/if:interfaces/if:interface/ip:ipv6/ip:address/ip:status`
|
||||
- `/if:interfaces/if:interface/ip:ipv4/ip:neighbor`
|
||||
- `/if:interfaces/if:interface/ip:ipv6/ip:neighbor`
|
||||
- [ietf-routing][]: Base model for routing
|
||||
- [ietf-ipv4-unicast-routing][]: Static unicast routing, incl. operational
|
||||
data, i.e., setting static IPv4 routes and reading IPv4 routing table
|
||||
- [infix-ethernet-interfaces][]: deviations for ieee802-ethernet-interfaces
|
||||
- [infix-routing][]: Limit ietf-routing to one instance `default` per
|
||||
routing protocol, also details unsupported features (deviations)
|
||||
- [infix-if-bridge][]: Linux bridge interfaces with native VLAN support
|
||||
- [infix-if-type][]: deviation for interface types, limiting number
|
||||
to supported types only. New identities are derived from default
|
||||
IANA interface types, ensuring compatibility with other standard
|
||||
models, e.g., `ieee802-ethernet-interface.yang`
|
||||
- [infix-if-veth][]: Linux VETH pairs
|
||||
- [infix-if-vlan][]: Linux VLAN interfaces, e.g. `eth0.10`
|
||||
- **Configurable services:**
|
||||
- [ieee802-dot1ab-lldp][]: stripped down to an `enabled` setting
|
||||
- [infix-services][]: support for enabling mDNS service/device discovery
|
||||
|
||||
[tzdata]: https://www.iana.org/time-zones
|
||||
[ietf-system]: https://www.rfc-editor.org/rfc/rfc7317.html
|
||||
[ietf-interfaces]: https://www.rfc-editor.org/rfc/rfc7223.html
|
||||
[ietf-ip]: https://www.rfc-editor.org/rfc/rfc8344.html
|
||||
[ietf-if-vlan-encapsulation]: https://www.ietf.org/id/draft-ietf-netmod-sub-intf-vlan-model-08.html
|
||||
[ieee802-dot1ab-lldp]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/ieee802-dot1ab-lldp%402022-03-15.yang
|
||||
[ieee802-ethernet-interfaces]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/ieee802-ethernet-interface%402019-06-21.yang
|
||||
[infix-if-bridge]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/infix-if-bridge%402023-11-08.yang
|
||||
[infix-if-type]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/infix-if-type%402023-08-21.yang
|
||||
[infix-if-veth]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/infix-if-veth%402023-06-05.yang
|
||||
[infix-if-vlan]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/infix-if-vlan%402023-10-25.yang
|
||||
[infix-ip]: https://github.com/kernelkit/infix/tree/985c2fd/src/confd/yang/infix-ip%402023-09-14.yang
|
||||
[infix-services]: https://github.com/kernelkit/infix/blob/985c2fd/src/confd/yang/infix-services%402023-10-16.yang
|
||||
[infix-system-software]: https://github.com/kernelkit/infix/tree/985c2fd/src/confd/yang/infix-system-software%402023-06-27.yang
|
||||
|
||||
### Changes
|
||||
|
||||
- The CLI built-in command `password generate` has been changed to use the
|
||||
secure mode of the `pwgen` tool, and 13 chars for increased entropy
|
||||
- The `qemu.sh -c` command, available in developer builds and the release zip,
|
||||
can now be used to modify the RAM size and enable VPD emulation
|
||||
- Add support for overriding generated factory defaults in derivatives
|
||||
using a `/etc/confdrc.lcocal` file -- incl. updated branding docs.
|
||||
- Add support for detecting factory reset condition from a bootloader
|
||||
- Ensure `/var` is also cleared (properly) during factory reset
|
||||
- Add support for port auto-negotiation status in operational datastore
|
||||
- Add CLI support for showing veth pairs in `show interfaces`
|
||||
- Speedups to CLI detailed view of a single interface
|
||||
- Updated documentation of VLAN interfaces and VLAN filtering bridge
|
||||
- Updated documentation for how to customize services in *Hybrid Mode*
|
||||
- In RMA mode (runlevel 9), the system no longer has any login services
|
||||
- Disable `root` login in all NETCONF builds, only `admin` available
|
||||
- Add support for VPD data in ONIE EEPROM format
|
||||
- Add `iito`, the intelligent input/output daemon for LED control
|
||||
- Add port autoneg and speed/duplex status to operational data
|
||||
- Upgrade Linux to v6.5.11, with kkit extensions
|
||||
- Add support for static IPv4 routing using `ietf-routing@2018-03-13.yang` and
|
||||
`ietf-ipv4-unicast-routing@2018-03-13.yang`, one `default` instance only
|
||||
- Add support for partitioning and self-provisioning of new devices
|
||||
- Add support for reading `admin` user's default password from VPD. Devices
|
||||
that do not have a VPD can set a password hash in the device tree
|
||||
- Add support for upgrading software bundles (images) from the CLI.
|
||||
Supported remote servers: ftp, tftp, and http/https.
|
||||
- Traversing the CLI configure context has been simplified by collapsing all
|
||||
YANG containers that only contain a single list element. Example:
|
||||
`edit interfaces interface eth0` becomes `edit interface eth0`
|
||||
- Add CLI support for creating configuration backups and transferring files
|
||||
to/from remote servers: tftp, ftp, http/https (download only). Issue #155
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix #111: fix auto-inference of dynamic interface types (bridge, veth)
|
||||
- Fix #125: improved feedback on invalid input in configure context
|
||||
- Fix #198: drop bridge default PVID setting, for VLAN filtering bridge.
|
||||
- Fix #215: impossible to enable NTP client, regression from v23.06.0
|
||||
All bridge ports must have explicit VLAN assignment (security)
|
||||
- Fix regression in CLI `show factory-config` command
|
||||
- Fix missing version in `/etc/os-release` variable `PRETTY_NAME`
|
||||
- Fix failure to start `podman` in GNS3 (missing Ext4 filesystem feature)
|
||||
- Fix initial terminal size probing in CLI when logging in from console port
|
||||
- Fix CLI `show running-config`, use proper JSON format like other files
|
||||
|
||||
|
||||
[v23.10.0][] - 2023-10-31
|
||||
-------------------------
|
||||
|
||||
@@ -15,23 +147,23 @@ All notable changes to the project are documented in this file.
|
||||
### YANG Status
|
||||
|
||||
- [ietf-system][]:
|
||||
- [infix-system][]: MotD (Message of the Day) augment
|
||||
- [infix-system][]: user login shell augment, default: `/bin/false`
|
||||
- [infix-system-software][]: system-state/software augment for
|
||||
remotely querying firmware version information
|
||||
- **augments:**
|
||||
- MotD (Message of the Day)
|
||||
- User login shell, default: `/bin/false`
|
||||
- State information for remotely querying firmware version information
|
||||
- **deviations:**
|
||||
- timezone-name, using IANA timezones instead of plain string
|
||||
- UTC offset, only support per-hour offsets with [tzdata][]
|
||||
- Usernames, clarifying Linux restrictions
|
||||
- Unsupported features marked as deviations, e.g. RADIUS
|
||||
- [infix-system-software][]: firmware upgrade with `install-bundle` RPC
|
||||
- [infix-system][]: timezone-name deviation, using with IANA timezones,
|
||||
deviation for UTC offset, only support per-hour offsets with [tzdata][].
|
||||
Also, username deviation, clarifying Linux restrictions.
|
||||
- [infix-system][]: deviations for unsupported features, e.g. RADIUS
|
||||
- [ietf-interfaces][]:
|
||||
- [infix-interfaces][]: deviation for `if:phys-address` to allow read-write
|
||||
- [ietf-ip][]: augmented with IPv4LL similar to standardized IPv6LL
|
||||
- [infix-ip][]: deviations (`not-supported`) added for IPv4 and IPv6:
|
||||
- deviation to allow read-write `if:phys-address` for custom MAC address
|
||||
- [ietf-ip][]: augments
|
||||
- IPv4LL similar to standardized IPv6LL
|
||||
- [ietf-ip][]: deviations (`not-supported`) added for IPv4 and IPv6:
|
||||
- `/if:interfaces/if:interface/ip:ipv4/ip:address/ip:subnet/ip:netmask`
|
||||
- `/if:interfaces/if:interface/ip:ipv6/ip:address/ip:status`
|
||||
- `/if:interfaces/if:interface/ip:ipv4/ip:mtu`
|
||||
- `/if:interfaces/if:interface/ip:ipv6/ip:mtu`
|
||||
- `/if:interfaces/if:interface/ip:ipv4/ip:neighbor`
|
||||
- `/if:interfaces/if:interface/ip:ipv6/ip:neighbor`
|
||||
- ~~[ietf-if-vlan-encapsulation][]:~~ Removed in favor of a native model.
|
||||
@@ -42,7 +174,7 @@ All notable changes to the project are documented in this file.
|
||||
models, e.g., `ieee802-ethernet-interface.yang`
|
||||
- [infix-if-veth][]: Linux VETH pairs
|
||||
- [infix-if-vlan][]: Linux VLAN interfaces, e.g. `eth0.10` (New model!)
|
||||
- Configurable services:
|
||||
- **Configurable services:**
|
||||
- [ieee802-dot1ab-lldp][]: stripped down to an `enabled` setting
|
||||
- [infix-services][]: support for enabling mDNS service/device discovery
|
||||
|
||||
@@ -57,10 +189,8 @@ All notable changes to the project are documented in this file.
|
||||
[infix-if-veth]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-if-veth%402023-06-05.yang
|
||||
[infix-if-vlan]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-if-vlan%402023-10-25.yang
|
||||
|
||||
[infix-interfaces]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-interfaces%402023-09-19.yang
|
||||
[infix-ip]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-ip%402023-09-14.yang
|
||||
[infix-services]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-services%402023-10-16.yang
|
||||
[infix-system]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-system%402023-10-19.yang
|
||||
[infix-system-software]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-system-software%402023-06-27.yang
|
||||
|
||||
### Changes
|
||||
|
||||
+4
-4
@@ -62,7 +62,7 @@ To mitigate the risk of a malicious user being able to circumvent the
|
||||
bootloader's validation procedure, user configuration is kept to a
|
||||
minimum. Two settings are available:
|
||||
|
||||
- **Boot order**: Since Infix maintains two copies of its firmware,
|
||||
- **Boot order**: Since Infix maintains two copies of its software image,
|
||||
and as some bootloaders support netbooting, the order in which boot
|
||||
sources are considered can be configured. To select the active
|
||||
source, use [RAUC][]:
|
||||
@@ -106,7 +106,7 @@ boot Infix over the network. DHCP is used to configure the network
|
||||
and TFTP to transfer the image to the system's RAM.
|
||||
|
||||
Access to U-Boot's shell is disabled to prevent side-loading of
|
||||
malicious firmware. To configure the active boot partition, refer to
|
||||
malicious software. To configure the active boot partition, refer to
|
||||
the [Bootloader Interface](#bootloader-interface) section.
|
||||
|
||||
|
||||
@@ -128,11 +128,11 @@ Interface](#bootloader-interface).
|
||||
System Upgrade
|
||||
==============
|
||||
|
||||
Much of the minutiae of firmware upgrades is delegated to [RAUC][],
|
||||
Much of the minutiae of software upgrades is delegated to [RAUC][],
|
||||
which offers lots of benefits out-of-the-box:
|
||||
|
||||
- Upgrade Bundles are always signed, such that their authenticity can
|
||||
be verified by the running firmware, before the new one is
|
||||
be verified by the running operating system, before the new one is
|
||||
installed.
|
||||
|
||||
- The bureaucracy of interfacing with different bootloaders, manage
|
||||
|
||||
@@ -41,6 +41,62 @@ Verify the result after a build by inspecting:
|
||||
printed on a label on the device.
|
||||
|
||||
|
||||
Factory Defaults
|
||||
----------------
|
||||
|
||||
The Infix default configuration, factory-config, is part static files
|
||||
and part per-device generated files, e.g., SSH hostkey and hostname.
|
||||
The latter is constructed from the file `/etc/hostname`, appended with
|
||||
the last three octets of the system's base MAC address. To override the
|
||||
base hostname, set `BR2_TARGET_GENERIC_HOSTNAME` in your defconfig.
|
||||
|
||||
The static files are installed by Infix `confd` in `/usr/share/confd/`
|
||||
at build time. It contains two subdirectories:
|
||||
|
||||
/usr/share/confd/
|
||||
|- factory.d/
|
||||
| |- 10-foo.json
|
||||
| |- 10-bar.json
|
||||
| `- 10-qux.json
|
||||
`- failure.d/
|
||||
|- 10-xyzzy.json
|
||||
`- 10-garply.json
|
||||
|
||||
To override, or extend, these files in you br2-external, set up a rootfs
|
||||
overlay and add it last in `BR2_ROOTFS_OVERLAY`. Your overlay can look
|
||||
something like this:
|
||||
|
||||
./board/common/rootfs/
|
||||
|- etc/
|
||||
| |- confdrc # See below
|
||||
| `- confdrc.local
|
||||
`- usr/
|
||||
`- share/
|
||||
`- confd/
|
||||
|- 10-foo.json # Override Infix foo
|
||||
|- 30-bar.json # Extend, probably 10-bar.json
|
||||
`- 30-fred.json # Extend, your own defaults
|
||||
|
||||
Using the same filename in your overlay, here `10-foo.json`, completely
|
||||
replaces the contents of the same file provided by Infix. If you just
|
||||
want to extend, or replace parts of an Infix default, use `30-....json`.
|
||||
Here the file `30-bar.json` is just a helpful hit to maintainers of your
|
||||
br2-external that it probably extends Infix' `10-bar.json`.
|
||||
|
||||
The reason for the jump in numbers is that 20 is reserved for files
|
||||
generated by Infix' `gen-function` scripts. Your br2-external can
|
||||
provide a few custom ones that the `bootstrap` knows about, e.g.,
|
||||
`gen-ifs-custom` that overrides `20-interfaces.json`. See the
|
||||
bootstrap script for more help, and up-to-date information.
|
||||
|
||||
> **Note:** you may not need to provide your own `/etc/confdrc`. The
|
||||
> one installed by `confd` is usually enough. However, if you want to
|
||||
> adjust the behavior of `bootstrap` you may want to override it. There
|
||||
> is also `confdrc.local`, which usually is enough to change arguments
|
||||
> to scripts like `gen-interfaces`, e.g., to create a bridge by default,
|
||||
> you may want to look into `GEN_IFACE_OPTS`.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
|
||||
+12
-12
@@ -35,7 +35,7 @@ The system has several datastores (or files):
|
||||
To save configuration changes made to the `running-config` so the system
|
||||
will use them consecutive reboots, use the `copy` command:
|
||||
|
||||
admin@infix-12-34-56:/> copy running-config startup-config
|
||||
admin@host-12-34-56:/> copy running-config startup-config
|
||||
|
||||
In *configure context* the following commands are available:
|
||||
|
||||
@@ -64,17 +64,17 @@ We inspect the system status to ensure the change took effect. Then we
|
||||
save the changes for the next reboot.
|
||||
|
||||
```
|
||||
admin@infix-12-34-56:/> configure
|
||||
admin@infix-12-34-56:/config/> edit interfaces interface eth0
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> set ipv4 <TAB>
|
||||
admin@host-12-34-56:/> configure
|
||||
admin@host-12-34-56:/config/> edit interface eth0
|
||||
admin@host-12-34-56:/config/interface/eth0/> set ipv4 <TAB>
|
||||
address autoconf bind-ni-name enabled
|
||||
forwarding mtu neighbor
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> show
|
||||
admin@host-12-34-56:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@host-12-34-56:/config/interface/eth0/> show
|
||||
type ethernetCsmacd;
|
||||
ipv4 address 192.168.2.200 prefix-length 24;
|
||||
ipv6 enabled true;
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> diff
|
||||
admin@host-12-34-56:/config/interface/eth0/> diff
|
||||
interfaces {
|
||||
interface eth0 {
|
||||
+ ipv4 {
|
||||
@@ -84,14 +84,14 @@ interfaces {
|
||||
+ }
|
||||
}
|
||||
}
|
||||
admin@infix-12-34-56:/config/interfaces/interface/eth0/> leave
|
||||
admin@infix-12-34-56:/> show interfaces brief
|
||||
admin@host-12-34-56:/config/interface/eth0/> leave
|
||||
admin@host-12-34-56:/> show interfaces brief
|
||||
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
|
||||
eth0 UP 52:54:00:12:34:56 <BROADCAST,MULTICAST,UP,LOWER_UP>
|
||||
admin@infix-12-34-56:/> show ip brief
|
||||
admin@host-12-34-56:/> show ip brief
|
||||
lo UNKNOWN 127.0.0.1/8 ::1/128
|
||||
eth0 UP 192.168.2.200/24 fe80::5054:ff:fe12:3456/64
|
||||
admin@infix-12-34-56:/> copy running-config startup-config
|
||||
admin@host-12-34-56:/> copy running-config startup-config
|
||||
```
|
||||
|
||||
One of the ideas behind a separate running and startup configuration is
|
||||
@@ -99,7 +99,7 @@ to be able to verify a configuration change. In case of an inadvertent
|
||||
change that, e.g., breaks networking, it is trivial to revert back by:
|
||||
|
||||
```
|
||||
admin@infix-12-34-56:/> copy startup-config running-config
|
||||
admin@host-12-34-56:/> copy startup-config running-config
|
||||
```
|
||||
|
||||
Or restarting the device.
|
||||
|
||||
+95
-35
@@ -1,9 +1,9 @@
|
||||
User Guide
|
||||
==========
|
||||
|
||||
The command line interface (CLI, see-el-i) is built on the open source
|
||||
component [klish][1], which implements a CISCO like, or Juniper Networks
|
||||
JunOS-like CLI on a UNIX system.
|
||||
The command line interface (CLI, see-ell-aye) is built on the open source
|
||||
component [klish][1], which implements a CISCO-like, or Juniper Networks
|
||||
JunOS-like, CLI for UNIX systems.
|
||||
|
||||
New users always get the CLI as the default "shell" when logging in, but
|
||||
the default `admin` user logs in to the Bash. To access the CLI, type:
|
||||
@@ -18,11 +18,11 @@ Key commands available in any context are:
|
||||
For each command it also possible to press the `?` key and `TAB` to get
|
||||
more help and suggestions for completion.
|
||||
|
||||
> **Note:** for the sake of brevity, the hostname in the following
|
||||
> examples has been shortened to `host`. The default name is composed
|
||||
> from a product specific string followed by the last three octets of
|
||||
> the system base MAC address, e.g., `infix-12-34-56`. An example of
|
||||
> how to change the hostname is included below.
|
||||
> **Note:** for the sake of brevity, the hostname in the following examples
|
||||
> has been shortened to `host`. The default name is composed from a product
|
||||
> specific string followed by the last three octets of the system base MAC
|
||||
> address, e.g., `switch-12-34-56`. An example of how to change the hostname
|
||||
> is included below.
|
||||
|
||||
|
||||
Admin Exec
|
||||
@@ -36,14 +36,74 @@ Available commands can be seen by pressing `?` at the prompt:
|
||||
|
||||
```
|
||||
admin@host:/>
|
||||
configure Create new candidate-config based on running-config
|
||||
copy Copy
|
||||
exit Exit
|
||||
logout Alias for exit
|
||||
shell Enter system shell
|
||||
show Show
|
||||
configure Create new candidate-config based on running-config
|
||||
copy Copy configuration, e.g., copy running-config startup-config
|
||||
exit Exit from CLI (log out)
|
||||
factory-reset Restore the system to factory default state
|
||||
follow Monitor a log file, use Ctrl-C to abort
|
||||
help Help system (also try '?' key)
|
||||
logout Alias to exit
|
||||
netcalc IP subnet calculator
|
||||
password Password tools
|
||||
ping Ping a network host or multicast group
|
||||
poweroff Poweroff system (system policy may yield reboot)
|
||||
reboot Reboot system
|
||||
set Set operations, e.g., current date/time
|
||||
shell Enter system shell
|
||||
show Show system status and configuration files
|
||||
tcpdump Capture network traffic
|
||||
upgrade Install a software update bundle
|
||||
```
|
||||
|
||||
To get more help for a given command, type the command, a space, and
|
||||
then tap `?` again. You can also tap the `Tab` key to see available
|
||||
argument completions.
|
||||
|
||||
### Upgrading the Software
|
||||
|
||||
The admin-exec command `upgrade` can be used to install software images, or
|
||||
bundles. A bundle is a signed and self-contained package that carries all the
|
||||
information necessary to determine if it holds a bootloader, a Linux image, or
|
||||
even both.
|
||||
|
||||
To install a new software image to the currently *inactive* partition[^1], we
|
||||
use the `upgrade` command and a URI to a ftp/tftp/sftp or http/https server
|
||||
that hosts the file:
|
||||
|
||||
```
|
||||
admin@host:/> upgrade tftp://192.168.122.1/firmware-x86_64-v23.11.pkg
|
||||
installing
|
||||
0% Installing
|
||||
0% Determining slot states
|
||||
20% Determining slot states done.
|
||||
20% Checking bundle
|
||||
20% Verifying signature
|
||||
40% Verifying signature done.
|
||||
40% Checking bundle done.
|
||||
40% Checking manifest contents
|
||||
60% Checking manifest contents done.
|
||||
60% Determining target install group
|
||||
80% Determining target install group done.
|
||||
80% Updating slots
|
||||
80% Checking slot rootfs.1
|
||||
90% Checking slot rootfs.1 done.
|
||||
90% Copying image to rootfs.1
|
||||
99% Copying image to rootfs.1 done.
|
||||
99% Updating slots done.
|
||||
100% Installing done.
|
||||
Installing `tftp://192.168.122.1/firmware-x86_64-v23.11.pkg` succeeded
|
||||
admin@host:/>
|
||||
```
|
||||
|
||||
The secondary partition (`rootfs.1`) has now been upgraded and will be used as
|
||||
the *active* partition on the next boot. Leaving the primary partition, with
|
||||
the version we are currently running, intact in case of trouble.
|
||||
|
||||
[^1]: It is not possible to upgrade the partition we booted from. Thankfully
|
||||
the underlying "rauc" subsystem keeps track of this. Hence, to upgrade
|
||||
both partitions you must reboot to the new version (to verify it works)
|
||||
and then repeat the same command.
|
||||
|
||||
Configure Context
|
||||
-----------------
|
||||
|
||||
@@ -73,15 +133,15 @@ admin@host:/config/>
|
||||
The `edit` command lets you change to a sub-configure context, e.g.:
|
||||
|
||||
```
|
||||
admin@host:/config/> edit interfaces interface eth0
|
||||
admin@host:/config/interfaces/interface/eth0/>
|
||||
admin@host:/config/> edit interface eth0
|
||||
admin@host:/config/interface/eth0/>
|
||||
```
|
||||
|
||||
Use `up` to go up one level.
|
||||
|
||||
```
|
||||
admin@host:/config/interfaces/interface/eth0/> up
|
||||
admin@host:/config/interfaces/>
|
||||
admin@host:/config/interface/eth0/> up
|
||||
admin@host:/config/>
|
||||
```
|
||||
|
||||
> **Note:** the tree structure in the configure context is automatically
|
||||
@@ -94,16 +154,16 @@ admin@host:/config/interfaces/>
|
||||
### Set IP Address on an Interface
|
||||
|
||||
```
|
||||
admin@host:/config/> edit interfaces interface eth0
|
||||
admin@host:/config/interfaces/interface/eth0/>
|
||||
admin@host:/config/interfaces/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
admin@host:/config/> edit interface eth0
|
||||
admin@host:/config/interface/eth0/>
|
||||
admin@host:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
|
||||
```
|
||||
|
||||
From anywhere in configure context you can see the changes you have
|
||||
made by typing `diff`:
|
||||
|
||||
```
|
||||
admin@host:/config/interfaces/interface/eth0/> diff
|
||||
admin@host:/config/interface/eth0/> diff
|
||||
interfaces {
|
||||
interface eth0 {
|
||||
+ ipv4 {
|
||||
@@ -121,7 +181,7 @@ interfaces {
|
||||
Apply the changes (from candidate to `running-config`):
|
||||
|
||||
```
|
||||
admin@host:/config/interfaces/> leave
|
||||
admin@host:/config/interface/eth0/> leave
|
||||
admin@host:/> show running-config
|
||||
...
|
||||
interfaces {
|
||||
@@ -199,11 +259,11 @@ pair which is useful for connecting, e.g., a container to the physical
|
||||
world. Here we also add an IPv4 address to one end of the pair.
|
||||
|
||||
```
|
||||
admin@host:/config/> edit interfaces interface veth0a
|
||||
admin@host:/config/interfaces/interface/veth0a/> set veth peer veth0b
|
||||
admin@host:/config/interfaces/interface/veth0a/> set ipv4 address 192.168.0.1 prefix-length 24
|
||||
admin@host:/config/interfaces/interface/veth0a/> up
|
||||
admin@host:/config/interfaces/> diff
|
||||
admin@host:/config/> edit interface veth0a
|
||||
admin@host:/config/interface/veth0a/> set veth peer veth0b
|
||||
admin@host:/config/interface/veth0a/> set ipv4 address 192.168.0.1 prefix-length 24
|
||||
admin@host:/config/interface/veth0a/> up
|
||||
admin@host:/config/> diff
|
||||
interfaces {
|
||||
+ interface veth0a {
|
||||
+ type veth;
|
||||
@@ -223,7 +283,7 @@ interfaces {
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
admin@host:/config/interfaces/> leave
|
||||
admin@host:/config/> leave
|
||||
```
|
||||
|
||||
See the bridging example below for more.
|
||||
@@ -241,12 +301,12 @@ between both its bridge ports: `eth0` and `vet0b`.
|
||||
|
||||
```
|
||||
admin@host:/> configure
|
||||
admin@host:/config/> edit interfaces interface br0
|
||||
admin@host:/config/interfaces/interface/br0/> set bridge ieee-group-forward lldp
|
||||
admin@host:/config/interfaces/interface/br0/> up
|
||||
admin@host:/config/interfaces/> set interface eth0 bridge-port bridge br0
|
||||
admin@host:/config/interfaces/> set interface veth0b bridge-port bridge br0
|
||||
admin@host:/config/interfaces/> diff
|
||||
admin@host:/config/> edit interface br0
|
||||
admin@host:/config/interface/br0/> set bridge ieee-group-forward lldp
|
||||
admin@host:/config/interface/br0/> up
|
||||
admin@host:/config/> set interface eth0 bridge-port bridge br0
|
||||
admin@host:/config/> set interface veth0b bridge-port bridge br0
|
||||
admin@host:/config/> diff
|
||||
interfaces {
|
||||
+ interface br0 {
|
||||
+ type bridge;
|
||||
|
||||
+7
-6
@@ -5,7 +5,7 @@ Containers in Infix
|
||||
* [Docker Containers with Podman](#docker-containers-with-podman)
|
||||
* [Multiple Networks](#multiple-networks)
|
||||
* [Hybrid Mode](#hybrid-mode)
|
||||
* [Enabling Containers](#enabling-containers)
|
||||
* [Enabling Container Support](#enabling-container-support)
|
||||
* [Debugging Containers](#debugging-containers)
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ inside the container will always be: `eth0`, `eth1`, etc.
|
||||
|
||||
A common setup is to use a VETH pair, with one end in the container and
|
||||
the other end routed, or bridged, to the rest of the world. The Infix
|
||||
[CLI Guide](cli/introduction.md) provides examples of both. In either case you need
|
||||
to create a matching CNI profile for one end of the VETH pair before
|
||||
starting the container, here we use two network profiles, the default
|
||||
podman bridge and the VETH profile:
|
||||
[CLI Guide](cli/introduction.md) provides examples of both. In either
|
||||
case you need to create a matching CNI profile for one end of the VETH
|
||||
pair before starting the container, here we use two network profiles,
|
||||
the default podman bridge and the VETH profile:
|
||||
|
||||
cni create host net1 veth0a 192.168.0.42/24
|
||||
podman run -d --rm --net=podman,net1 --entrypoint "/linuxrc" \
|
||||
@@ -160,7 +160,7 @@ downloaded with `podman pull docker://troglobit/buildroot:latest` and
|
||||
a container created (above):
|
||||
|
||||
```
|
||||
root@infix:/cfg/start.d$ cat <<EOF >20-enable-container.sh
|
||||
root@infix:/cfg/start.d$ cat <<HERE >20-enable-container.sh
|
||||
#!/bin/sh
|
||||
# Remember to create the veth0a <--> vet0b pair in the CLI first!
|
||||
cni create host net1 veth0a 192.168.0.42/24
|
||||
@@ -169,6 +169,7 @@ service name:pod :system pid:!/run/pod:system.pid podman --syslog start system -
|
||||
EOF
|
||||
initctl enable pod:system
|
||||
exit 0
|
||||
HERE
|
||||
root@infix:/cfg/start.d$ chmod +x 20-enable-container.sh
|
||||
```
|
||||
|
||||
|
||||
+15
-1
@@ -1,6 +1,20 @@
|
||||
Developer's Guide
|
||||
=================
|
||||
|
||||
Please note, by default the `root` account is disabled in Infix NETCONF
|
||||
builds. Meaning, the only way to access the system is with the `admin`
|
||||
account, which is created based on credentials found in the VPD area --
|
||||
for Qemu devices this is emulated using `qemu_fw_cfg`.
|
||||
|
||||
For developers this can be quite frustrating to be blocked from logging
|
||||
in to debug the system. So we recommend enabling the `root` account in
|
||||
the Buildroot `make menuconfig` system.
|
||||
|
||||
make menuconfig
|
||||
-> System configuration
|
||||
-> [*]Enable root login with password
|
||||
|
||||
|
||||
Cloning
|
||||
-------
|
||||
|
||||
@@ -75,7 +89,7 @@ To see available defconfigs for supported targets, use:
|
||||
Development
|
||||
-----------
|
||||
|
||||
When changing a package, locally kept sources, or when using `local.mk`,
|
||||
When changing a package, locally kept sources, or when using [`local.mk`](override-package.md),
|
||||
you only want to rebuild the parts you have modified:
|
||||
|
||||
make foo-rebuild
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 61 KiB |
+112
-46
@@ -8,7 +8,7 @@
|
||||
| -------- | ----------------- | ------------------------------------------------------------- |
|
||||
| bridge | infix-if-bridge | SW implementation of an IEEE 802.1Q bridge |
|
||||
| ip | ietf-ip, infix-ip | IP address to the subordinate interface |
|
||||
| vlan | ietf-vlan-encap | Capture all traffic belonging to a specific 802.1Q VID |
|
||||
| vlan | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
|
||||
| lag[^1] | infix-if-lag | Bonds multiple interfaces into one, creating a link aggregate |
|
||||
| lo | ietf-interfaces | Software loopback interface |
|
||||
| eth | ietf-interfaces | Physical Ethernet device/port |
|
||||
@@ -34,11 +34,11 @@ In Infix ports are by default not switch ports, unless the customer specific fac
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface br0
|
||||
admin@example:/config/interfaces/interface/br0/> up
|
||||
admin@example:/config/interfaces/> set interface eth0 bridge-port bridge br0
|
||||
admin@example:/config/interfaces/> set interface eth1 bridge-port bridge br0
|
||||
admin@example:/config/interfaces/> leave
|
||||
admin@example:/config/> edit interface br0
|
||||
admin@example:/config/interface/br0/> up
|
||||
admin@example:/config/> set interface eth0 bridge-port bridge br0
|
||||
admin@example:/config/> set interface eth1 bridge-port bridge br0
|
||||
admin@example:/config/> leave
|
||||
```
|
||||
|
||||
Here we add two ports to bridge `br0`: `eth0` and `eth1`.
|
||||
@@ -47,37 +47,62 @@ Here we add two ports to bridge `br0`: `eth0` and `eth1`.
|
||||
|
||||
#### VLAN Filtering Bridge
|
||||
|
||||
By default bridges in Linux do not filter based on VLAN tags. It can be enabled in Infix when creating a bridge by adding a port to a VLAN as a tagged or untagged member:
|
||||
By default bridges in Linux do not filter based on VLAN tags. It can be enabled in Infix when creating a bridge by adding a port to a VLAN as a tagged or untagged member.
|
||||
Use the port default VID (PVID) setting to control VLAN association for traffic ingressing a port untagged (default PVID: 1).
|
||||
|
||||
```
|
||||
admin@example:/config/> edit interfaces interface br0
|
||||
admin@example:/config/interfaces/interface/br0/> up
|
||||
admin@example:/config/interfaces/> set interface eth0 bridge-port bridge br0
|
||||
admin@example:/config/interfaces/> set interface eth1 bridge-port bridge br0
|
||||
admin@example:/config/interfaces/> edit interface br0
|
||||
admin@example:/config/interfaces/interface/br0/> set bridge vlans vlan 10 untagged eth0
|
||||
admin@example:/config/interfaces/interface/br0/> set bridge vlans vlan 20 untagged eth1
|
||||
admin@example:/config/> edit interface br0
|
||||
admin@example:/config/interface/br0/> up
|
||||
admin@example:/config/> set interface eth0 bridge-port bridge br0
|
||||
admin@example:/config/> set interface eth0 bridge-port pvid 10
|
||||
admin@example:/config interface eth1 bridge-port bridge br0
|
||||
admin@example:/config/> set interface eth1 bridge-port pvid 20
|
||||
admin@example:/config/> edit interface br0
|
||||
admin@example:/config/interface/br0/> set bridge vlans vlan 10 untagged eth0
|
||||
admin@example:/config/interface/br0/> set bridge vlans vlan 20 untagged eth1
|
||||
```
|
||||
|
||||
This sets `eth0` as an untagged member of VLAN 10 and `eth1` as an
|
||||
untagged member of VLAN 20. Switching between these ports is thus
|
||||
prohibited.
|
||||
|
||||
To terminate a VLAN in the switch itself, either for switch management or for routing, the bridge must become a (tagged) member of the VLAN.
|
||||
|
||||
```
|
||||
admin@example:/config/interface/br0/> set bridge vlans vlan 10 tagged br0
|
||||
admin@example:/config/interface/br0/> set bridge vlans vlan 20 tagged br0
|
||||
```
|
||||
> To route or to manage via a VLAN, a VLAN interface also needs to be created on top of the bridge, see section [VLAN Interfaces](#vlan-interfaces) below.
|
||||
|
||||
### VLAN Interfaces
|
||||
|
||||
Creating a VLAN can be done in many ways. This section assumes VLAN interfaces created atop another Linux interface. E.g., the VLAN interfaces created on top of the bridge in the picture above.
|
||||
Creating a VLAN can be done in many ways. This section assumes VLAN interfaces created atop another Linux interface. E.g., the VLAN interfaces created on top of the Ethernet interface or bridge in the picture below.
|
||||
|
||||
A VLAN interface is basically a filtering abstraction. When you run `tcpdump` on a VLAN interface you will only see the frames matching the VLAN ID of the interface, compared to *all* the VLAN IDs if you run `tcpdump` on the parent interface.
|
||||

|
||||
|
||||
A VLAN interface is basically a filtering abstraction. When you run `tcpdump` on a VLAN interface you will only see the frames matching the VLAN ID of the interface, compared to *all* the VLAN IDs if you run `tcpdump` on the lower-layer interface.
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0.20
|
||||
admin@example:/config/interfaces/interface/eth0.20/> set encapsulation dot1q-vlan outer-tag tag-type c-vlan vlan-id 20
|
||||
admin@example:/config/interfaces/interface/eth0.20/> set parent-interface eth0
|
||||
admin@example:/config/interfaces/interface/eth0.20/> leave
|
||||
admin@example:/config/> edit interface eth0.20
|
||||
admin@example:/config/interface/eth0.20/> set vlan id 20
|
||||
admin@example:/config/interface/eth0.20/> set vlan lower-layer-if eth0
|
||||
admin@example:/config/interface/eth0.20/> leave
|
||||
```
|
||||
|
||||
> **Note:** If you name your VLAN interface `foo0.N`, where `N` is a number, Infix will set the interface type automatically for you.
|
||||
The example below assumes bridge br0 is already created, see [VLAN Filtering Bridge](#vlan-filtering-bridge).
|
||||
|
||||
```
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface vlan10
|
||||
admin@example:/config/interface/vlan10/> set vlan id 10
|
||||
admin@example:/config/interface/vlan10/> set vlan lower-layer-if br0
|
||||
admin@example:/config/interface/vlan10/> leave
|
||||
```
|
||||
|
||||
As conventions, a VLAN interface for VID 20 on top of an Ethernet interface *eth0* is named *eth0.20*, and a VLAN interface for VID 10 on top of a bridge interface *br0* is named *vlan10*.
|
||||
|
||||
> **Note:** If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a number, Infix will set the interface type automatically for you.
|
||||
|
||||
## Management Plane
|
||||
|
||||
@@ -138,10 +163,10 @@ default.
|
||||

|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0 ipv4
|
||||
admin@example:/config/interfaces/interface/eth0/ipv4/> set address 10.0.1.1 prefix-length 24
|
||||
admin@example:/config/interfaces/interface/eth0/ipv4/> set autoconf enabled true
|
||||
admin@example:/config/interfaces/interface/eth0/ipv4/> diff
|
||||
admin@example:/config/> edit interface eth0 ipv4
|
||||
admin@example:/config/interface/eth0/ipv4/> set address 10.0.1.1 prefix-length 24
|
||||
admin@example:/config/interface/eth0/ipv4/> set autoconf enabled true
|
||||
admin@example:/config/interface/eth0/ipv4/> diff
|
||||
+interfaces {
|
||||
+ interface eth0 {
|
||||
+ ipv4 {
|
||||
@@ -154,7 +179,7 @@ default.
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
admin@example:/config/interfaces/interface/eth0/ipv4/> leave
|
||||
admin@example:/config/interface/eth0/ipv4/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
@@ -177,7 +202,7 @@ enabled true`. The resulting address (169.254.1.3/16) is of type
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit dhcp-client
|
||||
admin@example:/config/dhcp-client/> set client-if eth0
|
||||
admin@example:/config/dhcp-client/> set enabled true
|
||||
admin@example:/config/dhcp-client/> set enabled true
|
||||
admin@example:/config/dhcp-client/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
@@ -197,11 +222,11 @@ The resulting address (10.1.2.100/24) is of type *dhcp*.
|
||||
The (only) way to disable IPv6 link-local addresses is by disabling IPv6 on the interface.
|
||||
|
||||
```(disabling
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0 ipv6
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> set enabled false
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
|
||||
admin@example:/> show interfaces
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface eth0 ipv6
|
||||
admin@example:/config/interface/eth0/ipv6/> set enabled false
|
||||
admin@example:/config/interface/eth0/ipv6/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
@@ -214,10 +239,10 @@ admin@example:/>
|
||||
|
||||

|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0 ipv6
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> set address 2001:db8::1 prefix-length 64
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface eth0 ipv6
|
||||
admin@example:/config/interface/eth0/ipv6/> set address 2001:db8::1 prefix-length 64
|
||||
admin@example:/config/interface/eth0/ipv6/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
@@ -239,7 +264,7 @@ identifier. The resulting address is of type *link-layer*, as it
|
||||
is formed based on the interface identifier ([IETF
|
||||
ip-yang][ietf-ip-yang]).
|
||||
|
||||
admin@example:/> show interfaces
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
@@ -253,9 +278,9 @@ Disabling auto-configuration of global IPv6 addresses can be done as shown
|
||||
below.
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0 ipv6
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> set autoconf create-global-addresses false
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
|
||||
admin@example:/config/> edit interface eth0 ipv6
|
||||
admin@example:/config/interface/eth0/ipv6/> set autoconf create-global-addresses false
|
||||
admin@example:/config/interface/eth0/ipv6/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
@@ -272,7 +297,7 @@ below.
|
||||
By default, the auto-configured link-local and global IPv6 addresses
|
||||
are formed from a link-identifier based on the MAC address.
|
||||
|
||||
admin@example:/> show interfaces
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
@@ -285,10 +310,10 @@ are formed from a link-identifier based on the MAC address.
|
||||
To avoid revealing identity information in the IPv6 address, it is
|
||||
possible to specify use of a random identifier ([ietf-ip][ietf-ip-yang] YANG and [RFC8981][ietf-ipv6-privacy]).
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interfaces interface eth0 ipv6
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> set autoconf create-temporary-addresses true
|
||||
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit interface eth0 ipv6
|
||||
admin@example:/config/interface/eth0/ipv6/> set autoconf create-temporary-addresses true
|
||||
admin@example:/config/interface/eth0/ipv6/> leave
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
@@ -302,10 +327,51 @@ possible to specify use of a random identifier ([ietf-ip][ietf-ip-yang] YANG and
|
||||
Both the link-local address (fe80::) and the global address (2001:)
|
||||
have changed type to *random*.
|
||||
|
||||
## Routing support
|
||||
|
||||
| **Yang Model** | **Description** |
|
||||
|:--------------------------|:----------------------------------------------------------|
|
||||
| ietf-routing | Base routing model, required for all other routing models |
|
||||
| ietf-ipv4-unicast-routing | Static IPv4 unicast routing |
|
||||
|
||||
### Static routes
|
||||
|
||||
admin@example:/> configure
|
||||
admin@example:/config/> edit routing control-plane-protocol static name default
|
||||
admin@example:/config/routing/control-plane-protocol/static/name/default/> set ipv4 route 192.168.200.0/24 next-hop next-hop-address 192.168.1.1
|
||||
admin@example:/config/routing/control-plane-protocol/static/name/default/> leave
|
||||
admin@example:/>
|
||||
|
||||
> **Note:** The only name allowed for a control-plane-protocol is currently
|
||||
> *default*. Meaning, you can only have one instance per routing protocol.
|
||||
|
||||
### View IPv4 routing table
|
||||
|
||||
The routing table can be viewed from the operational datastore over
|
||||
NETCONF or using the CLI:
|
||||
|
||||
admin@example:/> show routes
|
||||
PREFIX NEXT-HOP METRIC PROTOCOL
|
||||
192.168.1.0/24 e0 kernel
|
||||
192.168.200.0/24 192.168.1.1 20 static
|
||||
|
||||
The source protocol describes the origin of the route.
|
||||
|
||||
| **Protocol** | **Description** |
|
||||
|:-------------|:---------------------------------------------------------------------|
|
||||
| kernel | Added when setting a subnet address on an interface |
|
||||
| static | User created static routes |
|
||||
| dhcp | Routes retrieved from DHCP |
|
||||
|
||||
The YANG model *ietf-routing* support multiple ribs but only two are
|
||||
currently supported, namely `ipv4` and `ipv6`.
|
||||
|
||||
[ietf-ip-yang]: https://www.rfc-editor.org/rfc/rfc8344.html
|
||||
[ietf-ipv6-privacy]: https://www.rfc-editor.org/rfc/rfc8981.html
|
||||
|
||||
[^1]: Please note, link aggregates are not yet supported in Infix.
|
||||
[^2]: Link-local IPv6 addresses are implicitly enabled when enabling IPv6. IPv6 can be enabled/disabled per interface in [ietf-ip][ietf-ip-yang] YANG model.
|
||||
[^2]: Link-local IPv6 addresses are implicitly enabled when enabling IPv6.
|
||||
IPv6 can be enabled/disabled per interface in the [ietf-ip][ietf-ip-yang]
|
||||
YANG model.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
Package override
|
||||
================
|
||||
|
||||
This guide demonstrates how the `local.mk` file is utilized to override
|
||||
a Linux Buildroot package. The example of `tcpdump` serves to illustrate
|
||||
this process.
|
||||
|
||||
In an instance such as `Infix` using tcpdump, the `local.mk` file is modified
|
||||
as shown below:
|
||||
|
||||
```
|
||||
TCPDUMP_OVERRIDE_SRCDIR = /path/to/tcpdump/repo
|
||||
```
|
||||
|
||||
and stored in the `output/` folder, alongside the `.config` file:
|
||||
```
|
||||
user@PC:~/infix$ll output/ | grep -e 'local.mk' -e '.config'
|
||||
-rw-r--r-- 1 group user 119936 Nov 10 18:04 .config
|
||||
-rw-r--r-- 1 group user 43 Nov 10 18:25 local.mk
|
||||
```
|
||||
|
||||
The execution of `make tcpdump-rebuild all` triggers a process where
|
||||
Buildroot synchronizes the tcpdump source code from the specified override directory
|
||||
to `output/build/tcpdump-custom`, followed by the rebuilding of the entire project.
|
||||
|
||||
```
|
||||
user@PC:~/infix$ make tcpdump-rebuild all
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
user@PC:~/infix$ ll /output/build/ | grep tcpdump
|
||||
drwxr-xr-x 7 group user 20480 Nov 10 18:26 tcpdump-4.99.4/
|
||||
drwxr-xr-x 7 group user 12288 Nov 10 18:28 tcpdump-custom/
|
||||
```
|
||||
|
||||
Buildroot follows a process of downloading and processing tarballs
|
||||
(extraction, configuration, compilation, and installation).
|
||||
The source code is stored in a temporary directory:
|
||||
`output/build/<package>-<version>` (i.e. `tcpdump-4.99.4/`),
|
||||
which is removed and recreated with each `make` command. That is why
|
||||
the direct modifications in the `output/build` directory are generally
|
||||
**not recommended**.
|
||||
|
||||
To manage the development changes more effectively, where the package source code
|
||||
remains untouched, Buildroot incorporates the `<pkg>_OVERRIDE_SRCDIR` feature.
|
||||
|
||||
For a comprehensive understanding of utilizing Buildroot during development,
|
||||
including detailed elaboration on the `<pkg>_OVERRIDE_SRCDIR` feature,
|
||||
refer to section 8.13.6 in [Using Buildroot during development](https://nightly.buildroot.org/).
|
||||
@@ -123,6 +123,30 @@ For more information, see [Containers in Infix](container.md).
|
||||
> of course also enable it yourself in Infix by using `make menuconfig`
|
||||
> followed by rebuilding the image.
|
||||
|
||||
### Customizing Services
|
||||
|
||||
When running containers a common question is: "what if we want an outside
|
||||
SSH connection on port 22 to be forwarded to the container instead of the
|
||||
Infix system?" There are two possible answers that currently require a
|
||||
Hybrid Mode fix since it is not yet possible to configure the SSH daemon:
|
||||
|
||||
1. Disable SSH daemon
|
||||
2. Run SSH daemon on another port
|
||||
|
||||
The first one is simple, use what you have learned above about start.d
|
||||
scripts and add one that does `initctl disable sshd`.
|
||||
|
||||
The second is a little bit more involved:
|
||||
|
||||
```
|
||||
root@infix:/cfg/start.d$ cat <<EOF >10-custom-sshd-port.sh
|
||||
#!/bin/sh
|
||||
echo SSHD_OPTS=\"-p222\" > /etc/default/sshd
|
||||
EOF
|
||||
root@infix:/cfg/start.d$ chmod +x 10-custom-sshd-port.sh
|
||||
```
|
||||
|
||||
|
||||
|
||||
[1]: https://www.sysrepo.org/
|
||||
[2]: https://github.com/CESNET/netopeer
|
||||
|
||||
@@ -17,3 +17,10 @@ run:
|
||||
run-menuconfig: $(BUILD_DIR)/buildroot-config/mconf
|
||||
CONFIG_="CONFIG_" BR2_CONFIG="$(BINARIES_DIR)/.config" \
|
||||
$(BUILD_DIR)/buildroot-config/mconf $(BINARIES_DIR)/Config.in
|
||||
|
||||
define FRR_POST_BUILD_HOOK
|
||||
mkdir -p $(TARGET_DIR)/etc/iproute2/
|
||||
cp -r $(@D)/tools/etc/iproute2/rt_protos.d/ $(TARGET_DIR)/etc/iproute2/
|
||||
endef
|
||||
|
||||
FRR_POST_BUILD_HOOKS += FRR_POST_BUILD_HOOK
|
||||
|
||||
+1
-1
@@ -5,13 +5,13 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/factory/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/faux/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/finit/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/ifupdown-ng/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/iito/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-infix/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/klish/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/libsrx/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/lowdown/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/mdnsd/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/net/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
|
||||
|
||||
@@ -11,22 +11,22 @@ service name:confd log <run/bootstrap/success> \
|
||||
[S12345789] sysrepo-plugind -f -p /run/confd.pid -n -v3 -- Configuration daemon
|
||||
|
||||
# Bootstrap system with startup-config
|
||||
run name:startup log:prio:user.notice norestart \
|
||||
[S] <pid/confd> /usr/libexec/confd/load -b startup-config \
|
||||
run name:startup log:prio:user.notice norestart <pid/confd> \
|
||||
[S] /usr/libexec/confd/load -b startup-config \
|
||||
-- Loading startup-config
|
||||
|
||||
# Run if loading startup-config fails for some reason
|
||||
run name:failure log:prio:user.critical norestart if:<run/startup/failure> \
|
||||
[S] <pid/confd> /usr/libexec/confd/load failure-config \
|
||||
run name:failure log:prio:user.critical norestart <pid/confd> if:<run/startup/failure> \
|
||||
[S] /usr/libexec/confd/load failure-config \
|
||||
-- Loading failure-config
|
||||
|
||||
run name:error :2 log:console norestart if:<run/failure/failure> \
|
||||
[S] /usr/libexec/confd/error --
|
||||
|
||||
service name:netopeer log \
|
||||
[12345789] <pid/confd> netopeer2-server -F -t 60 \
|
||||
service name:netopeer notify:none log <pid/confd> \
|
||||
[12345789] netopeer2-server -F -t 60 \
|
||||
-- NETCONF server
|
||||
|
||||
# Create initial /etc/resolv.conf after successful bootstrap
|
||||
task name:resolv :conf norestart if:<run/startup/success> \
|
||||
[S] <pid/dnsmasq> resolvconf -u -- Update DNS configuration
|
||||
task name:resolv :conf norestart <pid/dnsmasq> if:<run/startup/success> \
|
||||
[S] resolvconf -u -- Update DNS configuration
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
|
||||
sha256 f665a98cf5026f25a21b86d9cba55a8e6ee82f4f257a1b538bb4ebb7341c2179 faux-99c9cf7b95d8e2955519e2bec5ddb021eeda2d55-br1.tar.gz
|
||||
sha256 f8725f39b9d9d45c8ad6fd2cfc3c1c834a80c32b4217a3d07dd8ed7fe4b6e352 faux-df1d569287bc45d8fd880287c00e3874c5627c19-br1.tar.gz
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
FAUX_VERSION = 99c9cf7b95d8e2955519e2bec5ddb021eeda2d55
|
||||
FAUX_VERSION = df1d569287bc45d8fd880287c00e3874c5627c19
|
||||
FAUX_SITE = https://github.com/kernelkit/faux.git
|
||||
#FAUX_VERSION = tags/2.1.0
|
||||
#FAUX_SITE = https://src.libcode.org/pkun/faux.git
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# From https://github.com/troglobit/finit/releases/
|
||||
sha256 ef73d9ba01aefef1a2171483f26339c7aefdf92dd25d7b322f15efa48e78d655 finit-4.5.tar.gz
|
||||
sha256 84ce1623ee935dc5d2d615ca14ed087f4bb3c47207fda97f26b1346e4983a6b2 finit-4.6.tar.gz
|
||||
|
||||
# Locally calculated
|
||||
sha256 3a2b964c1772d03ab17b73a389ecce9151e0b190a9247817a2c009b16d356422 LICENSE
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
FINIT_VERSION = 4.5
|
||||
FINIT_VERSION = 4.6
|
||||
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
|
||||
FINIT_LICENSE = MIT
|
||||
FINIT_LICENSE_FILES = LICENSE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# From https://github.com/addiva-elektronik/greenpak-programmer/releases/download/v1.1/greenpak-programmer-1.1.tar.gz.sha256
|
||||
sha256 960521714312e3b519a238b6c527826c3aacf6af93252f9ceb2fa2a22e341449 greenpak-programmer-1.1.tar.gz
|
||||
# From https://github.com/addiva-elektronik/greenpak-programmer/releases/download/v1.2/greenpak-programmer-1.2.tar.gz.sha256
|
||||
sha256 6beec4e668f3f88c4a55c9784e4d34d1ec070a2f2cd33063c9cae0e02fc97cd9 greenpak-programmer-1.2.tar.gz
|
||||
|
||||
# Locally generated
|
||||
sha256 c1673b6eecedfe5f461ee719291ff81b57d31f64f36cad3d00fb97b14dffc025 LICENSE.txt
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GREENPAK_PROGRAMMER_VERSION = 1.1
|
||||
GREENPAK_PROGRAMMER_VERSION = 1.2
|
||||
GREENPAK_PROGRAMMER_SITE = https://github.com/addiva-elektronik/greenpak-programmer/releases/download/v$(GREENPAK_PROGRAMMER_VERSION)
|
||||
GREENPAK_PROGRAMMER_LICENSE = MIT
|
||||
GREENPAK_PROGRAMMER_LICENSE_FILES = LICENSE.txt
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
config BR2_PACKAGE_IITO
|
||||
bool "iito"
|
||||
depends on BR2_PACKAGE_HAS_UDEV
|
||||
select BR2_PACKAGE_JANSSON
|
||||
select BR2_PACKAGE_LIBEV
|
||||
help
|
||||
If Input, Then Output
|
||||
|
||||
Monitor input sources, and reflect their state on output sinks.
|
||||
|
||||
https://github.com/kernelkit/iito
|
||||
@@ -0,0 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 7db4077b7c132170e9c358397cc2a30ae810ce24b8a5b66eb6b31c7c203156c1 iito-1.1.0.tar.gz
|
||||
sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING
|
||||
@@ -0,0 +1,22 @@
|
||||
################################################################################
|
||||
#
|
||||
# iito
|
||||
#
|
||||
################################################################################
|
||||
|
||||
IITO_VERSION = 1.1.0
|
||||
IITO_SITE = https://github.com/kernelkit/iito/releases/download/v$(IITO_VERSION)
|
||||
IITO_LICENSE = GPL-2.0
|
||||
IITO_LICENSE_FILES = COPYING
|
||||
IITO_DEPENDENCIES = jansson libev udev
|
||||
|
||||
define IITO_INSTALL_HOOK
|
||||
$(INSTALL) -D -m 0644 $(IITO_PKGDIR)/iitod.svc $(FINIT_D)/available/iitod.conf
|
||||
$(INSTALL) -d -m 0755 $(FINIT_D)/enabled
|
||||
ln -sf ../available/iitod.conf $(FINIT_D)/enabled/iitod.conf
|
||||
cp $(IITO_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/iitod.conf
|
||||
endef
|
||||
|
||||
IITO_POST_INSTALL_TARGET_HOOKS += IITO_INSTALL_HOOK
|
||||
|
||||
$(eval $(autotools-package))
|
||||
@@ -0,0 +1 @@
|
||||
service [S0123456789] <!pid/syslogd> iitod -- LED daemon
|
||||
@@ -0,0 +1 @@
|
||||
d /run/led - - -
|
||||
@@ -1,3 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
|
||||
sha256 5b20f20d0054d2df61d301bd5cc84d7a4a31d06b5faf268fc17950d6f521fc73 klish-plugin-sysrepo-b345ab9da2684623dec801aa935e99595c218a7b-br1.tar.gz
|
||||
sha256 468b9a4da872257795964e2fff17fbfc5a592070a98a0a51e5f54464171ee73f klish-plugin-sysrepo-fa1228a7ff2b3500b8c1bc6f6f0d28bddd2d0a91-br1.tar.gz
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
KLISH_PLUGIN_SYSREPO_VERSION = b345ab9da2684623dec801aa935e99595c218a7b
|
||||
KLISH_PLUGIN_SYSREPO_VERSION = fa1228a7ff2b3500b8c1bc6f6f0d28bddd2d0a91
|
||||
KLISH_PLUGIN_SYSREPO_SITE = https://github.com/kernelkit/klish-plugin-sysrepo.git
|
||||
#KLISH_PLUGIN_SYSREPO_VERSION = cdd3eb51a7f7ee0ed5bd925fa636061d3b1b85fb
|
||||
#KLISH_PLUGIN_SYSREPO_SITE = https://src.libcode.org/pkun/klish-plugin-sysrepo.git
|
||||
@@ -17,8 +17,7 @@ KLISH_PLUGIN_SYSREPO_AUTORECONF = YES
|
||||
|
||||
ifeq ($(BR2_PACKAGE_KLISH_PLUGIN_SYSREPO_XML),y)
|
||||
define KLISH_PLUGIN_SYSREPO_INSTALL_XML
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \
|
||||
$(@D)/xml/sysrepo.xml
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 $(@D)/xml/sysrepo.xml
|
||||
endef
|
||||
KLISH_PLUGIN_SYSREPO_POST_INSTALL_TARGET_HOOKS += \
|
||||
KLISH_PLUGIN_SYSREPO_INSTALL_XML
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Overrides for config file /etc/klish/klish.conf
|
||||
|
||||
UnixSocketPath=/run/klishd.sock
|
||||
|
||||
# Klish can use an external pager for all output
|
||||
Pager="/usr/bin/less -I -F -e -X -K -d -r -S"
|
||||
UsePager=y
|
||||
|
||||
# Set max size of history. By default 100 lines are saved, for every new
|
||||
# line after that, the oldest line is dropped. Set to 0 for unlimited.
|
||||
#HistorySize=100
|
||||
|
||||
# Save history after each (unique/non-repeated) command.
|
||||
HistorySaveAlways=n
|
||||
@@ -1,3 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE
|
||||
sha256 fa1b616d478a627158823994da4768e8ab166c9d5c8689b0c7a3f15f289e5d8e klish-8022195e6ed8122bbf2de6d31aba85bef85f072c-br1.tar.gz
|
||||
sha256 0ef97fe42377e32be96a69096fc149e547568e6567d641cc50252356eb64e934 klish-ce81f52b50bcc3c37ce1ce2bec5a7965e2d698d2-br1.tar.gz
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
KLISH_VERSION = 8022195e6ed8122bbf2de6d31aba85bef85f072c
|
||||
KLISH_VERSION = ce81f52b50bcc3c37ce1ce2bec5a7965e2d698d2
|
||||
KLISH_SITE = https://github.com/kernelkit/klish.git
|
||||
#KLISH_VERSION = tags/3.0.0
|
||||
#KLISH_SITE = https://src.libcode.org/pkun/klish.git
|
||||
@@ -20,16 +20,14 @@ KLISH_CONF_OPTS += --with-libxml2
|
||||
define KLISH_INSTALL_CONFIG
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \
|
||||
$(@D)/plugins/klish/xml/ptypes.xml
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \
|
||||
$(@D)/klish.conf $(@D)/klishd.conf
|
||||
sed -i 's/#HistorySaveAlways=n/HistorySaveAlways=y/' $(TARGET_DIR)/etc/klish/klish.conf
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -m 0644 $(KLISH_PKGDIR)/klish.conf
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -m 0644 $(KLISH_PKGDIR)/klishd.conf
|
||||
endef
|
||||
KLISH_POST_INSTALL_TARGET_HOOKS += KLISH_INSTALL_CONFIG
|
||||
|
||||
ifeq ($(BR2_PACKAGE_KLISH_DEFAULT_XML),y)
|
||||
define KLISH_INSTALL_XML
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \
|
||||
$(BR2_EXTERNAL_INFIX_PATH)/package/klish/default.xml
|
||||
$(INSTALL) -t $(TARGET_DIR)/etc/klish -m 0644 $(KLISH_PKGDIR)/default.xml
|
||||
endef
|
||||
KLISH_POST_INSTALL_TARGET_HOOKS += KLISH_INSTALL_XML
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Overrides for config file /etc/klish/klishd.conf
|
||||
|
||||
UnixSocketPath=/run/klishd.sock
|
||||
|
||||
DBs=libxml2
|
||||
@@ -1,6 +0,0 @@
|
||||
config BR2_PACKAGE_NET
|
||||
bool "net"
|
||||
select BR2_PACKAGE_IPROUTE2
|
||||
select BR2_PACKAGE_LIBITE
|
||||
help
|
||||
Handles transitions between network states.
|
||||
@@ -1,21 +0,0 @@
|
||||
################################################################################
|
||||
#
|
||||
# net
|
||||
#
|
||||
################################################################################
|
||||
|
||||
NET_VERSION = 1.0
|
||||
NET_LICENSE = MIT
|
||||
NET_LICENSE_FILES = LICENSE
|
||||
NET_SITE_METHOD = local
|
||||
NET_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/net
|
||||
NET_REDISTRIBUTE = NO
|
||||
NET_DEPENDENCIES = libite
|
||||
NET_AUTORECONF = YES
|
||||
|
||||
define NET_INSTALL_EXTRA
|
||||
chmod +x $(TARGET_DIR)/usr/share/net/*.sh
|
||||
endef
|
||||
NET_POST_INSTALL_TARGET_HOOKS += NET_INSTALL_EXTRA
|
||||
|
||||
$(eval $(autotools-package))
|
||||
@@ -21,9 +21,9 @@ define SKELETON_INIT_FINIT_GETTY
|
||||
if [ $(SYSTEM_GETTY_BAUDRATE) -eq 0 ]; then \
|
||||
SYSTEM_GETTY_BAUDRATE=""; \
|
||||
fi; \
|
||||
echo "tty [12345789] $(SYSTEM_GETTY_PORT) $(SYSTEM_GETTY_BAUDRATE) $(SYSTEM_GETTY_TERM) noclear passenv"; \
|
||||
echo "tty [12345] $(SYSTEM_GETTY_PORT) $(SYSTEM_GETTY_BAUDRATE) $(SYSTEM_GETTY_TERM) noclear passenv"; \
|
||||
else \
|
||||
echo "tty [12345789] /sbin/getty -L $(SYSTEM_GETTY_OPTIONS) $(SYSTEM_GETTY_BAUDRATE) $(SYSTEM_GETTY_PORT) $(SYSTEM_GETTY_TERM)"; \
|
||||
echo "tty [12345] /sbin/getty -L $(SYSTEM_GETTY_OPTIONS) $(SYSTEM_GETTY_BAUDRATE) $(SYSTEM_GETTY_PORT) $(SYSTEM_GETTY_TERM)"; \
|
||||
fi
|
||||
endef
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# <!>: dropbear does not honor SIGHUP.
|
||||
# -R: Create hostkeys if needed.
|
||||
# -F: Run in foreground.
|
||||
service [2345789] <!> env:-/etc/default/dropbear dropbear -F -R $DROPBEAR_ARGS -- Dropbear SSH daemon
|
||||
service [2345] <!> env:-/etc/default/dropbear dropbear -F -R $DROPBEAR_ARGS -- Dropbear SSH daemon
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [2345789] log:null <!pid/zebra> ospfd -A 127.0.0.1 -u frr -g frr -- OSPF daemon
|
||||
service [2345789] log:null <!pid/zebra> ospfd -A 127.0.0.1 -u frr -g frr -f /etc/frr/ospfd.conf-- OSPF daemon
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [2345789] log:null <!pid/zebra> staticd -A 127.0.0.1 -u frr -g frr -- Static routing daemon
|
||||
service [2345789] log:null <!pid/zebra> staticd -A 127.0.0.1 -u frr -g frr -f /etc/frr/staticd.conf -- Static routing daemon
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [2345789] pid:!/run/quagga/zebra.pid zebra -A 127.0.0.1 -u frr -g frr -- Zebra routing daemon
|
||||
service [2345789] <!> pid:!/run/frr/zebra.pid zebra -A 127.0.0.1 -u frr -g frr -- Zebra routing daemon
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [2345789] env:-/etc/default/mini-snmpd /usr/sbin/mini-snmpd -sn $MINI_SNMPD_ARGS -- Mini snmpd
|
||||
service [2345] env:-/etc/default/mini-snmpd /usr/sbin/mini-snmpd -sn $MINI_SNMPD_ARGS -- Mini snmpd
|
||||
|
||||
@@ -1 +1 @@
|
||||
service [2345789] env:-/etc/default/nginx nginx -g 'daemon off;' $NGINX_ARGS -- Web server
|
||||
service [2345] env:-/etc/default/nginx nginx -g 'daemon off;' $NGINX_ARGS -- Web server
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Also needs the /var/run/agentx directory before starting
|
||||
service [2345789] env:-/etc/default/snmpd /usr/sbin/snmpd -f -LOw \
|
||||
-I -system_mib,smux,mteTrigger,mteTriggerConf \
|
||||
service [2345] env:-/etc/default/snmpd /usr/sbin/snmpd -f -LOw \
|
||||
-I -system_mib,smux,mteTrigger,mteTriggerConf \
|
||||
-p /run/snmpd.pid $SNMPD_ARGS \
|
||||
-- Net-SNMP daemon
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
task <pid/syslogd> \
|
||||
[S] /usr/bin/ssh-hostkeys -- Verifying SSH host keys
|
||||
service <task/ssh-hostkeys/success> env:-/etc/default/sshd \
|
||||
[2345789] /usr/sbin/sshd -D $SSHD_OPTS -- OpenSSH daemon
|
||||
[2345] /usr/sbin/sshd -D $SSHD_OPTS -- OpenSSH daemon
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
From 99e3fc4a7c6d31f5d0fdc7bb5c409c776c19012c Mon Sep 17 00:00:00 2001
|
||||
From e1011848d2c9476e20e6a4053b8ab46ce2a1506f Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 5 Oct 2023 16:09:25 +0200
|
||||
Subject: [PATCH 1/9] eth: fwnode: Fall back to NVMEM provided MAC address from
|
||||
OF
|
||||
Subject: [PATCH 01/17] eth: fwnode: Fall back to NVMEM provided MAC address
|
||||
from OF
|
||||
|
||||
In the cases where the fwnode is an OF node, make use of any NVMEM
|
||||
source of the interface's MAC address that might have been specified
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5ddc784a4c8803aff2c3fa3c6595e9d32933d4aa Mon Sep 17 00:00:00 2001
|
||||
From 1d6f30fce9f4516730439f72ee2134301d37654d Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 13:08:29 +0200
|
||||
Subject: [PATCH 2/9] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
Subject: [PATCH 02/17] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
counter
|
||||
|
||||
This change contains no functional change. We simply push the hardware
|
||||
@@ -18,7 +18,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
2 files changed, 105 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 7af2f08a62f1..1e944cf08233 100644
|
||||
index 0d4b236d1e34..139f4d55a284 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1082,7 +1082,7 @@ static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
|
||||
@@ -163,7 +163,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
if (chip->info->ops->serdes_get_stats) {
|
||||
@@ -4196,7 +4218,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
||||
@@ -4198,7 +4220,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -172,7 +172,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4234,7 +4256,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
||||
@@ -4236,7 +4258,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -181,7 +181,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
|
||||
.serdes_power = mv88e6185_serdes_power,
|
||||
.serdes_get_lane = mv88e6185_serdes_get_lane,
|
||||
@@ -4277,7 +4299,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
||||
@@ -4279,7 +4301,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -190,7 +190,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4323,7 +4345,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
||||
@@ -4325,7 +4347,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -199,7 +199,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4366,7 +4388,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
||||
@@ -4368,7 +4390,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -208,7 +208,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4415,7 +4437,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
||||
@@ -4417,7 +4439,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -217,7 +217,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4477,7 +4499,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
||||
@@ -4479,7 +4501,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -226,7 +226,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4515,7 +4537,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
||||
@@ -4517,7 +4539,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -235,7 +235,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4563,7 +4585,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
||||
@@ -4565,7 +4587,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -244,7 +244,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4612,7 +4634,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
@@ -4614,7 +4636,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -253,7 +253,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4668,7 +4690,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
||||
@@ -4670,7 +4692,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -262,7 +262,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4717,7 +4739,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
@@ -4719,7 +4741,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -271,7 +271,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4769,7 +4791,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
||||
@@ -4771,7 +4793,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -280,7 +280,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4820,7 +4842,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
||||
@@ -4822,7 +4844,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -289,7 +289,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4885,7 +4907,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
||||
@@ -4887,7 +4909,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -298,7 +298,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4948,7 +4970,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
@@ -4950,7 +4972,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -307,7 +307,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5014,7 +5036,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
@@ -5016,7 +5038,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -316,7 +316,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5074,7 +5096,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
||||
@@ -5076,7 +5098,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6250_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6250_stats_get_strings,
|
||||
@@ -325,7 +325,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6250_watchdog_ops,
|
||||
@@ -5121,7 +5143,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
@@ -5123,7 +5145,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -334,7 +334,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5187,7 +5209,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
@@ -5189,7 +5211,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -343,7 +343,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5234,7 +5256,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
@@ -5236,7 +5258,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -352,7 +352,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5283,7 +5305,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
@@ -5285,7 +5307,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -361,7 +361,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5348,7 +5370,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
@@ -5350,7 +5372,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -370,7 +370,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5394,7 +5416,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
@@ -5396,7 +5418,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -379,7 +379,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5445,7 +5467,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
@@ -5447,7 +5469,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -388,7 +388,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5514,7 +5536,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
@@ -5516,7 +5538,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -397,7 +397,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5583,7 +5605,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
@@ -5585,7 +5607,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -406,7 +406,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5652,7 +5674,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
@@ -5654,7 +5676,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 63c14938bdaa1891386989aa46bee4571c1c0777 Mon Sep 17 00:00:00 2001
|
||||
From f960475a96d2852d06ee062c970e35074f87659c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 21:10:15 +0200
|
||||
Subject: [PATCH 3/9] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
Subject: [PATCH 03/17] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
|
||||
With the upcoming standard counter group support, we are no longer
|
||||
reading out the whole set of counters, but rather mapping a subset to
|
||||
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 78 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 1e944cf08233..ea4fb0d3e628 100644
|
||||
index 139f4d55a284..4afe5c212a36 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1019,68 +1019,83 @@ static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
From ffd5442fcbadcbd8733b9ac870d83d7561cca9fc Mon Sep 17 00:00:00 2001
|
||||
From 6a612f46152d8567a16b7b15fdcc3081cbdbb3fb Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 21:15:52 +0200
|
||||
Subject: [PATCH 4/9] net: dsa: mv88e6xxx: Add "eth-mac" counter group support
|
||||
Subject: [PATCH 04/17] net: dsa: mv88e6xxx: Add "eth-mac" counter group
|
||||
support
|
||||
|
||||
After this change, mv88e6xxx ports can report the applicable subset of
|
||||
their counters using ethtool's standardized "eth-mac" counter group.
|
||||
@@ -12,7 +13,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 52 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index ea4fb0d3e628..ec3a4717bc44 100644
|
||||
index 4afe5c212a36..2cfc072b41b1 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1403,6 +1403,57 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
|
||||
@@ -73,7 +74,7 @@ index ea4fb0d3e628..ec3a4717bc44 100644
|
||||
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
@@ -7160,6 +7211,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
@@ -7162,6 +7213,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
|
||||
.get_strings = mv88e6xxx_get_strings,
|
||||
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 2cfafa598282efc980baf00b312a61032b9f5aa9 Mon Sep 17 00:00:00 2001
|
||||
From a85c55f3232d402780a22d42859bdc81150469b4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 6 Sep 2023 10:55:53 +0200
|
||||
Subject: [PATCH 5/9] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
Subject: [PATCH 05/17] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
|
||||
After this change, mv88e6xxx ports can report the applicable subset of
|
||||
their counters using ethtool's standardized "rmon" counter group.
|
||||
@@ -12,7 +12,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index ec3a4717bc44..eb5990cfc7d4 100644
|
||||
index 2cfc072b41b1..90dcd6c3be31 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1454,6 +1454,61 @@ static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
@@ -77,7 +77,7 @@ index ec3a4717bc44..eb5990cfc7d4 100644
|
||||
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
@@ -7212,6 +7267,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
@@ -7214,6 +7269,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
.get_strings = mv88e6xxx_get_strings,
|
||||
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
|
||||
.get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
From 7abdce276172fe74e24fd30d204a75e388bbab6c Mon Sep 17 00:00:00 2001
|
||||
From 6f684b1b9eb8a307b77aa4baa8531e2c423112af Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Sep 2023 11:10:26 +0200
|
||||
Subject: [PATCH 6/9] arm64: dts: marvell: cp11x: Provide clock names for MDIO
|
||||
controllers
|
||||
Subject: [PATCH 06/17] arm64: dts: marvell: cp11x: Provide clock names for
|
||||
MDIO controllers
|
||||
|
||||
This will let the driver figure out the rate of the core clk, such
|
||||
that custom MDC frequencies can be supported.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8dc464b6506fbc038ccdae0a88936989fdf32117 Mon Sep 17 00:00:00 2001
|
||||
From d5e03e7b44c8ac414927751097d8d65caffc33b4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:19:40 +0200
|
||||
Subject: [PATCH 7/9] net: mvmdio: Avoid excessive sleeps in polled mode
|
||||
Subject: [PATCH 07/17] net: mvmdio: Avoid excessive sleeps in polled mode
|
||||
|
||||
Before this change, when operating in polled mode, i.e. no IRQ is
|
||||
available, every individual C45 access would be hit with a 150us sleep
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1956176490d4eec3a889a38626326b375782a55a Mon Sep 17 00:00:00 2001
|
||||
From d389cc01295ebd7be228c8240f0061134b27f215 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Sep 2023 11:12:55 +0200
|
||||
Subject: [PATCH 8/9] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
Subject: [PATCH 08/17] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
controllers
|
||||
|
||||
Support the standard "clock-frequency" attribute to set the generated
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
From 0de9c5dfc6395eb2e3066488638ac86de58b8068 Mon Sep 17 00:00:00 2001
|
||||
From 46bbea6b9d692ac7460e4e278cedee9f88b6da0b Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:38:10 +0200
|
||||
Subject: [PATCH 9/9] net: phy: marvell10g: Support firmware loading on 88X3310
|
||||
Subject: [PATCH 09/17] net: phy: marvell10g: Support firmware loading on
|
||||
88X3310
|
||||
|
||||
If a device is found waiting for firmware to be loaded into its RAM,
|
||||
ask userspace for the binary and load it over XMDIO.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 312d3efde0fbe7cec3bf7ba1908c213c9cf69337 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:33 +0200
|
||||
Subject: [PATCH 10/17] led: trig: netdev: Fix requesting offload device
|
||||
|
||||
When the netdev trigger is activates, it tries to determine what
|
||||
device the LED blinks for, and what the current blink mode is.
|
||||
|
||||
The documentation for hw_control_get() says:
|
||||
|
||||
* Return 0 on success, a negative error number on failing parsing the
|
||||
* initial mode. Error from this function is NOT FATAL as the device
|
||||
* may be in a not supported initial state by the attached LED trigger.
|
||||
*/
|
||||
|
||||
For the Marvell PHY and the Armada 370-rd board, the initial LED blink
|
||||
mode is not supported by the trigger, so it returns an error. This
|
||||
resulted in not getting the device the LED is blinking for. As a
|
||||
result, the device is unknown and offloaded is never performed.
|
||||
|
||||
Change to condition to always get the device if offloading is
|
||||
supported, and reduce the scope of testing for an error from
|
||||
hw_control_get() to skip setting trigger internal state if there is an
|
||||
error.
|
||||
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/leds/trigger/ledtrig-netdev.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
index 03c58e50cc44..e9e4da217249 100644
|
||||
--- a/drivers/leds/trigger/ledtrig-netdev.c
|
||||
+++ b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct led_classdev *led_cdev)
|
||||
/* Check if hw control is active by default on the LED.
|
||||
* Init already enabled mode in hw control.
|
||||
*/
|
||||
- if (supports_hw_control(led_cdev) &&
|
||||
- !led_cdev->hw_control_get(led_cdev, &mode)) {
|
||||
+ if (supports_hw_control(led_cdev)) {
|
||||
dev = led_cdev->hw_control_get_device(led_cdev);
|
||||
if (dev) {
|
||||
const char *name = dev_name(dev);
|
||||
|
||||
set_device_name(trigger_data, name, strlen(name));
|
||||
trigger_data->hw_control = true;
|
||||
- trigger_data->mode = mode;
|
||||
+
|
||||
+ rc = led_cdev->hw_control_get(led_cdev, &mode);
|
||||
+ if (!rc)
|
||||
+ trigger_data->mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 83322015e7960ba0f1f3698e36333cfb6aecb931 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:36 +0200
|
||||
Subject: [PATCH 11/17] leds: trig-netdev: Disable offload on deactivation of
|
||||
trigger
|
||||
|
||||
Ensure that the offloading of blinking is stopped when the trigger is
|
||||
deactivated. Calling led_set_brightness() is documented as stopping
|
||||
offload and setting the LED to a constant brightness.
|
||||
|
||||
Suggested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-5-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/leds/trigger/ledtrig-netdev.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
index e9e4da217249..cc3261543a5e 100644
|
||||
--- a/drivers/leds/trigger/ledtrig-netdev.c
|
||||
+++ b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
@@ -595,6 +595,8 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev)
|
||||
|
||||
cancel_delayed_work_sync(&trigger_data->work);
|
||||
|
||||
+ led_set_brightness(led_cdev, LED_OFF);
|
||||
+
|
||||
dev_put(trigger_data->net_dev);
|
||||
|
||||
kfree(trigger_data);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
From a4f09c743da21f09b0fcc6e5842d665490f9f70e Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:34 +0200
|
||||
Subject: [PATCH 12/17] net: phy: phy_device: Call into the PHY driver to set
|
||||
LED offload
|
||||
|
||||
Linux LEDs can be requested to perform hardware accelerated blinking
|
||||
to indicate link, RX, TX etc. Pass the rules for blinking to the PHY
|
||||
driver, if it implements the ops needed to determine if a given
|
||||
pattern can be offloaded, to offload it, and what the current offload
|
||||
is. Additionally implement the op needed to get what device the LED is
|
||||
for.
|
||||
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/phy.h | 33 +++++++++++++++++
|
||||
2 files changed, 101 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
|
||||
index c7cf61fe41cf..d096d9d63617 100644
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -3020,6 +3020,61 @@ static int phy_led_blink_set(struct led_classdev *led_cdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
+static __maybe_unused struct device *
|
||||
+phy_led_hw_control_get_device(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+
|
||||
+ if (phydev->attached_dev)
|
||||
+ return &phydev->attached_dev->dev;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused
|
||||
+phy_led_hw_control_get(struct led_classdev *led_cdev,
|
||||
+ unsigned long *rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused
|
||||
+phy_led_hw_control_set(struct led_classdev *led_cdev,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static void phy_leds_unregister(struct phy_device *phydev)
|
||||
{
|
||||
struct phy_led *phyled;
|
||||
@@ -3057,6 +3112,19 @@ static int of_phy_led(struct phy_device *phydev,
|
||||
cdev->brightness_set_blocking = phy_led_set_brightness;
|
||||
if (phydev->drv->led_blink_set)
|
||||
cdev->blink_set = phy_led_blink_set;
|
||||
+
|
||||
+#ifdef CONFIG_LEDS_TRIGGERS
|
||||
+ if (phydev->drv->led_hw_is_supported &&
|
||||
+ phydev->drv->led_hw_control_set &&
|
||||
+ phydev->drv->led_hw_control_get) {
|
||||
+ cdev->hw_control_is_supported = phy_led_hw_is_supported;
|
||||
+ cdev->hw_control_set = phy_led_hw_control_set;
|
||||
+ cdev->hw_control_get = phy_led_hw_control_get;
|
||||
+ cdev->hw_control_trigger = "netdev";
|
||||
+ }
|
||||
+
|
||||
+ cdev->hw_control_get_device = phy_led_hw_control_get_device;
|
||||
+#endif
|
||||
cdev->max_brightness = 1;
|
||||
init_data.devicename = dev_name(&phydev->mdio.dev);
|
||||
init_data.fwnode = of_fwnode_handle(led);
|
||||
diff --git a/include/linux/phy.h b/include/linux/phy.h
|
||||
index 11c1e91563d4..0f9e4598c596 100644
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -1104,6 +1104,39 @@ struct phy_driver {
|
||||
int (*led_blink_set)(struct phy_device *dev, u8 index,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off);
|
||||
+ /**
|
||||
+ * @led_hw_is_supported: Can the HW support the given rules.
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules The core is interested in these rules
|
||||
+ *
|
||||
+ * Return 0 if yes, -EOPNOTSUPP if not, or an error code.
|
||||
+ */
|
||||
+ int (*led_hw_is_supported)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+ /**
|
||||
+ * @led_hw_control_set: Set the HW to control the LED
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules The rules used to control the LED
|
||||
+ *
|
||||
+ * Returns 0, or a an error code.
|
||||
+ */
|
||||
+ int (*led_hw_control_set)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+ /**
|
||||
+ * @led_hw_control_get: Get how the HW is controlling the LED
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules Pointer to the rules used to control the LED
|
||||
+ *
|
||||
+ * Set *@rules to how the HW is currently blinking. Returns 0
|
||||
+ * on success, or a error code if the current blinking cannot
|
||||
+ * be represented in rules, or some other error happens.
|
||||
+ */
|
||||
+ int (*led_hw_control_get)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long *rules);
|
||||
+
|
||||
};
|
||||
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
|
||||
struct phy_driver, mdiodrv)
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
From 5adf394404d4c8ac25fb1e36d7d3f23b699b3104 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 15 Nov 2023 20:58:42 +0100
|
||||
Subject: [PATCH 13/17] net: phy: marvell10g: Add LED support for 88X3310
|
||||
|
||||
Pickup the LEDs from the state in which the hardware reset or
|
||||
bootloader left them, but also support further configuration via
|
||||
device tree. This is primarily needed because the electrical polarity
|
||||
and drive behavior is software controlled and not possible to set via
|
||||
hardware strapping.
|
||||
|
||||
Trigger support:
|
||||
- "none"
|
||||
- "timer": Map 60-100 ms periods to the fast rate (81ms) and 1000-1600
|
||||
ms periods to the slow rate (1300ms). Defer everything else to
|
||||
software blinking
|
||||
- "netdev": Offload (per-medium) link or duplex information to the
|
||||
solid behavior; tx and/or rx activity to blink behavior.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/phy/marvell10g.c | 455 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 455 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
|
||||
index 155f439d9c1c..05ad7c769e24 100644
|
||||
--- a/drivers/net/phy/marvell10g.c
|
||||
+++ b/drivers/net/phy/marvell10g.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/marvell_phy.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/sfp.h>
|
||||
#include <linux/netdevice.h>
|
||||
@@ -136,6 +137,14 @@ enum {
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
|
||||
+ MV_V2_LED0_CONTROL = 0xf020,
|
||||
+ MV_V2_LED_CONTROL_POLARITY_MASK = 0x0003,
|
||||
+ MV_V2_LED_CONTROL_POLARITY_SHIFT = 0,
|
||||
+ MV_V2_LED_CONTROL_BLINK_RATE = BIT(2),
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_MASK = 0x00f8,
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT = 3,
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_MASK = 0x1f00,
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT = 8,
|
||||
MV_V2_PORT_INTR_STS = 0xf040,
|
||||
MV_V2_PORT_INTR_MASK = 0xf043,
|
||||
MV_V2_PORT_INTR_STS_WOL_EN = BIT(8),
|
||||
@@ -168,6 +177,16 @@ struct mv3310_chip {
|
||||
#endif
|
||||
};
|
||||
|
||||
+#define MV3310_N_LEDS 4
|
||||
+
|
||||
+struct mv3310_led {
|
||||
+ u8 index;
|
||||
+ u16 fw_ctrl;
|
||||
+
|
||||
+ unsigned copper:1;
|
||||
+ unsigned fiber:1;
|
||||
+};
|
||||
+
|
||||
struct mv3310_priv {
|
||||
DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX);
|
||||
|
||||
@@ -178,6 +197,8 @@ struct mv3310_priv {
|
||||
|
||||
struct device *hwmon_dev;
|
||||
char *hwmon_name;
|
||||
+
|
||||
+ struct mv3310_led led[MV3310_N_LEDS];
|
||||
};
|
||||
|
||||
static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
|
||||
@@ -185,6 +206,431 @@ static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
|
||||
return phydev->drv->driver_data;
|
||||
}
|
||||
|
||||
+enum mv3310_led_func {
|
||||
+ MV3310_LED_FUNC_OFF = 0x00,
|
||||
+ MV3310_LED_FUNC_TX_RX = 0x01,
|
||||
+ MV3310_LED_FUNC_TX = 0x02,
|
||||
+ MV3310_LED_FUNC_RX = 0x03,
|
||||
+ MV3310_LED_FUNC_COLLISION = 0x04,
|
||||
+ MV3310_LED_FUNC_LINK_COPPER = 0x05,
|
||||
+ MV3310_LED_FUNC_LINK_FIBER = 0x06,
|
||||
+ MV3310_LED_FUNC_LINK = 0x07,
|
||||
+ MV3310_LED_FUNC_10M_LINK = 0x08,
|
||||
+ MV3310_LED_FUNC_100M_LINK = 0x09,
|
||||
+ MV3310_LED_FUNC_1G_LINK = 0x0a,
|
||||
+ MV3310_LED_FUNC_10G_LINK = 0x0b,
|
||||
+ MV3310_LED_FUNC_10M_100M_LINK = 0x0c,
|
||||
+ MV3310_LED_FUNC_10M_100M_1G_LINK = 0x0d,
|
||||
+ MV3310_LED_FUNC_100M_10G_LINK = 0x0e,
|
||||
+ MV3310_LED_FUNC_1G_10G_LINK = 0x0f,
|
||||
+ MV3310_LED_FUNC_1G_10G_SLAVE = 0x10,
|
||||
+ MV3310_LED_FUNC_1G_10G_MASTER = 0x11,
|
||||
+ MV3310_LED_FUNC_HALF_DUPLEX = 0x12,
|
||||
+ MV3310_LED_FUNC_FULL_DUPLEX = 0x13,
|
||||
+ MV3310_LED_FUNC_LINK_EEE = 0x14,
|
||||
+ MV3310_LED_FUNC_2G5_LINK = 0x15,
|
||||
+ MV3310_LED_FUNC_5G_LINK = 0x16,
|
||||
+ MV3310_LED_FUNC_ON = 0x17,
|
||||
+ MV3310_LED_FUNC_2G5_5G_SLAVE = 0x18,
|
||||
+ MV3310_LED_FUNC_2G5_5G_MASTER = 0x19,
|
||||
+
|
||||
+ MV3310_LED_FUNC_SPEED_BLINK = 0x1f
|
||||
+};
|
||||
+
|
||||
+static int mv3310_led_flags_from_funcs(struct mv3310_led *led,
|
||||
+ enum mv3310_led_func solid,
|
||||
+ enum mv3310_led_func blink,
|
||||
+ unsigned long *flagsp)
|
||||
+{
|
||||
+ unsigned long flags = 0;
|
||||
+
|
||||
+ switch (solid) {
|
||||
+ case MV3310_LED_FUNC_OFF:
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_LINK_COPPER:
|
||||
+ case MV3310_LED_FUNC_LINK_FIBER:
|
||||
+ case MV3310_LED_FUNC_LINK:
|
||||
+ flags |= TRIGGER_NETDEV_LINK;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_HALF_DUPLEX:
|
||||
+ flags |= TRIGGER_NETDEV_HALF_DUPLEX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_FULL_DUPLEX:
|
||||
+ flags |= TRIGGER_NETDEV_FULL_DUPLEX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (blink) {
|
||||
+ case MV3310_LED_FUNC_OFF:
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_TX:
|
||||
+ flags |= TRIGGER_NETDEV_TX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_RX:
|
||||
+ flags |= TRIGGER_NETDEV_RX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_TX_RX:
|
||||
+ flags |= TRIGGER_NETDEV_TX | TRIGGER_NETDEV_RX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ *flagsp = flags;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_funcs_from_flags(struct mv3310_led *led,
|
||||
+ unsigned long flags,
|
||||
+ enum mv3310_led_func *solid,
|
||||
+ enum mv3310_led_func *blink)
|
||||
+{
|
||||
+ unsigned long activity, duplex, link;
|
||||
+
|
||||
+ if (flags & ~(BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX) |
|
||||
+ BIT(TRIGGER_NETDEV_RX)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ link = flags & BIT(TRIGGER_NETDEV_LINK);
|
||||
+
|
||||
+ duplex = flags & (BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX));
|
||||
+
|
||||
+ activity = flags & (BIT(TRIGGER_NETDEV_TX) |
|
||||
+ BIT(TRIGGER_NETDEV_RX));
|
||||
+
|
||||
+ if (link && duplex)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (solid) {
|
||||
+ if (link) {
|
||||
+ if (led->copper)
|
||||
+ *solid = MV3310_LED_FUNC_LINK_COPPER;
|
||||
+ else if (led->fiber)
|
||||
+ *solid = MV3310_LED_FUNC_LINK_FIBER;
|
||||
+ else
|
||||
+ *solid = MV3310_LED_FUNC_LINK;
|
||||
+ } else if (duplex) {
|
||||
+ switch (duplex) {
|
||||
+ case BIT(TRIGGER_NETDEV_HALF_DUPLEX):
|
||||
+ *solid = MV3310_LED_FUNC_HALF_DUPLEX;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_FULL_DUPLEX):
|
||||
+ *solid = MV3310_LED_FUNC_FULL_DUPLEX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ *solid = MV3310_LED_FUNC_OFF;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (blink) {
|
||||
+ switch (activity) {
|
||||
+ case 0:
|
||||
+ *blink = MV3310_LED_FUNC_OFF;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_TX):
|
||||
+ *blink = MV3310_LED_FUNC_TX;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_RX):
|
||||
+ *blink = MV3310_LED_FUNC_RX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ *blink = MV3310_LED_FUNC_TX_RX;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_get(struct phy_device *phydev,
|
||||
+ struct mv3310_led *led,
|
||||
+ enum mv3310_led_func *solid,
|
||||
+ enum mv3310_led_func *blink,
|
||||
+ bool *slow_blink)
|
||||
+{
|
||||
+ int ctrl;
|
||||
+
|
||||
+ ctrl = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + led->index);
|
||||
+ if (ctrl < 0)
|
||||
+ return ctrl;
|
||||
+
|
||||
+ *solid = (ctrl & MV_V2_LED_CONTROL_SOLID_FUNC_MASK) >>
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT;
|
||||
+ *blink = (ctrl & MV_V2_LED_CONTROL_BLINK_FUNC_MASK) >>
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT;
|
||||
+
|
||||
+ *slow_blink = !!(ctrl & MV_V2_LED_CONTROL_BLINK_RATE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_set(struct phy_device *phydev,
|
||||
+ struct mv3310_led *led,
|
||||
+ enum mv3310_led_func solid,
|
||||
+ enum mv3310_led_func blink,
|
||||
+ bool slow_blink)
|
||||
+{
|
||||
+ u16 ctrl = led->fw_ctrl;
|
||||
+
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_SOLID_FUNC_MASK;
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_BLINK_FUNC_MASK;
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_BLINK_RATE;
|
||||
+
|
||||
+ ctrl |= solid << MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT;
|
||||
+ ctrl |= blink << MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT;
|
||||
+
|
||||
+ if (slow_blink)
|
||||
+ ctrl |= MV_V2_LED_CONTROL_BLINK_RATE;
|
||||
+
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + led->index, ctrl);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+enum mv3310_led_polarity {
|
||||
+ MV3310_LED_POLARITY_ACTIVE_LOW = 0x0,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_HIGH = 0x1,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE = 0x2,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE = 0x3,
|
||||
+};
|
||||
+
|
||||
+static const char *mv3310_led_polarity_name[] = {
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_LOW] = "active-low",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_HIGH] = "active-high",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE] = "active-low-tristate",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE] = "active-high-tristate",
|
||||
+};
|
||||
+
|
||||
+static int mv3310_led_polarity_from_str(const char *str,
|
||||
+ enum mv3310_led_polarity *polarity)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mv3310_led_polarity_name); i++) {
|
||||
+ if (!mv3310_led_polarity_name[i])
|
||||
+ continue;
|
||||
+
|
||||
+ if (!strcmp(mv3310_led_polarity_name[i], str)) {
|
||||
+ *polarity = i;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_probe_of(struct phy_device *phydev,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_polarity polarity;
|
||||
+ struct mv3310_led *led;
|
||||
+ const char *str;
|
||||
+ u32 index;
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "reg", &index);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+ ctrl = led->fw_ctrl;
|
||||
+
|
||||
+ err = of_property_read_string(np, "marvell,media", &str);
|
||||
+ if (!err) {
|
||||
+ if (!strcmp(str, "copper"))
|
||||
+ led->copper = 1;
|
||||
+ else if (!strcmp(str, "fiber"))
|
||||
+ led->fiber = 1;
|
||||
+ }
|
||||
+
|
||||
+ err = of_property_read_string(np, "marvell,polarity", &str);
|
||||
+ err = err ? : mv3310_led_polarity_from_str(str, &polarity);
|
||||
+ if (!err) {
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_POLARITY_MASK;
|
||||
+ ctrl |= polarity << MV_V2_LED_CONTROL_POLARITY_SHIFT;
|
||||
+ }
|
||||
+
|
||||
+ if (ctrl != led->fw_ctrl) {
|
||||
+ led->fw_ctrl = ctrl;
|
||||
+
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + index, ctrl);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_leds_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct device_node *node = phydev->mdio.dev.of_node;
|
||||
+ struct device_node *pnp, *np;
|
||||
+ int err, val, index;
|
||||
+
|
||||
+ /* Save the state config left by HW reset or bootloader, this
|
||||
+ * may be further refined by configuration from DT, if
|
||||
+ * available.
|
||||
+ *
|
||||
+ * The resulting state is used as the fallback when no trigger
|
||||
+ * is active.
|
||||
+ */
|
||||
+ for (index = 0; index < MV3310_N_LEDS; index++) {
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + index);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ priv->led[index] = (struct mv3310_led) {
|
||||
+ .index = index,
|
||||
+ .fw_ctrl = val,
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ if (!node)
|
||||
+ return 0;
|
||||
+
|
||||
+ pnp = of_get_child_by_name(node, "leds");
|
||||
+ if (!pnp)
|
||||
+ return 0;
|
||||
+
|
||||
+ for_each_available_child_of_node(pnp, np) {
|
||||
+ err = mv3310_led_probe_of(phydev, np);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_brightness_set(struct phy_device *phydev,
|
||||
+ u8 index, enum led_brightness value)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid;
|
||||
+ struct mv3310_led *led;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ if (value == LED_OFF)
|
||||
+ solid = MV3310_LED_FUNC_OFF;
|
||||
+ else
|
||||
+ solid = MV3310_LED_FUNC_ON;
|
||||
+
|
||||
+ return mv3310_led_set(phydev, led, solid, MV3310_LED_FUNC_OFF, false);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_blink_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct mv3310_led *led;
|
||||
+ bool slow_blink;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ if (*delay_on != *delay_off)
|
||||
+ /* Defer anything other than 50% duty cycles to
|
||||
+ * software.
|
||||
+ */
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Accept values within ~20% of our supported rates (80ms or
|
||||
+ * 1300ms periods).
|
||||
+ */
|
||||
+ if ((*delay_on >= 30) && (*delay_on <= 50))
|
||||
+ slow_blink = false;
|
||||
+ else if (((*delay_on >= 500) && (*delay_on <= 800)) || (*delay_on == 0))
|
||||
+ slow_blink = true;
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ err = mv3310_led_set(phydev, led, MV3310_LED_FUNC_OFF,
|
||||
+ MV3310_LED_FUNC_ON, slow_blink);
|
||||
+ if (!err)
|
||||
+ *delay_on = *delay_off = slow_blink ? 650 : 40;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct mv3310_led *led;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ return mv3310_led_funcs_from_flags(led, flags, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_control_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid, blink;
|
||||
+ struct mv3310_led *led;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ err = mv3310_led_funcs_from_flags(led, flags, &solid, &blink);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv3310_led_set(phydev, led, solid, blink, false);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_control_get(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid, blink;
|
||||
+ struct mv3310_led *led;
|
||||
+ bool slow_blink;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ err = mv3310_led_get(phydev, led, &solid, &blink, &slow_blink);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv3310_led_flags_from_funcs(led, solid, blink, flags);
|
||||
+}
|
||||
+
|
||||
+
|
||||
#ifdef CONFIG_HWMON
|
||||
static umode_t mv3310_hwmon_is_visible(const void *data,
|
||||
enum hwmon_sensor_types type,
|
||||
@@ -697,6 +1143,10 @@ static int mv3310_probe(struct phy_device *phydev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = mv3310_leds_probe(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
chip->init_supported_interfaces(priv->supported_interfaces);
|
||||
|
||||
return phy_sfp_probe(phydev, &mv3310_sfp_ops);
|
||||
@@ -1502,6 +1952,11 @@ static struct phy_driver mv3310_drivers[] = {
|
||||
.set_loopback = genphy_c45_loopback,
|
||||
.get_wol = mv3110_get_wol,
|
||||
.set_wol = mv3110_set_wol,
|
||||
+ .led_brightness_set = mv3310_led_brightness_set,
|
||||
+ .led_blink_set = mv3310_led_blink_set,
|
||||
+ .led_hw_is_supported = mv3310_led_hw_is_supported,
|
||||
+ .led_hw_control_set = mv3310_led_hw_control_set,
|
||||
+ .led_hw_control_get = mv3310_led_hw_control_get,
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88X3310,
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
From 913a57a304e8024f4cea872fa904cee867c469a2 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 19:44:32 +0100
|
||||
Subject: [PATCH 14/17] net: dsa: mv88e6xxx: Add LED infrastructure
|
||||
|
||||
Parse DT for LEDs and register them for devices that support it,
|
||||
though no actual implementations exist yet.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/Makefile | 1 +
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 8 +-
|
||||
drivers/net/dsa/mv88e6xxx/chip.h | 17 +++
|
||||
drivers/net/dsa/mv88e6xxx/leds.c | 184 +++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mv88e6xxx/leds.h | 12 ++
|
||||
5 files changed, 221 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/dsa/mv88e6xxx/leds.c
|
||||
create mode 100644 drivers/net/dsa/mv88e6xxx/leds.h
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
index 1409e691ab77..ab07996aeb7f 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
@@ -9,6 +9,7 @@ mv88e6xxx-objs += global2.o
|
||||
mv88e6xxx-objs += global2_avb.o
|
||||
mv88e6xxx-objs += global2_scratch.o
|
||||
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
|
||||
+mv88e6xxx-objs += leds.o
|
||||
mv88e6xxx-objs += phy.o
|
||||
mv88e6xxx-objs += port.o
|
||||
mv88e6xxx-objs += port_hidden.o
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 90dcd6c3be31..d343ea5cc4a1 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "global1.h"
|
||||
#include "global2.h"
|
||||
#include "hwtstamp.h"
|
||||
+#include "leds.h"
|
||||
#include "phy.h"
|
||||
#include "port.h"
|
||||
#include "ptp.h"
|
||||
@@ -4259,11 +4260,16 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
|
||||
|
||||
static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port)
|
||||
{
|
||||
- return mv88e6xxx_setup_devlink_regions_port(ds, port);
|
||||
+ int err = 0;
|
||||
+
|
||||
+ err = err ? : mv88e6xxx_setup_devlink_regions_port(ds, port);
|
||||
+ err = err ? : mv88e6xxx_port_setup_leds(ds, port);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port)
|
||||
{
|
||||
+ /* LED resources are devm_ managed */
|
||||
mv88e6xxx_teardown_devlink_regions_port(ds, port);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
index 268c97cde8d8..fb0d2584af1b 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
@@ -205,6 +205,7 @@ struct mv88e6xxx_irq_ops;
|
||||
struct mv88e6xxx_gpio_ops;
|
||||
struct mv88e6xxx_avb_ops;
|
||||
struct mv88e6xxx_ptp_ops;
|
||||
+struct mv88e6xxx_led_ops;
|
||||
|
||||
struct mv88e6xxx_irq {
|
||||
u16 masked;
|
||||
@@ -329,6 +330,8 @@ struct mv88e6xxx_hw_stat {
|
||||
int type;
|
||||
};
|
||||
|
||||
+struct mv88e6xxx_led;
|
||||
+
|
||||
struct mv88e6xxx_chip {
|
||||
const struct mv88e6xxx_info *info;
|
||||
|
||||
@@ -672,6 +675,9 @@ struct mv88e6xxx_ops {
|
||||
/* Precision Time Protocol operations */
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops;
|
||||
|
||||
+ /* LED operations */
|
||||
+ const struct mv88e6xxx_led_ops *led_ops;
|
||||
+
|
||||
/* Phylink */
|
||||
void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_config *config);
|
||||
@@ -748,6 +754,17 @@ struct mv88e6xxx_ptp_ops {
|
||||
u32 cc_mult_dem;
|
||||
};
|
||||
|
||||
+struct mv88e6xxx_led_ops {
|
||||
+ int (*brightness_set)(struct mv88e6xxx_led *led,
|
||||
+ enum led_brightness brightness);
|
||||
+ int (*blink_set)(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *delay_on, unsigned long *delay_off);
|
||||
+ int (*hw_control_is_supported)(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags);
|
||||
+ int (*hw_control_set)(struct mv88e6xxx_led *led, unsigned long flags);
|
||||
+ int (*hw_control_get)(struct mv88e6xxx_led *led, unsigned long *flags);
|
||||
+};
|
||||
+
|
||||
static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
return chip->info->max_sid > 0 &&
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
new file mode 100644
|
||||
index 000000000000..42e1661e1f47
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
@@ -0,0 +1,184 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "chip.h"
|
||||
+#include "port.h"
|
||||
+
|
||||
+struct mv88e6xxx_led {
|
||||
+ struct mv88e6xxx_chip *chip;
|
||||
+ int port;
|
||||
+ u8 index;
|
||||
+
|
||||
+ struct led_classdev ldev;
|
||||
+};
|
||||
+
|
||||
+static int mv88e6xxx_led_brightness_set(struct led_classdev *ldev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->brightness_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->brightness_set(led, brightness);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_blink_set(struct led_classdev *ldev,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->blink_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->blink_set(led, delay_on, delay_off);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_is_supported(struct led_classdev *ldev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_is_supported)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_is_supported(led, flags);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_set(struct led_classdev *ldev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_set(led, flags);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_get(struct led_classdev *ldev,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_get)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_get(led, flags);
|
||||
+}
|
||||
+
|
||||
+static struct device *mv88e6xxx_led_hw_control_get_device(struct led_classdev *ldev)
|
||||
+{
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+ struct dsa_port *dp;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ dp = dsa_to_port(led->chip->ds, led->port);
|
||||
+
|
||||
+ if (dp && dp->slave)
|
||||
+ return &dp->slave->dev;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_port_setup_led(struct mv88e6xxx_chip *chip, int port,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ struct led_init_data init_data = {};
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+ char *devname;
|
||||
+ u32 index;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "reg", &index);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (index >= 2)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ led = devm_kzalloc(chip->dev, sizeof(*led), GFP_KERNEL);
|
||||
+ if (!led)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *led = (struct mv88e6xxx_led) {
|
||||
+ .chip = chip,
|
||||
+ .port = port,
|
||||
+ .index = index,
|
||||
+
|
||||
+ .ldev = {
|
||||
+ .max_brightness = 1,
|
||||
+ .brightness_set_blocking = mv88e6xxx_led_brightness_set,
|
||||
+ .blink_set = mv88e6xxx_led_blink_set,
|
||||
+
|
||||
+#ifdef CONFIG_LEDS_TRIGGERS
|
||||
+ .hw_control_trigger = "netdev",
|
||||
+ .hw_control_get_device = mv88e6xxx_led_hw_control_get_device,
|
||||
+
|
||||
+ .hw_control_is_supported = mv88e6xxx_led_hw_control_is_supported,
|
||||
+ .hw_control_set = mv88e6xxx_led_hw_control_set,
|
||||
+ .hw_control_get = mv88e6xxx_led_hw_control_get,
|
||||
+#endif
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ devname = devm_kasprintf(chip->dev, GFP_KERNEL, "%s.%d",
|
||||
+ dev_name(chip->dev), port);
|
||||
+ if (!devname)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ init_data = (struct led_init_data) {
|
||||
+ .fwnode = of_fwnode_handle(np),
|
||||
+ .devname_mandatory = true,
|
||||
+ .devicename = devname,
|
||||
+ };
|
||||
+
|
||||
+ return devm_led_classdev_register_ext(chip->dev, &led->ldev, &init_data);
|
||||
+}
|
||||
+
|
||||
+int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
+ struct mv88e6xxx_chip *chip = ds->priv;
|
||||
+ struct device_node *pnp, *np;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!chip->info->ops->led_ops)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!dp->dn)
|
||||
+ return 0;
|
||||
+
|
||||
+ pnp = of_get_child_by_name(dp->dn, "leds");
|
||||
+ if (!pnp)
|
||||
+ return 0;
|
||||
+
|
||||
+ for_each_available_child_of_node(pnp, np) {
|
||||
+ err = mv88e6xxx_port_setup_led(chip, port, np);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.h b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
new file mode 100644
|
||||
index 000000000000..8afa2a0c0527
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
@@ -0,0 +1,12 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+
|
||||
+/* Marvell 88E6xxx Switch leds support. */
|
||||
+
|
||||
+#ifndef _MV88E6XXX_LEDS_H
|
||||
+#define _MV88E6XXX_LEDS_H
|
||||
+
|
||||
+#include "chip.h"
|
||||
+
|
||||
+int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port);
|
||||
+
|
||||
+#endif /* _MV88E6XXX_LEDS_H */
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
From 8510028fa738493a46b235057ed166f9bbbf0ed4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 21:59:35 +0100
|
||||
Subject: [PATCH 15/17] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
|
||||
Trigger support:
|
||||
- "none"
|
||||
- "timer"
|
||||
- "netdev"
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
|
||||
drivers/net/dsa/mv88e6xxx/leds.c | 226 +++++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mv88e6xxx/leds.h | 2 +
|
||||
drivers/net/dsa/mv88e6xxx/port.c | 33 +++++
|
||||
drivers/net/dsa/mv88e6xxx/port.h | 7 +
|
||||
5 files changed, 269 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index d343ea5cc4a1..7d6b2b85fc31 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -5833,6 +5833,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
+ .led_ops = &mv88e6393x_led_ops,
|
||||
.phylink_get_caps = mv88e6393x_phylink_get_caps,
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
index 42e1661e1f47..b2a55d96b506 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
@@ -4,6 +4,13 @@
|
||||
#include "chip.h"
|
||||
#include "port.h"
|
||||
|
||||
+#define FLAG_ACT (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX))
|
||||
+#define FLAG_LINK BIT(TRIGGER_NETDEV_LINK)
|
||||
+#define FLAG_LINK_10 BIT(TRIGGER_NETDEV_LINK_10)
|
||||
+#define FLAG_LINK_100 BIT(TRIGGER_NETDEV_LINK_100)
|
||||
+#define FLAG_LINK_1G BIT(TRIGGER_NETDEV_LINK_1000)
|
||||
+#define FLAG_FULL BIT(TRIGGER_NETDEV_FULL_DUPLEX)
|
||||
+
|
||||
struct mv88e6xxx_led {
|
||||
struct mv88e6xxx_chip *chip;
|
||||
int port;
|
||||
@@ -12,6 +19,225 @@ struct mv88e6xxx_led {
|
||||
struct led_classdev ldev;
|
||||
};
|
||||
|
||||
+enum mv88e6393x_led_mode {
|
||||
+ MV88E6393X_LED_MODE_BLINK = 0xd,
|
||||
+ MV88E6393X_LED_MODE_OFF = 0xe,
|
||||
+ MV88E6393X_LED_MODE_ON = 0xf,
|
||||
+
|
||||
+ MV88E6393X_LED_MODES = 0x10
|
||||
+};
|
||||
+
|
||||
+static const unsigned long mv88e6393x_led_map_p1_p8[2][MV88E6393X_LED_MODES] = {
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT | FLAG_LINK_100 | FLAG_LINK_1G,
|
||||
+ [0x2] = FLAG_ACT | FLAG_LINK_1G,
|
||||
+ [0x3] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x6] = FLAG_FULL,
|
||||
+ [0x7] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x8] = FLAG_LINK,
|
||||
+ [0x9] = FLAG_LINK_10,
|
||||
+ [0xa] = FLAG_ACT | FLAG_LINK_10,
|
||||
+ [0xb] = FLAG_LINK_100 | FLAG_LINK_1G,
|
||||
+ },
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT,
|
||||
+ [0x2] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_100,
|
||||
+ [0x3] = FLAG_LINK_1G,
|
||||
+ [0x5] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x6] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x7] = FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x9] = FLAG_LINK_100,
|
||||
+ [0xa] = FLAG_ACT | FLAG_LINK_100,
|
||||
+ [0xb] = FLAG_LINK_10 | FLAG_LINK_100,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const unsigned long mv88e6393x_led_map_p9_p10[2][MV88E6393X_LED_MODES] = {
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT | FLAG_LINK,
|
||||
+ },
|
||||
+ {
|
||||
+ [0x6] = FLAG_FULL,
|
||||
+ [0x7] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x8] = FLAG_LINK,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+const unsigned long *mv88e6393x_led_map(struct mv88e6xxx_led *led)
|
||||
+{
|
||||
+ switch (led->port) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 3:
|
||||
+ case 4:
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ case 7:
|
||||
+ case 8:
|
||||
+ return mv88e6393x_led_map_p1_p8[led->index];
|
||||
+ case 9:
|
||||
+ case 10:
|
||||
+ return mv88e6393x_led_map_p9_p10[led->index];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_flags_to_mode(struct mv88e6xxx_led *led, unsigned long flags)
|
||||
+{
|
||||
+ const unsigned long *map = mv88e6393x_led_map(led);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (!flags)
|
||||
+ return MV88E6393X_LED_MODE_OFF;
|
||||
+
|
||||
+ for (i = 0; i < MV88E6393X_LED_MODES; i++) {
|
||||
+ if (map[i] == flags)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_mode_to_flags(struct mv88e6xxx_led *led, u8 mode,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ const unsigned long *map = mv88e6393x_led_map(led);
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (mode == MV88E6393X_LED_MODE_OFF) {
|
||||
+ *flags = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (map[mode]) {
|
||||
+ *flags = map[mode];
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_set(struct mv88e6xxx_led *led, int mode)
|
||||
+{
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ mv88e6xxx_reg_lock(led->chip);
|
||||
+
|
||||
+ err = mv88e6393x_port_led_read(led->chip, led->port, 0, &ctrl);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (led->index) {
|
||||
+ case 0:
|
||||
+ ctrl &= ~0x0f;
|
||||
+ ctrl |= mode;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ ctrl &= ~0xf0;
|
||||
+ ctrl |= mode << 4;
|
||||
+ }
|
||||
+
|
||||
+ err = mv88e6393x_port_led_write(led->chip, led->port, 0, ctrl);
|
||||
+out:
|
||||
+ mv88e6xxx_reg_unlock(led->chip);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_get(struct mv88e6xxx_led *led)
|
||||
+{
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ mv88e6xxx_reg_lock(led->chip);
|
||||
+ err = mv88e6393x_port_led_read(led->chip, led->port, 0, &ctrl);
|
||||
+ mv88e6xxx_reg_unlock(led->chip);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ switch (led->index) {
|
||||
+ case 0:
|
||||
+ return ctrl & 0xf;
|
||||
+ case 1:
|
||||
+ return (ctrl >> 4) & 0xf;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_brightness_set(struct mv88e6xxx_led *led,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ if (brightness == LED_OFF)
|
||||
+ return mv88e6393x_led_set(led, MV88E6393X_LED_MODE_OFF);
|
||||
+
|
||||
+ return mv88e6393x_led_set(led, MV88E6393X_LED_MODE_ON);
|
||||
+}
|
||||
+static int mv88e6393x_led_blink_set(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ /* Defer anything other than 50% duty cycles to software */
|
||||
+ if (*delay_on != *delay_off)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Reject values outside ~20% of our default rate (84ms) */
|
||||
+ if (*delay_on && ((*delay_on < 30) || (*delay_on > 50)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ err = mv88e6393x_led_set(led, MV88E6393X_LED_MODE_BLINK);
|
||||
+ if (!err)
|
||||
+ *delay_on = *delay_off = 42;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_is_supported(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_flags_to_mode(led, flags);
|
||||
+
|
||||
+ return (mode < 0) ? mode : 0;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_set(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_flags_to_mode(led, flags);
|
||||
+
|
||||
+ return mv88e6393x_led_set(led, mode);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_get(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_get(led);
|
||||
+
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ return mv88e6393x_led_mode_to_flags(led, mode, flags);
|
||||
+}
|
||||
+
|
||||
+const struct mv88e6xxx_led_ops mv88e6393x_led_ops = {
|
||||
+ .brightness_set = mv88e6393x_led_brightness_set,
|
||||
+ .blink_set = mv88e6393x_led_blink_set,
|
||||
+ .hw_control_is_supported = mv88e6393x_led_hw_control_is_supported,
|
||||
+ .hw_control_set = mv88e6393x_led_hw_control_set,
|
||||
+ .hw_control_get = mv88e6393x_led_hw_control_get,
|
||||
+};
|
||||
+
|
||||
static int mv88e6xxx_led_brightness_set(struct led_classdev *ldev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.h b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
index 8afa2a0c0527..542345d23dc5 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
+extern const struct mv88e6xxx_led_ops mv88e6393x_led_ops;
|
||||
+
|
||||
int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port);
|
||||
|
||||
#endif /* _MV88E6XXX_LEDS_H */
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
|
||||
index dd66ec902d4c..e6733a3ab19f 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/port.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/port.c
|
||||
@@ -1569,6 +1569,39 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
|
||||
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
|
||||
}
|
||||
|
||||
+/* Offset 0x16: LED Control Register */
|
||||
+
|
||||
+int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 data)
|
||||
+{
|
||||
+ u16 cmd = BIT(15) | ((pointer & 0x7) << 12) | (data & 0x7ff);
|
||||
+ int err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_LED_CONTROL, cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv88e6xxx_port_wait_bit(chip, port, MV88E6393X_PORT_LED_CONTROL, 15, 0);
|
||||
+}
|
||||
+
|
||||
+int mv88e6393x_port_led_read(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 *data)
|
||||
+{
|
||||
+ u16 cmd = (pointer & 0x7) << 12;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_LED_CONTROL, cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_read(chip, port, MV88E6393X_PORT_LED_CONTROL, &cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ *data = cmd & 0x7ff;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
|
||||
* Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
|
||||
*/
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
|
||||
index 86deeb347cbc..3605a59d1399 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/port.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/port.h
|
||||
@@ -294,6 +294,9 @@
|
||||
/* Offset 0x13: OutFiltered Counter */
|
||||
#define MV88E6XXX_PORT_OUT_FILTERED 0x13
|
||||
|
||||
+/* Offset 0x16: LED Control Register */
|
||||
+#define MV88E6393X_PORT_LED_CONTROL 0x16
|
||||
+
|
||||
/* Offset 0x18: IEEE Priority Mapping Table */
|
||||
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18
|
||||
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000
|
||||
@@ -410,6 +413,10 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
|
||||
enum mv88e6xxx_policy_action action);
|
||||
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
|
||||
u16 etype);
|
||||
+int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 data);
|
||||
+int mv88e6393x_port_led_read(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 *data);
|
||||
int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
|
||||
enum mv88e6xxx_egress_direction direction,
|
||||
int port);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From b70f0aa3eb77567a057c2f42f5012a3e009a95c8 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 21 Nov 2023 20:15:24 +0100
|
||||
Subject: [PATCH 16/17] net: phy: marvell10g: Fix power-up when strapped to
|
||||
start powered down
|
||||
|
||||
On devices which are hardware strapped to start powered down (PDSTATE
|
||||
== 1), make sure that we clear the power-down bit on all units
|
||||
affected by this setting.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/phy/marvell10g.c | 18 +++++++++++++++---
|
||||
1 file changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
|
||||
index 05ad7c769e24..1d86ee10650e 100644
|
||||
--- a/drivers/net/phy/marvell10g.c
|
||||
+++ b/drivers/net/phy/marvell10g.c
|
||||
@@ -782,11 +782,23 @@ static int mv3310_power_down(struct phy_device *phydev)
|
||||
|
||||
static int mv3310_power_up(struct phy_device *phydev)
|
||||
{
|
||||
+ static const u16 resets[][2] = {
|
||||
+ { MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_CTRL1 },
|
||||
+ { MDIO_MMD_PCS, MV_PCS_1000BASEX + MDIO_CTRL1 },
|
||||
+ { MDIO_MMD_PCS, MV_PCS_BASE_T + MDIO_CTRL1 },
|
||||
+ { MDIO_MMD_PMAPMD, MDIO_CTRL1 },
|
||||
+ { MDIO_MMD_VEND2, MV_V2_PORT_CTRL },
|
||||
+ };
|
||||
struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
- int ret;
|
||||
+ int i, ret;
|
||||
|
||||
- ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
|
||||
- MV_V2_PORT_CTRL_PWRDOWN);
|
||||
+ for (i = 0; i < ARRAY_SIZE(resets); i++) {
|
||||
+ ret = phy_clear_bits_mmd(phydev, resets[i][0], resets[i][1],
|
||||
+ MV_V2_PORT_CTRL_PWRDOWN);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
|
||||
/* Sometimes, the power down bit doesn't clear immediately, and
|
||||
* a read of this register causes the bit not to clear. Delay
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From dd693e037f0dd799e77af397b4d23190b66e9cf1 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Fri, 24 Nov 2023 23:29:55 +0100
|
||||
Subject: [PATCH 17/17] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
TLV is invalid
|
||||
|
||||
Before this change, probing an NVMEM device, expected to contain a
|
||||
valid TLV, would fail if it had not been provisioned yet. But an
|
||||
obvious way of provisioning is to write the TLV to the nvmem
|
||||
attribute, which would not be possible because the device would not
|
||||
be successfully probed.
|
||||
|
||||
Therefore, settle for reporting data corruption issues in the log, and
|
||||
simply refrain from registering any cells in those cases.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/nvmem/layouts/onie-tlv.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/nvmem/layouts/onie-tlv.c b/drivers/nvmem/layouts/onie-tlv.c
|
||||
index 59fc87ccfcff..834c46e46d0a 100644
|
||||
--- a/drivers/nvmem/layouts/onie-tlv.c
|
||||
+++ b/drivers/nvmem/layouts/onie-tlv.c
|
||||
@@ -196,7 +196,7 @@ static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
|
||||
|
||||
if (!onie_tlv_hdr_is_valid(dev, &hdr)) {
|
||||
dev_err(dev, "Invalid ONIE TLV header\n");
|
||||
- return -EINVAL;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len);
|
||||
@@ -204,7 +204,7 @@ static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
|
||||
table_len = hdr_len + data_len;
|
||||
if (table_len > ONIE_TLV_MAX_LEN) {
|
||||
dev_err(dev, "Invalid ONIE TLV data length\n");
|
||||
- return -EINVAL;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
table = devm_kmalloc(dev, table_len, GFP_KERNEL);
|
||||
@@ -216,7 +216,7 @@ static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem,
|
||||
return ret;
|
||||
|
||||
if (!onie_tlv_crc_is_valid(dev, table_len, table))
|
||||
- return -EINVAL;
|
||||
+ return 0;
|
||||
|
||||
data = table + hdr_len;
|
||||
ret = onie_tlv_add_cells(dev, nvmem, data_len, data);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
--- a/agent/snmpd.c 2023-11-10 08:51:59.539942616 +0100
|
||||
+++ b/agent/snmpd.c 2023-11-10 08:56:27.719112830 +0100
|
||||
@@ -179,6 +179,7 @@
|
||||
#define TIMETICK 500000L
|
||||
|
||||
int snmp_dump_packet;
|
||||
+static char *pid_file = NULL;
|
||||
static int reconfig = 0;
|
||||
int Facility = LOG_DAEMON;
|
||||
|
||||
@@ -397,7 +398,6 @@
|
||||
int dont_fork = 0, do_help = 0;
|
||||
int log_set = 0;
|
||||
int agent_mode = -1;
|
||||
- char *pid_file = NULL;
|
||||
char option_compatability[] = "-Le";
|
||||
#ifndef WIN32
|
||||
int prepared_sockets = 0;
|
||||
@@ -1174,6 +1174,10 @@
|
||||
ret = sigprocmask(SIG_UNBLOCK, &set, NULL);
|
||||
netsnmp_assert(ret == 0);
|
||||
#endif
|
||||
+ if (pid_file) {
|
||||
+ /* Signal readiness after reconf (Finit) */
|
||||
+ utimensat(0, pid_file, NULL, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
/*******************************************************************-o-******
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user