mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-26 18:53:01 +02:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1854bca98b | ||
|
|
00261fb120 | ||
|
|
4a69d1564d |
+20
-36
@@ -11,7 +11,7 @@ Talking about code and problems first is often the best way to get started
|
|||||||
before submitting a pull request.
|
before submitting a pull request.
|
||||||
|
|
||||||
When submitting a bug report, patch, or pull request, please start by
|
When submitting a bug report, patch, or pull request, please start by
|
||||||
stating the version the change is made against, what it does, *and why*.
|
stating the version the change is made against, what it does, and why.
|
||||||
|
|
||||||
Please take care to ensure you follow the project coding style and the
|
Please take care to ensure you follow the project coding style and the
|
||||||
commit message format. If you follow these recommendations you help
|
commit message format. If you follow these recommendations you help
|
||||||
@@ -21,28 +21,13 @@ the maintainer(s) and make it easier for them to include your code.
|
|||||||
Coding Style
|
Coding Style
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Before jumping into code, remember to **document new features** and bug
|
> **Tip:** Always submit code that follows the style of surrounding code!
|
||||||
fixes. Both the manual and ChangeLog are in the `doc/` sub-directory
|
|
||||||
and it is expected that you provide a human-readable summary for the
|
|
||||||
release notes (ChangeLog) and at least a configuration example in the
|
|
||||||
manual for new features.
|
|
||||||
|
|
||||||
> **Tip:** consider ["Readme driven development"][RDD] for new features.
|
First of all, lines are allowed to be longer than 72 characters these
|
||||||
> It is amazing how many flaws in your own bright ideas come to bare
|
days. In fact, there exist no enforced maximum, but keeping it around
|
||||||
> when you suddenly have to explain them to someone else!
|
100 chars is OK.
|
||||||
|
|
||||||
We expect code contributions for:
|
The coding style itself is otherwise strictly Linux [KNF][].
|
||||||
|
|
||||||
- C code in [Linux Coding Style][Linux]
|
|
||||||
- Python code should follow [PEP-8][]
|
|
||||||
|
|
||||||
> **However,** always submit code that follows the style of surrounding
|
|
||||||
> code! Legacy takes precedence, and remember, we read code a lot more
|
|
||||||
> than write it, so legibility is important.
|
|
||||||
|
|
||||||
As a final note, lines are allowed to be longer than 72 characters these
|
|
||||||
days. There is no enforced maximum, but the team usually keep it around
|
|
||||||
100 characters for both C and Python.
|
|
||||||
|
|
||||||
|
|
||||||
Commit Messages
|
Commit Messages
|
||||||
@@ -52,21 +37,22 @@ Commit messages exist to track *why* a change was made. Try to be as
|
|||||||
clear and concise as possible in your commit messages, and always, be
|
clear and concise as possible in your commit messages, and always, be
|
||||||
proud of your work and set up a proper GIT identity for your commits:
|
proud of your work and set up a proper GIT identity for your commits:
|
||||||
|
|
||||||
$ git config --global user.name "Jacky Linker"
|
git config --global user.name "Jane Doe"
|
||||||
$ git config --global user.email jacky.linker@example.com
|
git config --global user.email jane.doe@example.com
|
||||||
|
|
||||||
Example commit message from the [Pro Git][gitbook] online book, notice
|
Example commit message from the [Pro Git][gitbook] online book, notice
|
||||||
how `git commit -s` is used to automatically add a `Signed-off-by`:
|
how `git commit -s` is used to automatically add a `Signed-off-by`:
|
||||||
|
|
||||||
subsystem: brief, but clear and concise summary of changes
|
Brief, but clear and concise summary of changes
|
||||||
|
|
||||||
More detailed explanatory text, if necessary. Wrap it to about 72
|
More detailed explanatory text, if necessary. Wrap it to about 72
|
||||||
characters or so. In some contexts, the first line is treated as
|
characters or so. In some contexts, the first line is treated as
|
||||||
the subject of an email and the rest of the text as the body. The
|
the subject of an email and the rest of the text as the body. The
|
||||||
empty line separating summary from body is critical. Tools like
|
blank line separating the ummary from the body is critical (unless
|
||||||
rebase can get confused if the empty line is missing.
|
you omit the body entirely); tools like rebase can get confused if
|
||||||
|
you run the two together.
|
||||||
|
|
||||||
Further paragraphs should be separated with empty lines.
|
Further paragraphs come after blank lines.
|
||||||
|
|
||||||
- Bullet points are okay, too
|
- Bullet points are okay, too
|
||||||
|
|
||||||
@@ -74,19 +60,17 @@ how `git commit -s` is used to automatically add a `Signed-off-by`:
|
|||||||
by a single space, with blank lines in between, but conventions
|
by a single space, with blank lines in between, but conventions
|
||||||
vary here
|
vary here
|
||||||
|
|
||||||
Signed-off-by: Jacky Linker <jacky.linker@example.com>
|
Signed-off-by: Jane Doe <jane.doe@example.com>
|
||||||
|
|
||||||
|
|
||||||
Code of Conduct
|
Code of Conduct
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
It is expected of everyone to respect the [Code of Conduct][conduct].
|
It is expected of everyone to respect the [Code of Conduct][conduct].
|
||||||
The *"maintainers have the right and responsibility to remove, edit, or
|
The *"maintainers have the right and responsibility to remove, edit,
|
||||||
reject comments, commits, code, discussion forum threads, issues, and
|
or reject comments, commits, code, wiki edits, issues, and other
|
||||||
other contributions that are not aligned to this Code of Conduct."*
|
contributions that are not aligned to this Code of Conduct."*
|
||||||
|
|
||||||
[Linux]: https://www.kernel.org/doc/html/v6.9/process/coding-style.html
|
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
|
||||||
[PEP-8]: https://peps.python.org/pep-0008/
|
[gitbook]: https://git-scm.com/book/ch5-2.html
|
||||||
[RDD]: https://tom.preston-werner.com/2010/08/23/readme-driven-development
|
[conduct]: CODE-OF-CONDUCT.md
|
||||||
[gitbook]: https://git-scm.com/book/ch5-2.html
|
|
||||||
[conduct]: CODE-OF-CONDUCT.md
|
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
|
||||||
name: "\U0001F41E Bug report"
|
|
||||||
description: Create a bug report
|
|
||||||
labels:
|
|
||||||
- "bug"
|
|
||||||
- "triage"
|
|
||||||
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
**Thank :heart: you for taking the time to fill out this bug report!**
|
|
||||||
|
|
||||||
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for the bug you encountered.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Current Behavior
|
|
||||||
description: |
|
|
||||||
A clear and concise description of the issue you're experiencing.
|
|
||||||
value: |
|
|
||||||
For code snippets, logs, commands, etc., please use triple backticks:
|
|
||||||
```
|
|
||||||
admin@infix-c0-ff-ee:/> show log
|
|
||||||
May 15 07:21:02 infix-00-00-00 container[3192]: Failed creating container test from curios-httpd-v24.03.0
|
|
||||||
- (press h for help or q to quit)
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Expected Behavior
|
|
||||||
description: |
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
value: |
|
|
||||||
```
|
|
||||||
admin@infix-c0-ff-ee:/> show log
|
|
||||||
May 15 07:21:02 infix-c0-ff-ee container[3192]: Successfully created container test from curios-httpd-v24.03.0
|
|
||||||
- (press h for help or q to quit)
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Steps To Reproduce
|
|
||||||
description: |
|
|
||||||
Steps to reproduce the issue. For example:
|
|
||||||
|
|
||||||
1. Built from source
|
|
||||||
2. Upgrade to latest release, vYY.MM.P
|
|
||||||
3. Factory reset
|
|
||||||
4. Enable feature
|
|
||||||
5. Check the logs/show command/operational status
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Additional information
|
|
||||||
description: |
|
|
||||||
- Relevant parts of `startup-config`
|
|
||||||
- Output from `show interfaces`, if applicable
|
|
||||||
- Other observations, screenshots, log files ...
|
|
||||||
|
|
||||||
**Tip:** You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
contact_links:
|
|
||||||
- name: "🔍 Look for my Issue"
|
|
||||||
url: https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+
|
|
||||||
about: Thank ❤️ you for your time! We kindly ask that you first check if an issue already exists.
|
|
||||||
- name: "💬 Discussions and Q&A"
|
|
||||||
url: https://github.com/kernelkit/infix/discussions
|
|
||||||
about: Discussions are perfect for quick questions, bouncing ideas, and things that may be a bug.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
|
||||||
name: "\U0001F6E0️ Feature request"
|
|
||||||
description: Suggest a new feature, idea or improvement of the OS
|
|
||||||
labels:
|
|
||||||
- "feature"
|
|
||||||
- "triage"
|
|
||||||
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
**Thank :heart: you for taking the time to fill out this feature request!**
|
|
||||||
|
|
||||||
We kindly ask that you search to see if an issue [already exists](https://github.com/kernelkit/infix/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature. We are also happy to accept contributions from our users. For details see [CONTRIBUTING](https://github.com/kernelkit/infix/blob/master/.github/CONTRIBUTING.md).
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
||||||
description: |
|
|
||||||
A clear and concise description of the problem or missing feature.
|
|
||||||
**Example:** *I'm always frustrated when [...]*, or *I'd like to see support for [...]*
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Additional Information
|
|
||||||
description: |
|
|
||||||
Any other related information, e.g. existing YANG model(s), or possibly screenshots about the feature request here.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: General Information
|
|
||||||
description: |
|
|
||||||
Appended to all feature requests for future readers.
|
|
||||||
value: |
|
|
||||||
Anyone can help out by [sponsoring][1] development of new features or [contributing][2] pull requests.
|
|
||||||
Please use this issue for discussions related to the feature.
|
|
||||||
|
|
||||||
[1]: https://github.com/kernelkit/infix/blob/main/.github/SUPPORT.md
|
|
||||||
[2]: https://github.com/kernelkit/infix/blob/main/.github/CONTRIBUTING.md
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<!--- **Summarize** your changes in the title above -->
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -13,7 +15,7 @@
|
|||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
Tick *relevant* boxes, this PR is-a or has-a:
|
Tick relevant boxes, this PR is-a or has-a:
|
||||||
|
|
||||||
- [ ] Bugfix
|
- [ ] Bugfix
|
||||||
- [ ] Regression tests
|
- [ ] Regression tests
|
||||||
@@ -29,3 +31,7 @@ Tick *relevant* boxes, this PR is-a or has-a:
|
|||||||
- [ ] Documentation content changes
|
- [ ] Documentation content changes
|
||||||
- [ ] Other (please describe):
|
- [ ] Other (please describe):
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
<!-- Please list references to related issue(s) -->
|
||||||
|
|||||||
+27
-26
@@ -8,25 +8,30 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Infix ${{ matrix.target }}
|
name: Build Infix ${{ matrix.platform }}
|
||||||
runs-on: [ self-hosted, latest ]
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [aarch64, x86_64]
|
platform: [aarch64, x86_64]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
|
- name: Maintenance
|
||||||
|
run: |
|
||||||
|
docker image prune -af
|
||||||
|
docker volume prune -f
|
||||||
|
docker container prune -f
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
clean: true
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Set Build Variables
|
- name: Set Build Variables
|
||||||
id: vars
|
id: vars
|
||||||
run: |
|
run: |
|
||||||
target=${{ matrix.target }}
|
target=${{ matrix.platform }}
|
||||||
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
||||||
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
||||||
|
if [ "$target" = x86_64 ]; then
|
||||||
|
echo "out=$PWD/output" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "out=/mnt/x-$target" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
- name: Restore Cache of dl/
|
- name: Restore Cache of dl/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@@ -34,45 +39,43 @@ jobs:
|
|||||||
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
dl-
|
dl-
|
||||||
|
|
||||||
- name: Restore Cache of .ccache/
|
- name: Restore Cache of .ccache/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .ccache/
|
path: .ccache/
|
||||||
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
key: ccache-${{ matrix.platform }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
ccache-${{ matrix.target }}-
|
ccache-${{ matrix.platform }}-
|
||||||
ccache-
|
ccache-
|
||||||
|
|
||||||
- name: Configure & Build
|
- name: Configure & Build
|
||||||
run: |
|
run: |
|
||||||
target=${{ matrix.target }}_defconfig
|
target=${{ matrix.platform }}_defconfig
|
||||||
echo "Building $target ..."
|
echo "Building $target ..."
|
||||||
|
sudo mkdir ${{ steps.vars.outputs.out }}
|
||||||
|
sudo chown $(id -un):$(id -gn) ${{ steps.vars.outputs.out }}
|
||||||
|
export O=${{ steps.vars.outputs.out }}
|
||||||
make $target
|
make $target
|
||||||
make
|
make
|
||||||
|
|
||||||
- name: Prepare Artifact
|
- name: Prepare Artifact
|
||||||
run: |
|
run: |
|
||||||
cd output/
|
cd ${{ steps.vars.outputs.out }}
|
||||||
mv images ${{ steps.vars.outputs.dir }}
|
mv images ${{ steps.vars.outputs.dir }}
|
||||||
ln -s ${{ steps.vars.outputs.dir }} images
|
ln -s ${{ steps.vars.outputs.dir }} images
|
||||||
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
if: matrix.target == 'x86_64'
|
if: matrix.platform == 'x86_64'
|
||||||
run: |
|
run: |
|
||||||
make test
|
export O=${{ steps.vars.outputs.out }}
|
||||||
|
make test-qeneth
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: output/${{ steps.vars.outputs.tgz }}
|
path: ${{ steps.vars.outputs.out }}/${{ steps.vars.outputs.tgz }}
|
||||||
name: artifact-${{ matrix.target }}
|
name: artifact-${{ matrix.platform }}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
if: ${{github.repository_owner == 'kernelkit' && github.ref_name == 'main'}}
|
if: ${{github.repository_owner == 'kernelkit' && github.ref_name == 'main'}}
|
||||||
name: Upload Latest Build
|
name: Upload Latest Build
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: [ self-hosted, latest ]
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
@@ -80,7 +83,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
pattern: "artifact-*"
|
pattern: "artifact-*"
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- uses: ncipollo/release-action@v1
|
- uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
@@ -91,7 +93,6 @@ jobs:
|
|||||||
tag: "latest"
|
tag: "latest"
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
artifacts: "*.tar.gz"
|
artifacts: "*.tar.gz"
|
||||||
|
|
||||||
- name: Summary
|
- name: Summary
|
||||||
run: |
|
run: |
|
||||||
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ jobs:
|
|||||||
--post-data "token=$TOKEN&project=${PROJECT_NAME}&md5=1" \
|
--post-data "token=$TOKEN&project=${PROJECT_NAME}&md5=1" \
|
||||||
-O coverity-latest.tar.gz.md5
|
-O coverity-latest.tar.gz.md5
|
||||||
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
|
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
@@ -34,7 +33,6 @@ jobs:
|
|||||||
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
||||||
${{ runner.os }}-coverity-
|
${{ runner.os }}-coverity-
|
||||||
${{ runner.os }}-coverity
|
${{ runner.os }}-coverity
|
||||||
|
|
||||||
- name: Download Coverity Scan
|
- name: Download Coverity Scan
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
@@ -49,14 +47,12 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
mkdir coverity
|
mkdir coverity
|
||||||
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
|
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
|
sudo apt-get -y install pkg-config libjansson-dev libev-dev \
|
||||||
libaugeas-dev libglib2.0-dev libpcre2-dev \
|
libaugeas-dev libglib2.0-dev libpcre2-dev \
|
||||||
libuev-dev libite-dev
|
libuev-dev libite-dev
|
||||||
|
|
||||||
- name: Build dependencies
|
- name: Build dependencies
|
||||||
run: |
|
run: |
|
||||||
git clone https://github.com/CESNET/libyang.git
|
git clone https://github.com/CESNET/libyang.git
|
||||||
@@ -66,12 +62,10 @@ jobs:
|
|||||||
mkdir sysrepo/build
|
mkdir sysrepo/build
|
||||||
(cd sysrepo/build && cmake .. && make all && sudo make install)
|
(cd sysrepo/build && cmake .. && make all && sudo make install)
|
||||||
make dep
|
make dep
|
||||||
|
|
||||||
- name: Check applications
|
- name: Check applications
|
||||||
run: |
|
run: |
|
||||||
export PATH=`pwd`/coverity/bin:$PATH
|
export PATH=`pwd`/coverity/bin:$PATH
|
||||||
cov-build --dir cov-int make check
|
cov-build --dir cov-int make check
|
||||||
|
|
||||||
- name: Submit results to Coverity Scan
|
- name: Submit results to Coverity Scan
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
@@ -84,7 +78,6 @@ jobs:
|
|||||||
--form version=$(git rev-parse HEAD) \
|
--form version=$(git rev-parse HEAD) \
|
||||||
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
||||||
https://scan.coverity.com/builds?project=${PROJECT_NAME}
|
https://scan.coverity.com/builds?project=${PROJECT_NAME}
|
||||||
|
|
||||||
- name: Upload build.log
|
- name: Upload build.log
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -15,78 +15,61 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Regression Testing ${{ matrix.target }}
|
name: Regression Testing
|
||||||
runs-on: [ self-hosted, regression ]
|
runs-on: self-hosted
|
||||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
target: [aarch64, x86_64]
|
|
||||||
fail-fast: false
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
clean: true
|
submodules: 'true'
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Clean up cruft ...
|
- name: Clean up cruft ...
|
||||||
run: |
|
run: |
|
||||||
./test/env -c
|
./test/env -c
|
||||||
|
|
||||||
- name: Set Build Variables
|
- name: Set Build Variables
|
||||||
id: vars
|
id: vars
|
||||||
run: |
|
run: |
|
||||||
target=${{ matrix.target }}
|
target=x86_64
|
||||||
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
||||||
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Restore Cache of dl/
|
- name: Restore Cache of dl/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: dl/
|
path: dl/
|
||||||
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
key: dl-netconf-${{ hashFiles('.git/modules/buildroot/refs/heads/master', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
|
dl-netconf-
|
||||||
dl-
|
dl-
|
||||||
|
|
||||||
- name: Restore Cache of .ccache/
|
- name: Restore Cache of .ccache/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .ccache/
|
path: .ccache/
|
||||||
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
key: ccache-x86_64-${{ hashFiles('.git/modules/buildroot/refs/head/master', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
ccache-${{ matrix.target }}-
|
ccache-x86_64-
|
||||||
ccache-
|
ccache-
|
||||||
|
- name: Configure NETCONF
|
||||||
- name: Configure ${{ matrix.target }}
|
|
||||||
run: |
|
run: |
|
||||||
target=${{ matrix.target }}_defconfig
|
make x86_64_defconfig
|
||||||
echo "Building $target ..."
|
|
||||||
make $target
|
|
||||||
|
|
||||||
- name: Unit Test
|
- name: Unit Test
|
||||||
run: |
|
run: make test-unit
|
||||||
make test-unit
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
make
|
make
|
||||||
|
|
||||||
- name: Prepare Artifact
|
- name: Prepare Artifact
|
||||||
run: |
|
run: |
|
||||||
cd output/
|
cd output
|
||||||
mv images ${{ steps.vars.outputs.dir }}
|
mv images ${{ steps.vars.outputs.dir }}
|
||||||
ln -s ${{ steps.vars.outputs.dir }} images
|
ln -s ${{ steps.vars.outputs.dir }} images
|
||||||
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: output/${{ steps.vars.outputs.tgz }}
|
path: output/${{ steps.vars.outputs.tgz }}
|
||||||
name: artifact-${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Regression Test
|
- name: Regression Test
|
||||||
if: matrix.target == 'x86_64'
|
run: make test-qeneth
|
||||||
run: |
|
|
||||||
make test
|
|
||||||
|
|
||||||
- name: Publish Test Result
|
- name: Publish Test Result
|
||||||
# Ensure this runs even if Regression Test fails
|
# Ensure this runs even if Regression Test fails
|
||||||
|
|||||||
@@ -20,18 +20,19 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository == 'kernelkit/infix' && startsWith(github.ref, 'refs/tags/')
|
if: github.repository == 'kernelkit/infix' && startsWith(github.ref, 'refs/tags/')
|
||||||
name: Build Infix ${{ github.ref_name }} [${{ matrix.target }}]
|
name: Build Infix ${{ github.ref_name }} [${{ matrix.platform }}]
|
||||||
runs-on: [ self-hosted, release ]
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [aarch64, x86_64]
|
platform: [aarch64, x86_64]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
|
- name: Maintenance
|
||||||
|
run: |
|
||||||
|
docker image prune -af
|
||||||
|
docker volume prune -f
|
||||||
|
docker container prune -f
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
clean: true
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Set Release Variables
|
- name: Set Release Variables
|
||||||
id: vars
|
id: vars
|
||||||
run: |
|
run: |
|
||||||
@@ -42,10 +43,10 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "ver=${ver}" >> $GITHUB_OUTPUT
|
echo "ver=${ver}" >> $GITHUB_OUTPUT
|
||||||
fver=${ver#v}
|
fver=${ver#v}
|
||||||
target=${{ matrix.target }}-${fver}
|
target=${{ matrix.platform }}-${fver}
|
||||||
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
||||||
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
||||||
|
echo "out=/mnt/x-$target" >> $GITHUB_OUTPUT
|
||||||
- name: Restore Cache of dl/
|
- name: Restore Cache of dl/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@@ -53,55 +54,49 @@ jobs:
|
|||||||
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
dl-
|
dl-
|
||||||
|
|
||||||
- name: Restore Cache of .ccache/
|
- name: Restore Cache of .ccache/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .ccache/
|
path: .ccache/
|
||||||
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
key: ccache-${{ matrix.platform }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
ccache-${{ matrix.target }}-
|
ccache-${{ matrix.platform }}-
|
||||||
ccache-
|
ccache-
|
||||||
|
|
||||||
- name: Configure & Build
|
- name: Configure & Build
|
||||||
env:
|
env:
|
||||||
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
|
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
|
||||||
run: |
|
run: |
|
||||||
target=${{ matrix.target }}_defconfig
|
target=${{ matrix.platform }}_defconfig
|
||||||
echo "Building $target ..."
|
echo "Building $target ..."
|
||||||
|
sudo mkdir ${{ steps.vars.outputs.out }}
|
||||||
|
sudo chown $(id -un):$(id -gn) ${{ steps.vars.outputs.out }}
|
||||||
|
export O=${{ steps.vars.outputs.out }}
|
||||||
make $target
|
make $target
|
||||||
make
|
make
|
||||||
|
|
||||||
- name: Generate SBOM from Build
|
- name: Generate SBOM from Build
|
||||||
run: |
|
run: |
|
||||||
make legal-info
|
make legal-info
|
||||||
|
|
||||||
- name: Prepare Artifacts
|
- name: Prepare Artifacts
|
||||||
run: |
|
run: |
|
||||||
cd output/
|
cd ${{ steps.vars.outputs.out }}
|
||||||
mv images ${{ steps.vars.outputs.dir }}
|
mv images ${{ steps.vars.outputs.dir }}
|
||||||
ln -s ${{ steps.vars.outputs.dir }} images
|
ln -s ${{ steps.vars.outputs.dir }} images
|
||||||
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
tar chfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
|
||||||
|
|
||||||
mv legal-info legal-info-$target
|
mv legal-info legal-info-$target
|
||||||
tar chfz legal-info-$target.tar.gz legal-info-$target
|
tar chfz legal-info-$target.tar.gz legal-info-$target
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: artifact-${{ matrix.target }}
|
name: artifact-${{ matrix.platform }}
|
||||||
path: output/*.tar.gz
|
path: ${{ steps.vars.outputs.out }}/*.tar.gz
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Release Infix ${{ github.ref_name }}
|
name: Release Infix ${{ github.ref_name }}
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: [ self-hosted, release ]
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
|
|
||||||
- name: Set Release Variables
|
- name: Set Release Variables
|
||||||
id: rel
|
id: rel
|
||||||
run: |
|
run: |
|
||||||
@@ -123,24 +118,20 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "pre=${{ steps.rel.outputs.pre }}"
|
echo "pre=${{ steps.rel.outputs.pre }}"
|
||||||
echo "latest=${{ steps.rel.outputs.latest }}"
|
echo "latest=${{ steps.rel.outputs.latest }}"
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: "artifact-*"
|
pattern: "artifact-*"
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Create checksums ...
|
- name: Create checksums ...
|
||||||
run: |
|
run: |
|
||||||
for file in *.tar.gz; do
|
for file in *.tar.gz; do
|
||||||
sha256sum $file > $file.sha256
|
sha256sum $file > $file.sha256
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Extract ChangeLog entry ...
|
- name: Extract ChangeLog entry ...
|
||||||
run: |
|
run: |
|
||||||
awk '/^-----*$/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|
awk '/^-----*$/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|
||||||
|head -n -1 > release.md
|
|head -n -1 > release.md
|
||||||
cat release.md
|
cat release.md
|
||||||
|
|
||||||
- uses: ncipollo/release-action@v1
|
- uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: Infix ${{ github.ref_name }}
|
name: Infix ${{ github.ref_name }}
|
||||||
@@ -148,7 +139,6 @@ jobs:
|
|||||||
makeLatest: ${{ steps.rel.outputs.latest }}
|
makeLatest: ${{ steps.rel.outputs.latest }}
|
||||||
bodyFile: release.md
|
bodyFile: release.md
|
||||||
artifacts: "*.tar.gz*"
|
artifacts: "*.tar.gz*"
|
||||||
|
|
||||||
- name: Summary
|
- name: Summary
|
||||||
run: |
|
run: |
|
||||||
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ and testing, but can also be used for evaluation and demo purposes. For
|
|||||||
more information, see: [Infix in Virtual Environments](doc/virtual.md).
|
more information, see: [Infix in Virtual Environments](doc/virtual.md).
|
||||||
|
|
||||||
> See the [GitHub Releases](https://github.com/kernelkit/infix/releases)
|
> See the [GitHub Releases](https://github.com/kernelkit/infix/releases)
|
||||||
> page for our pre-built images. The *[Latest Build][]* has bleeding
|
> page for our pre-built images. The *Latest Build* has the bleeding
|
||||||
> edge images, if possible we recommend using a versioned release.
|
> edge images, if possible we recommend using a versioned release.
|
||||||
>
|
>
|
||||||
> For *customer specific builds* of Infix, see your product repository.
|
> For *customer specific builds* of Infix, see your product repository.
|
||||||
@@ -116,7 +116,6 @@ more information, see: [Infix in Virtual Environments](doc/virtual.md).
|
|||||||
[1]: https://buildroot.org/
|
[1]: https://buildroot.org/
|
||||||
[2]: https://www.sysrepo.org/
|
[2]: https://www.sysrepo.org/
|
||||||
[3]: doc/cli/introduction.md
|
[3]: doc/cli/introduction.md
|
||||||
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest
|
|
||||||
[License]: https://en.wikipedia.org/wiki/GPL_license
|
[License]: https://en.wikipedia.org/wiki/GPL_license
|
||||||
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
|
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
|
||||||
[GitHub]: https://github.com/kernelkit/infix/actions/workflows/build.yml/
|
[GitHub]: https://github.com/kernelkit/infix/actions/workflows/build.yml/
|
||||||
|
|||||||
+64
-4
@@ -1,7 +1,67 @@
|
|||||||
aarch64
|
aarch64
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Board Specific Documentation
|
Microchip SparX-5i PCB135 (eMMC)
|
||||||
----------------------------
|
--------------------------------
|
||||||
- [Marvell CN9130-CRB](cn9130-crb/)
|
|
||||||
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
|
At present, only FIT images are supported via the SparX-5i eval
|
||||||
|
board's U-Boot, which must contain a valid load address. If you are
|
||||||
|
using this board, after selecting your base configuration, run the
|
||||||
|
following command to supplement the existing config with the required
|
||||||
|
FIT options:
|
||||||
|
|
||||||
|
make board-enable-sparx-fit
|
||||||
|
|
||||||
|
### Unbricking
|
||||||
|
|
||||||
|
1. Don't load a corrupt bootloader to begin with
|
||||||
|
2. Done
|
||||||
|
|
||||||
|
If, for some reason, you didn't manage to follow step 1, you can use
|
||||||
|
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
|
||||||
|
directly.
|
||||||
|
|
||||||
|
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
|
||||||
|
you can load a new bootloader. The schematic below details how to
|
||||||
|
connect the Bus Blaster to the board, but the concept should be
|
||||||
|
portable to any debugger/device based around an FTDI2232 chip.
|
||||||
|
|
||||||
|
```
|
||||||
|
Bus Blaster: FLASH_PROG (J4):
|
||||||
|
.---. .---.
|
||||||
|
VTG >o o| VTG SCK >o o| GND
|
||||||
|
TRST |o o| GND MISO |o o| #RESET_FLASH
|
||||||
|
TDI |o o| GND o o| 3V3
|
||||||
|
TMS |o o| GND #CS |o o| #SYSRESET
|
||||||
|
TCK o o| GND MOSI |o o| GND
|
||||||
|
RTCK o o| GND '---'
|
||||||
|
TDO |o o| GND
|
||||||
|
TSRST |o o| GND
|
||||||
|
DBGRQ |o o| GND
|
||||||
|
DBGACK |o o| GND
|
||||||
|
'---'
|
||||||
|
```
|
||||||
|
|
||||||
|
| Bus Blaster | FLASH_PROG |
|
||||||
|
|-------------|----------------|
|
||||||
|
| `VTG` | `3V3` |
|
||||||
|
| `GND` | `GND` |
|
||||||
|
| | |
|
||||||
|
| `VTG` | `#RESET_FLASH` |
|
||||||
|
| `GND` | `#SYSRESET` |
|
||||||
|
| | |
|
||||||
|
| `TDI` | `MOSI` |
|
||||||
|
| `TMS` | `#CS` |
|
||||||
|
| `TCK` | `SCK` |
|
||||||
|
| `TDO` | `MISO` |
|
||||||
|
|
||||||
|
With the cable in place, build U-Boot with the correct configuration:
|
||||||
|
|
||||||
|
make fireant_boot_defconfig && make
|
||||||
|
|
||||||
|
To flash it to the board, connect the cable to `J4` and run:
|
||||||
|
|
||||||
|
make board-sparx-flash-uboot
|
||||||
|
|
||||||
|
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
|
||||||
|
[dangerspi]: https://github.com/wkz/dangerspi
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
Marvell CN9130-CRB
|
|
||||||
==================
|
|
||||||
|
|
||||||
## Build instructions
|
|
||||||
|
|
||||||
### Bootloader
|
|
||||||
|
|
||||||
Build the bootloader from the supplied `defconfig`. It might be useful
|
|
||||||
to build in a separate output directory if you want to build Infix
|
|
||||||
from the same working tree later:
|
|
||||||
|
|
||||||
make O=$(pwd)/x-cn9130-boot cn9130_crb_boot_defconfig
|
|
||||||
cd x-cn9130-boot
|
|
||||||
make
|
|
||||||
|
|
||||||
The artifact of interest is called `flash-image.bin`, which will be
|
|
||||||
located in the `images/` directory once the build completes.
|
|
||||||
|
|
||||||
|
|
||||||
### Infix
|
|
||||||
|
|
||||||
> If you do not want to build Infix from source, feel free to use a pre-built [release]
|
|
||||||
|
|
||||||
The standard `aarch64_defconfig` is compatible with this board:
|
|
||||||
|
|
||||||
make O=$(pwd)/x-aarch64 aarch64_defconfig
|
|
||||||
cd x-aarch64
|
|
||||||
make
|
|
||||||
|
|
||||||
Two artifacts from the `images/` directory of this build are required
|
|
||||||
to provision a new board:
|
|
||||||
|
|
||||||
- `rootfs.itb`: Netbootable image
|
|
||||||
- `infix-aarch64.pkg`: Standard upgrade bundle
|
|
||||||
|
|
||||||
## Provisioning
|
|
||||||
|
|
||||||
The overall provisioning flow, in which each step in described in
|
|
||||||
details in the following sections, is as follows:
|
|
||||||
|
|
||||||
- Strap board to boot from SPI FLASH
|
|
||||||
- Load `flash-image.bin` over UART
|
|
||||||
- Burn `flash-image.bin` to SPI FLASH
|
|
||||||
- Netboot `rootfs.itb`
|
|
||||||
- Run Infix's built-in provisioning script
|
|
||||||
- Reboot, now booting from the primary partition of the SD-card
|
|
||||||
|
|
||||||
#### Strap Board to Boot from SPI FLASH
|
|
||||||
|
|
||||||
By default, the board is strapped to boot from eMMC. However, Infix
|
|
||||||
assumes that the board will boot from SPI FLASH. Therefore we have to
|
|
||||||
ensure that the DIP switches of `SW2` on the board selects a
|
|
||||||
`BOOT_MODE` of `0x32`, meaning that the switches on positions 4, 3,
|
|
||||||
and 1 should be enabled (i.e. these need to be tied to ground):
|
|
||||||
|
|
||||||
```
|
|
||||||
.-----. .-----. .-----.
|
|
||||||
| | | | | PWR |
|
|
||||||
| SIM | | uSD | | |
|
|
||||||
| | | | '-----'
|
|
||||||
'-----' '-----'
|
|
||||||
|
|
||||||
|
|
|
||||||
v
|
|
||||||
.-----. .-----.
|
|
||||||
| SW1 | | SW2 |
|
|
||||||
'-----' '-----'
|
|
||||||
.--------------------------.
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| CN9130 |
|
|
||||||
```
|
|
||||||
|
|
||||||
#### UART Boot U-Boot
|
|
||||||
|
|
||||||
Make sure that:
|
|
||||||
- [mvebu64boot] is installed and available in your shell's `$PATH`
|
|
||||||
- No other program is attached to `ttyUSB0`
|
|
||||||
- No power is applied to the board
|
|
||||||
|
|
||||||
1. Start `mvebu64boot`:
|
|
||||||
|
|
||||||
mvebu64boot -b /path/to/flash-image.bin /dev/ttyUSB0
|
|
||||||
|
|
||||||
2. Apply power
|
|
||||||
|
|
||||||
As soon as `mvebu64boot` completes, attach to the serial port,
|
|
||||||
e.g. using `screen(1)`, or `console(1)` and stop the normal boot
|
|
||||||
process by hitting any key.
|
|
||||||
|
|
||||||
#### Burn U-Boot to SPI FLASH
|
|
||||||
|
|
||||||
Make sure that:
|
|
||||||
- `eth1` is connected to a machine which serves `flash-image.bin` over
|
|
||||||
TFTP
|
|
||||||
- U-Boot can reach the TFTP server. If the neighboring machine is also
|
|
||||||
set up as a DHCP server, simply run the command `dhcp -`
|
|
||||||
|
|
||||||
To burn the bootloader to SPI FLASH, run the `bubt` command:
|
|
||||||
|
|
||||||
bubt flash-image.bin
|
|
||||||
|
|
||||||
Once the command completes, reset the board to verify that it can now
|
|
||||||
boot unassisted:
|
|
||||||
|
|
||||||
reset
|
|
||||||
|
|
||||||
#### Boot up `rootfs.itb`
|
|
||||||
|
|
||||||
U-Boot will automatically fallback to netboot since the SD-card is
|
|
||||||
still blank. Make sure that the PC provides the path to `rootfs.itb`
|
|
||||||
in DHCP option 67 ("bootfile").
|
|
||||||
|
|
||||||
#### Install Firmware
|
|
||||||
|
|
||||||
Login as `admin`/`admin`, setup networking to the PC, ensure that the date on
|
|
||||||
the device is reasonably correct, and run the provisioning script:
|
|
||||||
|
|
||||||
admin@infix:~$ sudo -i
|
|
||||||
root@infix:~$ udhcpc -i e28
|
|
||||||
root@infix:~$ date -us YYYY-MM-DD
|
|
||||||
root@infix:~$ /libexec/infix/prod/provision tftp://<PC-IP>/infix-aarch64.pkg /dev/mmcblk0
|
|
||||||
|
|
||||||
After successful completion, the device is fully provisioned. On the
|
|
||||||
next boot, the device will boot of its own accord from the primary
|
|
||||||
SD-card partition.
|
|
||||||
|
|
||||||
> If possible, serve `infix-aarch64.pkg` over HTTP instead, as
|
|
||||||
> libcurl's TFTP implementation is quite slow.
|
|
||||||
|
|
||||||
[release]: https://github.com/kernelkit/infix/releases
|
|
||||||
[mvebu64boot]: https://github.com/addiva-elektronik/mvebu64boot
|
|
||||||
@@ -16,7 +16,36 @@ run ixboot
|
|||||||
";
|
";
|
||||||
boot_targets = "mmc1";
|
boot_targets = "mmc1";
|
||||||
ethprime = "eth1";
|
ethprime = "eth1";
|
||||||
bootdelay = "1";
|
|
||||||
|
/* Uncomment this if you're debugging U-Boot
|
||||||
|
*
|
||||||
|
* This will allow you to break out of the
|
||||||
|
* normal boot flow and into the interactive
|
||||||
|
* console.
|
||||||
|
*
|
||||||
|
* To upgrade U-Boot itself, simply set the
|
||||||
|
* `bootfile` variable to the path of
|
||||||
|
* `flash-image.bin` on your TFTP server, then
|
||||||
|
* issue `run ixupgradeboot`.
|
||||||
|
*/
|
||||||
|
/* bootdelay = "2"; */
|
||||||
|
/* ixupgradeboot = " */
|
||||||
|
/* dhcp */
|
||||||
|
/* setexpr fileblks ${filesize} + 0x1ff */
|
||||||
|
/* setexpr fileblks ${fileblks} / 0x200 */
|
||||||
|
|
||||||
|
/* mmc dev 1 */
|
||||||
|
/* part start mmc 1 boot bootstart */
|
||||||
|
/* part size mmc 1 boot bootsize */
|
||||||
|
|
||||||
|
|
||||||
|
/* mmc erase ${bootstart} ${bootsize} */
|
||||||
|
/* mmc write ${fileaddr} ${bootstart} ${fileblks} */
|
||||||
|
/* "; */
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* &cp0_eth0 { */
|
||||||
|
/* phy-mode = "10gbase-r"; */
|
||||||
|
/* }; */
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi cn9130-crb-env.dtsi"
|
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi cn9130-crb-env.dtsi"
|
||||||
CONFIG_SYS_PROMPT="(cn9130-crb) "
|
|
||||||
|
|
||||||
CONFIG_ENV_IS_NOWHERE=y
|
CONFIG_ENV_IS_NOWHERE=y
|
||||||
# CONFIG_ENV_IS_IN_MMC is not set
|
# CONFIG_ENV_IS_IN_MMC is not set
|
||||||
CONFIG_MVEBU_SPI_BOOT=y
|
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
#include "alder-mpp.h"
|
#include "alder-mpp.h"
|
||||||
|
|
||||||
|
&ap_crit {
|
||||||
|
temperature = <115000>;
|
||||||
|
};
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
model = "Alder";
|
model = "Alder";
|
||||||
compatible = "alder,alder",
|
compatible = "alder,alder",
|
||||||
@@ -354,7 +358,6 @@
|
|||||||
#define XSWP(_n, _label, _mac_offs, _phy) \
|
#define XSWP(_n, _label, _mac_offs, _phy) \
|
||||||
port@_n { \
|
port@_n { \
|
||||||
SWP_COMMON(_n, _label, _mac_offs, "usxgmii", _phy); \
|
SWP_COMMON(_n, _label, _mac_offs, "usxgmii", _phy); \
|
||||||
managed = "in-band-status"; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GSWP(_n, _label, _mac_offs, _phy) \
|
#define GSWP(_n, _label, _mac_offs, _phy) \
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2020 Marvell International Ltd.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cn9130-crb.dtsi"
|
|
||||||
|
|
||||||
/ {
|
|
||||||
model = "Marvell Armada CN9130-CRB-A";
|
|
||||||
|
|
||||||
chosen {
|
|
||||||
infix {
|
|
||||||
/* "admin" */
|
|
||||||
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
|
|
||||||
usb-ports = <&cp0_usb3_1>;
|
|
||||||
usb-port-names = "USB";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&cp0_pcie0 {
|
|
||||||
status = "okay";
|
|
||||||
num-lanes = <4>;
|
|
||||||
num-viewport = <8>;
|
|
||||||
/* Generic PHY, providing serdes lanes */
|
|
||||||
phys = <&cp0_comphy0 0
|
|
||||||
&cp0_comphy1 0
|
|
||||||
&cp0_comphy2 0
|
|
||||||
&cp0_comphy3 0>;
|
|
||||||
iommu-map =
|
|
||||||
<0x0 &smmu 0x480 0x20>,
|
|
||||||
<0x100 &smmu 0x4a0 0x20>,
|
|
||||||
<0x200 &smmu 0x4c0 0x20>;
|
|
||||||
iommu-map-mask = <0x031f>;
|
|
||||||
};
|
|
||||||
|
|
||||||
&cp0_usb3_0 {
|
|
||||||
status = "okay";
|
|
||||||
usb-phy = <&cp0_usb3_0_phy0>;
|
|
||||||
phy-names = "usb";
|
|
||||||
};
|
|
||||||
|
|
||||||
&cp0_usb3_1 {
|
|
||||||
status = "okay";
|
|
||||||
usb-phy = <&cp0_usb3_0_phy1>;
|
|
||||||
phy-names = "usb";
|
|
||||||
};
|
|
||||||
|
|
||||||
&cp0_eth2 {
|
|
||||||
status = "okay";
|
|
||||||
phy-mode = "2500base-x";
|
|
||||||
};
|
|
||||||
|
|
||||||
&cp0_pinctrl {
|
|
||||||
cp0_expander0_pins: cp0-expander-pins-0 {
|
|
||||||
marvell,pins = "mpp39";
|
|
||||||
marvell,function = "gpio";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&expander0 {
|
|
||||||
pinctrl-names = "default";
|
|
||||||
pinctrl-0 = <&cp0_expander0_pins>;
|
|
||||||
interrupt-parent = <&cp0_gpio2>;
|
|
||||||
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
|
||||||
interrupt-controller;
|
|
||||||
#interrupt-cells=<2>;
|
|
||||||
microchip,irq-mirror;
|
|
||||||
};
|
|
||||||
@@ -178,7 +178,6 @@ CONFIG_NET_SCHED=y
|
|||||||
CONFIG_NET_CLS_BASIC=y
|
CONFIG_NET_CLS_BASIC=y
|
||||||
CONFIG_NET_CLS_BPF=y
|
CONFIG_NET_CLS_BPF=y
|
||||||
CONFIG_NET_CLS_FLOWER=y
|
CONFIG_NET_CLS_FLOWER=y
|
||||||
CONFIG_DCB=y
|
|
||||||
CONFIG_NETLINK_DIAG=y
|
CONFIG_NETLINK_DIAG=y
|
||||||
CONFIG_MPLS=y
|
CONFIG_MPLS=y
|
||||||
CONFIG_NET_MPLS_GSO=y
|
CONFIG_NET_MPLS_GSO=y
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
Microchip SparX-5i PCB135 (eMMC)
|
|
||||||
================================
|
|
||||||
|
|
||||||
At present, only FIT images are supported via the SparX-5i eval
|
|
||||||
board's U-Boot, which must contain a valid load address. If you are
|
|
||||||
using this board, after selecting your base configuration, run the
|
|
||||||
following command to supplement the existing config with the required
|
|
||||||
FIT options:
|
|
||||||
|
|
||||||
make board-enable-sparx-fit
|
|
||||||
|
|
||||||
## Unbricking
|
|
||||||
|
|
||||||
1. Don't load a corrupt bootloader to begin with
|
|
||||||
2. Done
|
|
||||||
|
|
||||||
If, for some reason, you didn't manage to follow step 1, you can use
|
|
||||||
the `FLASH_PROG`(`J4`) connector on the board to access the SPI flash
|
|
||||||
directly.
|
|
||||||
|
|
||||||
Using a [Bus Blaster][BB3] in combination with [dangerspi][dangerspi],
|
|
||||||
you can load a new bootloader. The schematic below details how to
|
|
||||||
connect the Bus Blaster to the board, but the concept should be
|
|
||||||
portable to any debugger/device based around an FTDI2232 chip.
|
|
||||||
|
|
||||||
```
|
|
||||||
Bus Blaster: FLASH_PROG (J4):
|
|
||||||
.---. .---.
|
|
||||||
VTG >o o| VTG SCK >o o| GND
|
|
||||||
TRST |o o| GND MISO |o o| #RESET_FLASH
|
|
||||||
TDI |o o| GND o o| 3V3
|
|
||||||
TMS |o o| GND #CS |o o| #SYSRESET
|
|
||||||
TCK o o| GND MOSI |o o| GND
|
|
||||||
RTCK o o| GND '---'
|
|
||||||
TDO |o o| GND
|
|
||||||
TSRST |o o| GND
|
|
||||||
DBGRQ |o o| GND
|
|
||||||
DBGACK |o o| GND
|
|
||||||
'---'
|
|
||||||
```
|
|
||||||
|
|
||||||
| Bus Blaster | FLASH_PROG |
|
|
||||||
|-------------|----------------|
|
|
||||||
| `VTG` | `3V3` |
|
|
||||||
| `GND` | `GND` |
|
|
||||||
| | |
|
|
||||||
| `VTG` | `#RESET_FLASH` |
|
|
||||||
| `GND` | `#SYSRESET` |
|
|
||||||
| | |
|
|
||||||
| `TDI` | `MOSI` |
|
|
||||||
| `TMS` | `#CS` |
|
|
||||||
| `TCK` | `SCK` |
|
|
||||||
| `TDO` | `MISO` |
|
|
||||||
|
|
||||||
With the cable in place, build U-Boot with the correct configuration:
|
|
||||||
|
|
||||||
make fireant_boot_defconfig && make
|
|
||||||
|
|
||||||
To flash it to the board, connect the cable to `J4` and run:
|
|
||||||
|
|
||||||
make board-sparx-flash-uboot
|
|
||||||
|
|
||||||
[BB3]: http://dangerousprototypes.com/docs/Bus_Blaster#Bus_Blaster_v3
|
|
||||||
[dangerspi]: https://github.com/wkz/dangerspi
|
|
||||||
+2
-21
@@ -18,27 +18,7 @@ endchoice
|
|||||||
config SIGN_KEY
|
config SIGN_KEY
|
||||||
string "Signing key"
|
string "Signing key"
|
||||||
depends on SIGN_ENABLED
|
depends on SIGN_ENABLED
|
||||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development" if SIGN_SRC_DIR
|
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/dev-key" if SIGN_SRC_DIR
|
||||||
|
|
||||||
menuconfig TRUSTED_KEYS
|
|
||||||
bool "Trusted keys for image"
|
|
||||||
depends on SIGN_ENABLED
|
|
||||||
help
|
|
||||||
Keys that will be accepted for this image
|
|
||||||
|
|
||||||
|
|
||||||
config TRUSTED_KEYS_DEVELOPMENT
|
|
||||||
bool "Development key"
|
|
||||||
depends on TRUSTED_KEYS
|
|
||||||
|
|
||||||
config TRUSTED_KEYS_DEVELOPMENT_PATH
|
|
||||||
string
|
|
||||||
depends on TRUSTED_KEYS_DEVELOPMENT
|
|
||||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
|
|
||||||
|
|
||||||
config TRUSTED_KEYS_EXTRA_PATH
|
|
||||||
string "Path to extra keys to include in image"
|
|
||||||
depends on TRUSTED_KEYS
|
|
||||||
|
|
||||||
menuconfig DISK_IMAGE
|
menuconfig DISK_IMAGE
|
||||||
bool "Disk image"
|
bool "Disk image"
|
||||||
@@ -160,3 +140,4 @@ config FIT_ARCH
|
|||||||
config FIT_KERNEL_LOAD_ADDR
|
config FIT_KERNEL_LOAD_ADDR
|
||||||
string "Kernel load address"
|
string "Kernel load address"
|
||||||
depends on FIT_IMAGE
|
depends on FIT_IMAGE
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
ifeq ($(SIGN_ENABLED),y)
|
ifeq ($(SIGN_ENABLED),y)
|
||||||
include $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/uboot.mk
|
include $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/uboot.mk
|
||||||
|
|
||||||
TRUSTED_KEYS=$(TRUSTED_KEYS_DEVELOPMENT_PATH) $(TRUSTED_KEYS_EXTRA_PATH)
|
|
||||||
define RAUC_POST_BUILD_INSTALL_CERT
|
define RAUC_POST_BUILD_INSTALL_CERT
|
||||||
@$(call IXMSG,"Installing signing cert for RAUC")
|
@$(call IXMSG,"Installing signing cert for RAUC")
|
||||||
mkdir -p $(TARGET_DIR)/etc/rauc/keys
|
mkdir -p $(TARGET_DIR)/etc/rauc/keys
|
||||||
$(foreach crt,$(shell ls $(TRUSTED_KEYS)), \
|
$(foreach crt,$(shell ls $(SIGN_KEY)/*.crt), \
|
||||||
cp $(crt) $(TARGET_DIR)/etc/rauc/keys/$(shell openssl x509 -hash -noout <$(crt)).0;)
|
cp $(crt) $(TARGET_DIR)/etc/rauc/keys/$(shell openssl x509 -hash -noout <$(crt)).0;)
|
||||||
|
|
||||||
endef
|
endef
|
||||||
RAUC_POST_BUILD_HOOKS += RAUC_POST_BUILD_INSTALL_CERT
|
RAUC_POST_BUILD_HOOKS += RAUC_POST_BUILD_INSTALL_CERT
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -44,19 +44,16 @@ image @DISKIMG@ {
|
|||||||
partition aux {
|
partition aux {
|
||||||
offset = @AUXOFFS@
|
offset = @AUXOFFS@
|
||||||
image = "aux.ext4"
|
image = "aux.ext4"
|
||||||
partition-uuid = @AUXUUID@
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partition primary {
|
partition primary {
|
||||||
image = "rootfs.squashfs"
|
image = "rootfs.squashfs"
|
||||||
size = @IMGSIZE@
|
size = @IMGSIZE@
|
||||||
partition-uuid = @PRIMARYUUID@
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partition secondary {
|
partition secondary {
|
||||||
image = "rootfs.squashfs"
|
image = "rootfs.squashfs"
|
||||||
size = @IMGSIZE@
|
size = @IMGSIZE@
|
||||||
partition-uuid = @SECONDARYUUID@
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partition cfg {
|
partition cfg {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
|
||||||
|
|
||||||
. $BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/etc/partition-uuid
|
set -e
|
||||||
|
|
||||||
K=10
|
K=10
|
||||||
M=20
|
M=20
|
||||||
@@ -158,9 +157,6 @@ genboot
|
|||||||
# Use awk over sed because replacement text may contain newlines,
|
# Use awk over sed because replacement text may contain newlines,
|
||||||
# which sed does not approve of.
|
# which sed does not approve of.
|
||||||
awk \
|
awk \
|
||||||
-vauxuuid=$AUX_UUID \
|
|
||||||
-vprimaryuuid=$PRIMARY_UUID \
|
|
||||||
-vsecondaryuuid=$SECONDARY_UUID \
|
|
||||||
-vtotal=$total \
|
-vtotal=$total \
|
||||||
-vauxsize=$auxsize -vauxoffs=$auxoffs \
|
-vauxsize=$auxsize -vauxoffs=$auxoffs \
|
||||||
-vimgsize=$imgsize \
|
-vimgsize=$imgsize \
|
||||||
@@ -178,10 +174,6 @@ awk \
|
|||||||
sub(/@DISKIMG@/, diskimg);
|
sub(/@DISKIMG@/, diskimg);
|
||||||
sub(/@BOOTIMG@/, bootimg);
|
sub(/@BOOTIMG@/, bootimg);
|
||||||
sub(/@BOOTPART@/, bootpart);
|
sub(/@BOOTPART@/, bootpart);
|
||||||
sub(/@AUXUUID@/, auxuuid);
|
|
||||||
sub(/@PRIMARYUUID@/, primaryuuid);
|
|
||||||
sub(/@SECONDARYUUID@/, secondaryuuid);
|
|
||||||
|
|
||||||
}1' \
|
}1' \
|
||||||
< $common/genimage.cfg.in >$root/genimage.cfg
|
< $common/genimage.cfg.in >$root/genimage.cfg
|
||||||
|
|
||||||
|
|||||||
@@ -54,10 +54,11 @@ choice
|
|||||||
|
|
||||||
config QEMU_CONSOLE_VIRTIO
|
config QEMU_CONSOLE_VIRTIO
|
||||||
bool "Virtio (hvc0)"
|
bool "Virtio (hvc0)"
|
||||||
|
depends on QEMU_LOADER_KERNEL
|
||||||
|
|
||||||
config QEMU_CONSOLE_SERIAL
|
config QEMU_CONSOLE_SERIAL
|
||||||
bool "Serial (ttyS0/ttyAMA0)"
|
bool "Serial (ttyS0/ttyAMA0)"
|
||||||
depends on !QEMU_LOADER_OVMF
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config QEMU_MACHINE
|
config QEMU_MACHINE
|
||||||
|
|||||||
+12
-21
@@ -117,7 +117,7 @@ rootfs_args()
|
|||||||
echo -n "-device sd-card,drive=mmc "
|
echo -n "-device sd-card,drive=mmc "
|
||||||
echo -n "-drive id=mmc,file=$CONFIG_QEMU_ROOTFS,if=none,format=raw "
|
echo -n "-drive id=mmc,file=$CONFIG_QEMU_ROOTFS,if=none,format=raw "
|
||||||
elif [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
|
elif [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
|
||||||
echo -n "-drive file=$CONFIG_QEMU_ROOTFS.qcow2,if=virtio,format=qcow2,bus=0,unit=0 "
|
echo -n "-drive file=$CONFIG_QEMU_ROOTFS,if=virtio,format=raw,bus=0,unit=0 "
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,20 +148,14 @@ usb_args()
|
|||||||
dd if=/dev/zero of=${USBSTICK} bs=8M count=1 >/dev/null 2>&1
|
dd if=/dev/zero of=${USBSTICK} bs=8M count=1 >/dev/null 2>&1
|
||||||
mkfs.vfat $USBSTICK >/dev/null 2>&1
|
mkfs.vfat $USBSTICK >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
echo -n "-drive if=none,id=usbstick,format=raw,file=$USBSTICK "
|
echo -n "-drive if=none,id=usbstick,format=raw,file=${USBSTICK} "
|
||||||
echo -n "-usb "
|
echo -n "-usb "
|
||||||
echo -n "-device usb-ehci,id=ehci "
|
echo -n "-device usb-ehci,id=ehci "
|
||||||
echo -n "-device usb-storage,bus=ehci.0,drive=usbstick "
|
echo -n "-device usb-storage,bus=ehci.0,drive=usbstick "
|
||||||
}
|
}
|
||||||
rw_args()
|
rw_args()
|
||||||
{
|
{
|
||||||
[ "$CONFIG_QEMU_RW" ] || return
|
[ "$CONFIG_QEMU_RW" ] || return
|
||||||
|
|
||||||
if ! [ -f "aux.ext4" ]; then
|
|
||||||
dd if=/dev/zero of="aux.ext4" bs=1M count=1 >/dev/null 2>&1
|
|
||||||
mkfs.ext4 -L aux "aux.ext4" >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
echo -n "-drive file=aux.ext4,if=virtio,format=raw,bus=0,unit=3 "
|
|
||||||
|
|
||||||
if ! [ -f "$CONFIG_QEMU_RW" ]; then
|
if ! [ -f "$CONFIG_QEMU_RW" ]; then
|
||||||
dd if=/dev/zero of="$CONFIG_QEMU_RW" bs=16M count=1 >/dev/null 2>&1
|
dd if=/dev/zero of="$CONFIG_QEMU_RW" bs=16M count=1 >/dev/null 2>&1
|
||||||
@@ -204,10 +198,10 @@ net_args()
|
|||||||
echo -n "-fw_cfg name=opt/mactab,file=$mactab "
|
echo -n "-fw_cfg name=opt/mactab,file=$mactab "
|
||||||
|
|
||||||
if [ "$CONFIG_QEMU_NET_BRIDGE" = "y" ]; then
|
if [ "$CONFIG_QEMU_NET_BRIDGE" = "y" ]; then
|
||||||
echo -n "-netdev bridge,id=e1,br=$CONFIG_QEMU_NET_BRIDGE_DEV "
|
echo -n "-netdev bridge,id=e0,br=$CONFIG_QEMU_NET_BRIDGE_DEV "
|
||||||
net_dev_args 1
|
net_dev_args 0
|
||||||
elif [ "$CONFIG_QEMU_NET_TAP" = "y" ]; then
|
elif [ "$CONFIG_QEMU_NET_TAP" = "y" ]; then
|
||||||
for i in $(seq 1 $(($CONFIG_QEMU_NET_TAP_N))); do
|
for i in $(seq 0 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
|
||||||
echo -n "-netdev tap,id=e$i,ifname=qtap$i "
|
echo -n "-netdev tap,id=e$i,ifname=qtap$i "
|
||||||
net_dev_args $i
|
net_dev_args $i
|
||||||
done
|
done
|
||||||
@@ -215,8 +209,8 @@ net_args()
|
|||||||
local useropts=
|
local useropts=
|
||||||
[ "$CONFIG_QEMU_NET_USER_OPTS" ] && useropts=",$CONFIG_QEMU_NET_USER_OPTS"
|
[ "$CONFIG_QEMU_NET_USER_OPTS" ] && useropts=",$CONFIG_QEMU_NET_USER_OPTS"
|
||||||
|
|
||||||
echo -n "-netdev user,id=e1${useropts} "
|
echo -n "-netdev user,id=e0${useropts} "
|
||||||
net_dev_args 1
|
net_dev_args 0
|
||||||
else
|
else
|
||||||
echo -n "-nic none"
|
echo -n "-nic none"
|
||||||
fi
|
fi
|
||||||
@@ -257,9 +251,6 @@ wdt_args()
|
|||||||
|
|
||||||
run_qemu()
|
run_qemu()
|
||||||
{
|
{
|
||||||
if [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
|
|
||||||
qemu-img create -f qcow2 -o backing_file=$CONFIG_QEMU_ROOTFS -F raw $CONFIG_QEMU_ROOTFS.qcow2 > /dev/null
|
|
||||||
fi
|
|
||||||
local qemu
|
local qemu
|
||||||
read qemu <<EOF
|
read qemu <<EOF
|
||||||
$CONFIG_QEMU_MACHINE -m $CONFIG_QEMU_MACHINE_RAM \
|
$CONFIG_QEMU_MACHINE -m $CONFIG_QEMU_MACHINE_RAM \
|
||||||
@@ -312,10 +303,10 @@ generate_dot()
|
|||||||
{
|
{
|
||||||
[ "$CONFIG_QEMU_NET_TAP" = "y" ] || return
|
[ "$CONFIG_QEMU_NET_TAP" = "y" ] || return
|
||||||
|
|
||||||
hostports="<qtap1> qtap1"
|
hostports="<qtap0> qtap0"
|
||||||
targetports="<e1> e1"
|
targetports="<e0> e0"
|
||||||
edges="host:qtap1 -- target:e1 [kind=mgmt];"
|
edges="host:qtap0 -- target:e0 [kind=mgmt];"
|
||||||
for tap in $(seq 2 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
|
for tap in $(seq 1 $(($CONFIG_QEMU_NET_TAP_N - 1))); do
|
||||||
hostports="$hostports | <qtap$tap> qtap$tap "
|
hostports="$hostports | <qtap$tap> qtap$tap "
|
||||||
targetports="$targetports | <e$tap> e$tap "
|
targetports="$targetports | <e$tap> e$tap "
|
||||||
edges="$edges host:qtap$tap -- target:e$tap;"
|
edges="$edges host:qtap$tap -- target:e$tap;"
|
||||||
|
|||||||
Executable
+67
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Generate a self signed certificate with unlimited expire time
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from cryptography import x509
|
||||||
|
from cryptography.x509.oid import NameOID
|
||||||
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
# Generate private key
|
||||||
|
private_key = rsa.generate_private_key(
|
||||||
|
public_exponent=65537,
|
||||||
|
key_size=2048,
|
||||||
|
backend=default_backend()
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Generate a self signed certificate")
|
||||||
|
parser.add_argument('--country', required=True, help="Set country")
|
||||||
|
parser.add_argument('--state', required=True, help="Set state or province name")
|
||||||
|
parser.add_argument('--city', required=True, help="Set city name")
|
||||||
|
parser.add_argument('--organisation', required=True, help="Set organisation name")
|
||||||
|
parser.add_argument('--organisation-unit', required=True, help="Set organisation unit name")
|
||||||
|
parser.add_argument('--common-name', required=True, help="Set common name")
|
||||||
|
parser.add_argument('--out-certificate', required=True, help="Output certificate")
|
||||||
|
parser.add_argument('--out-key', required=True, help="Output key")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Builder for certificate
|
||||||
|
subject = issuer = x509.Name([
|
||||||
|
x509.NameAttribute(NameOID.COUNTRY_NAME, args.country),
|
||||||
|
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, args.state),
|
||||||
|
x509.NameAttribute(NameOID.LOCALITY_NAME, args.city),
|
||||||
|
x509.NameAttribute(NameOID.ORGANIZATION_NAME, args.organisation),
|
||||||
|
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, args.organisation_unit),
|
||||||
|
x509.NameAttribute(NameOID.COMMON_NAME, args.common_name),
|
||||||
|
])
|
||||||
|
certificate = x509.CertificateBuilder().subject_name(
|
||||||
|
subject
|
||||||
|
).issuer_name(
|
||||||
|
issuer
|
||||||
|
).public_key(
|
||||||
|
private_key.public_key()
|
||||||
|
).serial_number(
|
||||||
|
x509.random_serial_number()
|
||||||
|
).not_valid_before(
|
||||||
|
datetime(2000, 1, 1)
|
||||||
|
).not_valid_after(
|
||||||
|
datetime(9999, 1, 1)
|
||||||
|
).add_extension(
|
||||||
|
x509.SubjectAlternativeName([x509.DNSName(args.common_name)]),
|
||||||
|
critical=False,
|
||||||
|
).sign(private_key, hashes.SHA256(), default_backend())
|
||||||
|
|
||||||
|
# Serialize certificate and private key
|
||||||
|
with open(args.out_certificate, "wb") as f:
|
||||||
|
f.write(certificate.public_bytes(serialization.Encoding.PEM))
|
||||||
|
with open(args.out_key, "wb") as f:
|
||||||
|
f.write(private_key.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.PKCS8,
|
||||||
|
encryption_algorithm=serialization.NoEncryption()
|
||||||
|
))
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 -t 0
|
||||||
Executable
+76
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tstamp()
|
||||||
|
{
|
||||||
|
if [ "$1" = "head" ]; then
|
||||||
|
printf '%9s' time
|
||||||
|
else
|
||||||
|
printf '%9s' $(date +%T)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
thermal()
|
||||||
|
{
|
||||||
|
for th in /sys/class/thermal/thermal_zone*; do
|
||||||
|
if [ "$1" = "head" ]; then
|
||||||
|
printf '%5s' $(cat $th/type | \
|
||||||
|
sed -e 's/-thermal//' -e 's/ap-cpu/cpu/' -e 's/-ic//')
|
||||||
|
else
|
||||||
|
printf '%5d' \
|
||||||
|
$((($(cat $th/temp) + 500) / 1000))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hwmon()
|
||||||
|
{
|
||||||
|
for hw in /sys/class/hwmon/*; do
|
||||||
|
[ -f $hw/temp1_input ] || continue
|
||||||
|
|
||||||
|
if [ "$1" = "head" ]; then
|
||||||
|
printf '%5s' \
|
||||||
|
$(cat $hw/name | sed -e 's/cp0configspacef2000000mdio12a200switch0mdio0/p/' -e 's/f212a600mdiomii0/xp/')
|
||||||
|
else
|
||||||
|
printf '%5d' \
|
||||||
|
$((($(cat $hw/temp1_input) + 500) / 1000))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
xphys()
|
||||||
|
{
|
||||||
|
for xphy in 4 5; do
|
||||||
|
mdio f212a6* $xphy:31 0xf08a 0x4d00
|
||||||
|
|
||||||
|
if [ "$1" = "head" ]; then
|
||||||
|
printf '%5s' \
|
||||||
|
p$((xphy + 5))
|
||||||
|
else
|
||||||
|
printf '%5d' \
|
||||||
|
$(($(mdio f212a6* $xphy:31 0xf08a) & 0xff - 75))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" != "-H" ]; then
|
||||||
|
# tstamp head
|
||||||
|
thermal head
|
||||||
|
hwmon head
|
||||||
|
# xphys head
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
# tstamp
|
||||||
|
thermal
|
||||||
|
hwmon
|
||||||
|
# xphys
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ "$1" == "-n" ]; then
|
||||||
|
sleep ${2:-10}
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
service [2345789] log:/var/log/temp.log /bin/temp.sh -n 10 -- Temperature monitor
|
||||||
|
service [2345789] log:/var/log/load.log /bin/load.sh -- CPU load generator
|
||||||
|
service [2345789] log:/var/log/memtester.log /usr/bin/memtester 1G -- Memory load generator
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../available/temp.conf
|
||||||
@@ -19,4 +19,4 @@ LABEL=aux /mnt/aux auto noatime,nodiratime,noauto 0 0
|
|||||||
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
|
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
|
||||||
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 0 0
|
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 0 0
|
||||||
hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0
|
hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0
|
||||||
/libexec/infix/mnt# /cfg helper none 0 0
|
/libexec/infix/mnt# /cfg helper none 0 0
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
0 unspec
|
|
||||||
1 kernel_lo
|
|
||||||
2 kernel_ra
|
|
||||||
3 kernel_ll
|
|
||||||
4 static
|
4 static
|
||||||
5 dhcp
|
5 dhcp
|
||||||
6 random
|
6 random
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
configure ports dsa0 lldp status disabled
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
AUX_UUID="78460f84-de84-4fe7-89bd-4c1f433b2230"
|
|
||||||
PRIMARY_UUID="107ae911-a97b-4380-975c-7ce1a2dde1e0"
|
|
||||||
SECONDARY_UUID="352bd9b2-2ca9-44e2-bdc7-edbc87ba1e02"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
UsePAM yes
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
Reserved facilities for logging in various subsystems:
|
|
||||||
|
|
||||||
- local0: rauc
|
|
||||||
- local1: containers
|
|
||||||
- local2:
|
|
||||||
- local3:
|
|
||||||
- local5:
|
|
||||||
- local6: reserved
|
|
||||||
- local7: nginx
|
|
||||||
|
|
||||||
@@ -3,13 +3,12 @@
|
|||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
onieprom = importlib.machinery.SourceFileLoader("onieprom","/bin/onieprom").load_module()
|
onieprom = importlib.machinery.SourceFileLoader("onieprom","/bin/onieprom").load_module()
|
||||||
SYSTEM_JSON = "/run/system.json"
|
|
||||||
KKIT_IANA_PEM = 61046
|
KKIT_IANA_PEM = 61046
|
||||||
|
|
||||||
class DTSystem:
|
class DTSystem:
|
||||||
@@ -234,36 +233,8 @@ def vpd_inject(out, vpds):
|
|||||||
out["factory-password-hash"] = pwhash
|
out["factory-password-hash"] = pwhash
|
||||||
break
|
break
|
||||||
|
|
||||||
def qemu_base_mac():
|
|
||||||
"""Find MAC address of first non-loopback interface, subtract with 1"""
|
|
||||||
base_path = '/sys/class/net'
|
|
||||||
interfaces = []
|
|
||||||
|
|
||||||
for iface in os.listdir(base_path):
|
|
||||||
if iface == 'lo':
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
# pylint: disable=invalid-name
|
|
||||||
with open(os.path.join(base_path, iface, 'address'), 'r', encoding='ascii') as f:
|
|
||||||
mac = f.read().strip()
|
|
||||||
interfaces.append((mac, iface))
|
|
||||||
except FileNotFoundError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if interfaces:
|
|
||||||
interfaces.sort()
|
|
||||||
mac = interfaces[0][0]
|
|
||||||
mac = int(mac.replace(':', ''), 16)
|
|
||||||
mac -= 1
|
|
||||||
mac %= 1 << 48
|
|
||||||
mac = ':'.join(f"{(mac >> 8 * i) & 0xff:02x}" for i in range(5, -1, -1))
|
|
||||||
return mac
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def probe_qemusystem(out):
|
def probe_qemusystem(out):
|
||||||
"""Probe Qemu based test systems and 'make run'"""
|
ADMINHASH = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
|
||||||
admin_hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"
|
|
||||||
|
|
||||||
qsys = QEMUSystem()
|
qsys = QEMUSystem()
|
||||||
vpds = qsys.vpds()
|
vpds = qsys.vpds()
|
||||||
@@ -273,7 +244,6 @@ def probe_qemusystem(out):
|
|||||||
for (attr, default) in (
|
for (attr, default) in (
|
||||||
("vendor", "QEMU"),
|
("vendor", "QEMU"),
|
||||||
("product-name", "VM"),
|
("product-name", "VM"),
|
||||||
("mac-address", qemu_base_mac()),
|
|
||||||
):
|
):
|
||||||
if not out[attr]:
|
if not out[attr]:
|
||||||
out[attr] = default
|
out[attr] = default
|
||||||
@@ -282,14 +252,13 @@ def probe_qemusystem(out):
|
|||||||
not out["vpd"]["product"]["available"]:
|
not out["vpd"]["product"]["available"]:
|
||||||
# Virtual instance without VPD emulation, fallback to
|
# Virtual instance without VPD emulation, fallback to
|
||||||
# admin/admin
|
# admin/admin
|
||||||
out["factory-password-hash"] = admin_hash
|
out["factory-password-hash"] = ADMINHASH
|
||||||
|
|
||||||
# Let others react to the fact that we are running in QEMU
|
# Let others react to the fact that we are running in QEMU
|
||||||
subprocess.run("initctl -nbq cond set qemu".split(), check=False)
|
subprocess.run("initctl -nbq cond set qemu".split())
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def probe_dtsystem(out):
|
def probe_dtsystem(out):
|
||||||
"""Probe DTS based system, expects a VPD in ONIE PROM format."""
|
|
||||||
dtsys = DTSystem()
|
dtsys = DTSystem()
|
||||||
vpds = dtsys.infix_vpds()
|
vpds = dtsys.infix_vpds()
|
||||||
dtsys.infix_usb_devices(out)
|
dtsys.infix_usb_devices(out)
|
||||||
@@ -327,15 +296,11 @@ def main():
|
|||||||
return err
|
return err
|
||||||
|
|
||||||
if not out["factory-password-hash"]:
|
if not out["factory-password-hash"]:
|
||||||
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\n" +
|
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\nNO FACTORY PASSWORD FOUND\033[0m\n\n")
|
||||||
"NO FACTORY PASSWORD FOUND\033[0m\n\n")
|
|
||||||
err = 1
|
err = 1
|
||||||
|
|
||||||
os.umask(0o337)
|
json.dump(out, open("/run/system.json", "w"))
|
||||||
# pylint: disable=invalid-name
|
os.chmod("/run/system.json", 0o444)
|
||||||
with open(SYSTEM_JSON, "w", encoding="ascii") as f:
|
|
||||||
json.dump(out, f)
|
|
||||||
shutil.chown(SYSTEM_JSON, user="root", group="wheel")
|
|
||||||
return err
|
return err
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
|
||||||
|
|
||||||
. /etc/partition-uuid
|
set -e
|
||||||
|
|
||||||
disk=$1
|
disk=$1
|
||||||
bootoffs=$2
|
bootoffs=$2
|
||||||
@@ -28,11 +27,11 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sgdisk \
|
sgdisk \
|
||||||
-Z \
|
-o \
|
||||||
-n1:${bootoffs}:+${bootsize} -t1:8301 -c1:boot \
|
-n1:${bootoffs}:+${bootsize} -t1:8301 -c1:boot \
|
||||||
-n2::+${auxsize} -t2:8301 -c2:aux -u2:${AUX_UUID} \
|
-n2::+${auxsize} -t2:8301 -c2:aux \
|
||||||
-n3::+${imgsize} -t3:8300 -c3:primary -u3:${PRIMARY_UUID} \
|
-n3::+${imgsize} -t3:8300 -c3:primary \
|
||||||
-n4::+${imgsize} -t4:8300 -c4:secondary -u4:${SECONDARY_UUID} \
|
-n4::+${imgsize} -t4:8300 -c4:secondary \
|
||||||
-n5::+${cfgsize} -t5:8302 -c5:cfg \
|
-n5::+${cfgsize} -t5:8302 -c5:cfg \
|
||||||
-n6:: -t6:8310 -c6:var \
|
-n6:: -t6:8310 -c6:var \
|
||||||
-p \
|
-p \
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ action_exec()
|
|||||||
|
|
||||||
for node in $order; do
|
for node in $order; do
|
||||||
for work in $(find "$actdir/$node" -type f -executable 2>/dev/null | sort); do
|
for work in $(find "$actdir/$node" -type f -executable 2>/dev/null | sort); do
|
||||||
$work | ts >>"$work.log" 2>&1 || code=$?
|
$work >>"$work.log" 2>&1 || code=$?
|
||||||
echo "[exit:$code]" | ts >>"$work.log"
|
echo "[exit:$code]" >>"$work.log"
|
||||||
|
|
||||||
[ $code -eq 0 ] || abort "$work failed with exitcode $code"
|
[ $code -eq 0 ] || abort "$work failed with exitcode $code"
|
||||||
done
|
done
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
+21
-22
@@ -1,27 +1,26 @@
|
|||||||
define uboot-add-pubkey
|
# This is a bit awkward. If you know about a more straight forward way
|
||||||
$(call IXMSG,"Installing trusted key $1")
|
# of doing this, please simplify.
|
||||||
$(HOST_DIR)/bin/fdt_add_pubkey \
|
#
|
||||||
-a sha256,rsa$(shell \
|
# U-Boot needs the public part of the signing key to be preprocessed
|
||||||
openssl x509 -text -noout -in $1 | \
|
# and then inserted into its control DT. mkimage(1) can perform this
|
||||||
grep 'Public-Key: ' | \
|
# conversion, but only as a side-effect of building/signing an FIT
|
||||||
sed -e 's/.*(\(.*\) bit)/\1/') \
|
# image. Since we might not always be doing that, e.g. when only
|
||||||
-k $(dir $1) \
|
# building a hardware specific bootloader, we build a dummy FIT just
|
||||||
-n $(notdir $(basename $1)) \
|
# to get the key information into a DTB, which we then convert back to
|
||||||
-r image \
|
# a .dtsi and install in the U-Boot build tree. This will then be
|
||||||
$2
|
# built in to the final U-Boot image's control DT via the
|
||||||
endef
|
# CONFIG_DEVICE_TREE_INCLUDES option (see extras.config).
|
||||||
|
|
||||||
# U-Boot has its own public key format which has to be stored in its
|
|
||||||
# control DT. So we collect all of the trusted keys, convert them to
|
|
||||||
# the required format, and write the result to infix-key.dtb in the
|
|
||||||
# U-Boot build tree. This will then be built in to the final U-Boot
|
|
||||||
# image's control DT via the CONFIG_DEVICE_TREE_INCLUDES option (see
|
|
||||||
# extras.config).
|
|
||||||
define UBOOT_PRE_BUILD_INSTALL_KEY
|
define UBOOT_PRE_BUILD_INSTALL_KEY
|
||||||
|
@$(call IXMSG,"Installing Infix signing key ($(SIGN_KEY))")
|
||||||
$(HOST_DIR)/bin/dtc <(echo '/dts-v1/; / { signature {}; };') >$(@D)/infix-key.dtb
|
$(HOST_DIR)/bin/dtc <(echo '/dts-v1/; / { signature {}; };') >$(@D)/infix-key.dtb
|
||||||
$(foreach key, \
|
$(HOST_DIR)/bin/mkimage \
|
||||||
$(call qstrip,$(TRUSTED_KEYS_DEVELOPMENT_PATH)) $(call qstrip,$(TRUSTED_KEYS_EXTRA_PATH)),\
|
-k $(SIGN_KEY) \
|
||||||
$(call uboot-add-pubkey,$(key),$(@D)/infix-key.dtb))
|
-f $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/key-dummy.its \
|
||||||
|
-K $(@D)/infix-key.dtb \
|
||||||
|
$(if $(SIGN_SRC_PKCS11),-N pkcs11) \
|
||||||
|
-r \
|
||||||
|
$(@D)/key-dummy.itb
|
||||||
|
rm $(@D)/key-dummy.itb
|
||||||
$(HOST_DIR)/bin/dtc -I dtb -O dts \
|
$(HOST_DIR)/bin/dtc -I dtb -O dts \
|
||||||
<$(@D)/infix-key.dtb \
|
<$(@D)/infix-key.dtb \
|
||||||
| sed -e 's:/dts-v[0-9]\+/;::' >$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi
|
| sed -e 's:/dts-v[0-9]\+/;::' >$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
test-dir := $(BR2_EXTERNAL_INFIX_PATH)/test
|
||||||
|
INFIX_TESTS ?= $(test-dir)/case/all.yaml
|
||||||
|
|
||||||
|
test-env = $(test-dir)/env \
|
||||||
|
-f $(BINARIES_DIR)/infix-x86_64.img \
|
||||||
|
-p $(BINARIES_DIR)/infix-x86_64.pkg \
|
||||||
|
$(1) $(2)
|
||||||
|
|
||||||
|
test-env-qeneth = $(call test-env,-q $(test-dir)/virt/quad,$(1))
|
||||||
|
test-env-run = $(call test-env,-C -t $(BINARIES_DIR)/qemu.dot,$(1))
|
||||||
|
|
||||||
|
test test-qeneth:
|
||||||
|
$(call test-env-qeneth,\
|
||||||
|
$(BR2_EXTERNAL_INFIX_PATH)/test/9pm/9pm.py \
|
||||||
|
$(INFIX_TESTS))
|
||||||
|
test-sh test-qeneth-sh:
|
||||||
|
$(call test-env-qeneth,-i /bin/sh)
|
||||||
|
|
||||||
|
test-run: | ~/.infix-test-venv
|
||||||
|
$(call test-env-run,\
|
||||||
|
$(BR2_EXTERNAL_INFIX_PATH)/test/9pm/9pm.py \
|
||||||
|
$(INFIX_TESTS))
|
||||||
|
test-run-sh: | ~/.infix-test-venv
|
||||||
|
$(call test-env-run,/bin/sh)
|
||||||
|
|
||||||
|
test-run-play: | ~/.infix-test-venv
|
||||||
|
$(call test-env-run,$(test-dir)/case/meta/play.py)
|
||||||
|
|
||||||
|
~/.infix-test-venv:
|
||||||
|
$(test-dir)/docker/init-venv.sh $(test-dir)/docker/pip-requirements.txt
|
||||||
|
|
||||||
|
.PHONY: test test-sh test-qeneth test-qeneth-sh test-run test-run-sh test-run-play
|
||||||
|
|||||||
@@ -1,6 +1 @@
|
|||||||
search -l aux --set=aux
|
set prefix=(hd0,gpt2)/grub
|
||||||
search -l primary --set=primary
|
|
||||||
search -l secondary --set=secondary
|
|
||||||
|
|
||||||
set prefix=($aux)/grub
|
|
||||||
configfile ($aux)/grub/grub.cfg
|
|
||||||
|
|||||||
+5
-12
@@ -33,24 +33,17 @@ else
|
|||||||
set log="loglevel=4"
|
set log="loglevel=4"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# From board/common/rootfs/etc/partition-uuid
|
|
||||||
search -p 107ae911-a97b-4380-975c-7ce1a2dde1e0 --set primary
|
|
||||||
search -p 352bd9b2-2ca9-44e2-bdc7-edbc87ba1e02 --set secondary
|
|
||||||
|
|
||||||
export primary
|
|
||||||
export secondary
|
|
||||||
|
|
||||||
submenu "primary" "$log" {
|
submenu "primary" "$log" {
|
||||||
set slot="$1"
|
set slot="$1"
|
||||||
set append="console=ttyS0 console=hvc0 root=PARTLABEL=$slot $2"
|
set append="console=ttyS0 root=PARTLABEL=$slot $2"
|
||||||
set root="($primary)"
|
set root=(hd0,gpt3)
|
||||||
source /boot/grub/grub.cfg
|
source /boot/grub/grub.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
submenu "secondary" "$log" {
|
submenu "secondary" "$log" {
|
||||||
set slot="$1"
|
set slot="$1"
|
||||||
set append="console=ttyS0 console=hvc0 root=PARTLABEL=$slot $2"
|
set append="console=ttyS0 root=PARTLABEL=$slot $2"
|
||||||
set root="($secondary)"
|
set root=(hd0,gpt4)
|
||||||
source /boot/grub/grub.cfg
|
source /boot/grub/grub.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +56,7 @@ submenu "net" "$log" {
|
|||||||
set root=(initrd)
|
set root=(initrd)
|
||||||
|
|
||||||
set slot="$1"
|
set slot="$1"
|
||||||
set append="console=ttyS0 console=hvc0 qroot=/dev/ram0 ramdisk_size=65536 $2"
|
set append="console=ttyS0 root=/dev/ram0 ramdisk_size=65536 $2"
|
||||||
source /boot/grub/grub.cfg
|
source /boot/grub/grub.cfg
|
||||||
else
|
else
|
||||||
if [ -z "$net_efinet0_dhcp_next_server" ]; then
|
if [ -z "$net_efinet0_dhcp_next_server" ]; then
|
||||||
|
|||||||
+1
-1
Submodule buildroot updated: 1d96daca15...d49f1e9e90
@@ -13,9 +13,7 @@ BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
|
|||||||
BR2_INIT_FINIT=y
|
BR2_INIT_FINIT=y
|
||||||
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
||||||
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs"
|
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs"
|
||||||
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
|
|
||||||
BR2_SYSTEM_BIN_SH_BASH=y
|
BR2_SYSTEM_BIN_SH_BASH=y
|
||||||
BR2_TARGET_GENERIC_GETTY_PORT="@console"
|
|
||||||
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
|
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
|
||||||
BR2_SYSTEM_DHCP="eth0"
|
BR2_SYSTEM_DHCP="eth0"
|
||||||
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
||||||
@@ -47,6 +45,7 @@ BR2_PACKAGE_EUDEV_RULES_GEN=y
|
|||||||
BR2_PACKAGE_GPTFDISK=y
|
BR2_PACKAGE_GPTFDISK=y
|
||||||
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
BR2_PACKAGE_GPTFDISK_SGDISK=y
|
||||||
BR2_PACKAGE_MDIO_TOOLS=y
|
BR2_PACKAGE_MDIO_TOOLS=y
|
||||||
|
BR2_PACKAGE_MEMTESTER=y
|
||||||
BR2_PACKAGE_RNG_TOOLS=y
|
BR2_PACKAGE_RNG_TOOLS=y
|
||||||
BR2_PACKAGE_UBOOT_TOOLS=y
|
BR2_PACKAGE_UBOOT_TOOLS=y
|
||||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
|
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||||
@@ -54,6 +53,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
|||||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
||||||
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
||||||
BR2_PACKAGE_PYTHON3=y
|
BR2_PACKAGE_PYTHON3=y
|
||||||
|
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
|
||||||
BR2_PACKAGE_PYTHON_GUNICORN=y
|
BR2_PACKAGE_PYTHON_GUNICORN=y
|
||||||
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
||||||
BR2_PACKAGE_LIBSSH2=y
|
BR2_PACKAGE_LIBSSH2=y
|
||||||
@@ -62,8 +62,6 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
|
|||||||
BR2_PACKAGE_LIBCURL_CURL=y
|
BR2_PACKAGE_LIBCURL_CURL=y
|
||||||
BR2_PACKAGE_NETOPEER2_CLI=y
|
BR2_PACKAGE_NETOPEER2_CLI=y
|
||||||
BR2_PACKAGE_NSS_MDNS=y
|
BR2_PACKAGE_NSS_MDNS=y
|
||||||
BR2_PACKAGE_LINUX_PAM=y
|
|
||||||
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
|
|
||||||
BR2_PACKAGE_ONIGURUMA=y
|
BR2_PACKAGE_ONIGURUMA=y
|
||||||
BR2_PACKAGE_AVAHI=y
|
BR2_PACKAGE_AVAHI=y
|
||||||
BR2_PACKAGE_AVAHI_DAEMON=y
|
BR2_PACKAGE_AVAHI_DAEMON=y
|
||||||
@@ -131,7 +129,6 @@ INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
|||||||
BR2_PACKAGE_CONFD=y
|
BR2_PACKAGE_CONFD=y
|
||||||
BR2_PACKAGE_CURIOS_HTTPD=y
|
BR2_PACKAGE_CURIOS_HTTPD=y
|
||||||
BR2_PACKAGE_EXECD=y
|
BR2_PACKAGE_EXECD=y
|
||||||
BR2_PACKAGE_GENCERT=y
|
|
||||||
BR2_PACKAGE_STATD=y
|
BR2_PACKAGE_STATD=y
|
||||||
BR2_PACKAGE_FACTORY=y
|
BR2_PACKAGE_FACTORY=y
|
||||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||||
@@ -144,7 +141,6 @@ BR2_PACKAGE_IITO=y
|
|||||||
BR2_PACKAGE_K8S_LOGGER=y
|
BR2_PACKAGE_K8S_LOGGER=y
|
||||||
BR2_PACKAGE_KEYACK=y
|
BR2_PACKAGE_KEYACK=y
|
||||||
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
||||||
BR2_PACKAGE_LANDING=y
|
|
||||||
BR2_PACKAGE_LOWDOWN=y
|
BR2_PACKAGE_LOWDOWN=y
|
||||||
BR2_PACKAGE_MCD=y
|
BR2_PACKAGE_MCD=y
|
||||||
BR2_PACKAGE_MDNS_ALIAS=y
|
BR2_PACKAGE_MDNS_ALIAS=y
|
||||||
@@ -158,5 +154,3 @@ BR2_PACKAGE_LIBINPUT=y
|
|||||||
DISK_IMAGE_BOOT_BIN=y
|
DISK_IMAGE_BOOT_BIN=y
|
||||||
GNS3_APPLIANCE_RAM=512
|
GNS3_APPLIANCE_RAM=512
|
||||||
GNS3_APPLIANCE_IFNUM=10
|
GNS3_APPLIANCE_IFNUM=10
|
||||||
TRUSTED_KEYS=y
|
|
||||||
TRUSTED_KEYS_DEVELOPMENT=y
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image
|
|||||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||||
# BR2_TARGET_ROOTFS_TAR is not set
|
# BR2_TARGET_ROOTFS_TAR is not set
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y
|
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.9"
|
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="t9130"
|
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="t9130"
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
||||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
|
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
|
||||||
@@ -38,8 +36,8 @@ BR2_PACKAGE_HOST_RAUC=y
|
|||||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||||
TRUSTED_KEYS=y
|
# SIGN_ENABLED is not set
|
||||||
TRUSTED_KEYS_DEVELOPMENT=y
|
DISK_IMAGE=y
|
||||||
DISK_IMAGE_BOOT_BIN=y
|
DISK_IMAGE_BOOT_BIN=y
|
||||||
DISK_IMAGE_BOOT_DATA="${BINARIES_DIR}/flash-image.bin"
|
DISK_IMAGE_BOOT_DATA="${BINARIES_DIR}/flash-image.bin"
|
||||||
DISK_IMAGE_BOOT_OFFSET=0x00200000
|
DISK_IMAGE_BOOT_OFFSET=0x00200000
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ BR2_TARGET_GENERIC_HOSTNAME="infix"
|
|||||||
BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
|
BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
|
||||||
BR2_INIT_FINIT=y
|
BR2_INIT_FINIT=y
|
||||||
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
|
||||||
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs"
|
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_ENABLE_ROOT_LOGIN is not set
|
||||||
BR2_SYSTEM_BIN_SH_BASH=y
|
BR2_SYSTEM_BIN_SH_BASH=y
|
||||||
BR2_TARGET_GENERIC_GETTY_PORT="@console"
|
BR2_TARGET_GENERIC_GETTY_PORT="@console"
|
||||||
@@ -22,8 +22,8 @@ BR2_SYSTEM_DHCP="eth0"
|
|||||||
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
|
||||||
BR2_GENERATE_LOCALE="en_US en_CA"
|
BR2_GENERATE_LOCALE="en_US en_CA"
|
||||||
BR2_TARGET_TZ_INFO=y
|
BR2_TARGET_TZ_INFO=y
|
||||||
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rootfs"
|
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/rootfs"
|
||||||
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/post-build.sh"
|
||||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh support/scripts/genimage.sh"
|
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh support/scripts/genimage.sh"
|
||||||
BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/genimage.cfg"
|
BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/genimage.cfg"
|
||||||
BR2_LINUX_KERNEL=y
|
BR2_LINUX_KERNEL=y
|
||||||
@@ -64,6 +64,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
|||||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
||||||
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
||||||
BR2_PACKAGE_PYTHON3=y
|
BR2_PACKAGE_PYTHON3=y
|
||||||
|
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
|
||||||
BR2_PACKAGE_PYTHON_GUNICORN=y
|
BR2_PACKAGE_PYTHON_GUNICORN=y
|
||||||
BR2_PACKAGE_CA_CERTIFICATES=y
|
BR2_PACKAGE_CA_CERTIFICATES=y
|
||||||
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
||||||
@@ -73,8 +74,6 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
|
|||||||
BR2_PACKAGE_LIBCURL_CURL=y
|
BR2_PACKAGE_LIBCURL_CURL=y
|
||||||
BR2_PACKAGE_NETOPEER2_CLI=y
|
BR2_PACKAGE_NETOPEER2_CLI=y
|
||||||
BR2_PACKAGE_NSS_MDNS=y
|
BR2_PACKAGE_NSS_MDNS=y
|
||||||
BR2_PACKAGE_LINUX_PAM=y
|
|
||||||
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
|
|
||||||
BR2_PACKAGE_ONIGURUMA=y
|
BR2_PACKAGE_ONIGURUMA=y
|
||||||
BR2_PACKAGE_AVAHI=y
|
BR2_PACKAGE_AVAHI=y
|
||||||
BR2_PACKAGE_AVAHI_DAEMON=y
|
BR2_PACKAGE_AVAHI_DAEMON=y
|
||||||
@@ -160,7 +159,6 @@ INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
|
|||||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||||
BR2_PACKAGE_CONFD=y
|
BR2_PACKAGE_CONFD=y
|
||||||
BR2_PACKAGE_EXECD=y
|
BR2_PACKAGE_EXECD=y
|
||||||
BR2_PACKAGE_GENCERT=y
|
|
||||||
BR2_PACKAGE_STATD=y
|
BR2_PACKAGE_STATD=y
|
||||||
BR2_PACKAGE_FACTORY=y
|
BR2_PACKAGE_FACTORY=y
|
||||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||||
@@ -173,7 +171,6 @@ BR2_PACKAGE_IITO=y
|
|||||||
BR2_PACKAGE_K8S_LOGGER=y
|
BR2_PACKAGE_K8S_LOGGER=y
|
||||||
BR2_PACKAGE_KEYACK=y
|
BR2_PACKAGE_KEYACK=y
|
||||||
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
||||||
BR2_PACKAGE_LANDING=y
|
|
||||||
BR2_PACKAGE_LOWDOWN=y
|
BR2_PACKAGE_LOWDOWN=y
|
||||||
BR2_PACKAGE_MCD=y
|
BR2_PACKAGE_MCD=y
|
||||||
BR2_PACKAGE_MDNS_ALIAS=y
|
BR2_PACKAGE_MDNS_ALIAS=y
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
|||||||
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
|
||||||
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
|
||||||
BR2_PACKAGE_PYTHON3=y
|
BR2_PACKAGE_PYTHON3=y
|
||||||
|
BR2_PACKAGE_PYTHON_CRYPTOGRAPHY=y
|
||||||
BR2_PACKAGE_PYTHON_GUNICORN=y
|
BR2_PACKAGE_PYTHON_GUNICORN=y
|
||||||
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
BR2_PACKAGE_LIBSSH_OPENSSL=y
|
||||||
BR2_PACKAGE_LIBSSH2=y
|
BR2_PACKAGE_LIBSSH2=y
|
||||||
@@ -57,8 +58,6 @@ BR2_PACKAGE_LIBOPENSSL_BIN=y
|
|||||||
BR2_PACKAGE_LIBCURL_CURL=y
|
BR2_PACKAGE_LIBCURL_CURL=y
|
||||||
BR2_PACKAGE_NETOPEER2_CLI=y
|
BR2_PACKAGE_NETOPEER2_CLI=y
|
||||||
BR2_PACKAGE_NSS_MDNS=y
|
BR2_PACKAGE_NSS_MDNS=y
|
||||||
BR2_PACKAGE_LINUX_PAM=y
|
|
||||||
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
|
|
||||||
BR2_PACKAGE_ONIGURUMA=y
|
BR2_PACKAGE_ONIGURUMA=y
|
||||||
BR2_PACKAGE_AVAHI=y
|
BR2_PACKAGE_AVAHI=y
|
||||||
BR2_PACKAGE_AVAHI_DAEMON=y
|
BR2_PACKAGE_AVAHI_DAEMON=y
|
||||||
@@ -113,7 +112,7 @@ BR2_TARGET_ROOTFS_SQUASHFS=y
|
|||||||
BR2_TARGET_EDK2=y
|
BR2_TARGET_EDK2=y
|
||||||
BR2_TARGET_GRUB2=y
|
BR2_TARGET_GRUB2=y
|
||||||
BR2_TARGET_GRUB2_X86_64_EFI=y
|
BR2_TARGET_GRUB2_X86_64_EFI=y
|
||||||
BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 squash4 part_gpt normal efi_gop configfile loadenv test echo reboot net efinet tftp loopback cat search"
|
BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 squash4 part_gpt normal efi_gop configfile loadenv test echo reboot net efinet tftp loopback"
|
||||||
BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/grub-embed.cfg"
|
BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/grub-embed.cfg"
|
||||||
BR2_TARGET_GRUB2_INSTALL_TOOLS=y
|
BR2_TARGET_GRUB2_INSTALL_TOOLS=y
|
||||||
BR2_PACKAGE_HOST_DOSFSTOOLS=y
|
BR2_PACKAGE_HOST_DOSFSTOOLS=y
|
||||||
@@ -134,7 +133,6 @@ INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
|||||||
BR2_PACKAGE_CONFD=y
|
BR2_PACKAGE_CONFD=y
|
||||||
BR2_PACKAGE_CURIOS_HTTPD=y
|
BR2_PACKAGE_CURIOS_HTTPD=y
|
||||||
BR2_PACKAGE_EXECD=y
|
BR2_PACKAGE_EXECD=y
|
||||||
BR2_PACKAGE_GENCERT=y
|
|
||||||
BR2_PACKAGE_STATD=y
|
BR2_PACKAGE_STATD=y
|
||||||
BR2_PACKAGE_FACTORY=y
|
BR2_PACKAGE_FACTORY=y
|
||||||
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
|
||||||
@@ -147,7 +145,6 @@ BR2_PACKAGE_IITO=y
|
|||||||
BR2_PACKAGE_K8S_LOGGER=y
|
BR2_PACKAGE_K8S_LOGGER=y
|
||||||
BR2_PACKAGE_KEYACK=y
|
BR2_PACKAGE_KEYACK=y
|
||||||
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
|
||||||
BR2_PACKAGE_LANDING=y
|
|
||||||
BR2_PACKAGE_LOWDOWN=y
|
BR2_PACKAGE_LOWDOWN=y
|
||||||
BR2_PACKAGE_MCD=y
|
BR2_PACKAGE_MCD=y
|
||||||
BR2_PACKAGE_MDNS_ALIAS=y
|
BR2_PACKAGE_MDNS_ALIAS=y
|
||||||
@@ -159,5 +156,3 @@ BR2_PACKAGE_PODMAN_DRIVER_VFS=y
|
|||||||
BR2_PACKAGE_TETRIS=y
|
BR2_PACKAGE_TETRIS=y
|
||||||
GNS3_APPLIANCE_RAM=512
|
GNS3_APPLIANCE_RAM=512
|
||||||
GNS3_APPLIANCE_IFNUM=10
|
GNS3_APPLIANCE_IFNUM=10
|
||||||
TRUSTED_KEYS=y
|
|
||||||
TRUSTED_KEYS_DEVELOPMENT=y
|
|
||||||
|
|||||||
+21
-174
@@ -4,114 +4,23 @@ Change Log
|
|||||||
All notable changes to the project are documented in this file.
|
All notable changes to the project are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
[v24.05.0][UNRELEASED]
|
[v24.03.0][UNRELEASED]
|
||||||
----------------------
|
|
||||||
|
|
||||||
### Changes
|
|
||||||
- Default web landing page refactored into a Buildroot package to make
|
|
||||||
it possible to overload from customer repos.
|
|
||||||
- Enable DCB support in aarch64 kernel (for EtherType prio override)
|
|
||||||
- Topology mapper improvements, including option for deterministic
|
|
||||||
reproduction of logical to physical mappings
|
|
||||||
- New version of `gencert` tool, for self signed HTTPS certificates.
|
|
||||||
This allows dropping dependency on building a host rust toolchain
|
|
||||||
- Issue #374: add timestamps to dagger .log files
|
|
||||||
- Add small delay in U-Boot to allow stopping boot on reference boards
|
|
||||||
- Document how to provision the bootloader and Infix on a blank board
|
|
||||||
- Use initial hostname from `/etc/os-release` as configuration fallback
|
|
||||||
- Update documentation for use of VETH pairs in containers
|
|
||||||
- Issue #454: create bridges in `factory-config` with IGMP/MLD snooping
|
|
||||||
enabled by default
|
|
||||||
- Add support for optionally running user scripts from
|
|
||||||
`/cfg/user-scripts.d`
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
- Add missing LICENSE hash for factory reset tool
|
|
||||||
- Fix #424: regression, root user can log in without password
|
|
||||||
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
|
|
||||||
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
|
|
||||||
- Fix provisioning script after changes to make GRUB loading more robust
|
|
||||||
- Fix missing `/etc/resolv.conf`, as noticed by `avahi-daemon`, when a
|
|
||||||
user calls `no system` from the CLI
|
|
||||||
- Fix #428: loss of admin account after upgrade to v24.04
|
|
||||||
- Fix #429: failing to load `startup-config` does not trigger the fail
|
|
||||||
secure mode, causing the system to end up in an undefined state
|
|
||||||
- Fix #453: fix inconsistent behavior of custom MAC address (interface
|
|
||||||
`phys-address` for VETH pairs. Allows fixed MAC in containers
|
|
||||||
- Fix locking issue with standard counter groups on `mv88e6xxx`
|
|
||||||
- Fix MDB/ATU synchronization issue from IGMPv3/MLDv2 reports on
|
|
||||||
`mv88e6xxx` systems
|
|
||||||
|
|
||||||
|
|
||||||
[v24.04.2][] - 2024-05-15
|
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
### Changes
|
Please note, as of this release the Infix Classic variant has been
|
||||||
- Add small delay in U-Boot to allow stopping boot on reference boards
|
dropped. This was the legacy, pre-NETCONF, Infix with manual config of
|
||||||
- Document how to provision the bootloader and Infix on a blank board
|
the system using a persistent `/etc`. It may be resurrected later as a
|
||||||
- Use initial hostname from `/etc/os-release` as configuration fallback
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
- Fix build regressions in `cn9130_crb_boot_defconfig` caused by upgrade
|
|
||||||
to Buildroot v2024.02 and recent multi-key support in RAUC and U-Boot
|
|
||||||
- Fix provisioning script after changes to make GRUB loading more robust
|
|
||||||
- Fix missing `/etc/resolv.conf`, as noticed by `avahi-daemon`, when a
|
|
||||||
user calls `no system` from the CLI
|
|
||||||
- Fix #428: loss of admin account after upgrade to v24.04
|
|
||||||
- Fix #429: failing to load `startup-config` does not trigger the fail
|
|
||||||
secure mode, causing the system to end up in an undefined state
|
|
||||||
|
|
||||||
|
|
||||||
[v24.04.1][] - 2024-05-03
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
### Changes
|
|
||||||
- Default web landing page refactored into a Buildroot package to make
|
|
||||||
it possible to overload from customer repos.
|
|
||||||
- Enable DCB support in aarch64 kernel (for EtherType prio override)
|
|
||||||
- Topology mapper improvements, including option for deterministic
|
|
||||||
reproduction of logical to physical mappings
|
|
||||||
- New version of `gencert` tool, for self signed HTTPS certificates.
|
|
||||||
This allows dropping dependency on building a host rust toolchain
|
|
||||||
- Issue #374: add timestamps to dagger .log files
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
- Add missing LICENSE hash for factory reset tool
|
|
||||||
- Fix #424: regression, root user can log in without password
|
|
||||||
|
|
||||||
|
|
||||||
[v24.04.0][] - 2024-04-30
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
**News:** this release marks the first major upgrade of the underlying
|
|
||||||
Buildroot to the latest LTS release, v2024.02. This caused a few small
|
|
||||||
regressions in the release cycle, all known issues have been addressed.
|
|
||||||
|
|
||||||
Also worth highlighting, as of this release the Infix Classic variant
|
|
||||||
has been dropped. It was the legacy Infix with manual configuration of
|
|
||||||
the system using a persistent `/etc`. May be resurrected later as a
|
|
||||||
separate project. Going forward Infix' focus is entirely on NETCONF.
|
separate project. Going forward Infix' focus is entirely on NETCONF.
|
||||||
|
|
||||||
Finally, the YANG Status section has been dropped for this release, the
|
> Development in progress, for daily updates see the team board:
|
||||||
idea is to generate supported features from the models and include in
|
> <https://github.com/orgs/kernelkit/projects/3/views/2>
|
||||||
future releases.
|
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
- Bump the base Buildroot version to v2024.02 LTS
|
- Bump the base Linux kernel version to 6.6
|
||||||
- Bump the base Linux kernel version to 6.6 LTS
|
|
||||||
- Drop Classic variant to reduce overhead, simplify build & release
|
- Drop Classic variant to reduce overhead, simplify build & release
|
||||||
processes, and focus on NETCONF for Arm64 and Amd64 platforms
|
processes, and focus on NETCONF for Arm64 and Amd64 platforms
|
||||||
- Add hostname restrictions to ietf-system, and infix-dhcp-client
|
- Add hostname restrictions to ietf-system, and infix-dhcp-client
|
||||||
models. Max 64 characters on Linux systems
|
models. Max 64 characters on Linux systems
|
||||||
- Add mDNS CNAME (alias) advertisement, e.g., infix.local in addition to
|
|
||||||
the default infix-c0-ff-ee.local. Note: this is build-specific and
|
|
||||||
does not change if system hostname is changed
|
|
||||||
- Add mDNS browser web application, https://network.local that shows all
|
|
||||||
mDNS devices on the LAN. The network.local mDNS name is also a CNAME,
|
|
||||||
so with multiple Infix devices, only one will act as the mDNS browser
|
|
||||||
- Add temporary landing page to web server for https://infix.local
|
|
||||||
- Add web console using ttyd, https://infix.local:7681
|
|
||||||
- Add support for disabling web services using CLI
|
|
||||||
- The bridge model now has built-in validation of port memberships,
|
- The bridge model now has built-in validation of port memberships,
|
||||||
i.e., a port must be a bridge member to be used in VLAN filtering
|
i.e., a port must be a bridge member to be used in VLAN filtering
|
||||||
- The bridge model only permits the bridge itself to be a tagged
|
- The bridge model only permits the bridge itself to be a tagged
|
||||||
@@ -119,49 +28,8 @@ future releases.
|
|||||||
such bridges is to use a VLAN interface on top
|
such bridges is to use a VLAN interface on top
|
||||||
- A VLAN filtering bridge now validates that no IP address has been
|
- A VLAN filtering bridge now validates that no IP address has been
|
||||||
set. Use a VLAN interface on top for that (see above)
|
set. Use a VLAN interface on top for that (see above)
|
||||||
- Restructure documentation, let first page in doc/ be table of contents
|
- Container documentation: CLI prompts have been updated to match the
|
||||||
- Scripting Infix, new document on how to script Infix from remote,
|
examples used in other parts of the User Guide
|
||||||
e.g., for production or from a container
|
|
||||||
- Introduction, update documentation now that the `admin` user's default
|
|
||||||
login shell is `/bin/bash`
|
|
||||||
- System documentation, first outline of how to change hostname, add
|
|
||||||
users, add system administrator users, changing login banner, change
|
|
||||||
the system default editor, and more
|
|
||||||
- Network documentation, add section on VETH pairs
|
|
||||||
- Container documentation:
|
|
||||||
- CLI prompts have been updated to match the examples used in other
|
|
||||||
parts of the User Guide
|
|
||||||
- Default route example for static container interfaces
|
|
||||||
- How to upgrade a container image
|
|
||||||
- As a follow-up to port speed/duplex/autoneg support added in v24.02,
|
|
||||||
this release ensures flow-control is always disabled on all Ethernet
|
|
||||||
ports, as described in the IEEE Ethernet interfaces YANG model
|
|
||||||
- Add support for core dumps, saving them in `/var/crash`, max one dump
|
|
||||||
per process, for use with future support tarballs
|
|
||||||
- Add support for multicast snooping, both IPv4 (IGMP) and IPv6 (MLD) in
|
|
||||||
bridge setups, including offloading to switchdev
|
|
||||||
- Add support for acting as passive (proxy) or active IGMP querier
|
|
||||||
- Add support for static multicast filters, MAC, IPv4 and IPv6 groups
|
|
||||||
are supported -- multicast snooping must be enabled
|
|
||||||
- Include Buildroot `legal-info` in releases, i.e., licenses, sources
|
|
||||||
with patches, as well as csv files for packages and toolchain
|
|
||||||
- Drop `shell` command from CLI to allow confining users
|
|
||||||
- The CLI `copy` command now allows absolute paths
|
|
||||||
- Local resolver, `dnsmasq`, had port 53 visible from external `nmap`
|
|
||||||
scans, even though it dropped non-local requests, it now only binds to
|
|
||||||
the loopback interface reduce number of externally visible ports
|
|
||||||
- Kernel log messages, of severity error or higher, now log directly to
|
|
||||||
the console. This may cause some annoyance but has been enabled to
|
|
||||||
ease debugging, in particular issues where the system crashes before
|
|
||||||
the syslog daemon has flushed logs to disk. (Logs are still saved to
|
|
||||||
log files as well.)
|
|
||||||
- Issue #325: Add support for multiple administrator users by opening
|
|
||||||
up basic NETCONF ACM support. See documentation for details
|
|
||||||
- Any user can be added to the `admin` NACM group
|
|
||||||
- Any user *not* in the `admin` group is not allowed to have a login
|
|
||||||
shell other than the CLI (or disabled). POSIX shell, e.g., Bash is
|
|
||||||
reserved for system administrators
|
|
||||||
- Issue #327: Remove IPv6LL from bridge port interfaces
|
|
||||||
- Issue #358: translate YANG model's LOWER-LAYER-DOWN -> LINK-DOWN in
|
- Issue #358: translate YANG model's LOWER-LAYER-DOWN -> LINK-DOWN in
|
||||||
CLI `show interfaces` command
|
CLI `show interfaces` command
|
||||||
- Issue #360: document factory-config, startup-config, and the various
|
- Issue #360: document factory-config, startup-config, and the various
|
||||||
@@ -173,12 +41,20 @@ future releases.
|
|||||||
users to avoid enabling privileged mode
|
users to avoid enabling privileged mode
|
||||||
- Issue #367: setting date/time over NETCONF now saves system time also
|
- Issue #367: setting date/time over NETCONF now saves system time also
|
||||||
to the RTC, which otherwise is only saved on reboot or power-down
|
to the RTC, which otherwise is only saved on reboot or power-down
|
||||||
|
- Add support for static multicast filters, MAC, IPv4 and IPv6 groups
|
||||||
|
are supported.
|
||||||
|
- Include Buildroot `legal-info` in releases, i.e., licenses, sources
|
||||||
|
with patches, as well as csv files for packages and toolchain
|
||||||
- Issue #369: Remove limitation that the routing instance must be
|
- Issue #369: Remove limitation that the routing instance must be
|
||||||
named 'default'
|
named 'default'
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- confd: Fix memory leak when operating on candidate configuration
|
- Issue #391 Creating VLAN interface in the CLI with "edit interface vlanN"
|
||||||
- probe: Fix crash on systems without USB
|
does not set VLAN id to N.
|
||||||
|
- confd: Fix memory leak when operating on candidate configuration.
|
||||||
|
- CLI: fix VLAN inference for interfaces named `eth0.1`, i.e., VID 1 on
|
||||||
|
lower-layer-if `eth0`. Only affects automatic inference in the CLI,
|
||||||
|
entering the values manually (CLI/NETCONF) not affected by this bug
|
||||||
- Reduced syslog errors for accesses no non-existing xpaths
|
- Reduced syslog errors for accesses no non-existing xpaths
|
||||||
- Fix bogus warning about not properly updating `/etc/motd` in new
|
- Fix bogus warning about not properly updating `/etc/motd` in new
|
||||||
`motd-banner` setting, introduced in v24.02.0
|
`motd-banner` setting, introduced in v24.02.0
|
||||||
@@ -187,16 +63,8 @@ future releases.
|
|||||||
- Fix #328: when setting up a VLAN filtering bridge, the PVID for bridge
|
- Fix #328: when setting up a VLAN filtering bridge, the PVID for bridge
|
||||||
ports defaulted to 1, making it impossible to set up "tagged-only"
|
ports defaulted to 1, making it impossible to set up "tagged-only"
|
||||||
ports which drop ingressing untagged traffic
|
ports which drop ingressing untagged traffic
|
||||||
- Fix #329: VLAN inference for interfaces named `eth0.1`, i.e., VID 1 on
|
|
||||||
lower-layer-if `eth0`. Only affects automatic inference in the CLI,
|
|
||||||
entering the values manually (CLI/NETCONF) not affected by this bug
|
|
||||||
- Fix #331: inconsistent naming of 'enabled' in infix-routing.yang
|
|
||||||
- Fix #349: minor changes to `bridge-port` settings, like setting `pvid`
|
|
||||||
when you forget it, did not take without a reboot
|
|
||||||
- Fix #353: impossible to remove bridge port with `no bridge-port`
|
|
||||||
- Fix #358: MAC address no longer shown for bridge interfaces in CLI
|
- Fix #358: MAC address no longer shown for bridge interfaces in CLI
|
||||||
`show interfaces` command
|
`show interfaces` command
|
||||||
- Fix #365: not possible to run `ping` from container
|
|
||||||
- Fix #366: static routes from container host interfaces do not work.
|
- Fix #366: static routes from container host interfaces do not work.
|
||||||
Documentation updated with an example
|
Documentation updated with an example
|
||||||
- Fix #368: upgrading `oci-archive:/` images fail because system thinks
|
- Fix #368: upgrading `oci-archive:/` images fail because system thinks
|
||||||
@@ -206,25 +74,8 @@ future releases.
|
|||||||
declare `network` settings, Infix v23.02 had a late regression that
|
declare `network` settings, Infix v23.02 had a late regression that
|
||||||
reverted back to the podman default: network behind a CNI bridge
|
reverted back to the podman default: network behind a CNI bridge
|
||||||
(firewalled and NAT:ed, hidden from the rest of the network)
|
(firewalled and NAT:ed, hidden from the rest of the network)
|
||||||
- Fix #375: k8s-logger, used for containers, does not exit properly and
|
- Fix #385: segfault in helper function when disabling the DHCP client
|
||||||
causes 100% CPU load when container stop or are restarted. Also in
|
|
||||||
this issue: handle ip/route additions to container networks at runtime
|
|
||||||
- Fix #384: segfault in helper function when disabling the DHCP client
|
|
||||||
using `no dhcp-client` from the CLI
|
using `no dhcp-client` from the CLI
|
||||||
- Fix #391 Creating VLAN interface in the CLI with "edit interface vlanN"
|
|
||||||
does not set VLAN id to N.
|
|
||||||
- Fix #404: `lldpd` should be disabled on internal interface `dsa0`
|
|
||||||
- Fix #406: an overly restrictive `when` expression in the bridge YANG
|
|
||||||
model prevented users from adding VLAN interfaces as bridge ports.
|
|
||||||
E.g., creating interface `eth0.10` and adding that to `br0`
|
|
||||||
- Fix #412: after starting up with DHCP client enabled on any interface
|
|
||||||
`set dhcp-client enabled false` does not bite at runtime
|
|
||||||
- Fix #414: spelling error in `infix-hardware.yang`, leaf node `coutry`
|
|
||||||
- Fix #415: `startup-config` owned by `root` user and group instead of
|
|
||||||
`admin`. The file ownership is now adjusted on every boot
|
|
||||||
- Fix #416: `admin` user cannot perform a factory reset with RPC using
|
|
||||||
`sysrepocfg` tool over SSH
|
|
||||||
- Fix bogus syslog warning about not updating `/etc/motd` properly
|
|
||||||
|
|
||||||
|
|
||||||
[v24.02.0][] - 2024-03-01
|
[v24.02.0][] - 2024-03-01
|
||||||
@@ -919,11 +770,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
|
|||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
[buildroot]: https://buildroot.org/
|
[buildroot]: https://buildroot.org/
|
||||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.04.0...HEAD
|
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v24.02.0...HEAD
|
||||||
[v24.05.0]: https://github.com/kernelkit/infix/compare/v24.04.0...v24.05.0
|
|
||||||
[v24.04.2]: https://github.com/kernelkit/infix/compare/v24.04.1...v24.04.2
|
|
||||||
[v24.04.1]: https://github.com/kernelkit/infix/compare/v24.04.0...v24.04.1
|
|
||||||
[v24.04.0]: https://github.com/kernelkit/infix/compare/v24.02.0...v24.04.0
|
|
||||||
[v24.02.0]: https://github.com/kernelkit/infix/compare/v23.11.0...v24.02.0
|
[v24.02.0]: https://github.com/kernelkit/infix/compare/v23.11.0...v24.02.0
|
||||||
[v23.11.0]: https://github.com/kernelkit/infix/compare/v23.10.0...v23.11.0
|
[v23.11.0]: https://github.com/kernelkit/infix/compare/v23.10.0...v23.11.0
|
||||||
[v23.10.0]: https://github.com/kernelkit/infix/compare/v23.09.0...v23.10.0
|
[v23.10.0]: https://github.com/kernelkit/infix/compare/v23.09.0...v23.10.0
|
||||||
|
|||||||
+19
-60
@@ -390,30 +390,12 @@ network:
|
|||||||
|
|
||||||
### Container Host Interface
|
### Container Host Interface
|
||||||
|
|
||||||
Another common use-case is to move network interfaces into the network
|
Another common use-case is to move a network interface into the network
|
||||||
namespace of a container[^3]. This of course works with plain Ethernet
|
namespace of a container. Which the container bridge network type does
|
||||||
interfaces as well, but here we will use one end of a VETH pair as an
|
behind the scenes with one end of the automatically created VETH pair.
|
||||||
example.
|
This works with regular Ethernet interfaces as well, but here we will
|
||||||
|
use a VETH pair as an example along with a regular bridge (where other
|
||||||
[^3]: Something which the container bridge network type does behind the
|
Ethernet interfaces may live as well).
|
||||||
scenes with one end of an automatically created VETH pair.
|
|
||||||
|
|
||||||
#### Routed Setup
|
|
||||||
|
|
||||||
In this routed setup we reserve 192.168.0.0/24 for the network between
|
|
||||||
the host and the `ntpd` container.
|
|
||||||
|
|
||||||
_____________
|
|
||||||
| |
|
|
||||||
veth0 .1 | .2 eth0 |
|
|
||||||
\ 192.168.0.0/24 | / |
|
|
||||||
'--------------------' [ntpd] |
|
|
||||||
|_____________|
|
|
||||||
|
|
||||||
Configuration is a straight-forward VETH pair setup where we name the
|
|
||||||
container-end of pair `ntpd`. This is just a convenience for us when
|
|
||||||
reading the configuration later. The *real action* happens on the last
|
|
||||||
line where we declare the `ntpd` end as a container network interface:
|
|
||||||
|
|
||||||
admin@example:/config/> edit interface veth0
|
admin@example:/config/> edit interface veth0
|
||||||
admin@example:/config/interface/veth0/> set veth peer ntpd
|
admin@example:/config/interface/veth0/> set veth peer ntpd
|
||||||
@@ -421,49 +403,23 @@ line where we declare the `ntpd` end as a container network interface:
|
|||||||
admin@example:/config/interface/veth0/> end
|
admin@example:/config/interface/veth0/> end
|
||||||
admin@example:/config/> edit interface ntpd
|
admin@example:/config/> edit interface ntpd
|
||||||
admin@example:/config/interface/ntpd/> set ipv4 address 192.168.0.2 prefix-length 24
|
admin@example:/config/interface/ntpd/> set ipv4 address 192.168.0.2 prefix-length 24
|
||||||
admin@example:/config/interface/ntpd/> set phys-address 00:c0:ff:ee:00:01
|
|
||||||
admin@example:/config/interface/ntpd/> set container-network
|
admin@example:/config/interface/ntpd/> set container-network
|
||||||
|
|
||||||
> Notice how you can also set a custom MAC address at the same time.
|
This is a routed setup, where we reserve 192.168.0.0/24 for the network
|
||||||
|
between the host and the `ntpd` container. A perhaps more common case
|
||||||
|
is to put `veth0` as a port in a bridge with other physical ports. The
|
||||||
|
point of the routed case is that port forwarding from the container in
|
||||||
|
this case is limited to a single interface, not *all interfaces* as is
|
||||||
|
the default in the masquerading container bridge setup.
|
||||||
|
|
||||||
Adding the interface to the container is the same as before, but since
|
When a container has multiple host interfaces it can often be useful to
|
||||||
everything for host interfaces is set up in the interfaces context, we
|
have a default route installed. This can be added from the host with a
|
||||||
can take a bit of a shortcut.
|
`0.0.0.0/0` route on one of the interfaces. The following is an example
|
||||||
|
when adding a second VETH pair to the container:
|
||||||
admin@example:/config/container/ntpd/> set network ntpd
|
|
||||||
admin@example:/config/container/ntpd/> leave
|
|
||||||
|
|
||||||
The point of the routed case is that port forwarding from the container
|
|
||||||
in this case is limited to a single interface, not *all interfaces* as
|
|
||||||
is the default in the masquerading container bridge setup.
|
|
||||||
|
|
||||||
|
|
||||||
#### Bridged Setup
|
|
||||||
|
|
||||||
A perhaps more common case is to bridge the other end of the VETH pair
|
|
||||||
with other physical ports. In this section we show how to add a new
|
|
||||||
pair to give our container two interfaces:
|
|
||||||
|
|
||||||
_______________
|
|
||||||
| | .1 br0
|
|
||||||
veth0 .1 | .2 eth0 | / \
|
|
||||||
\ 192.168.0.0/24 | / eth1 .2 | veth1b e1
|
|
||||||
'------------------' \ | 192.168.1.0/24 /
|
|
||||||
| [ntpd] '------------------'
|
|
||||||
|_______________|
|
|
||||||
|
|
||||||
We start by adding the second VETH pair:
|
|
||||||
|
|
||||||
admin@example:/config/> edit interface veth1a
|
admin@example:/config/> edit interface veth1a
|
||||||
admin@example:/config/interface/veth1a/> set veth peer veth1b
|
admin@example:/config/interface/veth1a/> set veth peer veth1b
|
||||||
admin@example:/config/interface/veth1a/> set ipv4 address 192.168.1.2 prefix-length 24
|
admin@example:/config/interface/veth1a/> set ipv4 address 192.168.1.2 prefix-length 24
|
||||||
|
|
||||||
> The LAN bridge (br0) in this example has IP address 192.168.1.1.
|
|
||||||
|
|
||||||
When a container has multiple host interfaces it can often be useful to
|
|
||||||
have a default route installed. This can be added from the host with a
|
|
||||||
`0.0.0.0/0` route on one of the interfaces:
|
|
||||||
|
|
||||||
admin@example:/config/interface/veth1a/> set container-network route 0.0.0.0/0 gateway 192.168.1.1
|
admin@example:/config/interface/veth1a/> set container-network route 0.0.0.0/0 gateway 192.168.1.1
|
||||||
admin@example:/config/interface/veth1a/> show
|
admin@example:/config/interface/veth1a/> show
|
||||||
type veth;
|
type veth;
|
||||||
@@ -483,6 +439,9 @@ Please note, container network routes require the base interface also
|
|||||||
have a static IP address set. Setting only the route, but no address,
|
have a static IP address set. Setting only the route, but no address,
|
||||||
means the route is skipped.
|
means the route is skipped.
|
||||||
|
|
||||||
|
> The LAN bridge (br0) in this example has IP address 192.168.1.1.
|
||||||
|
|
||||||
|
|
||||||
### Host Networking
|
### Host Networking
|
||||||
|
|
||||||
The third use-case is host networking, this is where a container share
|
The third use-case is host networking, this is where a container share
|
||||||
|
|||||||
+6
-43
@@ -66,8 +66,7 @@ The instructions here are for Debian/Ubuntu based systems (YMMV):
|
|||||||
$ sudo apt install bc binutils build-essential bzip2 cpio \
|
$ sudo apt install bc binutils build-essential bzip2 cpio \
|
||||||
diffutils file findutils git gzip \
|
diffutils file findutils git gzip \
|
||||||
libncurses-dev libssl-dev perl patch \
|
libncurses-dev libssl-dev perl patch \
|
||||||
python3 rsync sed tar unzip wget \
|
python rsync sed tar unzip wget
|
||||||
autopoint bison flex
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For testing, a few more tools and services are required on your system:
|
For testing, a few more tools and services are required on your system:
|
||||||
@@ -97,10 +96,8 @@ To see available defconfigs for supported targets, use:
|
|||||||
Development
|
Development
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Developing with Infix is the same as [developing with Buildroot][4].
|
When changing a package, locally kept sources, or when using [`local.mk`](override-package.md),
|
||||||
When working with a package, be it locally kept sources, or when using
|
you only want to rebuild the parts you have modified:
|
||||||
[`local.mk`](override-package.md), you only want to rebuild the parts
|
|
||||||
you have modified:
|
|
||||||
|
|
||||||
make foo-rebuild
|
make foo-rebuild
|
||||||
|
|
||||||
@@ -108,7 +105,7 @@ or
|
|||||||
|
|
||||||
make foo-reconfigure
|
make foo-reconfigure
|
||||||
|
|
||||||
or, as a last resort when nothing seems to bite:
|
or, when nothing seems to bite:
|
||||||
|
|
||||||
make foo-dirclean foo-rebuild
|
make foo-dirclean foo-rebuild
|
||||||
|
|
||||||
@@ -121,38 +118,6 @@ This rebuilds (and installs) `foo` and `bar`, the `all` target calls
|
|||||||
on Buildroot to finalize the target filesystem and generate the images.
|
on Buildroot to finalize the target filesystem and generate the images.
|
||||||
The final `run` argument is explained below.
|
The final `run` argument is explained below.
|
||||||
|
|
||||||
### `confd`
|
|
||||||
|
|
||||||
The Infix `src/confd/` is the engine of the system. Currently it is a
|
|
||||||
plugin for `systemd-plugind` and contains XPath subscriptions to all the
|
|
||||||
supported YANG models.
|
|
||||||
|
|
||||||
There are essentially two ways of adding support for a new YANG model:
|
|
||||||
|
|
||||||
- The [sysrepo way][3], or
|
|
||||||
- The Infix way, using libsrx (the `lydx_*()` functions)
|
|
||||||
|
|
||||||
The former is well documented in sysrepo, and the latter is best taught
|
|
||||||
by example, e.g., `src/confd/src/infix-dhcp.c`. Essentially libsrx is a
|
|
||||||
way of traversing the libyang tree instead of fetching changes by XPath.
|
|
||||||
|
|
||||||
When working with `confd` you likely want to enable full debug mode,
|
|
||||||
this is how you do it:
|
|
||||||
|
|
||||||
1. Open the file `package/confd/confd.conf`
|
|
||||||
2. Uncomment the first line `set DEBUG=1`
|
|
||||||
3. Change the following line to add `-v3` at the end
|
|
||||||
|
|
||||||
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
|
|
||||||
|
|
||||||
to:
|
|
||||||
|
|
||||||
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -v3 -- Configuration daemon
|
|
||||||
|
|
||||||
Now you can rebuild `confd`, just as described above, and restart Infix:
|
|
||||||
|
|
||||||
make confd-rebuild all run
|
|
||||||
|
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
-------
|
-------
|
||||||
@@ -176,8 +141,8 @@ and then use GitHub to create a *Pull Reqeuest*.
|
|||||||
For this to work as painlessly as possible:
|
For this to work as painlessly as possible:
|
||||||
|
|
||||||
1. Fork Infix to your own user or organization[^1]
|
1. Fork Infix to your own user or organization[^1]
|
||||||
2. Fork all the Infix submodules, e.g., `kernelkit/buildroot` to your
|
2. Fork all the Infix submodules, e.g., `buildroot` to your own user
|
||||||
own user or organization as well
|
or organization as well
|
||||||
3. Clone your fork of Infix to your laptop/workstation
|
3. Clone your fork of Infix to your laptop/workstation
|
||||||
|
|
||||||
If you use a GitHub organization you get the added benefit of having
|
If you use a GitHub organization you get the added benefit of having
|
||||||
@@ -204,5 +169,3 @@ $ git submodule update --init
|
|||||||
[0]: https://github.com/kernelkit/infix/releases
|
[0]: https://github.com/kernelkit/infix/releases
|
||||||
[1]: https://buildroot.org/downloads/manual/manual.html
|
[1]: https://buildroot.org/downloads/manual/manual.html
|
||||||
[2]: https://github.com/wkz/qeneth
|
[2]: https://github.com/wkz/qeneth
|
||||||
[3]: https://netopeer.liberouter.org/doc/sysrepo/master/html/dev_guide.html
|
|
||||||
[4]: https://buildroot.org/downloads/manual/manual.html#_developer_guide
|
|
||||||
|
|||||||
@@ -114,169 +114,6 @@ admin@example:/config/interface/br0/> set bridge vlans vlan 20 tagged br0
|
|||||||
> on top of the bridge, see section [VLAN Interfaces](#vlan-interfaces)
|
> on top of the bridge, see section [VLAN Interfaces](#vlan-interfaces)
|
||||||
> below for more on this topic.
|
> below for more on this topic.
|
||||||
|
|
||||||
#### Multicast Filtering and Snooping
|
|
||||||
|
|
||||||
Multicast filtering in the bridge is handled by the bridge itself. It
|
|
||||||
can filter both IP multicast and MAC multicast. For IP multicast it
|
|
||||||
also supports "snooping", i.e., IGMP and MLD, to automatically reduce
|
|
||||||
the broadcast effects of multicast. See the next section for a summary
|
|
||||||
of the [terminology used](#terminology--abbreviations).
|
|
||||||
|
|
||||||
> **Note:** currently there is no way to just enable multicast filtering
|
|
||||||
> without also enabling snooping. This may change in the future, in
|
|
||||||
> which case a `filtering` enabled setting will be made available along
|
|
||||||
> with the existing `snooping` setting.
|
|
||||||
|
|
||||||
When creating your bridge you must decide if you need a VLAN filtering
|
|
||||||
bridge or a plain bridge (see previous section). Multicast filtering is
|
|
||||||
supported for either, but take note that it must be enabled and set up
|
|
||||||
per VLAN when VLAN filtering is enabled -- there are no global multicast
|
|
||||||
settings in this operating mode.
|
|
||||||
|
|
||||||
In the following example we have a regular 8-port bridge without VLAN
|
|
||||||
filtering. We focus on the multicast specific settings:
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@example:/> configure
|
|
||||||
admin@example:/config/> edit interface br0
|
|
||||||
admin@example:/config/interface/br0/> set bridge multicast snooping
|
|
||||||
admin@example:/config/interface/br0/> set ipv4 address 192.168.2.1 prefix-length 24
|
|
||||||
admin@example:/config/interface/br0/> leave
|
|
||||||
admin@example:/> copy running-config startup-config
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we enable snooping and set a static IPv4 address so that the switch
|
|
||||||
can take part in IGMP querier elections. (MLD querier election
|
|
||||||
currently not supported.) We can inspect the current state:
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@example:/> show ip multicast
|
|
||||||
Multicast Overview
|
|
||||||
Query Interval (default): 125 sec
|
|
||||||
Router Timeout : 255
|
|
||||||
Fast Leave Ports :
|
|
||||||
Router Ports :
|
|
||||||
Flood Ports : e0, e1, e2, e3, e4, e5, e6, e7
|
|
||||||
|
|
||||||
Interface VID Querier State Interval Timeout Ver
|
|
||||||
br0 192.168.2.1 Up 125 None 3
|
|
||||||
|
|
||||||
Bridge VID Multicast Group Ports
|
|
||||||
br0 224.1.1.1 e3, e2
|
|
||||||
br0 ff02::6a br0
|
|
||||||
```
|
|
||||||
|
|
||||||
It is a small LAN, so our bridge has already become the elected IGMP
|
|
||||||
querier. We see it is ours because the timeout is `None`, and we
|
|
||||||
recognize our IP address. We can also see two ports that have joined
|
|
||||||
the same IPv4 multicast group, 224.1.1.1, and one join from Infix itself
|
|
||||||
for the IPv6 group ff02::6a.
|
|
||||||
|
|
||||||
Now, let's see what happens when we add another bridge, with VLAN
|
|
||||||
filtering enabled. We skip the boring parts about how to move ports
|
|
||||||
e4-e7 to `br1` and assign them to VLANs, and again, focus on the
|
|
||||||
multicast bits only:
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@example:/> configure
|
|
||||||
admin@example:/config/> edit interface br1
|
|
||||||
admin@example:/config/interface/br1/> set bridge vlans vlan 1 multicast snooping
|
|
||||||
admin@example:/config/interface/br1/> set bridge vlans vlan 2 multicast snooping
|
|
||||||
admin@example:/config/interface/br1/> leave
|
|
||||||
admin@example:/> copy running-config startup-config
|
|
||||||
```
|
|
||||||
|
|
||||||
Let's see what we get:
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@example:/> show ip multicast
|
|
||||||
Multicast Overview
|
|
||||||
Query Interval (default): 125 sec
|
|
||||||
Router Timeout : 255
|
|
||||||
Fast Leave Ports : e5
|
|
||||||
Router Ports : e1, e2, e5, e6, e7
|
|
||||||
Flood Ports : e1, e2, e3, e4, e5, e6, e7, e8
|
|
||||||
|
|
||||||
Interface VID Querier State Interval Timeout Ver
|
|
||||||
br0 192.168.2.1 Up 125 None 3
|
|
||||||
br1 1 0.0.0.0 Up 125 None 3
|
|
||||||
br1 2 0.0.0.0 Up 125 None 3
|
|
||||||
|
|
||||||
Bridge VID Multicast Group Ports
|
|
||||||
br0 224.1.1.1 e2
|
|
||||||
br0 ff02::fb br0
|
|
||||||
br0 ff02::6a br0
|
|
||||||
br0 ff02::1:ff00:0 br0
|
|
||||||
br1 1 224.1.1.1 e5
|
|
||||||
br1 2 224.1.1.1 e7
|
|
||||||
br1 1 ff02::fb br1
|
|
||||||
br1 1 ff02::1:ff00:0 br1
|
|
||||||
```
|
|
||||||
|
|
||||||
In this setup we have a lot more going on. Multiple multicast router
|
|
||||||
ports have been detected, and behind the scenes someone has also added
|
|
||||||
an IGMP/MLD fast-leave port.
|
|
||||||
|
|
||||||
##### Terminology & Abbreviations
|
|
||||||
|
|
||||||
- **IGMP**: Internet Group Membership Protocol, multicast subscription
|
|
||||||
for IPv4, for details see [RFC3376][]
|
|
||||||
- **MLD**: Multicast Listener Discovery (Protocol), multicast
|
|
||||||
subscription for IPv6, for details see [RFC3810][]
|
|
||||||
- **Unknown/Unregistered multicast**: multicast groups that are *not*
|
|
||||||
in the multicast forwarding database (MDB)
|
|
||||||
- **Known/Registered multicast**: multicast groups that *are* in the
|
|
||||||
multicast forwarding database (MDB)
|
|
||||||
- **MDB**: the multicast forwarding database, consists of filters for
|
|
||||||
multicast groups, directing where multicast is allowed to egress. A
|
|
||||||
filter entry consists of a group and a port list. The bridge filters
|
|
||||||
with a unique database per VLAN, in the same was as the unicast FDB
|
|
||||||
- **Join/Leave**: the terminology used in earlier versions of the two
|
|
||||||
protocols to subscribe and unsubscribe to a multicast group. For
|
|
||||||
more information, see *Membership Report*
|
|
||||||
- **Membership Report** A membership report is sent by end-devices and
|
|
||||||
forwarded by switches to the elected querier on the LAN. They
|
|
||||||
consist of multiple "join" and "leave" operations on groups. They
|
|
||||||
can also, per group, list which senders to allow or block. Switches
|
|
||||||
usually only support the group subscription, and even more common
|
|
||||||
also only support filtering on the MAC level[^3]
|
|
||||||
- **Querier election**: the process of determining who is the elected
|
|
||||||
IGMP/MLD querier on a LAN. Lowest numerical IP address wins, the
|
|
||||||
special address 0.0.0.0 (proxy querier) never wins
|
|
||||||
- **Proxy querier**: when no better querier exists on a LAN, one or
|
|
||||||
more devices can send proxy queries with source address 0.0.0.0 (or
|
|
||||||
:: for IPv6). See **Query Interval**, below, why this is a good
|
|
||||||
thing
|
|
||||||
- **Query interval**: the time in seconds between two queries from an
|
|
||||||
IGMP/MLD querier. It is not uncommon that end-devices do not send
|
|
||||||
their membership reports unless they first hear a query
|
|
||||||
- **Fast Leave**: set on a bridge port to ensure multicast is pruned as
|
|
||||||
quickly as possible when a "leave" membership report is received. In
|
|
||||||
effect, this option marks the port as directly connected to an
|
|
||||||
end-device. When not set (default), a query with timeout is first
|
|
||||||
sent to ensure no unintentional loss of multicast is incurred
|
|
||||||
- **Router port**: can be both configured statically and detected at
|
|
||||||
runtime based on connected devices, usually multicast routers. On
|
|
||||||
a router port *all* multicast is forwarded, both known and unknown
|
|
||||||
- **Flood port**: set on a bridge port (default: enabled) to ensure
|
|
||||||
all *unknown* multicast is forwarded
|
|
||||||
- **Router timeout**: the time in seconds until a querier is deemed to
|
|
||||||
have been lost and another device (switch/router) takes over. In the
|
|
||||||
tables shown above, a *None* timeout is declared when the current
|
|
||||||
device is the active querier
|
|
||||||
|
|
||||||
> **Note:** the reason why multicast flooding is enabled by default is
|
|
||||||
> to ensure safe co-existence with MAC multicast, which is very common
|
|
||||||
> in industrial networks. It also allows end devices that do not know
|
|
||||||
> of IGMP/MLD to communicate over multicast as long as the group they
|
|
||||||
> have chosen is not used by other IGMP/MLD aware devices on the LAN.
|
|
||||||
>
|
|
||||||
> As soon as an IGMP/MLD membership report to "join" a group is received
|
|
||||||
> the group is added to the MDB and forwarding to other ports stop. The
|
|
||||||
> only exception to this rule is multicast router ports.
|
|
||||||
|
|
||||||
[RFC3376]: https://www.rfc-editor.org/rfc/rfc3376.html
|
|
||||||
[RFC3810]: https://www.rfc-editor.org/rfc/rfc3810.html
|
|
||||||
|
|
||||||
### VLAN Interfaces
|
### VLAN Interfaces
|
||||||
|
|
||||||
@@ -797,7 +634,3 @@ currently supported, namely `ipv4` and `ipv6`.
|
|||||||
[^2]: Link-local IPv6 addresses are implicitly enabled when enabling
|
[^2]: Link-local IPv6 addresses are implicitly enabled when enabling
|
||||||
IPv6. IPv6 can be enabled/disabled per interface in the
|
IPv6. IPv6 can be enabled/disabled per interface in the
|
||||||
[ietf-ip][2] YANG model.
|
[ietf-ip][2] YANG model.
|
||||||
[^3]: For example, IPv4 groups are mapped to MAC multicast addresses by
|
|
||||||
mapping the low-order 23-bits of the IP address in the low-order 23
|
|
||||||
bits of the Ethernet address 01:00:5E:00:00:00. Meaning, more than
|
|
||||||
one IP multicast group maps to the same MAC multicast group.
|
|
||||||
|
|||||||
+30
-55
@@ -1,75 +1,50 @@
|
|||||||
Package Override
|
Package override
|
||||||
================
|
================
|
||||||
|
|
||||||
This guide demonstrates how the `local.mk` file is utilized to override
|
This guide demonstrates how the `local.mk` file is utilized to override
|
||||||
a Linux Buildroot package. As an example we use `tcpdump` to illustrate
|
a Linux Buildroot package. The example of `tcpdump` serves to illustrate
|
||||||
this process.
|
this process.
|
||||||
|
|
||||||
> For a comprehensive guide to utilizing Buildroot during development,
|
In an instance such as `Infix` using tcpdump, the `local.mk` file is modified
|
||||||
> including the `<pkg>_OVERRIDE_SRCDIR` mechanism, shown below, please
|
as shown below:
|
||||||
> see [Using Buildroot during development][1] in the official docs.
|
|
||||||
|
|
||||||
|
|
||||||
Setup
|
|
||||||
-----
|
|
||||||
|
|
||||||
Since the `output/` directory is often wiped for rebuilds, make sure you
|
|
||||||
keep the file `local.mk` in the top directory and only symlink it to your
|
|
||||||
build directory:
|
|
||||||
|
|
||||||
~$ cd infix/
|
|
||||||
~/infix(main)$ touch local.mk
|
|
||||||
~/infix/output(main)$ ln -s ../local.mk .
|
|
||||||
~/infix/output(main)$ cd ..
|
|
||||||
|
|
||||||
|
|
||||||
Override
|
|
||||||
--------
|
|
||||||
|
|
||||||
Now edit the file:
|
|
||||||
|
|
||||||
~/infix(main)$ editor local.mk
|
|
||||||
|
|
||||||
Add an override for `tcpdump`. The file is a Makefile snippet so you
|
|
||||||
can add a lot of things. Comment out lines with the UNIX comment `#`
|
|
||||||
character if needed:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
TCPDUMP_OVERRIDE_SRCDIR = /path/to/tcpdump/repo
|
TCPDUMP_OVERRIDE_SRCDIR = /path/to/tcpdump/repo
|
||||||
```
|
```
|
||||||
|
|
||||||
Building
|
and stored in the `output/` folder, alongside the `.config` file:
|
||||||
--------
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
~/infix$(main)$ make tcpdump-rebuild all
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
Buildroot follows a process of downloading and processing tarballs:
|
The execution of `make tcpdump-rebuild all` triggers a process where
|
||||||
extraction, configuration, compilation, and installation. The source
|
Buildroot synchronizes the tcpdump source code from the specified override directory
|
||||||
for each package is extracted to a temporary build directory:
|
to `output/build/tcpdump-custom`, followed by the rebuilding of the entire project.
|
||||||
|
|
||||||
output/build/<package>-<version> # e.g., tcpdump-4.99.4
|
|
||||||
|
|
||||||
Let's have a look at what we got:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
~/infix$(main)$ ll /output/build/ | grep tcpdump
|
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 20480 Nov 10 18:26 tcpdump-4.99.4/
|
||||||
drwxr-xr-x 7 group user 12288 Nov 10 18:28 tcpdump-custom/
|
drwxr-xr-x 7 group user 12288 Nov 10 18:28 tcpdump-custom/
|
||||||
```
|
```
|
||||||
|
|
||||||
As long as your local override is in place, Buildroot will use your
|
Buildroot follows a process of downloading and processing tarballs
|
||||||
custom version.
|
(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**.
|
||||||
|
|
||||||
> **Remember:** the build directory is ephemeral, so be careful to
|
To manage the development changes more effectively, where the package source code
|
||||||
> change any of the files therein. It can be useful though during
|
remains untouched, Buildroot incorporates the `<pkg>_OVERRIDE_SRCDIR` feature.
|
||||||
> debugging, but just make sure to learn the difference between the
|
|
||||||
> various Buildroot commands to build, clean, reconfigure, etc.
|
|
||||||
|
|
||||||
[1]: https://buildroot.org/downloads/manual/manual.html#_using_buildroot_during_development
|
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/).
|
||||||
+3
-808
@@ -168,9 +168,9 @@ There are two ways to do it:
|
|||||||
1. Change the configuration without saving it to `startup-config`
|
1. Change the configuration without saving it to `startup-config`
|
||||||
2. Change the operational state
|
2. Change the operational state
|
||||||
|
|
||||||
The first involves sending a NETCONF command/config in XML. The second
|
The first involves sending a NETCONF command/config in XML, the second
|
||||||
we will cover here. We start by querying available interfaces (ports) on
|
we will cover here. We start by querying available interfaces (ports)
|
||||||
the remote system:
|
on the remote system:
|
||||||
|
|
||||||
```
|
```
|
||||||
~$ ssh admin@infix.local%qtap0 ip -br a
|
~$ ssh admin@infix.local%qtap0 ip -br a
|
||||||
@@ -331,811 +331,6 @@ admin@infix.local%eth0's password: *****
|
|||||||
~$
|
~$
|
||||||
```
|
```
|
||||||
|
|
||||||
### Controlling LEDs for Production Tests
|
|
||||||
|
|
||||||
As part of production testing, LED verification is often expected to
|
|
||||||
be performed. Infix uses standard [Linux support for LED
|
|
||||||
management][6], where LEDs appear in the file system under
|
|
||||||
/sys/class/leds and can be controlled using *echo* command. `sudo`
|
|
||||||
privileges are required.
|
|
||||||
|
|
||||||
When interacting with LEDs this way, first disable the Infix *iitod*
|
|
||||||
daemon to avoid conflicting LED control.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'initctl stop iitod'
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run the test, e.g., visually control that a red LED labeled
|
|
||||||
'LAN' is working.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
|
|
||||||
~$ ssh admin@example.local 'echo 1 | sudo tee /sys/class/leds/red\:lan/brightness'
|
|
||||||
```
|
|
||||||
|
|
||||||
To turn off the same LED, run the following commands.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'echo none | sudo tee /sys/class/leds/red\:lan/trigger'
|
|
||||||
~$ ssh admin@example.local 'echo 0 | sudo tee /sys/class/leds/red\:lan/brightness'
|
|
||||||
```
|
|
||||||
When done with LED testing, enable Infix *iitod* daemon again.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'initctl start iitod'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reading Power Feed Status for Production Tests
|
|
||||||
|
|
||||||
As part of production tests, verification of Power Feed sensors is
|
|
||||||
often expected to be performed. Infix uses standard [Linux support for
|
|
||||||
Power management][7], where power sources appear in the file system
|
|
||||||
under /sys/class/power_supply. The following example reads status of
|
|
||||||
two power supplies named *pwr1* and *pwr2*.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example 'cat /sys/class/power_supply/pwr1/online'
|
|
||||||
1
|
|
||||||
~$ ssh admin@example 'cat /sys/class/power_supply/pwr2/online'
|
|
||||||
0
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
Here, only *pwr1* happened to have power.
|
|
||||||
|
|
||||||
|
|
||||||
## Examples using SSH and sysrepocfg
|
|
||||||
|
|
||||||
|
|
||||||
[sysrepocfg][4] can be used to interact with the YANG models when logged
|
|
||||||
in to infix. Thus, *set config*, *read config*, *read status* and
|
|
||||||
*RPC* can be conducted using sysrepocfg for supported YANG models.
|
|
||||||
It is possible to make configuration changes by operating on the
|
|
||||||
*startup* database.
|
|
||||||
|
|
||||||
See [sysrepocfg][4] for information. Examples below will utilize
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- `sysrepocfg -I FILE -fjson -d DATABASE` to import/write a JSON
|
|
||||||
formatted configuration file to the specified database.
|
|
||||||
- `sysrepocfg -E FILE -fjson -d DATABASE` to edit/merge JSON formatted
|
|
||||||
configuration in FILE with the specified database.
|
|
||||||
- `sysrepocfg -R FILE -fjson` to execute remote procedure call (RPC) defined in
|
|
||||||
FILE (JSON formatted).
|
|
||||||
- `sysrepocfg -X -fjson -d DATABASE -x xpath` to read configuration or
|
|
||||||
status from specified database.
|
|
||||||
|
|
||||||
For importing (-I) and editing (-E), `-d running` is typically used in
|
|
||||||
examples below. Specify `-d startup` to apply changes to startup
|
|
||||||
configuration. Exporting (-X) could operate on configuration (e.g.,
|
|
||||||
`-d running`) or status (`-d operational`).
|
|
||||||
|
|
||||||
Some commands require a file as input. In examples below we assume
|
|
||||||
it been transferred to Infix in advance, e.g. using `scp` as shown below.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat file.json
|
|
||||||
{
|
|
||||||
"ietf-factory-default:factory-reset": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
### Factory Reset Using sysrepocfg
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat file.json
|
|
||||||
{
|
|
||||||
"ietf-factory-default:factory-reset": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
|
|
||||||
^C
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
See [Factory Reset](#factory-reset) for another (simpler) alternative.
|
|
||||||
|
|
||||||
If it is only wished to copy factory config to running config the
|
|
||||||
following RPC is available
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat file.json
|
|
||||||
{
|
|
||||||
"infix-factory-default:factory-default": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
|
|
||||||
^C
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### System Reboot Using sysrepocfg
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat /tmp/file.json
|
|
||||||
{
|
|
||||||
"ietf-system:system-restart": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
See [System Reboot](#system-reboot) for another (simpler) alternative.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Set Date and Time Using sysrepocfg
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'date'
|
|
||||||
Sun Nov 20 10:20:23 UTC 2005
|
|
||||||
~$ cat file.json
|
|
||||||
{
|
|
||||||
"ietf-system:set-current-datetime": {
|
|
||||||
"current-datetime": "2024-04-17T13:48:02-01:00"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -fjson -R /tmp/file.json'
|
|
||||||
~$ ssh admin@example.local 'date'
|
|
||||||
Wed Apr 17 14:48:12 UTC 2024
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
See [Set Date and Time](#set-date-and-time) for another (simpler) alternative.
|
|
||||||
|
|
||||||
### Remote Control of Ethernet Ports Using sysrepocfg
|
|
||||||
|
|
||||||
|
|
||||||
Reading administrative status of interface *e0* of running configuration.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running -e report-all -x \"/ietf-interfaces:interfaces/interface[name='e0']/enabled\"'
|
|
||||||
{
|
|
||||||
"ietf-interfaces:interfaces": {
|
|
||||||
"interface": [
|
|
||||||
{
|
|
||||||
"name": "e0",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
> Note: Without `-e report-all` argument the line `"enabled: true`
|
|
||||||
> would not be shown as `true` is default.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local "sysrepocfg -X -fjson -d running -x \"/ietf-interfaces:interfaces/interface[name='e0']/enabled\""
|
|
||||||
{
|
|
||||||
"ietf-interfaces:interfaces": {
|
|
||||||
"interface": [
|
|
||||||
{
|
|
||||||
"name": "e0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Setting the administrative status of interface *e0* of running configuration.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cat file.json
|
|
||||||
{
|
|
||||||
"ietf-interfaces:interfaces": {
|
|
||||||
"interface": [
|
|
||||||
{
|
|
||||||
"name": "e0",
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable/Disable DHCPv4 client
|
|
||||||
|
|
||||||
|
|
||||||
Enabling DHCPv4 client on interface *e0*, with current default options.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat /tmp/file.json
|
|
||||||
{
|
|
||||||
"infix-dhcp-client:dhcp-client": {
|
|
||||||
"enabled": true,
|
|
||||||
"client-if": [
|
|
||||||
{
|
|
||||||
"if-name": "e0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
Disabling DHCPv4 client.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat /tmp/file.json
|
|
||||||
{
|
|
||||||
"infix-dhcp-client:dhcp-client": {
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
Configuration for client interface *e0* remains, but does not apply as
|
|
||||||
DHCPv4 is disabled.
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@example:~$ sysrepocfg -X -fjson -d running -x "/infix-dhcp-client:dhcp-client"
|
|
||||||
{
|
|
||||||
"infix-dhcp-client:dhcp-client": {
|
|
||||||
"enabled": false,
|
|
||||||
"client-if": [
|
|
||||||
{
|
|
||||||
"if-name": "e0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
admin@example:~$
|
|
||||||
```
|
|
||||||
|
|
||||||
To fully remove the DHCPv4 client configuration or a specific
|
|
||||||
*client-if* with sysrepocfg, one would need to read out the full
|
|
||||||
configuration, remove relevant parts and read back.
|
|
||||||
|
|
||||||
|
|
||||||
### Enable/Disable IPv6
|
|
||||||
|
|
||||||
IPv6 is typically enabled on all interfaces by default. The example
|
|
||||||
below shows IPv4 and IPv6 addresses assigned on *e0*.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'ip addr show dev e0'
|
|
||||||
2: e0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
|
||||||
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
|
|
||||||
inet 10.0.2.15/24 scope global proto dhcp e0
|
|
||||||
valid_lft forever preferred_lft forever
|
|
||||||
inet6 fec0::ff:fe00:0/64 scope site dynamic mngtmpaddr proto kernel_ra
|
|
||||||
valid_lft 86380sec preferred_lft 14380sec
|
|
||||||
inet6 fe80::ff:fe00:0/64 scope link proto kernel_ll
|
|
||||||
valid_lft forever preferred_lft forever
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
IPv6 is enabled/disabled per interface. The example below disables IPv6
|
|
||||||
on interface *e0*.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ cat /tmp/file.json
|
|
||||||
{
|
|
||||||
"ietf-interfaces:interfaces": {
|
|
||||||
"interface": [
|
|
||||||
{
|
|
||||||
"name": "e0",
|
|
||||||
"ietf-ip:ipv6": {
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$ scp file.json admin@example.local:/tmp/file.json
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running'
|
|
||||||
~$ ssh admin@example.local 'ip addr show dev e0'
|
|
||||||
2: e0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
|
||||||
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
|
|
||||||
inet 10.0.2.15/24 scope global proto dhcp e0
|
|
||||||
valid_lft forever preferred_lft forever
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
### <a id="backup"></a> Backup Configuration Using sysrepocfg And scp
|
|
||||||
|
|
||||||
Displaying running or startup configuration is possible with
|
|
||||||
`sysrepocfg -X`, as shown below.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running'
|
|
||||||
{
|
|
||||||
"ieee802-dot1ab-lldp:lldp": {
|
|
||||||
"infix-lldp:enabled": true
|
|
||||||
...
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
An example for backing up startup configuration from remote PC.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d startup > /tmp/backup.json'
|
|
||||||
~$ scp admin@example.local:/tmp/backup.json .
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
Or possibly skip intermediate storage of file
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d startup' > backup.json
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
A final example is to only use `scp`. This is simpler, but only works to backup the
|
|
||||||
startup configuration (not running).
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ scp admin@example.local:/cfg/startup-config.cfg backup.json
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
### <a id="restore"></a> Restore Configuration Using sysrepocfg and ssh/scp
|
|
||||||
|
|
||||||
|
|
||||||
To restore a backup configuration to startup, the simplest way is to
|
|
||||||
use `scp` and reboot as shown below
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ scp admin@example.local:/cfg/startup-config.cfg backup.json
|
|
||||||
~$ ssh admin@example.local 'reboot'
|
|
||||||
Connection to switch.local closed by remote host.
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
An alternative method to restore a backup configuration is to use the
|
|
||||||
`sysrepocfg -I FILE` (import) command.
|
|
||||||
|
|
||||||
The example below imports the backup configuration to startup, and
|
|
||||||
reboots the unit.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ scp backup.json admin@example.local:/tmp/
|
|
||||||
~$ ssh admin@example.local 'sudo sysrepocfg -I /tmp/backup.json -fjson -d startup'
|
|
||||||
~$ ssh admin@example.local 'reboot'
|
|
||||||
Connection to switch.local closed by remote host.
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
> Note: admin login credentials (hash) are stored as part of the
|
|
||||||
> configuration file. When replacing a switch and applying the backed
|
|
||||||
> up configuration from the former switch, the password on the
|
|
||||||
> replacement unit will also change.
|
|
||||||
|
|
||||||
### Copy Running to Startup Using sysrepocfg
|
|
||||||
|
|
||||||
The following command reads out the running config via `sysrepocfg -X`
|
|
||||||
and writes the result to the startup configuration.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running > /cfg/startup-config.cfg'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
An alternative is to write it to a temporary file, and use `sysrepocfg
|
|
||||||
-I` to import it to startup.
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d running > /tmp/running.json'
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -I /tmp/running.json -fjson -d startup'
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
### Read Out Hardware Information Using sysrepocfg
|
|
||||||
|
|
||||||
Infix supports IETF Hardware YANG with augments for ONIE formatted
|
|
||||||
production data stored in EEPROMs, if available. See Infix [VPD
|
|
||||||
documentation][5], as well as *ietf-hardware* and *infix-hardware* YANG
|
|
||||||
models for details.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
~$ ssh admin@example.local 'sysrepocfg -X -fjson -d operational -x /ietf-hardware:hardware'
|
|
||||||
{
|
|
||||||
"ietf-hardware:hardware": {
|
|
||||||
"component": [
|
|
||||||
{
|
|
||||||
"name": "product",
|
|
||||||
"class": "infix-hardware:vpd",
|
|
||||||
"serial-num": "12345",
|
|
||||||
"model-name": "Switch2010",
|
|
||||||
"mfg-date": "2024-01-30T16:42:37+00:00",
|
|
||||||
"infix-hardware:vpd-data": {
|
|
||||||
"product-name": "Switch2010",
|
|
||||||
"part-number": "ABC123-001",
|
|
||||||
"serial-number": "007",
|
|
||||||
"mac-address": "00:53:00:01:23:45",
|
|
||||||
"manufacture-date": "01/30/2024 16:42:37",
|
|
||||||
"num-macs": 11,
|
|
||||||
"manufacturer": "ACME Production",
|
|
||||||
"vendor": "SanFran Networks"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "USB",
|
|
||||||
"class": "infix-hardware:usb",
|
|
||||||
"state": {
|
|
||||||
"admin-state": "unlocked",
|
|
||||||
"oper-state": "enabled"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~$
|
|
||||||
```
|
|
||||||
|
|
||||||
## Miscellaneous
|
|
||||||
|
|
||||||
### <a id="port-test-intro"></a> Port Configuration Example for Production Tests
|
|
||||||
|
|
||||||
As part of production tests, verification Ethernet ports are expected
|
|
||||||
to be performed. A common way is to connect a test PC to two ports and
|
|
||||||
send a *ping* traversing all ports. This can be achieved by using
|
|
||||||
VLANs on the switch as described in this section. The resulting
|
|
||||||
configuration file can be applied to the running configuration of the
|
|
||||||
produced unit, e.g, use config file restore as described
|
|
||||||
[above](#restore).
|
|
||||||
|
|
||||||
In this example we assume a 10 port switch, with ports e1-e10.
|
|
||||||
|
|
||||||
The following VLAN configuration and cable connections will be used:
|
|
||||||
|
|
||||||
| VLAN & Ports | Connect |
|
|
||||||
|:------------------|:----------|
|
|
||||||
| VLAN 10: e1 & e2 | e2 <=> e3 |
|
|
||||||
| VLAN 20: e3 & e4 | e4 <=> e5 |
|
|
||||||
| VLAN 30: e5 & e6 | e6 <=> e7 |
|
|
||||||
| VLAN 40: e7 & e8 | e8 <=> e9 |
|
|
||||||
| VLAN 50: e9 & e10 | |
|
|
||||||
|
|
||||||
The test PC is connected to e1 and e10 via different interfaces
|
|
||||||
(alternatively, two different PCs are used).
|
|
||||||
|
|
||||||
> Configuration here is done via console. When configuring remotely
|
|
||||||
> over SSH, remember to keep one IP address (the one used for the SSH
|
|
||||||
> connection)! I.e., set a static IP address first, then perform the
|
|
||||||
> VLAN configuration step."
|
|
||||||
|
|
||||||
#### Configuration at Start
|
|
||||||
|
|
||||||
Starting out, we assume a configuration where all ports are network
|
|
||||||
interfaces (possibly with IPv6 enabled).
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/> show interfaces
|
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
|
||||||
ipv4 127.0.0.1/8 (static)
|
|
||||||
ipv6 ::1/128 (static)
|
|
||||||
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
|
|
||||||
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
|
|
||||||
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
|
|
||||||
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
|
|
||||||
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
|
|
||||||
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
|
|
||||||
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
|
|
||||||
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
|
|
||||||
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
|
|
||||||
e10 ethernet UP 00:53:00:06:11:0a
|
|
||||||
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Creating Bridge and Adding Ports
|
|
||||||
|
|
||||||
The example below uses Infix documentation on [creating bridges][8].
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/> configure
|
|
||||||
admin@example:/config/> edit interface br0
|
|
||||||
admin@example:/config/interface/br0/> end
|
|
||||||
admin@example:/config/> set interface e1 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e2 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e3 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e4 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e5 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e6 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e7 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e8 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e9 bridge-port bridge br0
|
|
||||||
admin@example:/config/> set interface e10 bridge-port bridge br0
|
|
||||||
admin@example:/config/>
|
|
||||||
```
|
|
||||||
|
|
||||||
The interface status can be viewed using "show interface" after
|
|
||||||
leaving configuration context. If configuration via SSH, first assign
|
|
||||||
an IP address to br0 before *leaving* configuration context, e.g.,
|
|
||||||
`set interface br0 ipv6 enabled` to get auto-configured IPv6
|
|
||||||
address. Or skip 'leave' and stay in configuration context until done
|
|
||||||
with all sections, including the one on [Add IP on
|
|
||||||
Switch](#ip-on-switch).
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/config/> leave
|
|
||||||
admin@example:/>
|
|
||||||
admin@example:/> show interfaces
|
|
||||||
INTERFACE PROTOCOL STATE DATA
|
|
||||||
br0 bridge
|
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
|
||||||
├ e1 bridge LOWER-DOWN
|
|
||||||
├ e2 bridge LOWER-DOWN
|
|
||||||
├ e3 bridge LOWER-DOWN
|
|
||||||
├ e4 bridge LOWER-DOWN
|
|
||||||
├ e5 bridge LOWER-DOWN
|
|
||||||
├ e6 bridge LOWER-DOWN
|
|
||||||
├ e7 bridge LOWER-DOWN
|
|
||||||
├ e8 bridge LOWER-DOWN
|
|
||||||
├ e9 bridge LOWER-DOWN
|
|
||||||
└ e10 bridge FORWARDING
|
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
|
||||||
ipv4 127.0.0.1/8 (static)
|
|
||||||
ipv6 ::1/128 (static)
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Assign VLANs to Ports
|
|
||||||
|
|
||||||
Then configure VLANs as outlined [above](#port-test-intro):
|
|
||||||
default VID for ingress (PVID), which is done per port, and egress
|
|
||||||
mode (untagged), which is done at the bridge level. See Infix
|
|
||||||
[documentation for VLAN bridges][9] for more information.
|
|
||||||
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/>
|
|
||||||
admin@example:/> configure
|
|
||||||
admin@example:/config/> set interface e1 bridge-port pvid 10
|
|
||||||
admin@example:/config/> set interface e2 bridge-port pvid 10
|
|
||||||
admin@example:/config/> set interface e3 bridge-port pvid 20
|
|
||||||
admin@example:/config/> set interface e4 bridge-port pvid 20
|
|
||||||
admin@example:/config/> set interface e5 bridge-port pvid 30
|
|
||||||
admin@example:/config/> set interface e6 bridge-port pvid 30
|
|
||||||
admin@example:/config/> set interface e7 bridge-port pvid 40
|
|
||||||
admin@example:/config/> set interface e8 bridge-port pvid 40
|
|
||||||
admin@example:/config/> set interface e9 bridge-port pvid 50
|
|
||||||
admin@example:/config/> set interface e10 bridge-port pvid 50
|
|
||||||
admin@example:/config/> edit interface br0
|
|
||||||
admin@example:/config/interface/br0/> edit bridge vlans
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e1
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 untagged e2
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e3
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 20 untagged e4
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e5
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 30 untagged e6
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e7
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 40 untagged e8
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e9
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 50 untagged e10
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> leave
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Interface status would now should something like the following
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/> show interfaces
|
|
||||||
INTERFACE PROTOCOL STATE DATA
|
|
||||||
br0 bridge
|
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
|
||||||
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
|
|
||||||
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
|
|
||||||
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
|
|
||||||
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
|
|
||||||
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
|
|
||||||
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
|
|
||||||
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
|
|
||||||
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
|
|
||||||
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
|
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
|
||||||
ipv4 127.0.0.1/8 (static)
|
|
||||||
ipv6 ::1/128 (static)
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Connect Cables and Test
|
|
||||||
|
|
||||||
We can now connect the PC to e1 and e10, and the other ports are
|
|
||||||
patched according to plan [above](#port-test-intro). We should get
|
|
||||||
link up on all ports.
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/> show interfaces
|
|
||||||
INTERFACE PROTOCOL STATE DATA
|
|
||||||
br0 bridge
|
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
|
||||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
|
||||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
|
||||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
|
||||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
|
||||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
|
||||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
|
||||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
|
||||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
|
||||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
|
||||||
ipv4 127.0.0.1/8 (static)
|
|
||||||
ipv6 ::1/128 (static)
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we use IPv6 ping all hosts (ff02::1) on PC interface eth1 to
|
|
||||||
check reachability to the other interface of the PC.
|
|
||||||
|
|
||||||
> A recommendation is to use network name spaces on PC to ensure
|
|
||||||
> traffic really goes out to switch, instead of being looped
|
|
||||||
> internally. Or use two PCs.
|
|
||||||
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
~ $ ping -L ff02::1%eth1
|
|
||||||
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.496 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.514 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.473 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.736 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.563 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.507 ms
|
|
||||||
^C
|
|
||||||
--- ff02::1%eth1 ping statistics ---
|
|
||||||
6 packets transmitted, 6 received, 0% packet loss, time 5108ms
|
|
||||||
rtt min/avg/max/mdev = 0.473/0.548/0.736/0.088 ms
|
|
||||||
~ $
|
|
||||||
```
|
|
||||||
|
|
||||||
We can verify that traffic goes through the switch by disconnecting
|
|
||||||
one of the patch cables, e.g., between e4 and e5
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
~ $ ping -L ff02::1%eth1
|
|
||||||
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.510 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.448 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.583 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.515 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=5 ttl=64 time=0.521 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=6 ttl=64 time=0.495 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=7 ttl=64 time=0.743 ms
|
|
||||||
... Disconnecting patch cable, thus losing packets
|
|
||||||
... and reconnecting again. Connectivity resumes.
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=16 ttl=64 time=0.961 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=17 ttl=64 time=0.513 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=18 ttl=64 time=0.794 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=19 ttl=64 time=0.755 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=20 ttl=64 time=0.779 ms
|
|
||||||
^C
|
|
||||||
--- ff02::1%eth1 ping statistics ---
|
|
||||||
20 packets transmitted, 12 received, 40% packet loss, time 19432ms
|
|
||||||
rtt min/avg/max/mdev = 0.448/0.634/0.961/0.156 ms
|
|
||||||
~ $
|
|
||||||
```
|
|
||||||
|
|
||||||
#### <a id="ip-on-switch"></a> Add IP Address on Switch
|
|
||||||
|
|
||||||
The configuration so far does not provide a means to connect to the
|
|
||||||
switch management via SSH or NETCONF, as the switch has no IP
|
|
||||||
address. The example below shows how to add the switch to VLAN 10 (as
|
|
||||||
used for ports e1 and e2) and enables IPv6.
|
|
||||||
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/config/> edit interface vlan10
|
|
||||||
admin@example:/config/interface/vlan10/> set vlan lower-layer-if br0
|
|
||||||
admin@example:/config/interface/vlan10/> set ipv6 enabled
|
|
||||||
admin@example:/config/interface/vlan10/> show
|
|
||||||
type vlan;
|
|
||||||
ipv6 {
|
|
||||||
enabled true;
|
|
||||||
}
|
|
||||||
vlan {
|
|
||||||
tag-type c-vlan;
|
|
||||||
id 10;
|
|
||||||
lower-layer-if br0;
|
|
||||||
}
|
|
||||||
admin@example:/config/interface/vlan10/>
|
|
||||||
admin@example:/config/interface/vlan10/> end
|
|
||||||
admin@example:/config/> edit interface br0 bridge vlans
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> set vlan 10 tagged br0
|
|
||||||
admin@example:/config/interface/br0/bridge/vlans/> leave
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Interface *vlan10* with an auto-configured IPv6 address should appear.
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
admin@example:/> show interfaces
|
|
||||||
INTERFACE PROTOCOL STATE DATA
|
|
||||||
br0 bridge vlan:10t
|
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
|
||||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
|
||||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
|
||||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
|
||||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
|
||||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
|
||||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
|
||||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
|
||||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
|
||||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
|
||||||
ipv4 127.0.0.1/8 (static)
|
|
||||||
ipv6 ::1/128 (static)
|
|
||||||
vlan10 ethernet UP 00:53:00:06:11:01
|
|
||||||
│ ipv6 fe80::0053:00ff:fe06:1101/64 (link-layer)
|
|
||||||
└ br0 ethernet UP 00:53:00:06:11:01
|
|
||||||
admin@example:/>
|
|
||||||
```
|
|
||||||
|
|
||||||
When pinging "IPv6 all hosts" from the PC, there should be two
|
|
||||||
responses for every ping, one from the switch and one from the PC
|
|
||||||
attached to e10.
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
~ $ ping -L ff02::1%eth1
|
|
||||||
PING ff02::1%eth1(ff02::1%eth1) 56 data bytes
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=1 ttl=64 time=0.508 ms
|
|
||||||
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=1 ttl=64 time=0.968 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=2 ttl=64 time=0.866 ms
|
|
||||||
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=2 ttl=64 time=0.867 ms
|
|
||||||
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=3 ttl=64 time=0.467 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=3 ttl=64 time=0.469 ms
|
|
||||||
64 bytes from fe80::488a:a35f:9d41:ac9c%eth1: icmp_seq=4 ttl=64 time=0.452 ms
|
|
||||||
64 bytes from fe80::0053:00ff:fe06:1101%eth1: icmp_seq=4 ttl=64 time=0.453 ms
|
|
||||||
^C
|
|
||||||
--- ff02::1%eth1 ping statistics ---
|
|
||||||
4 packets transmitted, 4 received, +4 duplicates, 0% packet loss, time 3031ms
|
|
||||||
rtt min/avg/max/mdev = 0.452/0.631/0.968/0.211 ms
|
|
||||||
~ $
|
|
||||||
```
|
|
||||||
|
|
||||||
It should now be possible to access the switch from the PC via SSH (or NETCONF).
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
~ $ ssh admin@fe80::0053:00ff:fe06:1101%eth1
|
|
||||||
admin@fe80::0053:00ff:fe06:1101%eth1's password:
|
|
||||||
.-------.
|
|
||||||
| . . | Infix -- a Network Operating System
|
|
||||||
|-. v .-| https://kernelkit.github.io
|
|
||||||
'-'---'-'
|
|
||||||
|
|
||||||
Run the command 'cli' for interactive OAM
|
|
||||||
|
|
||||||
admin@example:~$ exit
|
|
||||||
~ $
|
|
||||||
```
|
|
||||||
|
|
||||||
See previous sections on [backup](#backup) and [restore](#restore) of
|
|
||||||
the created configuration.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[1]: discovery.md
|
[1]: discovery.md
|
||||||
[2]: https://rauc.io/
|
[2]: https://rauc.io/
|
||||||
[3]: boot.md#system-upgrade
|
[3]: boot.md#system-upgrade
|
||||||
[4]: https://netopeer.liberouter.org/doc/sysrepo/libyang1/html/sysrepocfg.html
|
|
||||||
[5]: vpd.md
|
|
||||||
[6]: https://docs.kernel.org/leds/leds-class.html
|
|
||||||
[7]: https://docs.kernel.org/power/power_supply_class.html
|
|
||||||
[8]: networking.md#bridging
|
|
||||||
[9]: networking.md#vlan-filtering-bridge
|
|
||||||
|
|||||||
@@ -70,72 +70,6 @@ admin@host:/config/system/authentication/user/admin/authorized-key/example@host/
|
|||||||
> does the job.
|
> does the job.
|
||||||
|
|
||||||
|
|
||||||
## Multiple Users
|
|
||||||
|
|
||||||
The system supports multiple users and multiple user levels, or groups,
|
|
||||||
that a user can be a member of. Access control is entirely handled by
|
|
||||||
the NETCONF ["NACM"][3] YANG model, which provides granular access to
|
|
||||||
configuration, data, and RPC commands over NETCONF.
|
|
||||||
|
|
||||||
By default the system ships with a single group, `admin`, which the
|
|
||||||
default user `admin` is a member of. The broad permissions granted by
|
|
||||||
the `admin` group is what gives its users full system administrator
|
|
||||||
privileges. There are no restrictions on the number of users with
|
|
||||||
administrator privileges, nor is the `admin` user reserved or protected
|
|
||||||
in any way -- it is completely possible to remove the default `admin`
|
|
||||||
user from the configuration. However, it is recommended to keep at
|
|
||||||
least one user with administrator privileges in the system, otherwise
|
|
||||||
the only way to regain full access is to perform a *factory reset*.
|
|
||||||
|
|
||||||
### Adding a User
|
|
||||||
|
|
||||||
Similar to how to change password, adding a new user is done using the
|
|
||||||
same set of commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@host:/config/> edit system authentication user jacky
|
|
||||||
admin@host:/config/system/authentication/user/jacky/> change password
|
|
||||||
New password:
|
|
||||||
Retype password:
|
|
||||||
admin@host:/config/system/authentication/user/jacky/> leave
|
|
||||||
```
|
|
||||||
|
|
||||||
An authorized SSH key is added the same way as presented previously.
|
|
||||||
|
|
||||||
### Adding a User to the Admin Group
|
|
||||||
|
|
||||||
The following commands add user `jacky` to the `admin` group.
|
|
||||||
|
|
||||||
```
|
|
||||||
admin@host:/config/> edit nacm group admin
|
|
||||||
admin@host:/config/nacm/group/admin/> set user-name jacky
|
|
||||||
admin@host:/config/nacm/group/admin/> leave
|
|
||||||
```
|
|
||||||
|
|
||||||
### Security Aspects
|
|
||||||
|
|
||||||
The NACM user levels apply primarily to NETCONF, with exception of the
|
|
||||||
`admin` group which is granted full system administrator privileges to
|
|
||||||
the underlying UNIX system with the following ACL rules:
|
|
||||||
|
|
||||||
```json
|
|
||||||
...
|
|
||||||
"module-name": "*",
|
|
||||||
"access-operations": "*",
|
|
||||||
"action": "permit",
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
A user in the `admin` group is allowed to also use a POSIX login shell
|
|
||||||
and use the `sudo` command to perform system administrative commands.
|
|
||||||
This makes it possible to use all the underlying UNIX tooling, which
|
|
||||||
to many can be very useful, in particular when debugging a system, but
|
|
||||||
please remember to use with care -- the system is not built to require
|
|
||||||
managing from the shell. The tools available in the CLI and automated
|
|
||||||
services, started from the system's configuration, are the recommended
|
|
||||||
way of using the system, in addition to NETCONF tooling.
|
|
||||||
|
|
||||||
|
|
||||||
## Changing Hostname
|
## Changing Hostname
|
||||||
|
|
||||||
Notice how the hostname in the prompt does not change until the change
|
Notice how the hostname in the prompt does not change until the change
|
||||||
@@ -203,4 +137,3 @@ admin@host:/>
|
|||||||
|
|
||||||
[1]: https://www.rfc-editor.org/rfc/rfc7317
|
[1]: https://www.rfc-editor.org/rfc/rfc7317
|
||||||
[2]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-system%402024-02-29.yang
|
[2]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-system%402024-02-29.yang
|
||||||
[3]: https://www.rfc-editor.org/rfc/rfc8341
|
|
||||||
|
|||||||
@@ -1,246 +0,0 @@
|
|||||||
Test System Architecture
|
|
||||||
========================
|
|
||||||
|
|
||||||
Tenets
|
|
||||||
------
|
|
||||||
|
|
||||||
- **Keep overhead to a minimum**. Tests should be fast to both write
|
|
||||||
and run. Ideally, the developer should _want_ to add tests early in
|
|
||||||
the development cycle because they instinctively feel that that is
|
|
||||||
the quickest route to arrive at a correct and robust implementation.
|
|
||||||
|
|
||||||
- **Both physical and virtual hardware matters**. Infix is primarily
|
|
||||||
deployed on physical hardware, so being able to run the test suite
|
|
||||||
on real devices is crucial to guarantee a high quality product. At
|
|
||||||
the same time, there is much value in running the same suite on
|
|
||||||
virtual hardware, as it makes it easy to catch regressions early.
|
|
||||||
It is also much more practical and economical to build large virtual
|
|
||||||
networks than physical ones.
|
|
||||||
|
|
||||||
- **Avoid CLI scipting & scraping**. Reliably interacting with a DUT
|
|
||||||
over a serial line in a robust way is _very_ hard to get right.
|
|
||||||
Given that we have a proper API (RESTCONF), we should leverage that
|
|
||||||
when testing. Front-ends can be tested by other means.
|
|
||||||
|
|
||||||
|
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The test system is made up of several independent components, which
|
|
||||||
are typically used in concert to run a full test suite.
|
|
||||||
|
|
||||||
### Test Cases
|
|
||||||
|
|
||||||
A test case is an executable, receiving the physical topology as a
|
|
||||||
positional argument, which produces [TAP][] compliant output on its
|
|
||||||
`stdout`. I.e., it is executed in the following manner:
|
|
||||||
|
|
||||||
test-case [OPTS] <physical-topology>
|
|
||||||
|
|
||||||
Test cases are typically written in Python, using the
|
|
||||||
[Infamy](#infamy) library. Ultimately though, it can be implemented
|
|
||||||
in any language, as long as it matches the calling convention above.
|
|
||||||
|
|
||||||
### Infamy
|
|
||||||
|
|
||||||
Rather than having each test case come up with its own implementation
|
|
||||||
of how to map topologies, how to push NETCONF data to a device, etc.,
|
|
||||||
we provide a library of functions to take care of all that, dubbed
|
|
||||||
"Infamy". When adding a new test case, ask yourself if any parts of
|
|
||||||
it might belong in Infamy as a generalized component that can be
|
|
||||||
reused by other tests.
|
|
||||||
|
|
||||||
Some of the core functions provided by Infamy are:
|
|
||||||
|
|
||||||
- Mapping a logical topology to a physical one
|
|
||||||
- Finding and attaching to a device over an Ethernet interface, using
|
|
||||||
NETCONF
|
|
||||||
- Pushing/pulling NETCONF data to/from a device
|
|
||||||
- Generating TAP compliant output
|
|
||||||
|
|
||||||
### 9PM
|
|
||||||
|
|
||||||
To run multiple tests, we employ [9PM][]. It let's us define test
|
|
||||||
suites as simple YAML files. Suites can also be hierarchically
|
|
||||||
structured, with a suite being made up of other suites, etc.
|
|
||||||
|
|
||||||
It also validates the TAP output, making sure to catch early exits
|
|
||||||
from a case, and produces a nice summary report.
|
|
||||||
|
|
||||||
### `/test/env`
|
|
||||||
|
|
||||||
A good way to ensure that nobody ever runs the test suite is to make
|
|
||||||
it _really_ hard to do so. `/test/env`'s job is instead to make it
|
|
||||||
very _easy_ to create a reproducible environment in which tests can be
|
|
||||||
executed.
|
|
||||||
|
|
||||||
Several technologies are leveraged to accomplish this:
|
|
||||||
|
|
||||||
- **Containers**: The entire execution is optionally done inside a
|
|
||||||
standardized `docker` container environment. This ensures that the
|
|
||||||
software needed to run the test suite is always available, no matter
|
|
||||||
which distribution the user is running on their machine.
|
|
||||||
|
|
||||||
- **Python Virtual Environments**: To make sure that the expected
|
|
||||||
versions of all Python packages are available, the execution is
|
|
||||||
wrapped inside a `venv`. This is true for containerized executions,
|
|
||||||
where the container comes with a pre-installed environment, but it
|
|
||||||
can also be sourced from the host system when running outside of the
|
|
||||||
container.
|
|
||||||
|
|
||||||
- **Virtual Test Topology**: Using [Qeneth][], the environment can
|
|
||||||
optionally be started with a virtual topology of DUTs to run the
|
|
||||||
tests on.
|
|
||||||
|
|
||||||
> `docker` is the only supported container environment when running
|
|
||||||
> tests in the host's network namespace. When running on a virtual
|
|
||||||
> Qeneth topology, `podman` may also be used by installing the
|
|
||||||
> `podman-docker` package from your host system's distro.
|
|
||||||
|
|
||||||
|
|
||||||
Physical and Logical Topologies
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Imagine that we want to create a test with three DUTs; one acting as a
|
|
||||||
DHCP server, and the other two as DHCP clients - with all three having
|
|
||||||
a management connection to the host PC running the test. In other
|
|
||||||
words, the test requires a _logical_ topology like the one below.
|
|
||||||
|
|
||||||
<img align="right" src="img/testing-log.dot.svg" alt="Example Logical Topology">
|
|
||||||
|
|
||||||
```dot
|
|
||||||
graph "dhcp-client-server" {
|
|
||||||
host [
|
|
||||||
label="host | { <c1> c1 | <srv> srv | <c2> c2 }",
|
|
||||||
kind="controller",
|
|
||||||
];
|
|
||||||
|
|
||||||
server [
|
|
||||||
label="{ <mgmt> mgmt } | server | { <c1> c1 | <c2> c2 }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
client1 [
|
|
||||||
label="{ <mgmt> mgmt } | client1 | { <srv> srv }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
client2 [
|
|
||||||
label="{ <mgmt> mgmt } | client2 | { <srv> srv }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
|
|
||||||
host:srv -- server:mgmt
|
|
||||||
host:c1 -- client1:mgmt
|
|
||||||
host:c2 -- client2:mgmt
|
|
||||||
|
|
||||||
server:c1 -- client1:srv;
|
|
||||||
server:c2 -- client2:srv;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When running in a virtualized environment, one could simply create a
|
|
||||||
setup that matches the test's logical topology. But in scenarios when
|
|
||||||
devices are physical systems, connected by real copper cables, this is
|
|
||||||
not possible (unless you have some wicked L1 relay matrix thingy).
|
|
||||||
|
|
||||||
Instead, the test implementation does not concern itself with the
|
|
||||||
exact nodes used to run the test, only that the _logical_ topology can
|
|
||||||
be _mapped_ to some subset of the _physical_ topology. In
|
|
||||||
mathematical terms, the physical topology must contain a subgraph that
|
|
||||||
is _isomorphic_ to the logical topology.
|
|
||||||
|
|
||||||
Standing on the shoulders of giants (i.e. people with mathematics
|
|
||||||
degrees), we can deploy well-known algorithms to find such subgraphs.
|
|
||||||
Continuing our example, let's say we want to run our DHCP test on the
|
|
||||||
_physical_ topology below.
|
|
||||||
|
|
||||||
<img align="right" src="img/testing-phy.dot.svg" alt="Example Physical Topology">
|
|
||||||
|
|
||||||
```dot
|
|
||||||
graph "quad-ring" {
|
|
||||||
host [
|
|
||||||
label="host | { <d1a> d1a | <d1b> d1b | <d1c> d1c | <d2a> d2a | <d2b> d2b | <d2c> d2c | <d3a> d3a | <d3b> d3b | <d3c> d3c | <d4a> d4a | <d4b> d4b | <d4c> d4c }",
|
|
||||||
kind="controller",
|
|
||||||
];
|
|
||||||
|
|
||||||
dut1 [
|
|
||||||
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut1 | { <e4> e4 | <e5> e5 }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
dut2 [
|
|
||||||
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut2 | { <e4> e4 | <e5> e5 }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
dut3 [
|
|
||||||
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut3 | { <e4> e4 | <e5> e5 }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
dut4 [
|
|
||||||
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut4 | { <e4> e4 | <e5> e5 }",
|
|
||||||
kind="infix",
|
|
||||||
];
|
|
||||||
|
|
||||||
host:d1a -- dut1:e1
|
|
||||||
host:d1b -- dut1:e2
|
|
||||||
host:d1c -- dut1:e3
|
|
||||||
|
|
||||||
host:d2a -- dut2:e1
|
|
||||||
host:d2b -- dut2:e2
|
|
||||||
host:d2c -- dut2:e3
|
|
||||||
|
|
||||||
host:d3a -- dut3:e1
|
|
||||||
host:d3b -- dut3:e2
|
|
||||||
host:d3c -- dut3:e3
|
|
||||||
|
|
||||||
host:d4a -- dut4:e1
|
|
||||||
host:d4b -- dut4:e2
|
|
||||||
host:d4c -- dut4:e3
|
|
||||||
|
|
||||||
dut1:e5 -- dut2:e4
|
|
||||||
dut2:e5 -- dut3:e4
|
|
||||||
dut3:e5 -- dut4:e4
|
|
||||||
dut4:e5 -- dut1:e4
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Our test (in fact, all tests) receives the physical topology as an
|
|
||||||
input parameter, and then maps the desired logical topology onto it,
|
|
||||||
producing a mapping from logical nodes and ports to their physical
|
|
||||||
counterparts.
|
|
||||||
|
|
||||||
```dot
|
|
||||||
{
|
|
||||||
"client1": "dut1",
|
|
||||||
"client1:mgmt": "dut1:e1",
|
|
||||||
"client1:srv": "dut1:e4",
|
|
||||||
"client2": "dut3",
|
|
||||||
"client2:mgmt": "dut3:e2",
|
|
||||||
"client2:srv": "dut3:e5",
|
|
||||||
"host": "host",
|
|
||||||
"host:c1": "host:d1a",
|
|
||||||
"host:c2": "host:d3b",
|
|
||||||
"host:srv": "host:d4c",
|
|
||||||
"server": "dut4",
|
|
||||||
"server:c1": "dut4:e5",
|
|
||||||
"server:c2": "dut4:e4",
|
|
||||||
"server:mgmt": "dut4:e3"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
With this information, the test knows that, in this particular
|
|
||||||
environment, the server should be managed via the port called `d4c` on
|
|
||||||
the node called `host`; that the port connected to the server on
|
|
||||||
`client1` is `e4` on `dut1`, etc. Thereby separating the
|
|
||||||
implementation of the test from any specific physical setup.
|
|
||||||
|
|
||||||
Testcases are not required to use a logical topology; they may choose
|
|
||||||
to accept whatever physical topology its given, and dynamically
|
|
||||||
determine the DUTs to use for testing. As an example, an STP test
|
|
||||||
could accept an arbitrary physical topology, run the STP algorithm on
|
|
||||||
it offline, enable STP on all DUTs, and then verify that the resulting
|
|
||||||
spanning tree matches the expected one.
|
|
||||||
|
|
||||||
[9PM]: https://github.com/rical/9pm
|
|
||||||
[Qeneth]: https://github.com/wkz/qeneth
|
|
||||||
[TAP]: https://testanything.org/
|
|
||||||
+284
-130
@@ -7,57 +7,287 @@ that one or more DUTs are configured over NETCONF; the resulting
|
|||||||
network is then black-box tested by injecting and inspecting network
|
network is then black-box tested by injecting and inspecting network
|
||||||
traffic at various points.
|
traffic at various points.
|
||||||
|
|
||||||
This document is intended to be a practical guide on how to run,
|
|
||||||
develop and debug tests. There is a separate document describing the
|
|
||||||
[Test System Architecture](test-arch.md).
|
|
||||||
|
|
||||||
|
TL;DR
|
||||||
|
-----
|
||||||
|
|
||||||
Modes of Testing
|
Build Infix and run the test suite on a set of virtual Infix nodes.
|
||||||
----------------
|
|
||||||
|
|
||||||
### Virtual Devices
|
|
||||||
|
|
||||||
By default, tests are run on a topology made up of virtual Infix nodes
|
|
||||||
using [Qeneth][]. To run the full regression test suite: build Infix
|
|
||||||
for `x86_64`:
|
|
||||||
|
|
||||||
$ make x86_64_defconfig
|
$ make x86_64_defconfig
|
||||||
$ make
|
$ make
|
||||||
$ make test
|
$ make test
|
||||||
|
|
||||||
### Physical Devices
|
To run a subset of tests, e.g., only the DHCP client tests:
|
||||||
|
|
||||||
To run the tests on a preexisting topology from the host's network
|
$ make test INFIX_TESTS=case/infix_dhcp/all.yaml
|
||||||
namespace, specify the `host` `TEST_MODE`:
|
|
||||||
|
|
||||||
$ make TEST_MODE=host test
|
> **Note:** see the below section [Quick Start Guide][] for how to
|
||||||
|
> connect to the test system, debug and develop tests, and more.
|
||||||
This typically used when testing on physical hardware. By default the
|
|
||||||
topology will be sourced from `/etc/infamy.dot`, but this can be
|
|
||||||
overwritten by setting the `TOPOLOGY` variable:
|
|
||||||
|
|
||||||
$ make TEST_MODE=host TOPOLOGY=~/my-topology.dot test
|
|
||||||
|
|
||||||
|
|
||||||
### `make run` Devices
|
Tenets
|
||||||
|
------
|
||||||
|
|
||||||
Some tests only require a single DUT. These can therefore be run
|
- **Keep overhead to a minimum**. Tests should be fast to both write
|
||||||
against an Infix image started from `make run`. This requires that the
|
and run. Ideally, the developer should _want_ to add tests early in
|
||||||
instance is configured to use TAP networking.
|
the development cycle because they instinctively feel that that is
|
||||||
|
the quickest route to arrive at a correct and robust implementation.
|
||||||
|
|
||||||
When the instance is running, you can open a separate terminal and run
|
- **Both physical and virtual hardware matters**. Infix is primarily
|
||||||
the subset of the test suite that can be mapped to it:
|
deployed on physical hardware, so being able to run the test suite
|
||||||
|
on real devices is crucial to guarantee a high quality product. At
|
||||||
|
the same time, there is much value in running the same suite on
|
||||||
|
virtual hardware, as it makes it easy to catch regressions early.
|
||||||
|
It is also much more practical and economical to build large virtual
|
||||||
|
networks than physical ones.
|
||||||
|
|
||||||
$ make TEST_MODE=run test
|
- **Avoid CLI scipting & scraping**. Reliably interacting with a DUT
|
||||||
|
over a serial line in a robust way is _very_ hard to get right.
|
||||||
|
Given that we have a proper API (RESTCONF), we should leverage that
|
||||||
|
when testing. Front-ends can be tested by other means.
|
||||||
|
|
||||||
|
|
||||||
|
Architectural Overview
|
||||||
|
----------------------
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The test system is made up of several independent components, which
|
||||||
|
are typically used in concert to run a full test suite.
|
||||||
|
|
||||||
|
### Test Cases
|
||||||
|
|
||||||
|
A test case is an executable, receiving the physical topology as a
|
||||||
|
positional argument, which produces [TAP][] compliant output on its
|
||||||
|
`stdout`. I.e., it is executed in the following manner:
|
||||||
|
|
||||||
|
test-case [OPTS] <physical-topology>
|
||||||
|
|
||||||
|
Test cases are typically written in Python, using the
|
||||||
|
[Infamy](#infamy) library. Ultimately though, it can be implemented
|
||||||
|
in any language, as long as it matches the calling convention above.
|
||||||
|
|
||||||
|
### Infamy
|
||||||
|
|
||||||
|
Rather than having each test case come up with its own implementation
|
||||||
|
of how to map topologies, how to push NETCONF data to a device, etc.,
|
||||||
|
we provide a library of functions to take care of all that, dubbed
|
||||||
|
"Infamy". When adding a new test case, ask yourself if any parts of
|
||||||
|
it might belong in Infamy as a generalized component that can be
|
||||||
|
reused by other tests.
|
||||||
|
|
||||||
|
Some of the core functions provided by Infamy are:
|
||||||
|
|
||||||
|
- Mapping a logical topology to a physical one
|
||||||
|
- Finding and attaching to a device over an Ethernet interface, using
|
||||||
|
NETCONF
|
||||||
|
- Pushing/pulling NETCONF data to/from a device
|
||||||
|
- Generating TAP compliant output
|
||||||
|
|
||||||
|
### 9PM
|
||||||
|
|
||||||
|
To run multiple tests, we employ [9PM][]. It let's us define test
|
||||||
|
suites as simple YAML files. Suites can also be hierarchically
|
||||||
|
structured, with a suite being made up of other suites, etc.
|
||||||
|
|
||||||
|
It also validates the TAP output, making sure to catch early exits
|
||||||
|
from a case, and produces a nice summary report.
|
||||||
|
|
||||||
|
### `/test/env`
|
||||||
|
|
||||||
|
A good way to ensure that nobody ever runs the test suite is to make
|
||||||
|
it _really_ hard to do so. `/test/env`'s job is instead to make it
|
||||||
|
very _easy_ to create a reproducible environment in which tests can be
|
||||||
|
executed.
|
||||||
|
|
||||||
|
Several technologies are leveraged to accomplish this:
|
||||||
|
|
||||||
|
- **Containers**: The entire execution is optionally done inside a
|
||||||
|
standardized container environment, using either `podman` or
|
||||||
|
`docker`. This ensures that the software needed to run the test
|
||||||
|
suite is always available, no matter which distribution the user is
|
||||||
|
running on their machine.
|
||||||
|
|
||||||
|
- **Python Virtual Environments**: To make sure that the expected
|
||||||
|
versions of all Python packages are available, the execution is
|
||||||
|
wrapped inside a `venv`. This is true for containerized executions,
|
||||||
|
where the container comes with a pre-installed environment, but it
|
||||||
|
can also be sourced from the host system when running outside of the
|
||||||
|
container.
|
||||||
|
|
||||||
|
- **Virtual Test Topology**: Using [Qeneth][], the environment can
|
||||||
|
optionally be started with a virtual topology of DUTs to run the
|
||||||
|
tests on.
|
||||||
|
|
||||||
|
|
||||||
Interactive Usage
|
Interactive Usage
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
When developing and debugging tests, the overhead of repeatedly
|
Some tests only require a single DUT. These can therefore be run
|
||||||
setting up and tearing down the test environment can quickly start to
|
against an Infix image started from `make run`. When the instance is
|
||||||
weigh you down. In these situation, you can start an interactive test
|
running, you can open a separate terminal and run `make test-run`, to
|
||||||
environment:
|
run the subset of the test suite that can be mapped to it.
|
||||||
|
|
||||||
|
Both `make test` and `make test-run` targets have a respective target
|
||||||
|
with a `-sh` suffix. These can be used to start an interactive session
|
||||||
|
in the reproducible environment, which is usually much easier to work
|
||||||
|
with during a debugging session.
|
||||||
|
|
||||||
|
Inside the reproducible environment, a wrapper for Qeneth is created for
|
||||||
|
the running network's directory. E.g., calling `qeneth status` inside a
|
||||||
|
`make test-sh` environment show the expected status information.
|
||||||
|
|
||||||
|
> **Note:** for more information and help writing a test, see the below
|
||||||
|
> [Quick Start Guide][].
|
||||||
|
|
||||||
|
|
||||||
|
Physical and Logical Topologies
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Imagine that we want to create a test with three DUTs; one acting as a
|
||||||
|
DHCP server, and the other two as DHCP clients - with all three having
|
||||||
|
a management connection to the host PC running the test. In other
|
||||||
|
words, the test requires a _logical_ topology like the one below.
|
||||||
|
|
||||||
|
<img align="right" src="img/testing-log.dot.svg" alt="Example Logical Topology">
|
||||||
|
|
||||||
|
```dot
|
||||||
|
graph "dhcp-client-server" {
|
||||||
|
host [
|
||||||
|
label="host | { <c1> c1 | <srv> srv | <c2> c2 }",
|
||||||
|
kind="controller",
|
||||||
|
];
|
||||||
|
|
||||||
|
server [
|
||||||
|
label="{ <mgmt> mgmt } | server | { <c1> c1 | <c2> c2 }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
client1 [
|
||||||
|
label="{ <mgmt> mgmt } | client1 | { <srv> srv }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
client2 [
|
||||||
|
label="{ <mgmt> mgmt } | client2 | { <srv> srv }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
|
||||||
|
host:srv -- server:mgmt
|
||||||
|
host:c1 -- client1:mgmt
|
||||||
|
host:c2 -- client2:mgmt
|
||||||
|
|
||||||
|
server:c1 -- client1:srv;
|
||||||
|
server:c2 -- client2:srv;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When running in a virtualized environment, one could simply create a
|
||||||
|
setup that matches the test's logical topology. But in scenarios when
|
||||||
|
devices are physical systems, connected by real copper cables, this is
|
||||||
|
not possible (unless you have some wicked L1 relay matrix thingy).
|
||||||
|
|
||||||
|
Instead, the test implementation does not concern itself with the
|
||||||
|
exact nodes used to run the test, only that the _logical_ topology can
|
||||||
|
be _mapped_ to some subset of the _physical_ topology. In
|
||||||
|
mathematical terms, the physical topology must contain a subgraph that
|
||||||
|
is _isomorphic_ to the logical topology.
|
||||||
|
|
||||||
|
Standing on the shoulders of giants (i.e. people with mathematics
|
||||||
|
degrees), we can deploy well-known algorithms to find such subgraphs.
|
||||||
|
Continuing our example, let's say we want to run our DHCP test on the
|
||||||
|
_physical_ topology below.
|
||||||
|
|
||||||
|
<img align="right" src="img/testing-phy.dot.svg" alt="Example Physical Topology">
|
||||||
|
|
||||||
|
```dot
|
||||||
|
graph "quad-ring" {
|
||||||
|
host [
|
||||||
|
label="host | { <d1a> d1a | <d1b> d1b | <d1c> d1c | <d2a> d2a | <d2b> d2b | <d2c> d2c | <d3a> d3a | <d3b> d3b | <d3c> d3c | <d4a> d4a | <d4b> d4b | <d4c> d4c }",
|
||||||
|
kind="controller",
|
||||||
|
];
|
||||||
|
|
||||||
|
dut1 [
|
||||||
|
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut1 | { <e4> e4 | <e5> e5 }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
dut2 [
|
||||||
|
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut2 | { <e4> e4 | <e5> e5 }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
dut3 [
|
||||||
|
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut3 | { <e4> e4 | <e5> e5 }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
dut4 [
|
||||||
|
label="{ <e1> e1 | <e2> e2 | <e3> e3 } | dut4 | { <e4> e4 | <e5> e5 }",
|
||||||
|
kind="infix",
|
||||||
|
];
|
||||||
|
|
||||||
|
host:d1a -- dut1:e1
|
||||||
|
host:d1b -- dut1:e2
|
||||||
|
host:d1c -- dut1:e3
|
||||||
|
|
||||||
|
host:d2a -- dut2:e1
|
||||||
|
host:d2b -- dut2:e2
|
||||||
|
host:d2c -- dut2:e3
|
||||||
|
|
||||||
|
host:d3a -- dut3:e1
|
||||||
|
host:d3b -- dut3:e2
|
||||||
|
host:d3c -- dut3:e3
|
||||||
|
|
||||||
|
host:d4a -- dut4:e1
|
||||||
|
host:d4b -- dut4:e2
|
||||||
|
host:d4c -- dut4:e3
|
||||||
|
|
||||||
|
dut1:e5 -- dut2:e4
|
||||||
|
dut2:e5 -- dut3:e4
|
||||||
|
dut3:e5 -- dut4:e4
|
||||||
|
dut4:e5 -- dut1:e4
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Our test (in fact, all tests) receives the physical topology as an
|
||||||
|
input parameter, and then maps the desired logical topology onto it,
|
||||||
|
producing a mapping from logical nodes and ports to their physical
|
||||||
|
counterparts.
|
||||||
|
|
||||||
|
```dot
|
||||||
|
{
|
||||||
|
"client1": "dut1",
|
||||||
|
"client1:mgmt": "dut1:e1",
|
||||||
|
"client1:srv": "dut1:e4",
|
||||||
|
"client2": "dut3",
|
||||||
|
"client2:mgmt": "dut3:e2",
|
||||||
|
"client2:srv": "dut3:e5",
|
||||||
|
"host": "host",
|
||||||
|
"host:c1": "host:d1a",
|
||||||
|
"host:c2": "host:d3b",
|
||||||
|
"host:srv": "host:d4c",
|
||||||
|
"server": "dut4",
|
||||||
|
"server:c1": "dut4:e5",
|
||||||
|
"server:c2": "dut4:e4",
|
||||||
|
"server:mgmt": "dut4:e3"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
With this information, the test knows that, in this particular
|
||||||
|
environment, the server should be managed via the port called `d4c` on
|
||||||
|
the node called `host`; that the port connected to the server on
|
||||||
|
`client1` is `e4` on `dut1`, etc. Thereby separating the
|
||||||
|
implementation of the test from any specific physical setup.
|
||||||
|
|
||||||
|
Testcases are not required to use a logical topology; they may choose
|
||||||
|
to accept whatever physical topology its given, and dynamically
|
||||||
|
determine the DUTs to use for testing. As an example, an STP test
|
||||||
|
could accept an arbitrary physical topology, run the STP algorithm on
|
||||||
|
it offline, enable STP on all DUTs, and then verify that the resulting
|
||||||
|
spanning tree matches the expected one.
|
||||||
|
|
||||||
|
|
||||||
|
Quick Start Guide
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
When developing a test, instead of blindly coding in Python and running
|
||||||
|
`make test` over and over, start a test shell:
|
||||||
|
|
||||||
$ make test-sh
|
$ make test-sh
|
||||||
Info: Generating topology
|
Info: Generating topology
|
||||||
@@ -69,28 +299,13 @@ environment:
|
|||||||
Info: Launching dut4
|
Info: Launching dut4
|
||||||
11:42:52 infamy0:test #
|
11:42:52 infamy0:test #
|
||||||
|
|
||||||
The example above uses the default mode (`qeneth`), but the `host` and
|
|
||||||
`run` modes also support the `test-sh` target.
|
|
||||||
|
|
||||||
It takes a little while to start up, but then we have a shell prompt
|
It takes a little while to start up, but then we have a shell prompt
|
||||||
inside the container running Infamy. It's a very limited environment,
|
inside the container running Infamy. It's a very limited environment,
|
||||||
but it has enough to easily run single tests, connect to the virtual
|
but it has enough to easily run single tests, connect to the virtual
|
||||||
devices, and *step* your code.
|
devices, and *step* your code. Let's run a test:
|
||||||
|
|
||||||
|
|
||||||
### Running Subsets of Tests
|
|
||||||
|
|
||||||
Each test case is a separate executable, which can be run without
|
|
||||||
arguments:
|
|
||||||
|
|
||||||
11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
11:42:53 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
||||||
|
|
||||||
To run a suite of tests, e.g., only the DHCP client tests, pass the
|
|
||||||
suite as an argument to [9PM][]:
|
|
||||||
|
|
||||||
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/all.yaml
|
|
||||||
|
|
||||||
|
|
||||||
### Connecting to Infamy
|
### Connecting to Infamy
|
||||||
|
|
||||||
The test system runs in a Docker container, so to get a shell prompt in
|
The test system runs in a Docker container, so to get a shell prompt in
|
||||||
@@ -98,7 +313,6 @@ The test system runs in a Docker container, so to get a shell prompt in
|
|||||||
with a helper script for this:
|
with a helper script for this:
|
||||||
|
|
||||||
$ ./test/shell
|
$ ./test/shell
|
||||||
11:42:53 infamy0:test #
|
|
||||||
|
|
||||||
By default it connect to the latest started Infamy instance. If you for
|
By default it connect to the latest started Infamy instance. If you for
|
||||||
some reason run multiple instances of Infamy the `shell` script takes an
|
some reason run multiple instances of Infamy the `shell` script takes an
|
||||||
@@ -106,8 +320,6 @@ optional argument "system", which is the hostname of the container you
|
|||||||
want to connect to:
|
want to connect to:
|
||||||
|
|
||||||
$ ./test/shell infamy2
|
$ ./test/shell infamy2
|
||||||
11:42:53 infamy2:test #
|
|
||||||
|
|
||||||
|
|
||||||
### Connecting to a DUT
|
### Connecting to a DUT
|
||||||
|
|
||||||
@@ -157,47 +369,10 @@ You can also connect to the console of a DUT from within a `shell`:
|
|||||||
> the BusyBox version so you press 'e' + enter instead of 'q' to quit.
|
> the BusyBox version so you press 'e' + enter instead of 'q' to quit.
|
||||||
|
|
||||||
|
|
||||||
### Attaching to MACVLANs
|
### Debug a Test
|
||||||
|
|
||||||
To fully isolate the host's interfaces from one another, many tests
|
First, add a Python `breakpoint()` to your test and run it from your
|
||||||
will stack a MACVLAN on an interface, which is then placed in a
|
`make test-sh` Infamy instance:
|
||||||
separate network namespace.
|
|
||||||
|
|
||||||
It is often useful to attach to those namespaces, so that you can
|
|
||||||
interactively inject traffic into the test setup.
|
|
||||||
|
|
||||||
First, connect to the Infamy instance in question:
|
|
||||||
|
|
||||||
$ ./test/shell
|
|
||||||
11:43:19 infamy0:test #
|
|
||||||
|
|
||||||
Then, attach to the MACVLAN namespace by running the `nsenter` helper
|
|
||||||
script from the test directory, supplying the base interface name as
|
|
||||||
the first argument:
|
|
||||||
|
|
||||||
11:43:19 infamy0:test # ./nsenter d1b
|
|
||||||
11:43:20 infamy0(d1b):test #
|
|
||||||
|
|
||||||
By default, an interactive shell is started, but you can also supply
|
|
||||||
another command:
|
|
||||||
|
|
||||||
11:43:19 infamy0:test # ./nsenter d1b ip -br addr
|
|
||||||
lo UNKNOWN 127.0.0.1/8 ::1/128
|
|
||||||
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
|
|
||||||
|
|
||||||
You can now freely debug the network activity of your test and the
|
|
||||||
responses from the DUT.
|
|
||||||
|
|
||||||
|
|
||||||
### Using the Python Debugger
|
|
||||||
|
|
||||||
The built in `breakpoint()` function in Python is very useful when you
|
|
||||||
want to run a test case to a certain point at which you might want to
|
|
||||||
interactively inspect either the test's or the device's state.
|
|
||||||
|
|
||||||
Simply insert a call to `breakpoint()` at the point of interest in
|
|
||||||
your test and run it as normal. Once Python executes the call, it will
|
|
||||||
drop you into the Python debugger:
|
|
||||||
|
|
||||||
11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
11:42:58 infamy0:test # ./case/infix_dhcp/dhcp_basic.py
|
||||||
# Starting (2024-02-10 11:42:59)
|
# Starting (2024-02-10 11:42:59)
|
||||||
@@ -207,55 +382,34 @@ drop you into the Python debugger:
|
|||||||
> /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)<module>()
|
> /home/jocke/src/infix/test/case/infix_dhcp/dhcp_basic.py(44)<module>()
|
||||||
(Pdb)
|
(Pdb)
|
||||||
|
|
||||||
At this point you have full access to the test's state, but it is also
|
You are now in the Python debugger, Pdb.
|
||||||
an opportunity to inspect the state of the DUTs (e.g. via their
|
|
||||||
console or over SSH).
|
|
||||||
|
|
||||||
It is also possible to run a test under Pdb from the get-go, if you
|
### Debug a Test in a MacVLAN
|
||||||
want to setup breakpoints without modifying the source, or simply step
|
|
||||||
through the code:
|
|
||||||
|
|
||||||
11:42:58 infamy0:test # python -m pdb case/infix_dhcp/dhcp_basic.py
|
Most tests use some sort of network connection to the DUTs. From a test
|
||||||
|
shell you cannot see or debug that connection by default. So you need
|
||||||
|
to employ a little trick.
|
||||||
|
|
||||||
|
Open another terminal, and start a test shell in your Infamy instance:
|
||||||
|
|
||||||
### Deterministic Topology Mappings
|
$ ./test/shell
|
||||||
|
11:43:19 infamy0:test #
|
||||||
|
|
||||||
By default, mappings from logical to physical topologies are not
|
MacVLAN interfaces created by Infamy run in another network namespace,
|
||||||
stable across test case executions. This can be very frustrating when
|
to enter it we can look for a sleeper process:
|
||||||
debugging a failing test, since logical nodes are suffled around
|
|
||||||
between phyical nodes. In such cases, supplying a `PYTHONHASHSEED`
|
|
||||||
variable (set to any 32-bit unsigned integer) when launching the test
|
|
||||||
environment will make sure that topology mappings are deterministic:
|
|
||||||
|
|
||||||
$ make PYTHONHASHSEED=0 test-sh
|
11:43:20 infamy0:test # nsenter -n U -t $(pidof sleep infinity)
|
||||||
|
|
||||||
If a seed is not supplied, a random value is chosen. This seed is
|
You are now one step further down:
|
||||||
logged by the `meta/reproducible.py` test case when running a test
|
|
||||||
suite:
|
|
||||||
|
|
||||||
$ make test
|
infamy0:/home/jocke/src/infix/test# ip -br a
|
||||||
Info: Generating topology
|
lo UNKNOWN 127.0.0.1/8 ::1/128
|
||||||
Info: Generating node YAML
|
iface@if7 UP 10.0.0.1/24 fe80::38d0:88ff:fe77:b7cd/64
|
||||||
Info: Generating executables
|
|
||||||
Info: Launching dut1
|
|
||||||
Info: Launching dut2
|
|
||||||
Info: Launching dut3
|
|
||||||
Info: Launching dut4
|
|
||||||
9PM - Simplicity is the ultimate sophistication
|
|
||||||
|
|
||||||
Starting test 0002-reproducible.py
|
You can now freely debug the network activity of your test and the
|
||||||
2024-05-03 10:40:30 # Starting (2024-05-03 10:40:30)
|
responses from the DUT.
|
||||||
2024-05-03 10:40:30 # Specify PYTHONHASHSEED=3773822171 to reproduce this test environment
|
|
||||||
2024-05-03 10:40:30 ok 1 - $PYTHONHASHSEED is set
|
|
||||||
2024-05-03 10:40:30 # Exiting (2024-05-03 10:40:30)
|
|
||||||
2024-05-03 10:40:30 1..1
|
|
||||||
...
|
|
||||||
|
|
||||||
This is useful because this value can then be used to rerun a test (or
|
|
||||||
the whole suite) with identical topology mappings:
|
|
||||||
|
|
||||||
$ make PYTHONHASHSEED=3773822171 INFIX_TESTS=case/ietf_system/hostname.py test
|
|
||||||
|
|
||||||
|
|
||||||
[9PM]: https://github.com/rical/9pm
|
[9PM]: https://github.com/rical/9pm
|
||||||
[Qeneth]: https://github.com/wkz/qeneth
|
[Qeneth]: https://github.com/wkz/qeneth
|
||||||
|
[TAP]: https://testanything.org/
|
||||||
|
|||||||
+2
-4
@@ -1,12 +1,10 @@
|
|||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/confd/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/confd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/curios-httpd/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/curios-httpd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/execd/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/execd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/gencert/Config.in"
|
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/statd/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/statd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/factory/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/factory/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/faux/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/finit/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/greenpak-programmer/Config.in"
|
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/ifupdown-ng/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/iito/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/k8s-logger/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/k8s-logger/Config.in"
|
||||||
@@ -14,13 +12,13 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/keyack/Config.in"
|
|||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-infix/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/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/landing/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/python-statd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/libsrx/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/lowdown/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/mcd/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/mcd/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/mdns-alias/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/mdns-alias/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/netbrowse/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/netbrowse/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/python-statd/Config.in"
|
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
|
||||||
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
|
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
|
||||||
|
source "$BR2_EXTERNAL_INFIX_PATH/package/greenpak-programmer/Config.in"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ run name:bootstrap log:prio:user.notice norestart <pid/syslogd> \
|
|||||||
run name:error :1 log:console norestart if:<run/bootstrap/failure> \
|
run name:error :1 log:console norestart if:<run/bootstrap/failure> \
|
||||||
[S] /usr/libexec/confd/error --
|
[S] /usr/libexec/confd/error --
|
||||||
|
|
||||||
service name:confd log:prio:daemon.err <run/bootstrap/success> \
|
service name:confd log <run/bootstrap/success> \
|
||||||
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
|
[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
|
||||||
|
|
||||||
# Bootstrap system with startup-config
|
# Bootstrap system with startup-config
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ CONFD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/confd
|
|||||||
CONFD_LICENSE = BSD-3-Clause
|
CONFD_LICENSE = BSD-3-Clause
|
||||||
CONFD_LICENSE_FILES = LICENSE
|
CONFD_LICENSE_FILES = LICENSE
|
||||||
CONFD_REDISTRIBUTE = NO
|
CONFD_REDISTRIBUTE = NO
|
||||||
CONFD_DEPENDENCIES = augeas jansson libite sysrepo libsrx libglib2
|
CONFD_DEPENDENCIES = augeas jansson libite sysrepo libsrx
|
||||||
CONFD_AUTORECONF = YES
|
CONFD_AUTORECONF = YES
|
||||||
define CONFD_CONF_ENV
|
define CONFD_CONF_ENV
|
||||||
CFLAGS="$(INFIX_CFLAGS)"
|
CFLAGS="$(INFIX_CFLAGS)"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ EXECD_CONF_OPTS = --prefix= --disable-silent-rules
|
|||||||
define EXECD_INSTALL_EXTRA
|
define EXECD_INSTALL_EXTRA
|
||||||
cp $(EXECD_PKGDIR)/execd.conf $(FINIT_D)/available/
|
cp $(EXECD_PKGDIR)/execd.conf $(FINIT_D)/available/
|
||||||
ln -sf ../available/execd.conf $(FINIT_D)/enabled/execd.conf
|
ln -sf ../available/execd.conf $(FINIT_D)/enabled/execd.conf
|
||||||
cp $(EXECD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/lib/tmpfiles.d/execd.conf
|
cp $(EXECD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/execd.conf
|
||||||
endef
|
endef
|
||||||
EXECD_TARGET_FINALIZE_HOOKS += EXECD_INSTALL_EXTRA
|
EXECD_TARGET_FINALIZE_HOOKS += EXECD_INSTALL_EXTRA
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
sha256 518cd23d81f17b912f1c4ccc6acb67ff614ddcc2caf14def5044126d1a60f364 LICENSE
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
From 6a89e60fc84b90e5f09f61d37892f3b17bd14631 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
Date: Wed, 24 Apr 2024 11:33:35 +0200
|
|
||||||
Subject: [PATCH 10/11] Fix #405: parsing >1 active consoles in tty @console
|
|
||||||
setups
|
|
||||||
Organization: Addiva Elektronik
|
|
||||||
|
|
||||||
Systems that have the following tty setup and multiple consoles listed
|
|
||||||
in /sys/class/tty/console/active misbehave:
|
|
||||||
|
|
||||||
tty [12345789] @console 0 xterm noclear passenv
|
|
||||||
|
|
||||||
Only the first listed console is started properly, the remaining ones
|
|
||||||
were registered using the wrong :ID and no arguments to getty.
|
|
||||||
|
|
||||||
This patch fixes the parsing and re-use of the base paramenters for
|
|
||||||
all consoles listed in the active file.
|
|
||||||
|
|
||||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
---
|
|
||||||
src/service.c | 45 +++++++++++++++++++++++----------------------
|
|
||||||
1 file changed, 23 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/service.c b/src/service.c
|
|
||||||
index eca9ed0..95a04b8 100644
|
|
||||||
--- a/src/service.c
|
|
||||||
+++ b/src/service.c
|
|
||||||
@@ -1633,10 +1633,16 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|
||||||
|
|
||||||
if (type == SVC_TYPE_TTY) {
|
|
||||||
size_t i, len = 0;
|
|
||||||
+ char *ptr;
|
|
||||||
|
|
||||||
if (tty_parse_args(&tty, cmd, &args))
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
+ if (tty_isatcon(tty.dev))
|
|
||||||
+ dev = tty_atcon();
|
|
||||||
+ else
|
|
||||||
+ dev = tty.dev;
|
|
||||||
+ next:
|
|
||||||
if (tty.cmd)
|
|
||||||
len += strlen(tty.cmd);
|
|
||||||
else
|
|
||||||
@@ -1659,14 +1665,22 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|
||||||
if (!cmd)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
- if (tty_isatcon(tty.dev))
|
|
||||||
- dev = tty_atcon();
|
|
||||||
- else
|
|
||||||
- dev = tty.dev;
|
|
||||||
-
|
|
||||||
/* tty's always respawn, never incr. restart_cnt */
|
|
||||||
respawn = 1;
|
|
||||||
- next:
|
|
||||||
+
|
|
||||||
+ /* Create name:id tuple for identity, e.g., tty:S0 */
|
|
||||||
+ ptr = strrchr(dev, '/');
|
|
||||||
+ if (ptr)
|
|
||||||
+ ptr++;
|
|
||||||
+ else
|
|
||||||
+ ptr = dev;
|
|
||||||
+ if (!strncmp(ptr, "tty", 3))
|
|
||||||
+ ptr += 3;
|
|
||||||
+
|
|
||||||
+ name = "tty";
|
|
||||||
+ if (!id || id[0] == 0)
|
|
||||||
+ id = ptr;
|
|
||||||
+
|
|
||||||
svc = svc_find_by_tty(dev);
|
|
||||||
} else
|
|
||||||
svc = svc_find(name, id);
|
|
||||||
@@ -1722,8 +1736,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|
||||||
conf_parse_cond(svc, cond);
|
|
||||||
|
|
||||||
if (type == SVC_TYPE_TTY) {
|
|
||||||
- char *ptr;
|
|
||||||
-
|
|
||||||
if (dev)
|
|
||||||
strlcpy(svc->dev, dev, sizeof(svc->dev));
|
|
||||||
if (tty.baud)
|
|
||||||
@@ -1738,19 +1750,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|
||||||
|
|
||||||
/* TTYs cannot be redirected */
|
|
||||||
log = NULL;
|
|
||||||
-
|
|
||||||
- /* Create name:id tuple for identity, e.g., tty:S0 */
|
|
||||||
- ptr = strrchr(svc->dev, '/');
|
|
||||||
- if (ptr)
|
|
||||||
- ptr++;
|
|
||||||
- else
|
|
||||||
- ptr = svc->dev;
|
|
||||||
- if (!strncmp(ptr, "tty", 3))
|
|
||||||
- ptr += 3;
|
|
||||||
- if (!id || id[0] == 0)
|
|
||||||
- id = ptr;
|
|
||||||
- strlcpy(svc->name, "tty", sizeof(svc->name));
|
|
||||||
- strlcpy(svc->id, id, sizeof(svc->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_cmdline_args(svc, cmd, &args);
|
|
||||||
@@ -1870,8 +1869,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|
||||||
/* continue expanding any 'tty @console ...' */
|
|
||||||
if (tty_isatcon(tty.dev)) {
|
|
||||||
dev = tty_atcon();
|
|
||||||
- if (dev)
|
|
||||||
+ if (dev) {
|
|
||||||
+ id = NULL; /* reset for next tty:ID */
|
|
||||||
goto next;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
From 340cae4afd0d11979322a6c2f4d40a12ea59817b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
Date: Wed, 24 Apr 2024 12:46:59 +0200
|
|
||||||
Subject: [PATCH 11/11] Change default behavior, allow kernel logs to console
|
|
||||||
Organization: Addiva Elektronik
|
|
||||||
|
|
||||||
A Linux system booted with the kernel command line option 'quiet' only
|
|
||||||
logs error (and above) severity messages to the console. For embedded
|
|
||||||
systems, which is the primary target for Finit, this is what you want
|
|
||||||
to see.
|
|
||||||
|
|
||||||
Hence, and after careful consideration, this patch changes the default
|
|
||||||
behavior of Finit to allow kernel logs to the console. A build-time
|
|
||||||
configure flags, --disable-kernel-logging, has been added to restore
|
|
||||||
legacy behavior.
|
|
||||||
|
|
||||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
---
|
|
||||||
configure.ac | 9 +++++++++
|
|
||||||
src/finit.c | 14 +++++++++++---
|
|
||||||
2 files changed, 20 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index a4470d0..31f4cff 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -71,6 +71,10 @@ AC_ARG_ENABLE(redirect,
|
|
||||||
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
|
|
||||||
enable_redirect=yes])
|
|
||||||
|
|
||||||
+AC_ARG_ENABLE(kernel_logging,
|
|
||||||
+ AS_HELP_STRING([--disable-kernel-logging], [Disable kernel logging to console (use 'quiet' instead!]),,[
|
|
||||||
+ enable_kernel_logging=yes])
|
|
||||||
+
|
|
||||||
AC_ARG_ENABLE(logrotate,
|
|
||||||
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
|
|
||||||
enable_logrotate=yes])
|
|
||||||
@@ -181,6 +185,9 @@ AS_IF([test "x$enable_auto_reload" = "xyes"], [
|
|
||||||
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
|
|
||||||
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
|
|
||||||
|
|
||||||
+AS_IF([test "x$enable_kernel_logging" = "xyes"], [
|
|
||||||
+ AC_DEFINE(KERNEL_LOGGING, 1, [Keep kernel warn/err logs to console])])
|
|
||||||
+
|
|
||||||
AS_IF([test "x$enable_fastboot" = "xyes"], [
|
|
||||||
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
|
|
||||||
|
|
||||||
@@ -382,6 +389,8 @@ Optional features:
|
|
||||||
Built-in sulogin......: $with_sulogin $sulogin
|
|
||||||
Built-in watchdogd....: $with_watchdog $watchdog
|
|
||||||
Built-in logrotate....: $enable_logrotate
|
|
||||||
+ Parse kernel cmdline..: $enable_kernel_cmdline
|
|
||||||
+ Keep kernel logging...: $enable_kernel_logging
|
|
||||||
Skip fsck check.......: $enable_fastboot
|
|
||||||
Run fsck fix mode.....: $enable_fsckfix
|
|
||||||
Redirect output.......: $enable_redirect
|
|
||||||
diff --git a/src/finit.c b/src/finit.c
|
|
||||||
index 27b81e9..38b1278 100644
|
|
||||||
--- a/src/finit.c
|
|
||||||
+++ b/src/finit.c
|
|
||||||
@@ -87,14 +87,22 @@ svc_t *wdog = NULL; /* No watchdog by default */
|
|
||||||
*/
|
|
||||||
static void banner(void)
|
|
||||||
{
|
|
||||||
+#ifndef KERNEL_LOGGING
|
|
||||||
/*
|
|
||||||
* Silence kernel logs, assuming users have sysklogd or
|
|
||||||
- * similar enabled to start emptying /dev/kmsg, but for
|
|
||||||
- * our progress we want to own the console.
|
|
||||||
+ * similar enabled to start emptying /dev/kmsg.
|
|
||||||
+ *
|
|
||||||
+ * Instead of using `configure --disable-kernel-logging`, we
|
|
||||||
+ * recommend adjusting the kernel log level in the kernel's
|
|
||||||
+ * menuconfig, or using sysctl kernel.printk, or setting the
|
|
||||||
+ * desired log level, on the kernel cmdline, e.g. 'quiet'.
|
|
||||||
+ *
|
|
||||||
+ * By default KERNEL_LOGGING is enabled so you can see any
|
|
||||||
+ * warnings/errors or higher on your system console.
|
|
||||||
*/
|
|
||||||
if (!debug && !kerndebug)
|
|
||||||
klogctl(6, NULL, 0);
|
|
||||||
-
|
|
||||||
+#endif
|
|
||||||
/*
|
|
||||||
* First level hooks, if you want to run here, you're
|
|
||||||
* pretty much on your own. Nothing's up yet ...
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
@@ -51,17 +51,6 @@ config BR2_PACKAGE_FINIT_INITCTL_GROUP
|
|||||||
to their shared UNIX group, usually "wheel", to allow
|
to their shared UNIX group, usually "wheel", to allow
|
||||||
them to start/stop services and reboot the system.
|
them to start/stop services and reboot the system.
|
||||||
|
|
||||||
config BR2_PACKAGE_FINIT_SILENCE_KERNEL
|
|
||||||
bool "Silence kernel logs to console"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
By default, Finit >= 4.8 no longer disable kernel logging
|
|
||||||
to console. This option can be used to re-enable legacy
|
|
||||||
klogctl() code to silence the kernel output.
|
|
||||||
|
|
||||||
Please note, sysklogd has a similar command line option to
|
|
||||||
keep kernel logging, which needs to be disabled as well.
|
|
||||||
|
|
||||||
config BR2_PACKAGE_FINIT_KEVENTD
|
config BR2_PACKAGE_FINIT_KEVENTD
|
||||||
bool "finit-keventd"
|
bool "finit-keventd"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -42,12 +42,6 @@ FINIT_CONF_OPTS += --without-fstab
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_FINIT_SILENCE_KERNEL),y)
|
|
||||||
FINIT_CONF_OPTS += --disable-kernel-logging
|
|
||||||
else
|
|
||||||
FINIT_CONF_OPTS += --enable-kernel-logging
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_FINIT_KEVENTD),y)
|
ifeq ($(BR2_PACKAGE_FINIT_KEVENTD),y)
|
||||||
FINIT_CONF_OPTS += --with-keventd
|
FINIT_CONF_OPTS += --with-keventd
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
config BR2_PACKAGE_GENCERT
|
|
||||||
bool "gencert"
|
|
||||||
select BR2_PACKAGE_OPENSSL
|
|
||||||
help
|
|
||||||
Generate a self-signed certificate for embedded systems confused
|
|
||||||
about the current time. Start date: 2000-01-01, end: 9999-01-01
|
|
||||||
|
|
||||||
https://github.com/kernelkit/infix
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
sha256 fff5e150e496c6bb6035ae388ee13cf2d0df842335e5145a4b902ef6b7892088 LICENSE
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
#
|
|
||||||
# gencert
|
|
||||||
#
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
GENCERT_VERSION = 1.0
|
|
||||||
GENCERT_SITE_METHOD = local
|
|
||||||
GENCERT_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/gencert
|
|
||||||
GENCERT_LICENSE = ISC
|
|
||||||
GENCERT_LICENSE_FILES = LICENSE
|
|
||||||
GENCERT_REDISTRIBUTE = NO
|
|
||||||
GENCERT_DEPENDENCIES = host-pkgconf libopenssl
|
|
||||||
GENCERT_AUTORECONF = YES
|
|
||||||
|
|
||||||
define GENCERT_CONF_ENV
|
|
||||||
CFLAGS="$(INFIX_CFLAGS)"
|
|
||||||
endef
|
|
||||||
|
|
||||||
GENCERT_CONF_OPTS = --prefix= --disable-silent-rules
|
|
||||||
|
|
||||||
$(eval $(autotools-package))
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
config BR2_PACKAGE_LANDING
|
|
||||||
bool "Landing page (temporary)"
|
|
||||||
help
|
|
||||||
Temporary landing page before upcoming webui.
|
|
||||||
|
|
||||||
https://github.com/kernelkit/infix
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
sha256 fff5e150e496c6bb6035ae388ee13cf2d0df842335e5145a4b902ef6b7892088 LICENSE
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
#
|
|
||||||
# landing
|
|
||||||
#
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
LANDING_VERSION = 1.0
|
|
||||||
LANDING_SITE_METHOD = local
|
|
||||||
LANDING_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/landing
|
|
||||||
LANDING_LICENSE = ISC
|
|
||||||
LANDING_LICENSE_FILES = LICENSE
|
|
||||||
|
|
||||||
define LANDING_INSTALL_TARGET_CMDS
|
|
||||||
cp $(@D)/*.html $(TARGET_DIR)/usr/html/
|
|
||||||
cp $(@D)/*.png $(TARGET_DIR)/usr/html/
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(generic-package))
|
|
||||||
@@ -11,7 +11,7 @@ LIBSRX_LICENSE = BSD-3-Clause
|
|||||||
LIBSRX_LICENSE_FILES = LICENSE
|
LIBSRX_LICENSE_FILES = LICENSE
|
||||||
LIBSRX_INSTALL_STAGING = YES
|
LIBSRX_INSTALL_STAGING = YES
|
||||||
LIBSRX_REDISTRIBUTE = NO
|
LIBSRX_REDISTRIBUTE = NO
|
||||||
LIBSRX_DEPENDENCIES = sysrepo libite
|
LIBSRX_DEPENDENCIES = sysrepo
|
||||||
LIBSRX_AUTORECONF = YES
|
LIBSRX_AUTORECONF = YES
|
||||||
define LIBSRX_CONF_ENV
|
define LIBSRX_CONF_ENV
|
||||||
CFLAGS="$(INFIX_CFLAGS)"
|
CFLAGS="$(INFIX_CFLAGS)"
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
sha256 dcd639c77689c432e84e63267202c00958fb1032e066ae355e3cbc68d9fcd063 mcd-2.3.tar.gz
|
sha256 818c003ff153d914a829cd169a7cddb06643f423ebbf8b9e3932aad34c5ed60d mcd-2.1.tar.gz
|
||||||
sha256 99a0480db163445c5a1a5bf7f85bc37cbb5be8c40e9e441291ad78e8d4252d0b LICENSE
|
sha256 99a0480db163445c5a1a5bf7f85bc37cbb5be8c40e9e441291ad78e8d4252d0b LICENSE
|
||||||
|
|||||||
+1
-2
@@ -4,11 +4,10 @@
|
|||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
MCD_VERSION = 2.3
|
MCD_VERSION = 2.1
|
||||||
MCD_SITE = https://github.com/kernelkit/mcd/releases/download/v$(MCD_VERSION)
|
MCD_SITE = https://github.com/kernelkit/mcd/releases/download/v$(MCD_VERSION)
|
||||||
MCD_LICENSE = BSD-3-Clause
|
MCD_LICENSE = BSD-3-Clause
|
||||||
MCD_LICENSE_FILES = LICENSE
|
MCD_LICENSE_FILES = LICENSE
|
||||||
MCD_CONF_OPTS = --disable-silent-rules --with-group=wheel
|
|
||||||
|
|
||||||
define MCD_INSTALL_CONFIG
|
define MCD_INSTALL_CONFIG
|
||||||
$(INSTALL) -D -m 0644 $(@D)/mcd.conf $(TARGET_DIR)/etc/mcd.conf
|
$(INSTALL) -D -m 0644 $(@D)/mcd.conf $(TARGET_DIR)/etc/mcd.conf
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
config BR2_PACKAGE_PYTHON_STATD
|
config BR2_PACKAGE_PYTHON_STATD
|
||||||
bool "python-statd"
|
bool "python-statd"
|
||||||
select BR2_PACKAGE_HOST_PYTHON3
|
select BR2_PACKAGE_HOST_PYTHON3
|
||||||
|
select BR2_PACKAGE_STATD
|
||||||
help
|
help
|
||||||
Python helpers for statd.
|
Python helpers for statd.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
sha256 360336cbf0f228b12b7ca0996b33e442d97f496edcf2ec31b655e63631e7f96f LICENSE
|
sha256 755d3a387cd124ff34e2b73cc58e7cec4d8d85ae6c295e30ffeb8d36eacecb1d LICENSE
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
PYTHON_STATD_VERSION = 1.0
|
PYTHON_STATD_VERSION = 1.0
|
||||||
PYTHON_STATD_SITE_METHOD = local
|
PYTHON_STATD_SITE_METHOD = local
|
||||||
PYTHON_STATD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/statd/python
|
PYTHON_STATD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/statd/python
|
||||||
PYTHON_STATD_LICENSE = BSD-3-Clause
|
STATD_LICENSE = BSD-3-Clause
|
||||||
PYTHON_STATD_LICENSE_FILES = LICENSE
|
STATD_LICENSE_FILES = LICENSE
|
||||||
PYTHON_STATD_DEPENDENCIES = host-python3 python3 host-python-poetry-core
|
PYTHON_STATD_DEPENDENCIES = host-python3 python3 host-python-poetry-core
|
||||||
PYTHON_STATD_SETUP_TYPE = pep517 # poetry
|
PYTHON_STATD_SETUP_TYPE = pep517 # poetry
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -l :: Keep kernel looging to console
|
|
||||||
# -m0 :: Disable periodic syslog MARK entries
|
# -m0 :: Disable periodic syslog MARK entries
|
||||||
# -s :: Enable secure mode, don't listen to remote logs
|
# -s :: Enable secure mode, don't listen to remote logs
|
||||||
# -r 1M:5 :: Log rotation every 1 MiB and keep 5 rotated ones
|
# -r 1M:5 :: Log rotation every 1 MiB and keep 5 rotated ones
|
||||||
SYSLOGD_ARGS="-l -m0 -s -r 1M:10"
|
SYSLOGD_ARGS="-m0 -s -r 1M:5"
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
task [2] run-parts /cfg/user-scripts.d -- Running user startup scripts
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
root:x:0:
|
|
||||||
daemon:x:1:
|
|
||||||
bin:x:2:
|
|
||||||
sys:x:3:
|
|
||||||
adm:x:4:
|
|
||||||
tty:x:5:
|
|
||||||
disk:x:6:
|
|
||||||
lp:x:7:
|
|
||||||
mail:x:8:
|
|
||||||
kmem:x:9:
|
|
||||||
wheel:x:10:root
|
|
||||||
cdrom:x:11:
|
|
||||||
dialout:x:18:
|
|
||||||
floppy:x:19:
|
|
||||||
video:x:28:
|
|
||||||
audio:x:29:
|
|
||||||
tape:x:32:
|
|
||||||
www-data:x:33:
|
|
||||||
backup:x:34:
|
|
||||||
utmp:x:43:
|
|
||||||
plugdev:x:46:
|
|
||||||
lock:x:54:
|
|
||||||
netdev:x:82:
|
|
||||||
users:x:100:
|
|
||||||
nobody:x:65534:
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
root:x:0:0:root:/root:/bin/sh
|
|
||||||
daemon:x:1:1:daemon:/usr/sbin:/bin/false
|
|
||||||
bin:x:2:2:bin:/bin:/bin/false
|
|
||||||
sys:x:3:3:sys:/dev:/bin/false
|
|
||||||
sync:x:4:100:sync:/bin:/bin/sync
|
|
||||||
mail:x:8:8:mail:/var/spool/mail:/bin/false
|
|
||||||
www-data:x:33:33:www-data:/var/www:/bin/false
|
|
||||||
backup:x:34:34:backup:/var/backups:/bin/false
|
|
||||||
nobody:x:65534:65534:nobody:/home:/bin/false
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
root::::::::
|
|
||||||
daemon:*:::::::
|
|
||||||
bin:*:::::::
|
|
||||||
sys:*:::::::
|
|
||||||
sync:*:::::::
|
|
||||||
mail:*:::::::
|
|
||||||
www-data:*:::::::
|
|
||||||
backup:*:::::::
|
|
||||||
nobody:*:::::::
|
|
||||||
@@ -1,3 +1 @@
|
|||||||
#set DEBUG=1
|
|
||||||
|
|
||||||
service name:statd log [S12345] <pid/confd> statd -f -p /run/statd.pid -n -- Status daemon
|
service name:statd log [S12345] <pid/confd> statd -f -p /run/statd.pid -n -- Status daemon
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
sha256 360336cbf0f228b12b7ca0996b33e442d97f496edcf2ec31b655e63631e7f96f LICENSE
|
sha256 755d3a387cd124ff34e2b73cc58e7cec4d8d85ae6c295e30ffeb8d36eacecb1d LICENSE
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ STATD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/statd
|
|||||||
STATD_LICENSE = BSD-3-Clause
|
STATD_LICENSE = BSD-3-Clause
|
||||||
STATD_LICENSE_FILES = LICENSE
|
STATD_LICENSE_FILES = LICENSE
|
||||||
STATD_REDISTRIBUTE = NO
|
STATD_REDISTRIBUTE = NO
|
||||||
STATD_DEPENDENCIES = sysrepo libev libsrx jansson python-statd libyang
|
STATD_DEPENDENCIES = sysrepo libev libsrx jansson python-statd
|
||||||
STATD_AUTORECONF = YES
|
STATD_AUTORECONF = YES
|
||||||
|
|
||||||
define STATD_CONF_ENV
|
define STATD_CONF_ENV
|
||||||
|
|||||||
@@ -1,205 +0,0 @@
|
|||||||
commit 06dda0cf4e5ed8705c474c8ecec4e56d25169033
|
|
||||||
Author: Mattias Walström <lazzer@gmail.com>
|
|
||||||
Date: Sat Apr 20 17:01:59 2024 +0200
|
|
||||||
|
|
||||||
This adds the feature to search for GPT partitions by
|
|
||||||
partition UUID.
|
|
||||||
|
|
||||||
diff --git a/grub-core/Makefile.core.am b/grub-core/Makefile.core.am
|
|
||||||
index 20efe61..f33e199 100644
|
|
||||||
--- a/grub-core/Makefile.core.am
|
|
||||||
+++ b/grub-core/Makefile.core.am
|
|
||||||
@@ -8610,6 +8610,26 @@ CLEANFILES += search_fs_file.marker
|
|
||||||
search_fs_file.marker: $(search_fs_file_module_SOURCES) $(nodist_search_fs_file_module_SOURCES)
|
|
||||||
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(search_fs_file_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
|
|
||||||
grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new
|
|
||||||
+platform_PROGRAMS += search_partuuid.module
|
|
||||||
+MODULE_FILES += search_partuuid.module$(EXEEXT)
|
|
||||||
+search_partuuid_module_SOURCES = commands/search_partuuid.c ## platform sources
|
|
||||||
+nodist_search_partuuid_module_SOURCES = ## platform nodist sources
|
|
||||||
+search_partuuid_module_LDADD =
|
|
||||||
+search_partuuid_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE)
|
|
||||||
+search_partuuid_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE)
|
|
||||||
+search_partuuid_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE)
|
|
||||||
+search_partuuid_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE)
|
|
||||||
+search_partuuid_module_DEPENDENCIES = $(TARGET_OBJ2ELF)
|
|
||||||
+dist_noinst_DATA +=
|
|
||||||
+BUILT_SOURCES += $(nodist_search_partuuid_module_SOURCES)
|
|
||||||
+CLEANFILES += $(nodist_search_partuuid_module_SOURCES)
|
|
||||||
+MOD_FILES += search_partuuid.mod
|
|
||||||
+MARKER_FILES += search_partuuid.marker
|
|
||||||
+CLEANFILES += search_partuuid.marker
|
|
||||||
+
|
|
||||||
+search_partuuid.marker: $(search_partuuid_module_SOURCES) $(nodist_search_partuuid_module_SOURCES)
|
|
||||||
+ $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(search_partuuid_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
|
|
||||||
+ grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new
|
|
||||||
platform_PROGRAMS += search_fs_uuid.module
|
|
||||||
MODULE_FILES += search_fs_uuid.module$(EXEEXT)
|
|
||||||
search_fs_uuid_module_SOURCES = commands/search_uuid.c ## platform sources
|
|
||||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
|
||||||
index 1571421..b8ca02d 100644
|
|
||||||
--- a/grub-core/Makefile.core.def
|
|
||||||
+++ b/grub-core/Makefile.core.def
|
|
||||||
@@ -1087,6 +1087,11 @@ module = {
|
|
||||||
extra_dist = commands/search.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
+module = {
|
|
||||||
+ name = search_partuuid;
|
|
||||||
+ common = commands/search_partuuid.c;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
module = {
|
|
||||||
name = search_fs_file;
|
|
||||||
common = commands/search_file.c;
|
|
||||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
|
||||||
index 263f150..135b27b 100644
|
|
||||||
--- a/grub-core/commands/search.c
|
|
||||||
+++ b/grub-core/commands/search.c
|
|
||||||
@@ -30,6 +30,7 @@
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/partition.h>
|
|
||||||
+#include <grub/gpt_partition.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -92,7 +93,55 @@ iterate_device (const char *name, void *data)
|
|
||||||
#define compare_fn grub_strcmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-#ifdef DO_SEARCH_FILE
|
|
||||||
+#if defined (DO_SEARCH_PARTUUID)
|
|
||||||
+ {
|
|
||||||
+ grub_device_t dev;
|
|
||||||
+ char val[37] = "none";
|
|
||||||
+
|
|
||||||
+ dev = grub_device_open (name);
|
|
||||||
+ if (!dev)
|
|
||||||
+ {
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
+ if (dev->disk && dev->disk->partition)
|
|
||||||
+ {
|
|
||||||
+ struct grub_partition *p = dev->disk->partition;
|
|
||||||
+ grub_disk_t disk = grub_disk_open(dev->disk->name);
|
|
||||||
+
|
|
||||||
+ if (!disk)
|
|
||||||
+ {
|
|
||||||
+ grub_device_close (dev);
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (grub_strcmp(dev->disk->partition->partmap->name, "gpt") == 0)
|
|
||||||
+ {
|
|
||||||
+ struct grub_gpt_partentry entry;
|
|
||||||
+ grub_guid_t *guid;
|
|
||||||
+
|
|
||||||
+ if (grub_disk_read(disk, p->offset, p->index, sizeof(entry), &entry))
|
|
||||||
+ {
|
|
||||||
+ grub_error_push ();
|
|
||||||
+ grub_disk_close (disk);
|
|
||||||
+ grub_device_close (dev);
|
|
||||||
+ grub_error_pop ();
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
+ guid = &entry.guid;
|
|
||||||
+ guid->data1 = grub_le_to_cpu32 (guid->data1);
|
|
||||||
+ guid->data2 = grub_le_to_cpu16 (guid->data2);
|
|
||||||
+ guid->data3 = grub_le_to_cpu16 (guid->data3);
|
|
||||||
+ grub_snprintf (val, sizeof(val), "%pG", guid);
|
|
||||||
+
|
|
||||||
+ if (grub_strcmp(val, ctx->key) == 0)
|
|
||||||
+ found = 1;
|
|
||||||
+ }
|
|
||||||
+ if (disk)
|
|
||||||
+ grub_disk_close (disk);
|
|
||||||
+ }
|
|
||||||
+ grub_device_close (dev);
|
|
||||||
+ }
|
|
||||||
+#elif defined (DO_SEARCH_FILE)
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
grub_file_t file;
|
|
||||||
@@ -333,6 +382,8 @@ static grub_command_t cmd;
|
|
||||||
|
|
||||||
#ifdef DO_SEARCH_FILE
|
|
||||||
GRUB_MOD_INIT(search_fs_file)
|
|
||||||
+#elif defined (DO_SEARCH_PARTUUID)
|
|
||||||
+GRUB_MOD_INIT(search_partuuid)
|
|
||||||
#elif defined (DO_SEARCH_FS_UUID)
|
|
||||||
GRUB_MOD_INIT(search_fs_uuid)
|
|
||||||
#else
|
|
||||||
@@ -347,6 +398,8 @@ GRUB_MOD_INIT(search_label)
|
|
||||||
|
|
||||||
#ifdef DO_SEARCH_FILE
|
|
||||||
GRUB_MOD_FINI(search_fs_file)
|
|
||||||
+#elif defined (DO_SEARCH_PARTUUID)
|
|
||||||
+GRUB_MOD_FINI(search_partuuid)
|
|
||||||
#elif defined (DO_SEARCH_FS_UUID)
|
|
||||||
GRUB_MOD_FINI(search_fs_uuid)
|
|
||||||
#else
|
|
||||||
diff --git a/grub-core/commands/search_partuuid.c b/grub-core/commands/search_partuuid.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..e4aa20b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/grub-core/commands/search_partuuid.c
|
|
||||||
@@ -0,0 +1,5 @@
|
|
||||||
+#define DO_SEARCH_PARTUUID 1
|
|
||||||
+#define FUNC_NAME grub_search_partuuid
|
|
||||||
+#define COMMAND_NAME "search.partuuid"
|
|
||||||
+#define HELP_MESSAGE N_("Search devices by PARTUUID. If VARIABLE is specified, the first device found is set to a variable.")
|
|
||||||
+#include "search.c"
|
|
||||||
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
|
|
||||||
index 318581f..4a61093 100644
|
|
||||||
--- a/grub-core/commands/search_wrap.c
|
|
||||||
+++ b/grub-core/commands/search_wrap.c
|
|
||||||
@@ -36,6 +36,8 @@ static const struct grub_arg_option options[] =
|
|
||||||
0, 0},
|
|
||||||
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
|
|
||||||
0, 0},
|
|
||||||
+ {"partuuid", 'p', 0, N_("Search devices by a PARTUUID."),
|
|
||||||
+ 0, 0},
|
|
||||||
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
|
|
||||||
N_("Set a variable to the first device found."), N_("VARNAME"),
|
|
||||||
ARG_TYPE_STRING},
|
|
||||||
@@ -72,6 +74,7 @@ enum options
|
|
||||||
SEARCH_FILE,
|
|
||||||
SEARCH_LABEL,
|
|
||||||
SEARCH_FS_UUID,
|
|
||||||
+ SEARCH_PARTUUID,
|
|
||||||
SEARCH_SET,
|
|
||||||
SEARCH_NO_FLOPPY,
|
|
||||||
SEARCH_EFIDISK_ONLY,
|
|
||||||
@@ -193,6 +196,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
grub_search_label (id, var, flags, hints, nhints);
|
|
||||||
else if (state[SEARCH_FS_UUID].set)
|
|
||||||
grub_search_fs_uuid (id, var, flags, hints, nhints);
|
|
||||||
+ else if (state[SEARCH_PARTUUID].set)
|
|
||||||
+ grub_search_partuuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
|
||||||
+ hints, nhints);
|
|
||||||
else if (state[SEARCH_FILE].set)
|
|
||||||
grub_search_fs_file (id, var, flags, hints, nhints);
|
|
||||||
else
|
|
||||||
@@ -213,7 +219,7 @@ GRUB_MOD_INIT(search)
|
|
||||||
N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
|
|
||||||
" NAME"),
|
|
||||||
N_("Search devices by file, filesystem label"
|
|
||||||
- " or filesystem UUID."
|
|
||||||
+ " PARTUUID or filesystem UUID."
|
|
||||||
" If --set is specified, the first device found is"
|
|
||||||
" set to a variable. If no variable name is"
|
|
||||||
" specified, `root' is used."),
|
|
||||||
diff --git a/include/grub/search.h b/include/grub/search.h
|
|
||||||
index ffd2411..06468a8 100644
|
|
||||||
--- a/include/grub/search.h
|
|
||||||
+++ b/include/grub/search.h
|
|
||||||
@@ -35,5 +35,7 @@ void grub_search_fs_uuid (const char *key, const char *var,
|
|
||||||
void grub_search_label (const char *key, const char *var,
|
|
||||||
enum search_flags flags,
|
|
||||||
char **hints, unsigned nhints);
|
|
||||||
-
|
|
||||||
+void grub_search_partuuid (const char *key, const char *var,
|
|
||||||
+ enum search_flags flags,
|
|
||||||
+ char **hints, unsigned nhints);
|
|
||||||
#endif
|
|
||||||
@@ -1,20 +1,3 @@
|
|||||||
From 50fafdc63dc3d6152e2494cc693871e9bd04bfe5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
Date: Tue, 5 Mar 2024 09:41:46 +0100
|
|
||||||
Subject: [PATCH 1/2] iplink_bridge: add mcast_flood_always bridge option
|
|
||||||
Organization: Addiva Elektronik
|
|
||||||
|
|
||||||
- Break out boolopt handling to simplify parsing and setting
|
|
||||||
- Add set/get support for mcast_flood_always
|
|
||||||
- Add get support for mst_enabled
|
|
||||||
|
|
||||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
---
|
|
||||||
include/uapi/linux/if_bridge.h | 1 +
|
|
||||||
ip/iplink_bridge.c | 75 +++++++++++++++++++++++++---------
|
|
||||||
man/man8/ip-link.8.in | 12 ++++++
|
|
||||||
3 files changed, 68 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
|
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
|
||||||
index adb75f7d..611ab413 100644
|
index adb75f7d..611ab413 100644
|
||||||
--- a/include/uapi/linux/if_bridge.h
|
--- a/include/uapi/linux/if_bridge.h
|
||||||
@@ -170,6 +153,3 @@ index 6764a9ad..8f77c5ad 100644
|
|||||||
.BI mcast_snooping " MULTICAST_SNOOPING "
|
.BI mcast_snooping " MULTICAST_SNOOPING "
|
||||||
- turn multicast snooping on
|
- turn multicast snooping on
|
||||||
.RI ( MULTICAST_SNOOPING " > 0) "
|
.RI ( MULTICAST_SNOOPING " > 0) "
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
From 226a8b532fc074165ba76d71c4488629daed2625 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
Date: Mon, 20 May 2024 21:35:11 +0200
|
|
||||||
Subject: [PATCH 2/2] ipaddress: accept symbolic names also for show
|
|
||||||
Organization: Addiva Elektronik
|
|
||||||
|
|
||||||
This is a follow-up to 709063e, which in turn was a follow-up to
|
|
||||||
bdb8d85, to add support for 'ip addr show proto static', where
|
|
||||||
'static' is defined in /etc/iproute2/rt_addrprotos.
|
|
||||||
|
|
||||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
|
||||||
---
|
|
||||||
ip/ipaddress.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
|
|
||||||
index e536912f..19900157 100644
|
|
||||||
--- a/ip/ipaddress.c
|
|
||||||
+++ b/ip/ipaddress.c
|
|
||||||
@@ -2217,7 +2217,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|
||||||
__u8 proto;
|
|
||||||
|
|
||||||
NEXT_ARG();
|
|
||||||
- if (get_u8(&proto, *argv, 0))
|
|
||||||
+ if (rtnl_addrprot_a2n(&proto, *argv))
|
|
||||||
invarg("\"proto\" value is invalid\n", *argv);
|
|
||||||
filter.have_proto = true;
|
|
||||||
filter.proto = proto;
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
From 79abf7872e35080ca5b519bb4ad2acc1fbd96e8c Mon Sep 17 00:00:00 2001
|
From 79abf7872e35080ca5b519bb4ad2acc1fbd96e8c Mon Sep 17 00:00:00 2001
|
||||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||||
Date: Thu, 25 Jan 2024 21:36:59 +0100
|
Date: Thu, 25 Jan 2024 21:36:59 +0100
|
||||||
Subject: [PATCH 01/30] net: phy: add support for PHY LEDs polarity modes
|
Subject: [PATCH 01/24] net: phy: add support for PHY LEDs polarity modes
|
||||||
Organization: Addiva Elektronik
|
Organization: Addiva Elektronik
|
||||||
|
|
||||||
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
|
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 424ddb5d5d8ce06c578cc08cbedf519c42dd8b69 Mon Sep 17 00:00:00 2001
|
From 424ddb5d5d8ce06c578cc08cbedf519c42dd8b69 Mon Sep 17 00:00:00 2001
|
||||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
Date: Mon, 4 Dec 2023 11:08:11 +0100
|
Date: Mon, 4 Dec 2023 11:08:11 +0100
|
||||||
Subject: [PATCH 02/30] net: mvmdio: Support setting the MDC frequency on XSMI
|
Subject: [PATCH 02/24] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||||
controllers
|
controllers
|
||||||
Organization: Addiva Elektronik
|
Organization: Addiva Elektronik
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From 337cf21833cef6ab456a8562338de88ab1a84ead Mon Sep 17 00:00:00 2001
|
From 337cf21833cef6ab456a8562338de88ab1a84ead Mon Sep 17 00:00:00 2001
|
||||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
Date: Thu, 14 Dec 2023 14:50:23 +0100
|
Date: Thu, 14 Dec 2023 14:50:23 +0100
|
||||||
Subject: [PATCH 03/30] net: dsa: mv88e6xxx: Create API to read a single stat
|
Subject: [PATCH 03/24] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||||
counter
|
counter
|
||||||
Organization: Addiva Elektronik
|
Organization: Addiva Elektronik
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
From dbdbfd57998b4f8224146ac94cd5d0a577326087 Mon Sep 17 00:00:00 2001
|
From dbdbfd57998b4f8224146ac94cd5d0a577326087 Mon Sep 17 00:00:00 2001
|
||||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
Date: Thu, 14 Dec 2023 14:50:25 +0100
|
Date: Thu, 14 Dec 2023 14:50:25 +0100
|
||||||
Subject: [PATCH 04/30] net: dsa: mv88e6xxx: Give each hw stat an ID
|
Subject: [PATCH 04/24] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||||
Organization: Addiva Elektronik
|
Organization: Addiva Elektronik
|
||||||
|
|
||||||
With the upcoming standard counter group support, we are no longer
|
With the upcoming standard counter group support, we are no longer
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user