Compare commits
91 commits
master
...
openwrt-19
Author | SHA1 | Date | |
---|---|---|---|
|
820bb60ac2 | ||
|
790bffb57a | ||
|
33254957df | ||
|
6c7306602a | ||
|
8f23999365 | ||
|
04e7f66aa7 | ||
|
bf77e5f0e0 | ||
|
01417ad681 | ||
|
653ec59929 | ||
|
3f095f7f7e | ||
|
c1a2f7a252 | ||
|
2f9236d864 | ||
|
20f3e51710 | ||
|
e05cb068c4 | ||
|
e37cf04da4 | ||
|
95cd0ce4b5 | ||
|
00eacef47b | ||
|
84b7b3c553 | ||
|
f17815946a | ||
|
372ec62886 | ||
|
ce5adaab95 | ||
|
2ed5a04ab8 | ||
|
c755ab8dce | ||
|
cccff55a62 | ||
|
63625f7e19 | ||
|
a30ac2558e | ||
|
df9f33c522 | ||
|
ee0fbac610 | ||
|
7a3e63fd45 | ||
|
c8734df677 | ||
|
ef3e03a367 | ||
|
3c10076826 | ||
|
101632e153 | ||
|
a995b62043 | ||
|
118536cfb0 | ||
|
9d6ef13203 | ||
|
e26b474520 | ||
|
369908cb0a | ||
|
97e7600955 | ||
|
0a3432d633 | ||
|
596dc84b65 | ||
|
862a2dfb5f | ||
|
02b4dbfcb7 | ||
|
59e8d5fa8c | ||
|
685968996f | ||
|
b77498bd56 | ||
|
6dea537c07 | ||
|
0e5c75f536 | ||
|
ad8f02a4aa | ||
|
017d89d569 | ||
|
ad79a0f065 | ||
|
4c05fe97d9 | ||
|
822b55ff7d | ||
|
3f8571194c | ||
|
9b42e24a54 | ||
|
5dd2f44a5b | ||
|
8b25c90ed6 | ||
|
094e9b0f94 | ||
|
20b98f094e | ||
|
bd25cae2c4 | ||
|
9f21b212ef | ||
|
dc81e506ca | ||
|
6e51cca4ea | ||
|
3a800853d6 | ||
|
38f2ed9466 | ||
|
b8fd8c8b9f | ||
|
18a724e154 | ||
|
efa6e5445a | ||
|
f1b0476edc | ||
|
839ea37939 | ||
|
c82ce8d095 | ||
|
242185e386 | ||
|
8d5ee29f08 | ||
|
a2f2a13386 | ||
|
931f947dd6 | ||
|
56878ac500 | ||
|
e53bb5eed6 | ||
|
774b7c60d7 | ||
|
953cd03492 | ||
|
e0787e950d | ||
|
e0b319cb9f | ||
|
66c20292c6 | ||
|
b04d24313d | ||
|
784ae0e42d | ||
|
9d559fdae9 | ||
|
d65d6f1ea3 | ||
|
6ea9e9b093 | ||
|
a93e68447a | ||
|
830440d25a | ||
|
bef6617141 | ||
|
18ec6d717b |
288 changed files with 17750 additions and 5349 deletions
|
@ -1,91 +0,0 @@
|
||||||
name: Check autorelease deprecation
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened, synchronize, converted_to_draft, ready_for_review, edited]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Check autorelease deprecation
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Determine branch name
|
|
||||||
run: |
|
|
||||||
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
|
|
||||||
echo "Building for $BRANCH"
|
|
||||||
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Determine changed packages
|
|
||||||
run: |
|
|
||||||
RET=0
|
|
||||||
|
|
||||||
# only detect packages with changes
|
|
||||||
PKG_ROOTS=$(find . -name Makefile | \
|
|
||||||
grep -v ".*/src/Makefile" | \
|
|
||||||
sed -e 's@./\(.*\)/Makefile@\1/@')
|
|
||||||
CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH...)
|
|
||||||
|
|
||||||
for ROOT in $PKG_ROOTS; do
|
|
||||||
for CHANGE in $CHANGES; do
|
|
||||||
if [[ "$CHANGE" == "$ROOT"* ]]; then
|
|
||||||
if grep -q '$(AUTORELEASE)' "$ROOT/Makefile"; then
|
|
||||||
CONTAINS_AUTORELEASE+="$ROOT"
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -n "$CONTAINS_AUTORELEASE" ]; then
|
|
||||||
RET=1
|
|
||||||
cat > "$GITHUB_WORKSPACE/pr_comment.md" << EOF
|
|
||||||
Please do no longer set *PKG_RELEASE* to *AUTORELEASE* as the
|
|
||||||
feature is deprecated. Please use an integer instead. Below is a
|
|
||||||
list of affected packages including correct *PKG_RELEASE*:
|
|
||||||
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
for ROOT in $CONTAINS_AUTORELEASE; do
|
|
||||||
echo -n " - ${ROOT}Makefile: PKG_RELEASE:=" >> "$GITHUB_WORKSPACE/pr_comment.md"
|
|
||||||
last_bump="$(git log --pretty=format:'%h %s' "$ROOT" |
|
|
||||||
grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' |
|
|
||||||
cut -f 1 -d ' ')"
|
|
||||||
|
|
||||||
if [ -n "$last_bump" ]; then
|
|
||||||
echo -n $(($(git rev-list --count "$last_bump..HEAD" "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
|
|
||||||
else
|
|
||||||
echo -n $(($(git rev-list --count HEAD "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
|
|
||||||
fi
|
|
||||||
echo >> "$GITHUB_WORKSPACE/pr_comment.md"
|
|
||||||
done
|
|
||||||
|
|
||||||
exit $RET
|
|
||||||
|
|
||||||
- name: Find Comment
|
|
||||||
uses: peter-evans/find-comment@v2
|
|
||||||
if: ${{ failure() }}
|
|
||||||
id: fc
|
|
||||||
with:
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
comment-author: 'github-actions[bot]'
|
|
||||||
|
|
||||||
- name: Create or update comment
|
|
||||||
uses: peter-evans/create-or-update-comment@v2
|
|
||||||
if: ${{ failure() }}
|
|
||||||
with:
|
|
||||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
body-file: 'pr_comment.md'
|
|
||||||
edit-mode: replace
|
|
33
.github/workflows/entrypoint.sh
vendored
33
.github/workflows/entrypoint.sh
vendored
|
@ -1,22 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# not enabling `errtrace` and `pipefail` since those are bash specific
|
|
||||||
set -o errexit # failing commands causes script to fail
|
|
||||||
set -o nounset # undefined variables causes script to fail
|
|
||||||
|
|
||||||
echo "src/gz packages_ci file:///ci" >> /etc/opkg/distfeeds.conf
|
|
||||||
|
|
||||||
FINGERPRINT="$(usign -F -p /ci/packages_ci.pub)"
|
|
||||||
cp /ci/packages_ci.pub "/etc/opkg/keys/$FINGERPRINT"
|
|
||||||
|
|
||||||
mkdir -p /var/lock/
|
mkdir -p /var/lock/
|
||||||
|
|
||||||
opkg update
|
opkg update
|
||||||
|
|
||||||
[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
|
[ -n "$CI_HELPER" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
|
||||||
|
|
||||||
for PKG in /ci/*.ipk; do
|
for PKG in /ci/*.ipk; do
|
||||||
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
|
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
|
||||||
# package name including variant
|
# package name including variant
|
||||||
PKG_NAME=$(sed -ne 's#^Package: \(.*\)$#\1#p' ./control)
|
PKG_NAME=$(sed -ne 's#^Package: \(.*\)$#\1#p' ./control)
|
||||||
# package version without release
|
# package version without release
|
||||||
|
@ -26,24 +17,10 @@ for PKG in /ci/*.ipk; do
|
||||||
|
|
||||||
echo "Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE"
|
echo "Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE"
|
||||||
|
|
||||||
export PKG_NAME PKG_VERSION CI_HELPER
|
|
||||||
|
|
||||||
PRE_TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/pre-test.sh
|
|
||||||
|
|
||||||
if [ -f "$PRE_TEST_SCRIPT" ]; then
|
|
||||||
echo "Use package specific pre-test.sh"
|
|
||||||
if sh "$PRE_TEST_SCRIPT" "$PKG_NAME" "$PKG_VERSION"; then
|
|
||||||
echo "Pre-test successful"
|
|
||||||
else
|
|
||||||
echo "Pre-test failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "No pre-test.sh script available"
|
|
||||||
fi
|
|
||||||
|
|
||||||
opkg install "$PKG"
|
opkg install "$PKG"
|
||||||
|
|
||||||
|
export PKG_NAME PKG_VERSION CI_HELPER
|
||||||
|
|
||||||
TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/test.sh
|
TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/test.sh
|
||||||
|
|
||||||
if [ -f "$TEST_SCRIPT" ]; then
|
if [ -f "$TEST_SCRIPT" ]; then
|
||||||
|
@ -58,5 +35,5 @@ for PKG in /ci/*.ipk; do
|
||||||
echo "No test.sh script available"
|
echo "No test.sh script available"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove --autoremove || true
|
opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove
|
||||||
done
|
done
|
||||||
|
|
2
.github/workflows/formal.yml
vendored
2
.github/workflows/formal.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
85
.github/workflows/multi-arch-test-build.yml
vendored
85
.github/workflows/multi-arch-test-build.yml
vendored
|
@ -3,10 +3,6 @@ name: Test Build
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Test ${{ matrix.arch }}
|
name: Test ${{ matrix.arch }}
|
||||||
|
@ -15,44 +11,40 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: aarch64_generic
|
- arch: arc_archs
|
||||||
target: armsr-armv8
|
target: archs38-generic
|
||||||
runtime_test: true
|
runtime_test: false
|
||||||
|
|
||||||
- arch: arm_cortex-a15_neon-vfpv4
|
|
||||||
target: armsr-armv7
|
|
||||||
runtime_test: true
|
|
||||||
|
|
||||||
- arch: arm_cortex-a9_vfpv3-d16
|
- arch: arm_cortex-a9_vfpv3-d16
|
||||||
target: mvebu-cortexa9
|
target: mvebu-cortexa9
|
||||||
runtime_test: false
|
runtime_test: false
|
||||||
|
|
||||||
- arch: i386_pentium-mmx
|
|
||||||
target: x86-geode
|
|
||||||
runtime_test: true
|
|
||||||
|
|
||||||
- arch: mips_24kc
|
- arch: mips_24kc
|
||||||
target: ath79-generic
|
target: ath79-generic
|
||||||
runtime_test: true
|
runtime_test: false
|
||||||
|
|
||||||
- arch: powerpc_464fp
|
- arch: powerpc_464fp
|
||||||
target: apm821xx-nand
|
target: apm821xx-nand
|
||||||
runtime_test: false
|
runtime_test: false
|
||||||
|
|
||||||
- arch: powerpc_8548
|
- arch: powerpc_8540
|
||||||
target: mpc85xx-p1010
|
target: mpc85xx-p1010
|
||||||
runtime_test: false
|
runtime_test: false
|
||||||
|
|
||||||
- arch: riscv64_riscv64
|
- arch: aarch64_cortex-a53
|
||||||
target: sifiveu-generic
|
target: mvebu-cortexa53
|
||||||
runtime_test: false
|
runtime_test: true
|
||||||
|
|
||||||
|
- arch: arm_cortex-a15_neon-vfpv4
|
||||||
|
target: armvirt-32
|
||||||
|
runtime_test: true
|
||||||
|
|
||||||
- arch: x86_64
|
- arch: x86_64
|
||||||
target: x86-64
|
target: x86-64
|
||||||
runtime_test: true
|
runtime_test: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
@ -81,44 +73,28 @@ jobs:
|
||||||
|
|
||||||
# fallback to test packages if nothing explicitly changes this is
|
# fallback to test packages if nothing explicitly changes this is
|
||||||
# should run if other mechanics in packages.git changed
|
# should run if other mechanics in packages.git changed
|
||||||
PACKAGES="${PACKAGES:-bird2 cjdns olsrd}"
|
PACKAGES="${PACKAGES:-vim attendedsysupgrade-common bmon}"
|
||||||
|
|
||||||
echo "Building $PACKAGES"
|
echo "Building $PACKAGES"
|
||||||
echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
|
echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Generate build keys
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y signify-openbsd
|
|
||||||
signify-openbsd -G -n -c 'DO NOT USE - OpenWrt packages feed CI' -p packages_ci.pub -s packages_ci.sec
|
|
||||||
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
|
||||||
echo "KEY_BUILD<<$EOF" >> $GITHUB_ENV
|
|
||||||
cat packages_ci.sec >> $GITHUB_ENV
|
|
||||||
echo "$EOF" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
uses: openwrt/gh-action-sdk@v5
|
uses: openwrt/gh-action-sdk@v4
|
||||||
env:
|
env:
|
||||||
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
|
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
|
||||||
FEEDNAME: packages_ci
|
FEEDNAME: packages_ci
|
||||||
INDEX: 1
|
|
||||||
KEY_BUILD: ${{ env.KEY_BUILD }}
|
|
||||||
|
|
||||||
- name: Move created packages to project dir
|
- name: Move created packages to project dir
|
||||||
run: cp bin/packages/${{ matrix.arch }}/packages_ci/* . || true
|
run: cp bin/packages/${{ matrix.arch }}/packages_ci/*.ipk . || true
|
||||||
|
|
||||||
- name: Store packages
|
- name: Store packages
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: ${{env.ARCHIVE_NAME}}-packages
|
name: ${{ matrix.arch}}-packages
|
||||||
path: |
|
path: "*.ipk"
|
||||||
Packages
|
|
||||||
Packages.*
|
|
||||||
*.ipk
|
|
||||||
PKG-INFO
|
|
||||||
|
|
||||||
- name: Store logs
|
- name: Store logs
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.arch}}-logs
|
name: ${{ matrix.arch}}-logs
|
||||||
path: logs/
|
path: logs/
|
||||||
|
@ -126,32 +102,19 @@ jobs:
|
||||||
- name: Remove logs
|
- name: Remove logs
|
||||||
run: sudo rm -rf logs/ || true
|
run: sudo rm -rf logs/ || true
|
||||||
|
|
||||||
- name: Check if any packages were built
|
|
||||||
run: |
|
|
||||||
if [ -n "$(find . -maxdepth 1 -type f -name '*.ipk' -print -quit)" ]; then
|
|
||||||
echo "Found *.ipk files"
|
|
||||||
HAVE_IPKS=true
|
|
||||||
else
|
|
||||||
echo "No *.ipk files found"
|
|
||||||
HAVE_IPKS=false
|
|
||||||
fi
|
|
||||||
echo "HAVE_IPKS=$HAVE_IPKS" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Register QEMU
|
- name: Register QEMU
|
||||||
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
|
if: ${{ matrix.runtime_test }}
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo docker run --rm --privileged aptman/qus -s -- -p
|
||||||
sudo apt-get install -y qemu-user-static binfmt-support
|
|
||||||
sudo update-binfmts --import
|
|
||||||
|
|
||||||
- name: Build Docker container
|
- name: Build Docker container
|
||||||
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
|
if: ${{ matrix.runtime_test }}
|
||||||
run: |
|
run: |
|
||||||
docker build -t test-container --build-arg ARCH .github/workflows/
|
docker build -t test-container --build-arg ARCH .github/workflows/
|
||||||
env:
|
env:
|
||||||
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
|
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
|
||||||
|
|
||||||
- name: Test via Docker container
|
- name: Test via Docker container
|
||||||
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
|
if: ${{ matrix.runtime_test }}
|
||||||
run: |
|
run: |
|
||||||
docker run --rm -v $GITHUB_WORKSPACE:/ci test-container
|
docker run --rm -v $GITHUB_WORKSPACE:/ci test-container
|
||||||
|
|
18
README
Normal file
18
README
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
This is an OpenWrt package feed containing community maintained routing packages.
|
||||||
|
|
||||||
|
To use these packages, add the following line to the feeds.conf
|
||||||
|
in the OpenWrt buildroot:
|
||||||
|
|
||||||
|
src-git routing git://github.com/openwrt-routing/packages.git
|
||||||
|
|
||||||
|
Update the feed:
|
||||||
|
|
||||||
|
./scripts/feeds update routing
|
||||||
|
|
||||||
|
Activate the package:
|
||||||
|
|
||||||
|
./scripts/feeds install -a -p routing
|
||||||
|
|
||||||
|
The routing packages should now appear in menuconfig.
|
||||||
|
|
||||||
|
|
21
README.md
21
README.md
|
@ -1,21 +0,0 @@
|
||||||
# OpenWrt Routing Feed
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
This OpenWrt package feed contains community maintained routing packages.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
|
|
||||||
This repository is intended to be layered on-top of an OpenWrt buildroot.
|
|
||||||
If you do not have an OpenWrt buildroot installed, see the documentation at:
|
|
||||||
[OpenWrt Buildroot – Installation][1] on the OpenWrt support site.
|
|
||||||
|
|
||||||
This feed is enabled by default. To install all its package definitions, run:
|
|
||||||
|
|
||||||
```
|
|
||||||
./scripts/feeds update routing
|
|
||||||
./scripts/feeds install -a -p routing
|
|
||||||
```
|
|
||||||
|
|
||||||
[1]: https://openwrt.org/docs/guide-developer/build-system/install-buildsystem
|
|
|
@ -1,55 +1,49 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
#
|
||||||
|
# Copyright (C) 2013 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=alfred
|
PKG_NAME:=alfred
|
||||||
PKG_VERSION:=2024.0
|
PKG_VERSION:=2019.2
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=3
|
||||||
|
PKG_HASH:=b656f0e9a97a99c7531b6d49ebfd663451c16cdd275bbf7d48ff8daed3880bf2
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
PKG_HASH:=d029a43638ab16771e5f71e134bc843d1713d74041c65bcda18a31d18f5531bd
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
|
|
||||||
PKG_LICENSE:=GPL-2.0-only MIT
|
|
||||||
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT
|
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
|
||||||
PKG_BUILD_FLAGS:=gc-sections lto
|
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS += \
|
|
||||||
CONFIG_ALFRED_NEEDS_lua \
|
|
||||||
CONFIG_ALFRED_NEEDS_libgps \
|
|
||||||
CONFIG_PACKAGE_ALFRED_VIS \
|
|
||||||
CONFIG_PACKAGE_ALFRED_BATHOSTS \
|
|
||||||
CONFIG_PACKAGE_ALFRED_GPSD
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
init-y := alfred
|
||||||
|
|
||||||
define Package/alfred
|
define Package/alfred
|
||||||
|
URL:=https://www.open-mesh.org/
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
TITLE:=A.L.F.R.E.D. - Almighty Lightweight Fact Remote Exchange Daemon
|
TITLE:=A.L.F.R.E.D. - Almighty Lightweight Fact Remote Exchange Daemon
|
||||||
URL:=https://www.open-mesh.org/
|
|
||||||
DEPENDS:= +libc @IPV6 +libnl-tiny +librt \
|
DEPENDS:= +libc @IPV6 +libnl-tiny +librt \
|
||||||
+ALFRED_NEEDS_lua:lua \
|
+ALFRED_NEEDS_lua:lua \
|
||||||
+ALFRED_NEEDS_libgps:libgps
|
+ALFRED_NEEDS_libgps:libgps
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/alfred/description
|
define Package/alfred/description
|
||||||
alfred is a user space daemon for distributing arbitrary local information
|
alfred is a user space daemon for distributing arbitrary local information over
|
||||||
over the mesh/network in a decentralized fashion. This data can be anything
|
the mesh/network in a decentralized fashion. This data can be anything which
|
||||||
which appears to be useful - originally designed to replace the batman-adv
|
appears to be useful - originally designed to replace the batman-adv
|
||||||
visualization (vis), you may distribute hostnames, phone books, administration
|
visualization (vis), you may distribute hostnames, phone books, administration
|
||||||
information, DNS information, the local weather forecast ...
|
information, DNS information, the local weather forecast ...
|
||||||
|
|
||||||
alfred runs as daemon in the background of the system. A user may insert
|
alfred runs as daemon in the background of the system. A user may insert
|
||||||
information by using the alfred binary on the command line, or use special
|
information by using the alfred binary on the command line, or use special
|
||||||
programs to communicate with alfred (done via unix sockets). alfred then takes
|
programs to communicate with alfred (done via unix sockets). alfred then takes
|
||||||
care of distributing the local information to other alfred servers on other
|
care of distributing the local information to other alfred servers on other
|
||||||
nodes. This is done via IPv6 link-local multicast, and does not require any
|
nodes. This is done via IPv6 link-local multicast, and does not require any
|
||||||
configuration. A user can request data from alfred, and will receive the
|
configuration. A user can request data from alfred, and will receive the
|
||||||
information available from all alfred servers in the network.
|
information available from all alfred servers in the network.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/alfred/conffiles
|
define Package/alfred/conffiles
|
||||||
|
@ -60,13 +54,22 @@ define Package/alfred/config
|
||||||
source "$(SOURCE)/Config.in"
|
source "$(SOURCE)/Config.in"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
MAKE_FLAGS += \
|
MAKE_ALFRED_FLAGS=\
|
||||||
CONFIG_ALFRED_VIS=$(if $(CONFIG_PACKAGE_ALFRED_VIS),y,n) \
|
CONFIG_ALFRED_VIS=$(if $(CONFIG_PACKAGE_ALFRED_VIS),y,n) \
|
||||||
CONFIG_ALFRED_GPSD=$(if $(CONFIG_PACKAGE_ALFRED_GPSD),y,n) \
|
CONFIG_ALFRED_GPSD=$(if $(CONFIG_PACKAGE_ALFRED_GPSD),y,n) \
|
||||||
CONFIG_ALFRED_CAPABILITIES=n \
|
CONFIG_ALFRED_CAPABILITIES=n \
|
||||||
LIBNL_NAME="libnl-tiny" \
|
LIBNL_NAME="libnl-tiny" \
|
||||||
LIBNL_GENL_NAME="libnl-tiny" \
|
LIBNL_GENL_NAME="libnl-tiny" \
|
||||||
REVISION="$(PKG_VERSION)-openwrt-$(PKG_RELEASE)"
|
REVISION="openwrt-$(PKG_VERSION)-$(PKG_RELEASE)"
|
||||||
|
|
||||||
|
TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
|
||||||
|
TARGET_LDFLAGS += -Wl,--gc-sections -fuse-linker-plugin
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
|
||||||
|
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS) $(MAKE_ALFRED_FLAGS) all
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/alfred/install
|
define Package/alfred/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
config 'alfred' 'alfred'
|
config 'alfred' 'alfred'
|
||||||
list interface 'br-lan'
|
option interface 'br-lan'
|
||||||
option mode 'master'
|
option mode 'master'
|
||||||
option batmanif 'bat0'
|
option batmanif 'bat0'
|
||||||
option start_vis '1'
|
option start_vis '1'
|
||||||
|
|
|
@ -13,16 +13,10 @@ facters_dir="/etc/alfred"
|
||||||
enable=0
|
enable=0
|
||||||
vis_enable=0
|
vis_enable=0
|
||||||
|
|
||||||
append_interface()
|
|
||||||
{
|
|
||||||
append "interfaces" "$1" ","
|
|
||||||
}
|
|
||||||
|
|
||||||
alfred_start() {
|
alfred_start() {
|
||||||
local args=""
|
local args=""
|
||||||
local section="$1"
|
local section="$1"
|
||||||
local disabled interface mode
|
local disabled interface mode
|
||||||
local interfaces
|
|
||||||
|
|
||||||
# check if section is disabled
|
# check if section is disabled
|
||||||
config_get_bool disabled "$section" disabled 0
|
config_get_bool disabled "$section" disabled 0
|
||||||
|
@ -30,12 +24,8 @@ alfred_start() {
|
||||||
|
|
||||||
args="-f"
|
args="-f"
|
||||||
|
|
||||||
config_list_foreach "$section" "interface" append_interface
|
config_get interface "$section" interface
|
||||||
if [ -z "$interfaces" ]; then
|
append args "-i $interface"
|
||||||
config_get interface "$section" interface
|
|
||||||
append_interface "$interface"
|
|
||||||
fi
|
|
||||||
append args "-i $interfaces"
|
|
||||||
|
|
||||||
config_get mode "$section" mode
|
config_get mode "$section" mode
|
||||||
[ "$mode" = "master" ] && append args "-m"
|
[ "$mode" = "master" ] && append args "-m"
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 19 Jun 2019 21:38:09 +0200
|
||||||
|
Subject: alfred: vis: Use rtnl to query list of hardifs of meshif
|
||||||
|
|
||||||
|
The normal way of network related programs to query the state of interfaces
|
||||||
|
is to use the rtnetlink. Most of these data can also be queried via sysfs
|
||||||
|
but it is better to use the same way for both retrieving the list of
|
||||||
|
interfaces and modifying the list of interfaces.
|
||||||
|
|
||||||
|
Also the sysfs files are deprecated and cause warnings when access:
|
||||||
|
|
||||||
|
batman_adv: [Deprecated]: batadv-vis (pid 832) Use of sysfs file "mesh_iface".
|
||||||
|
Use batadv genl family instead
|
||||||
|
|
||||||
|
In worst case, the file doesn't even exist when batman-adv was compiled
|
||||||
|
without sysfs support.
|
||||||
|
|
||||||
|
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/a34f044de561ce90f67b5760059f818bfb35b449
|
||||||
|
|
||||||
|
diff --git a/vis/vis.c b/vis/vis.c
|
||||||
|
index beaeca150bcac583e9506b9504fa026131f50d5d..37956b100fad72257f5bab2b9f49908da59520cc 100644
|
||||||
|
--- a/vis/vis.c
|
||||||
|
+++ b/vis/vis.c
|
||||||
|
@@ -372,70 +372,146 @@ static void clear_lists(struct globals *globals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct ifinfomsg rt_hdr = {
|
||||||
|
+ .ifi_family = IFLA_UNSPEC,
|
||||||
|
+ };
|
||||||
|
+ struct nl_sock *sock;
|
||||||
|
+ struct nl_msg *msg;
|
||||||
|
+ struct nl_cb *cb;
|
||||||
|
+ int err = 0;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ sock = nl_socket_alloc();
|
||||||
|
+ if (!sock)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ ret = nl_connect(sock, NETLINK_ROUTE);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_sock;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||||
|
+ if (!cb) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_sock;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, func, arg);
|
||||||
|
+
|
||||||
|
+ msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP);
|
||||||
|
+ if (!msg) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_cb;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = nlmsg_append(msg, &rt_hdr, sizeof(rt_hdr), NLMSG_ALIGNTO);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_msg;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = nla_put_u32(msg, IFLA_MASTER, ifindex);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_msg;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = nl_send_auto_complete(sock, msg);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto err_free_msg;
|
||||||
|
+
|
||||||
|
+ nl_recvmsgs(sock, cb);
|
||||||
|
+
|
||||||
|
+err_free_msg:
|
||||||
|
+ nlmsg_free(msg);
|
||||||
|
+err_free_cb:
|
||||||
|
+ nl_cb_put(cb);
|
||||||
|
+err_free_sock:
|
||||||
|
+ nl_socket_free(sock);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct register_interfaces_rtnl_arg {
|
||||||
|
+ struct globals *globals;
|
||||||
|
+ int ifindex;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct nla_policy link_policy[IFLA_MAX + 1] = {
|
||||||
|
+ [IFLA_IFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
|
||||||
|
+ [IFLA_MASTER] = { .type = NLA_U32 },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct register_interfaces_rtnl_arg *register_arg = arg;
|
||||||
|
+ struct nlattr *attrs[IFLA_MAX + 1];
|
||||||
|
+ char path_buff[PATH_BUFF_LEN];
|
||||||
|
+ struct ifinfomsg *ifm;
|
||||||
|
+ char *content_newline;
|
||||||
|
+ char *file_content;
|
||||||
|
+ char *ifname;
|
||||||
|
+ int master;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ifm = nlmsg_data(nlmsg_hdr(msg));
|
||||||
|
+ ret = nlmsg_parse(nlmsg_hdr(msg), sizeof(*ifm), attrs, IFLA_MAX,
|
||||||
|
+ link_policy);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ if (!attrs[IFLA_IFNAME])
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ if (!attrs[IFLA_MASTER])
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ ifname = nla_get_string(attrs[IFLA_IFNAME]);
|
||||||
|
+ master = nla_get_u32(attrs[IFLA_MASTER]);
|
||||||
|
+
|
||||||
|
+ /* required on older kernels which don't prefilter the results */
|
||||||
|
+ if (master != register_arg->ifindex)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, ifname);
|
||||||
|
+ file_content = read_file(path_buff);
|
||||||
|
+ if (!file_content)
|
||||||
|
+ goto free_file;
|
||||||
|
+
|
||||||
|
+ content_newline = strstr(file_content, "\n");
|
||||||
|
+ if (content_newline)
|
||||||
|
+ *content_newline = '\0';
|
||||||
|
+
|
||||||
|
+ if (strcmp(file_content, "active") != 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ get_if_index_byname(register_arg->globals, ifname);
|
||||||
|
+
|
||||||
|
+free_file:
|
||||||
|
+ free(file_content);
|
||||||
|
+ file_content = NULL;
|
||||||
|
+err:
|
||||||
|
+ return NL_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int register_interfaces(struct globals *globals)
|
||||||
|
{
|
||||||
|
- DIR *iface_base_dir;
|
||||||
|
- struct dirent *iface_dir;
|
||||||
|
- char *path_buff, *file_content;
|
||||||
|
- char *content_newline;
|
||||||
|
+ struct register_interfaces_rtnl_arg register_arg = {
|
||||||
|
+ .globals = globals,
|
||||||
|
+ };
|
||||||
|
|
||||||
|
- path_buff = malloc(PATH_BUFF_LEN);
|
||||||
|
- if (!path_buff) {
|
||||||
|
- perror("Error - could not allocate path buffer");
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
+ register_arg.ifindex = if_nametoindex(globals->interface);
|
||||||
|
+ if (!globals->interface)
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
|
||||||
|
- iface_base_dir = opendir(SYS_IFACE_PATH);
|
||||||
|
- if (!iface_base_dir) {
|
||||||
|
- fprintf(stderr, "Error - the directory '%s' could not be read: %s\n",
|
||||||
|
- SYS_IFACE_PATH, strerror(errno));
|
||||||
|
- fprintf(stderr, "Is the batman-adv module loaded and sysfs mounted ?\n");
|
||||||
|
- goto err_buff;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- while ((iface_dir = readdir(iface_base_dir)) != NULL) {
|
||||||
|
- snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name);
|
||||||
|
- file_content = read_file(path_buff);
|
||||||
|
- if (!file_content)
|
||||||
|
- continue;
|
||||||
|
+ query_rtnl_link(register_arg.ifindex, register_interfaces_rtnl_parse,
|
||||||
|
+ ®ister_arg);
|
||||||
|
|
||||||
|
- if (file_content[strlen(file_content) - 1] == '\n')
|
||||||
|
- file_content[strlen(file_content) - 1] = '\0';
|
||||||
|
-
|
||||||
|
- if (strcmp(file_content, "none") == 0)
|
||||||
|
- goto free_line;
|
||||||
|
-
|
||||||
|
- if (strcmp(file_content, globals->interface) != 0)
|
||||||
|
- goto free_line;
|
||||||
|
-
|
||||||
|
- free(file_content);
|
||||||
|
- file_content = NULL;
|
||||||
|
-
|
||||||
|
- snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name);
|
||||||
|
- file_content = read_file(path_buff);
|
||||||
|
- if (!file_content)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- content_newline = strstr(file_content, "\n");
|
||||||
|
- if (content_newline)
|
||||||
|
- *content_newline = '\0';
|
||||||
|
-
|
||||||
|
- if (strcmp(file_content, "active") == 0)
|
||||||
|
- get_if_index_byname(globals, iface_dir->d_name);
|
||||||
|
-
|
||||||
|
-free_line:
|
||||||
|
- free(file_content);
|
||||||
|
- file_content = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- free(path_buff);
|
||||||
|
- closedir(iface_base_dir);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
-
|
||||||
|
-err_buff:
|
||||||
|
- free(path_buff);
|
||||||
|
-err:
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int parse_orig_list_mandatory[] = {
|
||||||
|
diff --git a/vis/vis.h b/vis/vis.h
|
||||||
|
index 6870dd4ad8570135f4ab2edf0219d74778b7d061..b04a89351778806e84acae88ff3869cf68bcb1a3 100644
|
||||||
|
--- a/vis/vis.h
|
||||||
|
+++ b/vis/vis.h
|
||||||
|
@@ -25,7 +25,6 @@
|
||||||
|
|
||||||
|
#define SYS_IFACE_PATH "/sys/class/net"
|
||||||
|
#define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%s"
|
||||||
|
-#define SYS_MESH_IFACE_FMT SYS_IFACE_PATH"/%s/batman_adv/mesh_iface"
|
||||||
|
#define SYS_IFACE_STATUS_FMT SYS_IFACE_PATH"/%s/batman_adv/iface_status"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 19 Jun 2019 21:38:10 +0200
|
||||||
|
Subject: alfred: vis: Retrieve hardif status via generic netlink
|
||||||
|
|
||||||
|
The batman-adv kernel module can now be compiled without support for sysfs.
|
||||||
|
But the batadv-vis interface retriever can only get the status via the per
|
||||||
|
hardif sysfs file iface_status. To still have some information, use
|
||||||
|
BATADV_CMD_GET_HARDIF to retrieve the status and fall back to sysfs when
|
||||||
|
the status could not retrieved via generic netlink.
|
||||||
|
|
||||||
|
This also solved the warning about deprecated sysfs file access
|
||||||
|
|
||||||
|
batman_adv: [Deprecated]: batadv-vis (pid 1365) Use of sysfs file "iface_status".
|
||||||
|
Use batadv genl family instead
|
||||||
|
|
||||||
|
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/0fc6e6674428ce7085b07645895ef837604e18b5
|
||||||
|
|
||||||
|
diff --git a/vis/vis.c b/vis/vis.c
|
||||||
|
index 37956b100fad72257f5bab2b9f49908da59520cc..947456343125458845f26dc38b53f18d6fd42d75 100644
|
||||||
|
--- a/vis/vis.c
|
||||||
|
+++ b/vis/vis.c
|
||||||
|
@@ -27,6 +27,8 @@
|
||||||
|
#include "netlink.h"
|
||||||
|
#include "debugfs.h"
|
||||||
|
|
||||||
|
+#define IFACE_STATUS_LEN 256
|
||||||
|
+
|
||||||
|
static struct globals vis_globals;
|
||||||
|
|
||||||
|
struct vis_netlink_opts {
|
||||||
|
@@ -435,6 +437,131 @@ err_free_sock:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int get_iface_status_netlink_parse(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *attrs[NUM_BATADV_ATTR];
|
||||||
|
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
+ char *iface_status = arg;
|
||||||
|
+ struct genlmsghdr *ghdr;
|
||||||
|
+
|
||||||
|
+ if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ ghdr = nlmsg_data(nlh);
|
||||||
|
+ if (ghdr->cmd != BATADV_CMD_GET_HARDIF)
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
+ genlmsg_len(ghdr), batadv_netlink_policy))
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ if (attrs[BATADV_ATTR_ACTIVE])
|
||||||
|
+ strncpy(iface_status, "active\n", IFACE_STATUS_LEN);
|
||||||
|
+ else
|
||||||
|
+ strncpy(iface_status, "inactive\n", IFACE_STATUS_LEN);
|
||||||
|
+
|
||||||
|
+ iface_status[IFACE_STATUS_LEN - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ return NL_STOP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
|
||||||
|
+ char *iface_status)
|
||||||
|
+{
|
||||||
|
+ char *ret_status = NULL;
|
||||||
|
+ struct nl_sock *sock;
|
||||||
|
+ struct nl_msg *msg;
|
||||||
|
+ int batadv_family;
|
||||||
|
+ struct nl_cb *cb;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ iface_status[0] = '\0';
|
||||||
|
+
|
||||||
|
+ sock = nl_socket_alloc();
|
||||||
|
+ if (!sock)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ ret = genl_connect(sock);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto err_free_sock;
|
||||||
|
+
|
||||||
|
+ batadv_family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
|
||||||
|
+ if (batadv_family < 0)
|
||||||
|
+ goto err_free_sock;
|
||||||
|
+
|
||||||
|
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||||
|
+ if (!cb)
|
||||||
|
+ goto err_free_sock;
|
||||||
|
+
|
||||||
|
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_iface_status_netlink_parse,
|
||||||
|
+ iface_status);
|
||||||
|
+
|
||||||
|
+ msg = nlmsg_alloc();
|
||||||
|
+ if (!msg)
|
||||||
|
+ goto err_free_cb;
|
||||||
|
+
|
||||||
|
+ genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, batadv_family,
|
||||||
|
+ 0, 0, BATADV_CMD_GET_HARDIF, 1);
|
||||||
|
+
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, meshif);
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, hardif);
|
||||||
|
+
|
||||||
|
+ ret = nl_send_auto_complete(sock, msg);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto err_free_msg;
|
||||||
|
+
|
||||||
|
+ nl_recvmsgs(sock, cb);
|
||||||
|
+
|
||||||
|
+ if (strlen(iface_status) > 0)
|
||||||
|
+ ret_status = iface_status;
|
||||||
|
+
|
||||||
|
+err_free_msg:
|
||||||
|
+ nlmsg_free(msg);
|
||||||
|
+err_free_cb:
|
||||||
|
+ nl_cb_put(cb);
|
||||||
|
+err_free_sock:
|
||||||
|
+ nl_socket_free(sock);
|
||||||
|
+
|
||||||
|
+ return ret_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool interface_active(unsigned int meshif, unsigned int hardif,
|
||||||
|
+ const char *ifname)
|
||||||
|
+{
|
||||||
|
+ char iface_status[IFACE_STATUS_LEN];
|
||||||
|
+ char path_buff[PATH_BUFF_LEN];
|
||||||
|
+ char *file_content = NULL;
|
||||||
|
+ char *content_newline;
|
||||||
|
+ bool active = false;
|
||||||
|
+ char *status;
|
||||||
|
+
|
||||||
|
+ status = get_iface_status_netlink(meshif, hardif, iface_status);
|
||||||
|
+ if (!status) {
|
||||||
|
+ snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT,
|
||||||
|
+ ifname);
|
||||||
|
+ file_content = read_file(path_buff);
|
||||||
|
+ if (!file_content)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ status = file_content;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ content_newline = strstr(status, "\n");
|
||||||
|
+ if (content_newline)
|
||||||
|
+ *content_newline = '\0';
|
||||||
|
+
|
||||||
|
+ if (strcmp(status, "active") != 0)
|
||||||
|
+ goto free_file;
|
||||||
|
+
|
||||||
|
+ active = true;
|
||||||
|
+
|
||||||
|
+free_file:
|
||||||
|
+ free(file_content);
|
||||||
|
+ file_content = NULL;
|
||||||
|
+
|
||||||
|
+ return active;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct register_interfaces_rtnl_arg {
|
||||||
|
struct globals *globals;
|
||||||
|
int ifindex;
|
||||||
|
@@ -449,10 +576,7 @@ static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct register_interfaces_rtnl_arg *register_arg = arg;
|
||||||
|
struct nlattr *attrs[IFLA_MAX + 1];
|
||||||
|
- char path_buff[PATH_BUFF_LEN];
|
||||||
|
struct ifinfomsg *ifm;
|
||||||
|
- char *content_newline;
|
||||||
|
- char *file_content;
|
||||||
|
char *ifname;
|
||||||
|
int master;
|
||||||
|
int ret;
|
||||||
|
@@ -476,23 +600,11 @@ static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
|
||||||
|
if (master != register_arg->ifindex)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, ifname);
|
||||||
|
- file_content = read_file(path_buff);
|
||||||
|
- if (!file_content)
|
||||||
|
- goto free_file;
|
||||||
|
-
|
||||||
|
- content_newline = strstr(file_content, "\n");
|
||||||
|
- if (content_newline)
|
||||||
|
- *content_newline = '\0';
|
||||||
|
-
|
||||||
|
- if (strcmp(file_content, "active") != 0)
|
||||||
|
+ if (!interface_active(master, ifm->ifi_index, ifname))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
get_if_index_byname(register_arg->globals, ifname);
|
||||||
|
|
||||||
|
-free_file:
|
||||||
|
- free(file_content);
|
||||||
|
- file_content = NULL;
|
||||||
|
err:
|
||||||
|
return NL_OK;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 1 Aug 2019 15:54:32 +0200
|
||||||
|
Subject: alfred: vis: Add missing include for ifinfomsg
|
||||||
|
|
||||||
|
Fixes: 0fc6e6674428 ("alfred: vis: Retrieve hardif status via generic netlink")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/ce26453bd72829ac9561acd8d3a06a3937341687
|
||||||
|
|
||||||
|
diff --git a/vis/vis.c b/vis/vis.c
|
||||||
|
index 947456343125458845f26dc38b53f18d6fd42d75..8df3056612d5da3678603a6e6430923c0c86cde0 100644
|
||||||
|
--- a/vis/vis.c
|
||||||
|
+++ b/vis/vis.c
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
+#include <linux/rtnetlink.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <signal.h>
|
|
@ -0,0 +1,29 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 19:56:22 +0100
|
||||||
|
Subject: alfred: Show error message for invalid batadv interface
|
||||||
|
|
||||||
|
The alfred server process always stopped without any informational message
|
||||||
|
when the provided batman-adv was not "none" and was not accessible. This
|
||||||
|
made it extremely hard to debug the reason why alfred directly stopped
|
||||||
|
after launching it.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-1-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index 18109cc76283484a67f54fbc34f88039b9602531..47e9ae28b703da23fb930756d2971161ab332bc1 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -385,8 +385,11 @@ int alfred_server(struct globals *globals)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(globals->mesh_iface, "none") != 0 &&
|
||||||
|
- batadv_interface_check(globals->mesh_iface) < 0)
|
||||||
|
+ batadv_interface_check(globals->mesh_iface) < 0) {
|
||||||
|
+ fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
|
||||||
|
+ globals->mesh_iface);
|
||||||
|
return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
num_socks = netsock_open_all(globals);
|
||||||
|
if (num_socks <= 0) {
|
|
@ -0,0 +1,72 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:16:15 +0100
|
||||||
|
Subject: alfred: Allow exactly one interface for secondary mode
|
||||||
|
|
||||||
|
A primary alfred daemon allows syncing over more than one interface. But
|
||||||
|
the secondary alfred daemon needs exactly one interface. But the check for
|
||||||
|
this property was insufficient because it allowed paramters like
|
||||||
|
"-i wlan0,asd" when wlan0 is valid and asd is not valid.
|
||||||
|
|
||||||
|
The better solution is to really use the number of interfaces given to
|
||||||
|
alfred instead of the number of interfaces evaluated as "valid".
|
||||||
|
|
||||||
|
Fixes: 67ae5f57eedd ("alfred: Add support for multiple interfaces per master")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-2-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index c7ee518eb9dc02c10fe1b19cea5c928915048d97..24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -182,6 +182,7 @@ int unix_sock_req_data_finish(struct globals *globals,
|
||||||
|
int vis_update_data(struct globals *globals);
|
||||||
|
/* netsock.c */
|
||||||
|
int netsock_open_all(struct globals *globals);
|
||||||
|
+size_t netsocket_count_interfaces(struct globals *globals);
|
||||||
|
void netsock_close_all(struct globals *globals);
|
||||||
|
int netsock_set_interfaces(struct globals *globals, char *interfaces);
|
||||||
|
struct interface *netsock_first_interface(struct globals *globals);
|
||||||
|
diff --git a/netsock.c b/netsock.c
|
||||||
|
index fcbc20be34504e271187fa9e0a120f271e622140..418b378e43144a24d4ff53544b387b1a6e7642e9 100644
|
||||||
|
--- a/netsock.c
|
||||||
|
+++ b/netsock.c
|
||||||
|
@@ -471,6 +471,17 @@ int netsock_open_all(struct globals *globals)
|
||||||
|
return num_socks;
|
||||||
|
}
|
||||||
|
|
||||||
|
+size_t netsocket_count_interfaces(struct globals *globals)
|
||||||
|
+{
|
||||||
|
+ struct interface *interface;
|
||||||
|
+ size_t count = 0;
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(interface, &globals->interfaces, list)
|
||||||
|
+ count++;
|
||||||
|
+
|
||||||
|
+ return count;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void netsock_reopen(struct globals *globals)
|
||||||
|
{
|
||||||
|
struct interface *interface;
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index 47e9ae28b703da23fb930756d2971161ab332bc1..95fc3bc895bf46eb775bf64d963a6eec77399dba 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -371,6 +371,7 @@ int alfred_server(struct globals *globals)
|
||||||
|
int maxsock, ret, recvs;
|
||||||
|
struct timespec last_check, now, tv;
|
||||||
|
fd_set fds, errfds;
|
||||||
|
+ size_t num_interfaces;
|
||||||
|
int num_socks;
|
||||||
|
|
||||||
|
if (create_hashes(globals))
|
||||||
|
@@ -397,7 +398,8 @@ int alfred_server(struct globals *globals)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (num_socks > 1 && globals->opmode == OPMODE_SLAVE) {
|
||||||
|
+ num_interfaces = netsocket_count_interfaces(globals);
|
||||||
|
+ if (num_interfaces > 1 && globals->opmode == OPMODE_SLAVE) {
|
||||||
|
fprintf(stderr, "More than one interface specified in slave mode\n");
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:34:54 +0100
|
||||||
|
Subject: alfred: Save global mode flags in bitfield
|
||||||
|
|
||||||
|
The verbose and ipv4mode entries in the globals structure is only used to
|
||||||
|
save a boolean information. So just use a bit in a bitfield to store this
|
||||||
|
information instead of a full int.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-3-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index 24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f..f09eb497a6efe62d38891dcac2149a6473f9215a 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -115,8 +115,8 @@ struct globals {
|
||||||
|
enum clientmode clientmode;
|
||||||
|
int clientmode_arg;
|
||||||
|
int clientmode_version;
|
||||||
|
- int verbose;
|
||||||
|
- int ipv4mode;
|
||||||
|
+ uint8_t verbose:1;
|
||||||
|
+ uint8_t ipv4mode:1;
|
||||||
|
|
||||||
|
int unix_sock;
|
||||||
|
const char *unix_path;
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index f633462bcc55b1ae3369c42ccf8f030e671ab268..c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -184,8 +185,8 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->clientmode_version = 0;
|
||||||
|
globals->mesh_iface = "bat0";
|
||||||
|
globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
|
||||||
|
- globals->verbose = 0;
|
||||||
|
- globals->ipv4mode = 0;
|
||||||
|
+ globals->verbose = false;
|
||||||
|
+ globals->ipv4mode = false;
|
||||||
|
globals->update_command = NULL;
|
||||||
|
globals->sync_period.tv_sec = ALFRED_INTERVAL;
|
||||||
|
globals->sync_period.tv_nsec = 0;
|
||||||
|
@@ -253,7 +254,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->unix_path = optarg;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
- globals->verbose++;
|
||||||
|
+ globals->verbose = true;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
globals->update_command = optarg;
|
||||||
|
@@ -269,7 +270,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
printf(" ** Setting sync interval to: %.9f seconds (%ld.%09ld)\n", sync_period, globals->sync_period.tv_sec, globals->sync_period.tv_nsec);
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
- globals->ipv4mode = 1;
|
||||||
|
+ globals->ipv4mode = true;
|
||||||
|
inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
|
||||||
|
printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
|
||||||
|
break;
|
|
@ -0,0 +1,102 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:52:17 +0100
|
||||||
|
Subject: alfred: Allow start of server without valid interface
|
||||||
|
|
||||||
|
The alfred server always needs interfaces to operate on. But these
|
||||||
|
interfaces might not exist at the moment when the daemon process is
|
||||||
|
started. This caused an error and stopped the process.
|
||||||
|
|
||||||
|
But alfred is able to deal with interfaces which disappeared at runtime but
|
||||||
|
existed at startup. To force a similar behavior for the alfred startup, the
|
||||||
|
parameter "--force" or "-f" is introduced.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-4-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index f09eb497a6efe62d38891dcac2149a6473f9215a..5bd118cbc6052932cfad9f3eb258ceb4ce06cdc3 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -117,6 +117,7 @@ struct globals {
|
||||||
|
int clientmode_version;
|
||||||
|
uint8_t verbose:1;
|
||||||
|
uint8_t ipv4mode:1;
|
||||||
|
+ uint8_t force:1;
|
||||||
|
|
||||||
|
int unix_sock;
|
||||||
|
const char *unix_path;
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1..2f77e1eb524f621391bf8ea7d56335e927e5197e 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -164,6 +164,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
{"version", no_argument, NULL, 'v'},
|
||||||
|
{"verbose", no_argument, NULL, 'd'},
|
||||||
|
{"sync-period", required_argument, NULL, 'p'},
|
||||||
|
+ {"force", no_argument, NULL, 'f'},
|
||||||
|
{NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -187,6 +188,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
|
||||||
|
globals->verbose = false;
|
||||||
|
globals->ipv4mode = false;
|
||||||
|
+ globals->force = false;
|
||||||
|
globals->update_command = NULL;
|
||||||
|
globals->sync_period.tv_sec = ALFRED_INTERVAL;
|
||||||
|
globals->sync_period.tv_nsec = 0;
|
||||||
|
@@ -194,7 +196,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
|
||||||
|
time_random_seed();
|
||||||
|
|
||||||
|
- while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:", long_options,
|
||||||
|
+ while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:f", long_options,
|
||||||
|
&opt_ind)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'r':
|
||||||
|
@@ -274,6 +276,9 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
|
||||||
|
printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
|
||||||
|
break;
|
||||||
|
+ case 'f':
|
||||||
|
+ globals->force = true;
|
||||||
|
+ break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
alfred_usage();
|
||||||
|
diff --git a/man/alfred.8 b/man/alfred.8
|
||||||
|
index 7e31e12df0b7254e517001be5964d8c5088881e6..424633d4bdb16d25ce7b1a573cc58ab9f0dd1371 100644
|
||||||
|
--- a/man/alfred.8
|
||||||
|
+++ b/man/alfred.8
|
||||||
|
@@ -72,6 +72,9 @@ Collect data from the network and prints it on the network
|
||||||
|
\fB\-d\fP, \fB\-\-verbose\fP
|
||||||
|
Show extra information in the data output
|
||||||
|
.TP
|
||||||
|
+\fB\-d\fP, \fB\-\-force\fP
|
||||||
|
+Start server even when batman-adv or interface(s) are not yet available.
|
||||||
|
+.TP
|
||||||
|
\fB\-V\fP, \fB\-\-req\-version\fP \fIversion\fP
|
||||||
|
Specify the data version set for \fB\-s\fP
|
||||||
|
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index 95fc3bc895bf46eb775bf64d963a6eec77399dba..de7ddcff2de8163457bd377c8da99ab3c66ff00e 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -386,14 +386,15 @@ int alfred_server(struct globals *globals)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(globals->mesh_iface, "none") != 0 &&
|
||||||
|
- batadv_interface_check(globals->mesh_iface) < 0) {
|
||||||
|
+ batadv_interface_check(globals->mesh_iface) < 0 &&
|
||||||
|
+ !globals->force) {
|
||||||
|
fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
|
||||||
|
globals->mesh_iface);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_socks = netsock_open_all(globals);
|
||||||
|
- if (num_socks <= 0) {
|
||||||
|
+ if (num_socks <= 0 && !globals->force) {
|
||||||
|
fprintf(stderr, "Failed to open interfaces\n");
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -1,21 +1,22 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2007-2021 OpenWrt.org
|
# Copyright (C) 2007-2009 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
#
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=babeld
|
PKG_NAME:=babeld
|
||||||
PKG_VERSION:=1.13.1
|
PKG_VERSION:=1.9.2
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
|
PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
|
||||||
PKG_HASH:=15f24d26da0ccfc073abcdef0309f281e4684f2aa71126f826572c4c845e8dd9
|
PKG_HASH:=154f00e0a8bf35d6ea9028886c3dc5c3c342dd1a367df55ef29a547b75867f07
|
||||||
|
|
||||||
PKG_MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>, \
|
PKG_MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>, \
|
||||||
Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>, \
|
Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>
|
||||||
Nick Hainke <vincent@systemli.org>
|
|
||||||
PKG_LICENSE:=MIT
|
PKG_LICENSE:=MIT
|
||||||
PKG_LICENSE_FILES:=LICENCE
|
PKG_LICENSE_FILES:=LICENCE
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ define Package/babeld
|
||||||
SUBMENU:=Routing and Redirection
|
SUBMENU:=Routing and Redirection
|
||||||
TITLE:=A loop-avoiding distance-vector routing protocol
|
TITLE:=A loop-avoiding distance-vector routing protocol
|
||||||
URL:=https://www.irif.fr/~jch/software/babel/
|
URL:=https://www.irif.fr/~jch/software/babel/
|
||||||
DEPENDS:=@IPV6 +libubus +libubox
|
DEPENDS:=@IPV6
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/babeld/description
|
define Package/babeld/description
|
||||||
|
@ -35,7 +36,7 @@ define Package/babeld/description
|
||||||
with fast convergence properties. It is based on the ideas in DSDV, AODV and
|
with fast convergence properties. It is based on the ideas in DSDV, AODV and
|
||||||
Cisco's EIGRP, but is designed to work well not only in wired networks but
|
Cisco's EIGRP, but is designed to work well not only in wired networks but
|
||||||
also in wireless mesh networks, and has been extended with support for
|
also in wireless mesh networks, and has been extended with support for
|
||||||
overlay networks. Babel is an IETF standard protocol (RFC 8966).
|
overlay networks. Babel is in the process of becoming an IETF Standard.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/babeld/conffiles
|
define Package/babeld/conffiles
|
||||||
|
@ -46,7 +47,6 @@ endef
|
||||||
MAKE_FLAGS+= \
|
MAKE_FLAGS+= \
|
||||||
CFLAGS="$(TARGET_CFLAGS)" \
|
CFLAGS="$(TARGET_CFLAGS)" \
|
||||||
LDLIBS="" \
|
LDLIBS="" \
|
||||||
LDLIBS+="-lubus -lubox"
|
|
||||||
|
|
||||||
define Package/babeld/install
|
define Package/babeld/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
|
|
@ -24,7 +24,6 @@ config general
|
||||||
## See comment at the top of this file for more details.
|
## See comment at the top of this file for more details.
|
||||||
# option 'conf_file' '/etc/babeld.conf'
|
# option 'conf_file' '/etc/babeld.conf'
|
||||||
# option 'conf_dir' '/tmp/babel.d/'
|
# option 'conf_dir' '/tmp/babel.d/'
|
||||||
# option 'ubus_bindings' 'false'
|
|
||||||
|
|
||||||
config interface
|
config interface
|
||||||
## Remove this line to enable babeld on this interface
|
## Remove this line to enable babeld on this interface
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
--- a/babeld.c
|
|
||||||
+++ b/babeld.c
|
|
||||||
@@ -54,6 +54,8 @@ THE SOFTWARE.
|
|
||||||
#include "local.h"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
+#include "ubus.h"
|
|
||||||
+
|
|
||||||
struct timeval now;
|
|
||||||
|
|
||||||
unsigned char myid[8];
|
|
||||||
@@ -505,6 +507,9 @@ main(int argc, char **argv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ babeld_add_ubus();
|
|
||||||
+
|
|
||||||
init_signals();
|
|
||||||
rc = resize_receive_buffer(1500);
|
|
||||||
if(rc < 0)
|
|
||||||
@@ -597,6 +602,8 @@ main(int argc, char **argv)
|
|
||||||
FD_SET(local_sockets[i].fd, &readfds);
|
|
||||||
maxfd = MAX(maxfd, local_sockets[i].fd);
|
|
||||||
}
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ maxfd = babeld_ubus_add_read_sock(&readfds, maxfd);
|
|
||||||
rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
|
|
||||||
if(rc < 0) {
|
|
||||||
if(errno != EINTR) {
|
|
||||||
@@ -665,6 +672,9 @@ main(int argc, char **argv)
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ babeld_ubus_receive(&readfds);
|
|
||||||
+
|
|
||||||
if(reopening) {
|
|
||||||
kernel_dump_time = now.tv_sec;
|
|
||||||
check_neighbours_timeout = now;
|
|
||||||
--- a/generate-version.sh
|
|
||||||
+++ b/generate-version.sh
|
|
||||||
@@ -10,4 +10,4 @@ else
|
|
||||||
version="unknown"
|
|
||||||
fi
|
|
||||||
|
|
||||||
-echo "#define BABELD_VERSION \"$version\""
|
|
||||||
+echo "#define BABELD_VERSION \"$version-ubus-mod\""
|
|
||||||
--- a/configuration.c
|
|
||||||
+++ b/configuration.c
|
|
||||||
@@ -42,6 +42,8 @@ THE SOFTWARE.
|
|
||||||
#include "hmac.h"
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
+#include "ubus.h"
|
|
||||||
+
|
|
||||||
static struct filter *input_filters = NULL;
|
|
||||||
static struct filter *output_filters = NULL;
|
|
||||||
static struct filter *redistribute_filters = NULL;
|
|
||||||
@@ -1024,7 +1026,8 @@ parse_option(int c, gnc_t gnc, void *clo
|
|
||||||
strcmp(token, "daemonise") == 0 ||
|
|
||||||
strcmp(token, "skip-kernel-setup") == 0 ||
|
|
||||||
strcmp(token, "ipv6-subtrees") == 0 ||
|
|
||||||
- strcmp(token, "reflect-kernel-metric") == 0) {
|
|
||||||
+ strcmp(token, "reflect-kernel-metric") == 0 ||
|
|
||||||
+ strcmp(token, "ubus-bindings") == 0) {
|
|
||||||
int b;
|
|
||||||
c = getbool(c, &b, gnc, closure);
|
|
||||||
if(c < -1)
|
|
||||||
@@ -1042,6 +1045,8 @@ parse_option(int c, gnc_t gnc, void *clo
|
|
||||||
has_ipv6_subtrees = b;
|
|
||||||
else if(strcmp(token, "reflect-kernel-metric") == 0)
|
|
||||||
reflect_kernel_metric = b;
|
|
||||||
+ else if(strcmp(token, "ubus-bindings") == 0)
|
|
||||||
+ ubus_bindings = b;
|
|
||||||
else
|
|
||||||
abort();
|
|
||||||
} else if(strcmp(token, "protocol-group") == 0) {
|
|
||||||
--- a/local.c
|
|
||||||
+++ b/local.c
|
|
||||||
@@ -42,6 +42,8 @@ THE SOFTWARE.
|
|
||||||
#include "local.h"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
+#include "ubus.h"
|
|
||||||
+
|
|
||||||
int local_server_socket = -1;
|
|
||||||
struct local_socket local_sockets[MAX_LOCAL_SOCKETS];
|
|
||||||
int num_local_sockets = 0;
|
|
||||||
@@ -191,6 +193,8 @@ local_notify_neighbour(struct neighbour
|
|
||||||
if(local_sockets[i].monitor)
|
|
||||||
local_notify_neighbour_1(&local_sockets[i], neigh, kind);
|
|
||||||
}
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ ubus_notify_neighbour(neigh, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -228,6 +232,8 @@ local_notify_xroute(struct xroute *xrout
|
|
||||||
if(local_sockets[i].monitor)
|
|
||||||
local_notify_xroute_1(&local_sockets[i], xroute, kind);
|
|
||||||
}
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ ubus_notify_xroute(xroute, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -273,6 +279,8 @@ local_notify_route(struct babel_route *r
|
|
||||||
if(local_sockets[i].monitor)
|
|
||||||
local_notify_route_1(&local_sockets[i], route, kind);
|
|
||||||
}
|
|
||||||
+ if(ubus_bindings)
|
|
||||||
+ ubus_notify_route(route, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
--- a/Makefile
|
|
||||||
+++ b/Makefile
|
|
||||||
@@ -11,11 +11,11 @@ LDLIBS = -lrt
|
|
||||||
|
|
||||||
SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
|
|
||||||
route.c xroute.c message.c resend.c configuration.c local.c \
|
|
||||||
- hmac.c rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c
|
|
||||||
+ hmac.c ubus.c rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c
|
|
||||||
|
|
||||||
OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
|
|
||||||
route.o xroute.o message.o resend.o configuration.o local.o \
|
|
||||||
- hmac.o rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o
|
|
||||||
+ hmac.o ubus.o rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o
|
|
||||||
|
|
||||||
babeld: $(OBJS)
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
|
|
|
@ -1,535 +0,0 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
|
|
||||||
#include <libubox/blob.h>
|
|
||||||
#include <libubox/blobmsg.h>
|
|
||||||
#include <libubox/list.h>
|
|
||||||
#include <libubus.h>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include "babeld.h"
|
|
||||||
#include "configuration.h"
|
|
||||||
#include "interface.h"
|
|
||||||
#include "kernel.h"
|
|
||||||
#include "local.h"
|
|
||||||
#include "message.h"
|
|
||||||
#include "neighbour.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "resend.h"
|
|
||||||
#include "route.h"
|
|
||||||
#include "source.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "xroute.h"
|
|
||||||
|
|
||||||
#include "ubus.h"
|
|
||||||
|
|
||||||
// Definition of header variable whether to enable ubus bindings.
|
|
||||||
int ubus_bindings = 0;
|
|
||||||
|
|
||||||
// Shared state maintained throughout calls to handle ubus messages.
|
|
||||||
static struct ubus_context *shared_ctx;
|
|
||||||
|
|
||||||
// List of exported routes (to be used with ubox's list helpers).
|
|
||||||
struct xroute_list_entry {
|
|
||||||
struct list_head list;
|
|
||||||
struct xroute *xroute;
|
|
||||||
};
|
|
||||||
|
|
||||||
// List of received routes (to be used with ubox's list helpers).
|
|
||||||
struct route_list_entry {
|
|
||||||
struct list_head list;
|
|
||||||
struct babel_route *route;
|
|
||||||
};
|
|
||||||
|
|
||||||
// List of neighbours (to be used with ubox's list helpers).
|
|
||||||
struct neighbour_list_entry {
|
|
||||||
struct list_head list;
|
|
||||||
struct neighbour *neighbour;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Definition of interface function enums (to be used with ubox's blobmsg
|
|
||||||
// helpers).
|
|
||||||
enum { INTERFACE_IFNAME, __INTERFACE_MAX };
|
|
||||||
|
|
||||||
// Definition of interface parsing (to be used with ubox's blobmsg helpers).
|
|
||||||
static const struct blobmsg_policy interface_policy[__INTERFACE_MAX] = {
|
|
||||||
[INTERFACE_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Definition of filter function enums (to be used with ubox's blobmsg
|
|
||||||
// helpers).
|
|
||||||
enum { FILTER_IFNAME, FILTER_TYPE, FILTER_METRIC, __FILTER_MAX };
|
|
||||||
|
|
||||||
// Definition of filter parsing (to be used with ubox's blobmsg helpers).
|
|
||||||
static const struct blobmsg_policy filter_policy[__FILTER_MAX] = {
|
|
||||||
[FILTER_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING},
|
|
||||||
[FILTER_TYPE] = {"type", BLOBMSG_TYPE_INT32},
|
|
||||||
[FILTER_METRIC] = {"metric", BLOBMSG_TYPE_INT32},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds a filter (ubus equivalent to "filter"-function).
|
|
||||||
static int babeld_ubus_add_filter(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method, struct blob_attr *msg) {
|
|
||||||
struct blob_attr *tb[__FILTER_MAX];
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
struct filter *filter = NULL;
|
|
||||||
char *ifname;
|
|
||||||
int metric, type;
|
|
||||||
|
|
||||||
blobmsg_parse(filter_policy, __FILTER_MAX, tb, blob_data(msg), blob_len(msg));
|
|
||||||
|
|
||||||
if (!tb[FILTER_IFNAME])
|
|
||||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
if (!tb[FILTER_TYPE])
|
|
||||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
type = blobmsg_get_u32(tb[FILTER_TYPE]);
|
|
||||||
|
|
||||||
if (tb[FILTER_METRIC])
|
|
||||||
metric = blobmsg_get_u32(tb[FILTER_METRIC]);
|
|
||||||
|
|
||||||
filter = calloc(1, sizeof(struct filter));
|
|
||||||
if (filter == NULL)
|
|
||||||
return UBUS_STATUS_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
filter->af = AF_INET6;
|
|
||||||
filter->proto = 0;
|
|
||||||
filter->plen_le = 128;
|
|
||||||
filter->src_plen_le = 128;
|
|
||||||
filter->action.add_metric = metric;
|
|
||||||
|
|
||||||
ifname = blobmsg_get_string(tb[FILTER_IFNAME]);
|
|
||||||
filter->ifname = strdup(ifname);
|
|
||||||
filter->ifindex = if_nametoindex(filter->ifname);
|
|
||||||
|
|
||||||
add_filter(filter, type);
|
|
||||||
|
|
||||||
return UBUS_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds an inteface (ubus equivalent to "interface"-function).
|
|
||||||
static int babeld_ubus_add_interface(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method,
|
|
||||||
struct blob_attr *msg) {
|
|
||||||
struct blob_attr *tb[__INTERFACE_MAX];
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
struct interface *ifp = NULL;
|
|
||||||
char *ifname;
|
|
||||||
|
|
||||||
blobmsg_parse(interface_policy, __INTERFACE_MAX, tb, blob_data(msg),
|
|
||||||
blob_len(msg));
|
|
||||||
|
|
||||||
if (!tb[INTERFACE_IFNAME])
|
|
||||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
ifname = blobmsg_get_string(tb[INTERFACE_IFNAME]);
|
|
||||||
|
|
||||||
ifp = add_interface(ifname, NULL);
|
|
||||||
if (ifp == NULL)
|
|
||||||
return UBUS_STATUS_UNKNOWN_ERROR;
|
|
||||||
|
|
||||||
return UBUS_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends a babel info message on ubus socket.
|
|
||||||
static int babeld_ubus_babeld_info(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method, struct blob_attr *msg) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
void *prefix;
|
|
||||||
char host[64];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
blobmsg_add_string(&b, "babeld-version", BABELD_VERSION);
|
|
||||||
blobmsg_add_string(&b, "my-id", format_eui64(myid));
|
|
||||||
if (!gethostname(host, sizeof(host)))
|
|
||||||
blobmsg_add_string(&b, "host", host);
|
|
||||||
|
|
||||||
ret = ubus_send_reply(ctx_local, req, b.head);
|
|
||||||
if (ret)
|
|
||||||
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
|
|
||||||
|
|
||||||
blob_buf_free(&b);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appends an exported route message entry to the buffer.
|
|
||||||
static void babeld_add_xroute_buf(struct xroute *xroute, struct blob_buf *b) {
|
|
||||||
void *prefix;
|
|
||||||
|
|
||||||
prefix = blobmsg_open_table(b, format_prefix(xroute->prefix, xroute->plen));
|
|
||||||
|
|
||||||
blobmsg_add_string(b, "src-prefix",
|
|
||||||
format_prefix(xroute->src_prefix, xroute->src_plen));
|
|
||||||
blobmsg_add_u32(b, "metric", xroute->metric);
|
|
||||||
blobmsg_close_table(b, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends an exported routes message on ubus socket, splitting apart IPv4 and
|
|
||||||
// IPv6 routes.
|
|
||||||
static int babeld_ubus_get_xroutes(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method, struct blob_attr *msg) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
struct xroute_stream *xroutes;
|
|
||||||
struct xroute_list_entry *cur, *tmp;
|
|
||||||
void *ipv4, *ipv6;
|
|
||||||
int ret;
|
|
||||||
LIST_HEAD(xroute_ipv4_list);
|
|
||||||
LIST_HEAD(xroute_ipv6_list);
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
|
|
||||||
xroutes = xroute_stream();
|
|
||||||
if (xroutes) {
|
|
||||||
while (1) {
|
|
||||||
struct xroute *xroute = xroute_stream_next(xroutes);
|
|
||||||
if (xroute == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
struct xroute_list_entry *xr =
|
|
||||||
calloc(1, sizeof(struct xroute_list_entry));
|
|
||||||
xr->xroute = xroute;
|
|
||||||
|
|
||||||
if (v4mapped(xroute->prefix)) {
|
|
||||||
list_add(&xr->list, &xroute_ipv4_list);
|
|
||||||
} else {
|
|
||||||
list_add(&xr->list, &xroute_ipv6_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xroute_stream_done(xroutes);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4 = blobmsg_open_table(&b, "IPv4");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &xroute_ipv4_list, list) {
|
|
||||||
babeld_add_xroute_buf(cur->xroute, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv4);
|
|
||||||
|
|
||||||
ipv6 = blobmsg_open_table(&b, "IPv6");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &xroute_ipv6_list, list) {
|
|
||||||
babeld_add_xroute_buf(cur->xroute, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv6);
|
|
||||||
|
|
||||||
ret = ubus_send_reply(ctx_local, req, b.head);
|
|
||||||
if (ret)
|
|
||||||
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
|
|
||||||
|
|
||||||
blob_buf_free(&b);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appends an route message entry to the buffer.
|
|
||||||
static void babeld_add_route_buf(struct babel_route *route,
|
|
||||||
struct blob_buf *b) {
|
|
||||||
void *prefix;
|
|
||||||
|
|
||||||
prefix = blobmsg_open_table(
|
|
||||||
b, format_prefix(route->src->prefix, route->src->plen));
|
|
||||||
|
|
||||||
blobmsg_add_string(
|
|
||||||
b, "src-prefix",
|
|
||||||
format_prefix(route->src->src_prefix, route->src->src_plen));
|
|
||||||
blobmsg_add_u32(b, "route_metric", route_metric(route));
|
|
||||||
blobmsg_add_u32(b, "route_smoothed_metric", route_smoothed_metric(route));
|
|
||||||
blobmsg_add_u32(b, "refmetric", route->refmetric);
|
|
||||||
blobmsg_add_string(b, "id", format_eui64(route->src->id));
|
|
||||||
blobmsg_add_u32(b, "seqno", (uint32_t)route->seqno);
|
|
||||||
blobmsg_add_u32(b, "age", (int)(now.tv_sec - route->time));
|
|
||||||
blobmsg_add_string(b, "via", format_address(route->neigh->address));
|
|
||||||
if (memcmp(route->nexthop, route->neigh->address, 16) != 0)
|
|
||||||
blobmsg_add_string(b, "nexthop", format_address(route->nexthop));
|
|
||||||
|
|
||||||
blobmsg_add_u8(b, "installed", route->installed);
|
|
||||||
blobmsg_add_u8(b, "feasible", route_feasible(route));
|
|
||||||
|
|
||||||
blobmsg_close_table(b, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends received routes message on ubus socket, splitting apart IPv4 and IPv6
|
|
||||||
// routes.
|
|
||||||
static int babeld_ubus_get_routes(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method, struct blob_attr *msg) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
struct route_stream *routes;
|
|
||||||
struct route_list_entry *cur, *tmp;
|
|
||||||
void *prefix, *ipv4, *ipv6;
|
|
||||||
int ret;
|
|
||||||
LIST_HEAD(route_ipv4_list);
|
|
||||||
LIST_HEAD(route_ipv6_list);
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
|
|
||||||
routes = route_stream(0);
|
|
||||||
if (routes) {
|
|
||||||
while (1) {
|
|
||||||
struct babel_route *route = route_stream_next(routes);
|
|
||||||
if (route == NULL)
|
|
||||||
break;
|
|
||||||
struct route_list_entry *r = calloc(1, sizeof(struct route_list_entry));
|
|
||||||
r->route = route;
|
|
||||||
|
|
||||||
if (v4mapped(route->src->prefix)) {
|
|
||||||
list_add(&r->list, &route_ipv4_list);
|
|
||||||
} else {
|
|
||||||
list_add(&r->list, &route_ipv6_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
route_stream_done(routes);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4 = blobmsg_open_table(&b, "IPv4");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &route_ipv4_list, list) {
|
|
||||||
babeld_add_route_buf(cur->route, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv4);
|
|
||||||
|
|
||||||
ipv6 = blobmsg_open_table(&b, "IPv6");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &route_ipv6_list, list) {
|
|
||||||
babeld_add_route_buf(cur->route, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv6);
|
|
||||||
|
|
||||||
ret = ubus_send_reply(ctx_local, req, b.head);
|
|
||||||
if (ret)
|
|
||||||
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
|
|
||||||
|
|
||||||
blob_buf_free(&b);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appends an neighbour entry to the buffer.
|
|
||||||
static void babeld_add_neighbour_buf(struct neighbour *neigh,
|
|
||||||
struct blob_buf *b) {
|
|
||||||
void *neighbour;
|
|
||||||
|
|
||||||
neighbour = blobmsg_open_table(b, format_address(neigh->address));
|
|
||||||
blobmsg_add_string(b, "dev", neigh->ifp->name);
|
|
||||||
blobmsg_add_u32(b, "hello-reach", neigh->hello.reach);
|
|
||||||
blobmsg_add_u32(b, "uhello-reach", neigh->uhello.reach);
|
|
||||||
blobmsg_add_u32(b, "rxcost", neighbour_rxcost(neigh));
|
|
||||||
blobmsg_add_u32(b, "txcost", neigh->txcost);
|
|
||||||
blobmsg_add_string(b, "rtt", format_thousands(neigh->rtt));
|
|
||||||
blobmsg_add_u8(b, "if_up", if_up(neigh->ifp));
|
|
||||||
blobmsg_close_table(b, neighbour);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends neighbours message on ubus socket, splitting apart IPv4 and IPv6
|
|
||||||
// neighbours.
|
|
||||||
static int babeld_ubus_get_neighbours(struct ubus_context *ctx_local,
|
|
||||||
struct ubus_object *obj,
|
|
||||||
struct ubus_request_data *req,
|
|
||||||
const char *method,
|
|
||||||
struct blob_attr *msg) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
struct neighbour *neigh;
|
|
||||||
struct neighbour_list_entry *cur, *tmp;
|
|
||||||
void *ipv4, *ipv6;
|
|
||||||
int ret;
|
|
||||||
LIST_HEAD(neighbour_ipv4_list);
|
|
||||||
LIST_HEAD(neighbour_ipv6_list);
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
|
|
||||||
FOR_ALL_NEIGHBOURS(neigh) {
|
|
||||||
struct neighbour_list_entry *n =
|
|
||||||
calloc(1, sizeof(struct neighbour_list_entry));
|
|
||||||
n->neighbour = neigh;
|
|
||||||
if (v4mapped(neigh->address)) {
|
|
||||||
list_add(&n->list, &neighbour_ipv4_list);
|
|
||||||
} else {
|
|
||||||
list_add(&n->list, &neighbour_ipv6_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4 = blobmsg_open_table(&b, "IPv4");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &neighbour_ipv4_list, list) {
|
|
||||||
babeld_add_neighbour_buf(cur->neighbour, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv4);
|
|
||||||
|
|
||||||
ipv6 = blobmsg_open_table(&b, "IPv6");
|
|
||||||
list_for_each_entry_safe(cur, tmp, &neighbour_ipv6_list, list) {
|
|
||||||
babeld_add_neighbour_buf(cur->neighbour, &b);
|
|
||||||
list_del(&cur->list);
|
|
||||||
free(cur);
|
|
||||||
}
|
|
||||||
blobmsg_close_table(&b, ipv6);
|
|
||||||
|
|
||||||
ret = ubus_send_reply(ctx_local, req, b.head);
|
|
||||||
if (ret)
|
|
||||||
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
|
|
||||||
|
|
||||||
blob_buf_free(&b);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// List of functions we expose via the ubus bus.
|
|
||||||
static const struct ubus_method babeld_methods[] = {
|
|
||||||
UBUS_METHOD("add_interface", babeld_ubus_add_interface, interface_policy),
|
|
||||||
UBUS_METHOD("add_filter", babeld_ubus_add_filter, filter_policy),
|
|
||||||
UBUS_METHOD_NOARG("get_info", babeld_ubus_babeld_info),
|
|
||||||
UBUS_METHOD_NOARG("get_xroutes", babeld_ubus_get_xroutes),
|
|
||||||
UBUS_METHOD_NOARG("get_routes", babeld_ubus_get_routes),
|
|
||||||
UBUS_METHOD_NOARG("get_neighbours", babeld_ubus_get_neighbours),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Definition of the ubus object type.
|
|
||||||
static struct ubus_object_type babeld_object_type =
|
|
||||||
UBUS_OBJECT_TYPE("babeld", babeld_methods);
|
|
||||||
|
|
||||||
// Object we announce via the ubus bus.
|
|
||||||
static struct ubus_object babeld_object = {
|
|
||||||
.name = "babeld",
|
|
||||||
.type = &babeld_object_type,
|
|
||||||
.methods = babeld_methods,
|
|
||||||
.n_methods = ARRAY_SIZE(babeld_methods),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Registers handlers for babel methods in the global ubus context.
|
|
||||||
static bool ubus_init_object() {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = ubus_add_object(shared_ctx, &babeld_object);
|
|
||||||
if (ret) {
|
|
||||||
fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes the global ubus context, connecting to the bus to be able to
|
|
||||||
// receive and send messages.
|
|
||||||
static bool babeld_ubus_init(void) {
|
|
||||||
if (shared_ctx)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
shared_ctx = ubus_connect(NULL);
|
|
||||||
if (!shared_ctx)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ubus_notify_route(struct babel_route *route, int kind) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
char method[50]; // possible methods are route.change, route.add, route.flush
|
|
||||||
|
|
||||||
if (!babeld_object.has_subscribers)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!route)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!shared_ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
babeld_add_route_buf(route, &b);
|
|
||||||
snprintf(method, sizeof(method), "route.%s", local_kind(kind));
|
|
||||||
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
|
|
||||||
blob_buf_free(&b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ubus_notify_xroute(struct xroute *xroute, int kind) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
char method[50]; // possible methods are xroute.change, xroute.add,
|
|
||||||
// xroute.flush
|
|
||||||
|
|
||||||
if (!babeld_object.has_subscribers)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!xroute)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!shared_ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
babeld_add_xroute_buf(xroute, &b);
|
|
||||||
snprintf(method, sizeof(method), "xroute.%s", local_kind(kind));
|
|
||||||
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
|
|
||||||
blob_buf_free(&b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ubus_notify_neighbour(struct neighbour *neigh, int kind) {
|
|
||||||
struct blob_buf b = {0};
|
|
||||||
char method[50]; // possible methods are neigh.change, neigh.add, neigh.flush
|
|
||||||
|
|
||||||
if (!babeld_object.has_subscribers)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!neigh)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!shared_ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
|
||||||
babeld_add_neighbour_buf(neigh, &b);
|
|
||||||
snprintf(method, sizeof(method), "neigh.%s", local_kind(kind));
|
|
||||||
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
|
|
||||||
blob_buf_free(&b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void babeld_ubus_receive(fd_set *readfds) {
|
|
||||||
if (!shared_ctx)
|
|
||||||
return;
|
|
||||||
if (FD_ISSET(shared_ctx->sock.fd, readfds))
|
|
||||||
ubus_handle_event(shared_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
int babeld_ubus_add_read_sock(fd_set *readfds, int maxfd) {
|
|
||||||
if (!shared_ctx)
|
|
||||||
return maxfd;
|
|
||||||
|
|
||||||
FD_SET(shared_ctx->sock.fd, readfds);
|
|
||||||
return MAX(maxfd, shared_ctx->sock.fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool babeld_add_ubus() {
|
|
||||||
if (!babeld_ubus_init()) {
|
|
||||||
fprintf(stderr, "Failed to initialize ubus!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ubus_init_object()) {
|
|
||||||
fprintf(stderr, "Failed to add objects to ubus!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
IPC integration of babeld with OpenWrt.
|
|
||||||
|
|
||||||
The ubus interface offers following functions:
|
|
||||||
- add_filter '{"ifname":"eth0", "type":0, "metric":5000}'
|
|
||||||
type:
|
|
||||||
0: FILTER_TYPE_INPUT
|
|
||||||
1: FILTER_TYPE_OUTPUT
|
|
||||||
2: FILTER_TYPE_REDISTRIBUTE
|
|
||||||
3: FILTER_TYPE_INSTALL
|
|
||||||
- add_interface '{"ifname":"eth0"}'
|
|
||||||
- get_info
|
|
||||||
- get_neighbours
|
|
||||||
- get_xroutes
|
|
||||||
- get_routes
|
|
||||||
|
|
||||||
All output is divided into IPv4 and IPv6.
|
|
||||||
|
|
||||||
Ubus notifications are sent if we receive updates for
|
|
||||||
- xroutes
|
|
||||||
- routes
|
|
||||||
- neighbours
|
|
||||||
|
|
||||||
The format is:
|
|
||||||
- {route,xroute,neighbour}.add: Object was added
|
|
||||||
- {route,xroute,neighbour}.change: Object was changed
|
|
||||||
- {route,xroute,neighbour}.flush: Object was flushed
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
|
|
||||||
struct babel_route;
|
|
||||||
struct neighbour;
|
|
||||||
struct xroute;
|
|
||||||
|
|
||||||
// Whether to enable ubus bindings (boolean option).
|
|
||||||
extern int ubus_bindings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize ubus interface.
|
|
||||||
*
|
|
||||||
* Connect to the ubus daemon and expose the ubus functions.
|
|
||||||
*
|
|
||||||
* @return if initializing ubus was successful
|
|
||||||
*/
|
|
||||||
bool babeld_add_ubus();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add ubus socket to given filedescriptor set.
|
|
||||||
*
|
|
||||||
* We need to check repeatedly if the ubus socket has something to read.
|
|
||||||
* The functions allows to add the ubus socket to the normal while(1)-loop of
|
|
||||||
* babeld.
|
|
||||||
*
|
|
||||||
* @param readfs: the filedescriptor set
|
|
||||||
* @param maxfd: the current maximum file descriptor
|
|
||||||
* @return the maximum file descriptor
|
|
||||||
*/
|
|
||||||
int babeld_ubus_add_read_sock(fd_set *readfds, int maxfd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check and process ubus socket.
|
|
||||||
*
|
|
||||||
* If the ubus-socket signals that data is available, the ubus_handle_event is
|
|
||||||
* called.
|
|
||||||
*/
|
|
||||||
void babeld_ubus_receive(fd_set *readfds);
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Notify the ubus bus that a new xroute is received.
|
|
||||||
*
|
|
||||||
* If a new xroute is received or changed, we will notify subscribers.
|
|
||||||
*
|
|
||||||
* @param xroute: xroute that experienced some change
|
|
||||||
* @param kind: kind that describes if we have a flush, add or change
|
|
||||||
*/
|
|
||||||
void ubus_notify_xroute(struct xroute *xroute, int kind);
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Notify the ubus bus that a new route is received.
|
|
||||||
*
|
|
||||||
* If a new route is received or changed, we will notify subscribers.
|
|
||||||
*
|
|
||||||
* @param route: route that experienced some change
|
|
||||||
* @param kind: kind that describes if we have a flush, add or change
|
|
||||||
*/
|
|
||||||
void ubus_notify_route(struct babel_route *route, int kind);
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Notify the ubus bus that a new neighbour is received.
|
|
||||||
*
|
|
||||||
* If a new neighbour is received or changed, we will notify subscribers.
|
|
||||||
*
|
|
||||||
* @param neigh: neighbour that experienced some change
|
|
||||||
* @param kind: kind that describes if we have a flush, add or change
|
|
||||||
*/
|
|
||||||
void ubus_notify_neighbour(struct neighbour *neigh, int kind);
|
|
105
batctl/Makefile
105
batctl/Makefile
|
@ -1,50 +1,53 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
#
|
||||||
|
# Copyright (C) 2014 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=batctl
|
PKG_NAME:=batctl
|
||||||
PKG_VERSION:=2024.0
|
|
||||||
PKG_RELEASE:=1
|
PKG_VERSION:=2019.2
|
||||||
|
PKG_RELEASE:=8
|
||||||
|
PKG_HASH:=fb656208ff7d4cd8b1b422f60c9e6d8747302a347cbf6c199d7afa9b80f80ea3
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
PKG_HASH:=76853e87201af63c411db152fd0c625a729a9733115897d1331604e2c5a67c7d
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
|
||||||
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
|
|
||||||
PKG_LICENSE:=GPL-2.0-only ISC MIT
|
|
||||||
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT LICENSES/deprecated/ISC
|
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
|
||||||
PKG_BUILD_FLAGS:=gc-sections lto
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define Package/batctl/Default
|
define Package/batctl/Default
|
||||||
|
URL:=https://www.open-mesh.org/
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
URL:=https://www.open-mesh.org/
|
|
||||||
DEPENDS:=+libnl-tiny +libc +librt
|
DEPENDS:=+libnl-tiny +libc +librt
|
||||||
PROVIDES:=batctl
|
PROVIDES:=batctl
|
||||||
|
MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/batctl/description
|
define Package/batctl/description
|
||||||
batctl is a more intuitive managment utility for B.A.T.M.A.N.-Advanced.
|
batctl is a more intuitive managment utility for B.A.T.M.A.N.-Advanced.
|
||||||
It is an easier method for configuring batman-adv and provides some
|
It is an easier method for configuring batman-adv and provides some
|
||||||
additional tools for debugging as well. This package builds
|
additional tools for debugging as well. This package builds
|
||||||
version $(PKG_VERSION) of the user space utility.
|
version $(PKG_VERSION) of the user space utility.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/batctl-tiny
|
define Package/batctl-tiny
|
||||||
$(call Package/batctl/Default)
|
$(call Package/batctl/Default)
|
||||||
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool (Minimal)
|
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool (Minimal)
|
||||||
VARIANT:=tiny
|
VARIANT:=tiny
|
||||||
|
PROVIDES:=batctl
|
||||||
ALTERNATIVES:=100:/usr/sbin/batctl:/usr/libexec/batctl-tiny
|
ALTERNATIVES:=100:/usr/sbin/batctl:/usr/libexec/batctl-tiny
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/batctl-tiny/description
|
define Package/batctl-tiny/description
|
||||||
$(Package/batctl/description)
|
$(Package/batctl/description)
|
||||||
Only configuration relevant subcommands are enabled.
|
Only configuration relevant subcommands are enabled.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/batctl-default
|
define Package/batctl-default
|
||||||
|
@ -56,7 +59,7 @@ endef
|
||||||
|
|
||||||
define Package/batctl-default/description
|
define Package/batctl-default/description
|
||||||
$(Package/batctl/description)
|
$(Package/batctl/description)
|
||||||
Standard subcommands for configuration and online debugging are enabled.
|
Standard subcommands for configuration and online debugging are enabled.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/batctl-full
|
define Package/batctl-full
|
||||||
|
@ -68,15 +71,36 @@ endef
|
||||||
|
|
||||||
define Package/batctl-full/description
|
define Package/batctl-full/description
|
||||||
$(Package/batctl/description)
|
$(Package/batctl/description)
|
||||||
Subcommands for configuration, online and offline debugging are enabled.
|
Subcommands for configuration, online and offline debugging are enabled.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
MAKE_VARS += \
|
# The linker can identify unused sections of a binary when each symbol is stored
|
||||||
|
# in a separate section. This mostly removes unused linker sections and reduces
|
||||||
|
# the size by ~3% on mipsel.
|
||||||
|
|
||||||
|
TARGET_CFLAGS += -ffunction-sections -fdata-sections
|
||||||
|
TARGET_LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
# Link-time optimization allows to move parts of the optimization from the single
|
||||||
|
# source file to the global source view. This is done by emitting the GIMPLE
|
||||||
|
# representation in each object file and analyzing it again during the link step.
|
||||||
|
|
||||||
|
TARGET_CFLAGS += -flto
|
||||||
|
TARGET_LDFLAGS += -fuse-linker-plugin
|
||||||
|
|
||||||
|
MAKE_BATCTL_ENV += \
|
||||||
|
CPPFLAGS="$(TARGET_CPPFLAGS)" \
|
||||||
|
CFLAGS="$(TARGET_CFLAGS)" \
|
||||||
|
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||||
LIBNL_NAME="libnl-tiny" \
|
LIBNL_NAME="libnl-tiny" \
|
||||||
LIBNL_GENL_NAME="libnl-tiny"
|
LIBNL_GENL_NAME="libnl-tiny"
|
||||||
|
|
||||||
MAKE_FLAGS += \
|
MAKE_BATCTL_ARGS += \
|
||||||
REVISION="$(PKG_VERSION)-openwrt-$(PKG_RELEASE)"
|
REVISION="$(PKG_BATCTL_SHORTREV)" \
|
||||||
|
CC="$(TARGET_CC)" \
|
||||||
|
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||||
|
batctl install \
|
||||||
|
REVISION="openwrt-$(PKG_VERSION)-$(PKG_RELEASE)"
|
||||||
|
|
||||||
config-n := \
|
config-n := \
|
||||||
aggregation \
|
aggregation \
|
||||||
|
@ -84,37 +108,28 @@ config-n := \
|
||||||
backbonetable \
|
backbonetable \
|
||||||
bisect_iv \
|
bisect_iv \
|
||||||
bonding \
|
bonding \
|
||||||
bla_backbone_json \
|
|
||||||
bla_claim_json \
|
|
||||||
bridge_loop_avoidance \
|
bridge_loop_avoidance \
|
||||||
claimtable \
|
claimtable \
|
||||||
dat_cache \
|
dat_cache \
|
||||||
dat_cache_json \
|
|
||||||
distributed_arp_table \
|
distributed_arp_table \
|
||||||
elp_interval \
|
elp_interval \
|
||||||
event \
|
event \
|
||||||
fragmentation \
|
fragmentation \
|
||||||
gateways \
|
gateways \
|
||||||
gateways_json \
|
|
||||||
gw_mode \
|
gw_mode \
|
||||||
hardif_json \
|
|
||||||
hardifs_json \
|
|
||||||
hop_penalty \
|
hop_penalty \
|
||||||
interface \
|
interface \
|
||||||
isolation_mark \
|
isolation_mark \
|
||||||
loglevel \
|
loglevel \
|
||||||
mcast_flags \
|
mcast_flags \
|
||||||
mcast_flags_json \
|
|
||||||
mesh_json \
|
|
||||||
multicast_fanout \
|
multicast_fanout \
|
||||||
multicast_forceflood \
|
multicast_forceflood \
|
||||||
multicast_mode \
|
multicast_mode \
|
||||||
|
nc_nodes \
|
||||||
neighbors \
|
neighbors \
|
||||||
neighbors_json \
|
|
||||||
network_coding \
|
network_coding \
|
||||||
orig_interval \
|
orig_interval \
|
||||||
originators \
|
originators \
|
||||||
originators_json \
|
|
||||||
ping \
|
ping \
|
||||||
routing_algo \
|
routing_algo \
|
||||||
statistics \
|
statistics \
|
||||||
|
@ -125,9 +140,6 @@ config-n := \
|
||||||
transglobal \
|
transglobal \
|
||||||
translate \
|
translate \
|
||||||
translocal \
|
translocal \
|
||||||
transtable_global_json \
|
|
||||||
transtable_local_json \
|
|
||||||
vlan_json \
|
|
||||||
|
|
||||||
config-settings := \
|
config-settings := \
|
||||||
aggregation \
|
aggregation \
|
||||||
|
@ -156,27 +168,13 @@ config-tables := \
|
||||||
dat_cache \
|
dat_cache \
|
||||||
gateways \
|
gateways \
|
||||||
mcast_flags \
|
mcast_flags \
|
||||||
|
nc_nodes \
|
||||||
neighbors \
|
neighbors \
|
||||||
originators \
|
originators \
|
||||||
statistics \
|
statistics \
|
||||||
transglobal \
|
transglobal \
|
||||||
translocal \
|
translocal \
|
||||||
|
|
||||||
config-json := \
|
|
||||||
bla_backbone_json \
|
|
||||||
bla_claim_json \
|
|
||||||
dat_cache_json \
|
|
||||||
gateways_json \
|
|
||||||
hardif_json \
|
|
||||||
hardifs_json \
|
|
||||||
mcast_flags_json \
|
|
||||||
mesh_json \
|
|
||||||
neighbors_json \
|
|
||||||
originators_json \
|
|
||||||
transtable_global_json \
|
|
||||||
transtable_local_json \
|
|
||||||
vlan_json \
|
|
||||||
|
|
||||||
config-tools := \
|
config-tools := \
|
||||||
event \
|
event \
|
||||||
ping \
|
ping \
|
||||||
|
@ -200,7 +198,6 @@ ifeq ($(BUILD_VARIANT),default)
|
||||||
config-y := \
|
config-y := \
|
||||||
$(config-settings) \
|
$(config-settings) \
|
||||||
$(config-tables) \
|
$(config-tables) \
|
||||||
$(config-json) \
|
|
||||||
$(config-tools) \
|
$(config-tools) \
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -210,7 +207,6 @@ ifeq ($(BUILD_VARIANT),full)
|
||||||
config-y := \
|
config-y := \
|
||||||
$(config-settings) \
|
$(config-settings) \
|
||||||
$(config-tables) \
|
$(config-tables) \
|
||||||
$(config-json) \
|
|
||||||
$(config-tools) \
|
$(config-tools) \
|
||||||
$(config-extratools) \
|
$(config-extratools) \
|
||||||
|
|
||||||
|
@ -226,7 +222,10 @@ $(call ConfigVars,n)$(call ConfigVars,y)
|
||||||
endef
|
endef
|
||||||
$(eval $(call shexport,batctl_config))
|
$(eval $(call shexport,batctl_config))
|
||||||
|
|
||||||
MAKE_FLAGS += $$$$$(call shvar,batctl_config)
|
define Build/Compile
|
||||||
|
$(MAKE_BATCTL_ENV) $(MAKE) -C "$(PKG_BUILD_DIR)" $(MAKE_BATCTL_ARGS) \
|
||||||
|
$$$$$(call shvar,batctl_config)
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/batctl-tiny/install
|
define Package/batctl-tiny/install
|
||||||
$(INSTALL_DIR) $(1)/usr/libexec
|
$(INSTALL_DIR) $(1)/usr/libexec
|
||||||
|
|
592
batctl/patches/0001-batctl-Make-vlan-setting-explicit.patch
Normal file
592
batctl/patches/0001-batctl-Make-vlan-setting-explicit.patch
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Tue, 9 Jul 2019 19:26:46 +0200
|
||||||
|
Subject: batctl: Make vlan setting explicit
|
||||||
|
|
||||||
|
The requirement to have a VLAN master device on top of the batadv mesh
|
||||||
|
interface is artificially limiting the capabilities of batctl. Not all
|
||||||
|
master devices in linux which register a VLAN are from type "vlan" and are
|
||||||
|
only registering a single VLAN.
|
||||||
|
|
||||||
|
For example VLAN aware bridges can create multiple VLANs. These require
|
||||||
|
that the VLAN is identified using the VID and not the vlan device.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/4704c5e05af7a4f6a397d80ff80f2f2c56fe8f2c
|
||||||
|
|
||||||
|
diff --git a/ap_isolation.c b/ap_isolation.c
|
||||||
|
index 71dcd00eac845d488c4969b17e1339f181c6c913..36fd4d607d03768251150951ebe450740501d446 100644
|
||||||
|
--- a/ap_isolation.c
|
||||||
|
+++ b/ap_isolation.c
|
||||||
|
@@ -28,7 +28,7 @@ static int get_attrs_ap_isolation(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct state *state = arg;
|
||||||
|
|
||||||
|
- if (state->vid >= 0)
|
||||||
|
+ if (state->selector == SP_VLAN)
|
||||||
|
nla_put_u16(msg, BATADV_ATTR_VLANID, state->vid);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -38,7 +38,7 @@ static int get_ap_isolation(struct state *state)
|
||||||
|
{
|
||||||
|
enum batadv_nl_commands nl_cmd = BATADV_CMD_SET_MESH;
|
||||||
|
|
||||||
|
- if (state->vid >= 0)
|
||||||
|
+ if (state->selector == SP_VLAN)
|
||||||
|
nl_cmd = BATADV_CMD_GET_VLAN;
|
||||||
|
|
||||||
|
return sys_simple_nlquery(state, nl_cmd, get_attrs_ap_isolation,
|
||||||
|
@@ -53,7 +53,7 @@ static int set_attrs_ap_isolation(struct nl_msg *msg, void *arg)
|
||||||
|
|
||||||
|
nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, data->val);
|
||||||
|
|
||||||
|
- if (state->vid >= 0)
|
||||||
|
+ if (state->selector == SP_VLAN)
|
||||||
|
nla_put_u16(msg, BATADV_ATTR_VLANID, state->vid);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -63,7 +63,7 @@ static int set_ap_isolation(struct state *state)
|
||||||
|
{
|
||||||
|
enum batadv_nl_commands nl_cmd = BATADV_CMD_SET_MESH;
|
||||||
|
|
||||||
|
- if (state->vid >= 0)
|
||||||
|
+ if (state->selector == SP_VLAN)
|
||||||
|
nl_cmd = BATADV_CMD_SET_VLAN;
|
||||||
|
|
||||||
|
return sys_simple_nlquery(state, nl_cmd, set_attrs_ap_isolation, NULL);
|
||||||
|
@@ -81,3 +81,8 @@ COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting,
|
||||||
|
COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
|
||||||
|
&batctl_settings_ap_isolation,
|
||||||
|
"[0|1] \tdisplay or modify ap_isolation setting");
|
||||||
|
+
|
||||||
|
+COMMAND_NAMED(SUBCOMMAND_VID, ap_isolation, "ap", handle_sys_setting,
|
||||||
|
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
|
||||||
|
+ &batctl_settings_ap_isolation,
|
||||||
|
+ "[0|1] \tdisplay or modify ap_isolation setting for vlan device or id");
|
||||||
|
diff --git a/functions.c b/functions.c
|
||||||
|
index aad6327a8f0fe6e512157e427d88dd0649acd052..61ea4879ebffbdadf8ef5bb12bb737c1ed7ff76f 100644
|
||||||
|
--- a/functions.c
|
||||||
|
+++ b/functions.c
|
||||||
|
@@ -919,32 +919,44 @@ static int query_rtnl_link_single(int mesh_ifindex,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int translate_mesh_iface(struct state *state)
|
||||||
|
+int translate_vlan_iface(struct state *state, const char *vlandev)
|
||||||
|
{
|
||||||
|
struct rtnl_link_iface_data link_data;
|
||||||
|
unsigned int arg_ifindex;
|
||||||
|
|
||||||
|
- arg_ifindex = if_nametoindex(state->arg_iface);
|
||||||
|
+ arg_ifindex = if_nametoindex(vlandev);
|
||||||
|
if (arg_ifindex == 0)
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -ENODEV;
|
||||||
|
|
||||||
|
query_rtnl_link_single(arg_ifindex, &link_data);
|
||||||
|
if (!link_data.vid_found)
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -ENODEV;
|
||||||
|
|
||||||
|
if (!link_data.link_found)
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
if (!link_data.kind_found)
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
if (strcmp(link_data.kind, "vlan") != 0)
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
if (!if_indextoname(link_data.link, state->mesh_iface))
|
||||||
|
- goto fallback_meshif;
|
||||||
|
+ return -ENODEV;
|
||||||
|
|
||||||
|
state->vid = link_data.vid;
|
||||||
|
+ state->selector = SP_VLAN;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int translate_mesh_iface_vlan(struct state *state, const char *vlandev)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = translate_vlan_iface(state, vlandev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto fallback_meshif;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
@@ -952,9 +964,36 @@ int translate_mesh_iface(struct state *state)
|
||||||
|
/* if there is no vid then the argument must be the
|
||||||
|
* mesh interface
|
||||||
|
*/
|
||||||
|
- snprintf(state->mesh_iface, sizeof(state->mesh_iface), "%s",
|
||||||
|
- state->arg_iface);
|
||||||
|
- state->vid = -1;
|
||||||
|
+ snprintf(state->mesh_iface, sizeof(state->mesh_iface), "%s", vlandev);
|
||||||
|
+ state->selector = SP_NONE_OR_MESHIF;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int translate_vid(struct state *state, const char *vidstr)
|
||||||
|
+{
|
||||||
|
+ unsigned long vid;
|
||||||
|
+ char *endptr;
|
||||||
|
+
|
||||||
|
+ if (vidstr[0] == '\0') {
|
||||||
|
+ fprintf(stderr, "Error - unparsable vid\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vid = strtoul(vidstr, &endptr, 0);
|
||||||
|
+ if (!endptr || *endptr != '\0') {
|
||||||
|
+ fprintf(stderr, "Error - unparsable vid\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (vid > 4095) {
|
||||||
|
+ fprintf(stderr, "Error - too large vid (max 4095)\n");
|
||||||
|
+ return -ERANGE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get mesh interface and overwrite vid afterwards */
|
||||||
|
+ state->vid = vid;
|
||||||
|
+ state->selector = SP_VLAN;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/functions.h b/functions.h
|
||||||
|
index d4a556879664eb5b4b11e6c638c22728db7a83a4..7474c40bbcdcb8fac8865def2e82514aede62b69 100644
|
||||||
|
--- a/functions.h
|
||||||
|
+++ b/functions.h
|
||||||
|
@@ -50,7 +50,9 @@ struct ether_addr *translate_mac(const char *mesh_iface,
|
||||||
|
struct ether_addr *resolve_mac(const char *asc);
|
||||||
|
int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
|
||||||
|
int netlink_simple_request(struct nl_msg *msg);
|
||||||
|
-int translate_mesh_iface(struct state *state);
|
||||||
|
+int translate_mesh_iface_vlan(struct state *state, const char *vlandev);
|
||||||
|
+int translate_vlan_iface(struct state *state, const char *vlandev);
|
||||||
|
+int translate_vid(struct state *state, const char *vidstr);
|
||||||
|
int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
|
||||||
|
int check_mesh_iface(struct state *state);
|
||||||
|
int check_mesh_iface_ownership(struct state *state, char *hard_iface);
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index 278683c6080e3ff4a9f3225931d0c5eb44f89595..309087799b839848029bd5cbec60cbe1213f9190 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -28,48 +28,75 @@ extern const struct command *__stop___command[];
|
||||||
|
|
||||||
|
static void print_usage(void)
|
||||||
|
{
|
||||||
|
- enum command_type type[] = {
|
||||||
|
- SUBCOMMAND,
|
||||||
|
- DEBUGTABLE,
|
||||||
|
+ struct {
|
||||||
|
+ const char *label;
|
||||||
|
+ uint32_t types;
|
||||||
|
+ } type[] = {
|
||||||
|
+ {
|
||||||
|
+ .label = "commands:\n",
|
||||||
|
+ .types = BIT(SUBCOMMAND) |
|
||||||
|
+ BIT(SUBCOMMAND_VID),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .label = "debug tables: \tdisplay the corresponding debug table\n",
|
||||||
|
+ .types = BIT(DEBUGTABLE),
|
||||||
|
+ },
|
||||||
|
+ };
|
||||||
|
+ const char *default_prefixes[] = {
|
||||||
|
+ "",
|
||||||
|
+ NULL,
|
||||||
|
+ };
|
||||||
|
+ const char *vlan_prefixes[] = {
|
||||||
|
+ "vlan <vdev> ",
|
||||||
|
+ "vid <vid> ",
|
||||||
|
+ NULL,
|
||||||
|
};
|
||||||
|
const struct command **p;
|
||||||
|
- char buf[32];
|
||||||
|
+ const char **prefixes;
|
||||||
|
+ const char **prefix;
|
||||||
|
+ char buf[64];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
fprintf(stderr, "Usage: batctl [options] command|debug table [parameters]\n");
|
||||||
|
fprintf(stderr, "options:\n");
|
||||||
|
- fprintf(stderr, " \t-m mesh interface or VLAN created on top of a mesh interface (default 'bat0')\n");
|
||||||
|
+ fprintf(stderr, " \t-m mesh interface (default 'bat0')\n");
|
||||||
|
fprintf(stderr, " \t-h print this help (or 'batctl <command|debug table> -h' for the parameter help)\n");
|
||||||
|
fprintf(stderr, " \t-v print version\n");
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(type) / sizeof(*type); i++) {
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
- switch (type[i]) {
|
||||||
|
- case SUBCOMMAND:
|
||||||
|
- fprintf(stderr, "commands:\n");
|
||||||
|
- break;
|
||||||
|
- case DEBUGTABLE:
|
||||||
|
- fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n");
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ fprintf(stderr, "%s", type[i].label);
|
||||||
|
|
||||||
|
for (p = __start___command; p < __stop___command; p++) {
|
||||||
|
const struct command *cmd = *p;
|
||||||
|
|
||||||
|
- if (cmd->type != type[i])
|
||||||
|
+ if (!(BIT(cmd->type) & type[i].types))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!cmd->usage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (strcmp(cmd->name, cmd->abbr) == 0)
|
||||||
|
- snprintf(buf, sizeof(buf), "%s", cmd->name);
|
||||||
|
- else
|
||||||
|
- snprintf(buf, sizeof(buf), "%s|%s", cmd->name,
|
||||||
|
- cmd->abbr);
|
||||||
|
+ switch (cmd->type) {
|
||||||
|
+ case SUBCOMMAND_VID:
|
||||||
|
+ prefixes = vlan_prefixes;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ prefixes = default_prefixes;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage);
|
||||||
|
+ for (prefix = &prefixes[0]; *prefix; prefix++) {
|
||||||
|
+ if (strcmp(cmd->name, cmd->abbr) == 0)
|
||||||
|
+ snprintf(buf, sizeof(buf), "%s%s",
|
||||||
|
+ *prefix, cmd->name);
|
||||||
|
+ else
|
||||||
|
+ snprintf(buf, sizeof(buf), "%s%s|%s",
|
||||||
|
+ *prefix, cmd->name, cmd->abbr);
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, " \t%-35s%s\n", buf,
|
||||||
|
+ cmd->usage);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -93,13 +120,17 @@ static void version(void)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const struct command *find_command(const char *name)
|
||||||
|
+static const struct command *find_command_by_types(uint32_t types,
|
||||||
|
+ const char *name)
|
||||||
|
{
|
||||||
|
const struct command **p;
|
||||||
|
|
||||||
|
for (p = __start___command; p < __stop___command; p++) {
|
||||||
|
const struct command *cmd = *p;
|
||||||
|
|
||||||
|
+ if (!(BIT(cmd->type) & types))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if (strcmp(cmd->name, name) == 0)
|
||||||
|
return cmd;
|
||||||
|
|
||||||
|
@@ -110,13 +141,123 @@ static const struct command *find_command(const char *name)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const struct command *find_command(struct state *state, const char *name)
|
||||||
|
+{
|
||||||
|
+ uint32_t types;
|
||||||
|
+
|
||||||
|
+ switch (state->selector) {
|
||||||
|
+ case SP_NONE_OR_MESHIF:
|
||||||
|
+ types = BIT(SUBCOMMAND) |
|
||||||
|
+ BIT(DEBUGTABLE);
|
||||||
|
+ break;
|
||||||
|
+ case SP_VLAN:
|
||||||
|
+ types = BIT(SUBCOMMAND_VID);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return find_command_by_types(types, name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int detect_selector_prefix(int argc, char *argv[],
|
||||||
|
+ enum selector_prefix *selector)
|
||||||
|
+{
|
||||||
|
+ /* not enough remaining arguments to detect anything */
|
||||||
|
+ if (argc < 2)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* only detect selector prefix which identifies meshif */
|
||||||
|
+ if (strcmp(argv[0], "vlan") == 0) {
|
||||||
|
+ *selector = SP_VLAN;
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int parse_meshif_args(struct state *state, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ enum selector_prefix selector;
|
||||||
|
+ int parsed_args;
|
||||||
|
+ char *dev_arg;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ parsed_args = detect_selector_prefix(argc, argv, &selector);
|
||||||
|
+ if (parsed_args < 1)
|
||||||
|
+ goto fallback_meshif_vlan;
|
||||||
|
+
|
||||||
|
+ dev_arg = argv[parsed_args - 1];
|
||||||
|
+
|
||||||
|
+ switch (selector) {
|
||||||
|
+ case SP_VLAN:
|
||||||
|
+ ret = translate_vlan_iface(state, dev_arg);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ fprintf(stderr, "Error - invalid vlan device %s: %s\n",
|
||||||
|
+ dev_arg, strerror(-ret));
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return parsed_args;
|
||||||
|
+ case SP_NONE_OR_MESHIF:
|
||||||
|
+ /* not allowed - see detect_selector_prefix */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+fallback_meshif_vlan:
|
||||||
|
+ /* parse vlan as part of -m parameter or mesh_dfl_iface */
|
||||||
|
+ translate_mesh_iface_vlan(state, state->arg_iface);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int parse_dev_args(struct state *state, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ int dev_arguments;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* try to parse selector prefix which can be used to identify meshif */
|
||||||
|
+ dev_arguments = parse_meshif_args(state, argc, argv);
|
||||||
|
+ if (dev_arguments < 0)
|
||||||
|
+ return dev_arguments;
|
||||||
|
+
|
||||||
|
+ /* try to parse secondary prefix selectors which cannot be used to
|
||||||
|
+ * identify the meshif
|
||||||
|
+ */
|
||||||
|
+ argv += dev_arguments;
|
||||||
|
+ argc -= dev_arguments;
|
||||||
|
+
|
||||||
|
+ switch (state->selector) {
|
||||||
|
+ case SP_NONE_OR_MESHIF:
|
||||||
|
+ /* continue below */
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return dev_arguments;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* enough room for additional selectors? */
|
||||||
|
+ if (argc < 2)
|
||||||
|
+ return dev_arguments;
|
||||||
|
+
|
||||||
|
+ if (strcmp(argv[0], "vid") == 0) {
|
||||||
|
+ ret = translate_vid(state, argv[1]);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ return dev_arguments + 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return dev_arguments;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct command *cmd;
|
||||||
|
struct state state = {
|
||||||
|
.arg_iface = mesh_dfl_iface,
|
||||||
|
+ .selector = SP_NONE_OR_MESHIF,
|
||||||
|
.cmd = NULL,
|
||||||
|
};
|
||||||
|
+ int dev_arguments;
|
||||||
|
int opt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -152,7 +293,20 @@ int main(int argc, char **argv)
|
||||||
|
argc -= optind;
|
||||||
|
optind = 0;
|
||||||
|
|
||||||
|
- cmd = find_command(argv[0]);
|
||||||
|
+ /* parse arguments to identify vlan, ... */
|
||||||
|
+ dev_arguments = parse_dev_args(&state, argc, argv);
|
||||||
|
+ if (dev_arguments < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ argv += dev_arguments;
|
||||||
|
+ argc -= dev_arguments;
|
||||||
|
+
|
||||||
|
+ if (argc == 0) {
|
||||||
|
+ fprintf(stderr, "Error - no command specified\n");
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cmd = find_command(&state, argv[0]);
|
||||||
|
if (!cmd) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error - no valid command or debug table specified: %s\n",
|
||||||
|
@@ -162,8 +316,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
|
state.cmd = cmd;
|
||||||
|
|
||||||
|
- translate_mesh_iface(&state);
|
||||||
|
-
|
||||||
|
if (cmd->flags & COMMAND_FLAG_MESH_IFACE &&
|
||||||
|
check_mesh_iface(&state) < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
diff --git a/main.h b/main.h
|
||||||
|
index 1a4701513c49ad8974b9c9189619f5dde622acd4..efc277c5465942d7b4dba284d29f653273b42dce 100644
|
||||||
|
--- a/main.h
|
||||||
|
+++ b/main.h
|
||||||
|
@@ -56,13 +56,20 @@ enum command_flags {
|
||||||
|
COMMAND_FLAG_INVERSE = BIT(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
+enum selector_prefix {
|
||||||
|
+ SP_NONE_OR_MESHIF,
|
||||||
|
+ SP_VLAN,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
enum command_type {
|
||||||
|
SUBCOMMAND,
|
||||||
|
+ SUBCOMMAND_VID,
|
||||||
|
DEBUGTABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct state {
|
||||||
|
char *arg_iface;
|
||||||
|
+ enum selector_prefix selector;
|
||||||
|
char mesh_iface[IF_NAMESIZE];
|
||||||
|
unsigned int mesh_ifindex;
|
||||||
|
int vid;
|
||||||
|
@@ -84,7 +91,7 @@ struct command {
|
||||||
|
};
|
||||||
|
|
||||||
|
#define COMMAND_NAMED(_type, _name, _abbr, _handler, _flags, _arg, _usage) \
|
||||||
|
- static const struct command command_ ## _name = { \
|
||||||
|
+ static const struct command command_ ## _name ## _ ## _type = { \
|
||||||
|
.type = (_type), \
|
||||||
|
.name = (#_name), \
|
||||||
|
.abbr = _abbr, \
|
||||||
|
@@ -93,8 +100,8 @@ struct command {
|
||||||
|
.arg = (_arg), \
|
||||||
|
.usage = (_usage), \
|
||||||
|
}; \
|
||||||
|
- static const struct command *__command_ ## _name \
|
||||||
|
- __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
|
||||||
|
+ static const struct command *__command_ ## _name ## _ ## _type \
|
||||||
|
+ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name ## _ ## _type
|
||||||
|
|
||||||
|
#define COMMAND(_type, _handler, _abbr, _flags, _arg, _usage) \
|
||||||
|
COMMAND_NAMED(_type, _handler, _abbr, _handler, _flags, _arg, _usage)
|
||||||
|
diff --git a/man/batctl.8 b/man/batctl.8
|
||||||
|
index 0b430313075b5a7a4c796eba0867954e10061002..a5656cf9059bd82c1b85928c22e30d01c56e475f 100644
|
||||||
|
--- a/man/batctl.8
|
||||||
|
+++ b/man/batctl.8
|
||||||
|
@@ -46,7 +46,7 @@ performances, is also included.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.I \fBoptions:
|
||||||
|
-\-m specify mesh interface or VLAN created on top of a mesh interface (default 'bat0')
|
||||||
|
+\-m specify mesh interface (default 'bat0')
|
||||||
|
.br
|
||||||
|
\-h print general batctl help
|
||||||
|
.br
|
||||||
|
@@ -70,7 +70,11 @@ originator interval. The interval is in units of milliseconds.
|
||||||
|
.br
|
||||||
|
.IP "\fBap_isolation\fP|\fBap\fP [\fB0\fP|\fB1\fP]"
|
||||||
|
If no parameter is given the current ap isolation setting is displayed. Otherwise the parameter is used to enable or
|
||||||
|
-disable ap isolation. This command can be used in conjunction with "\-m" option to target per VLAN configurations.
|
||||||
|
+disable ap isolation.
|
||||||
|
+.br
|
||||||
|
+.IP "<\fBvlan <vdev>\fP|\fBvid <vid>\fP> \fBap_isolation\fP|\fBap\fP [\fB0\fP|\fB1\fP]"
|
||||||
|
+If no parameter is given the current ap isolation setting for the specified VLAN is displayed. Otherwise the parameter is used to enable or
|
||||||
|
+disable ap isolation for the specified VLAN.
|
||||||
|
.br
|
||||||
|
.IP "\fBbridge_loop_avoidance\fP|\fBbl\fP [\fB0\fP|\fB1\fP]"
|
||||||
|
If no parameter is given the current bridge loop avoidance setting is displayed. Otherwise the parameter is used to enable
|
||||||
|
diff --git a/sys.c b/sys.c
|
||||||
|
index 39123db87d391b8898b7454eba7708515bfb3c78..61a314d88010ef34507ec9dd6a77b53f318f63a8 100644
|
||||||
|
--- a/sys.c
|
||||||
|
+++ b/sys.c
|
||||||
|
@@ -141,9 +141,35 @@ int sys_simple_print_boolean(struct nl_msg *msg, void *arg,
|
||||||
|
|
||||||
|
static void settings_usage(struct state *state)
|
||||||
|
{
|
||||||
|
- fprintf(stderr, "Usage: batctl [options] %s|%s [parameters] %s\n",
|
||||||
|
- state->cmd->name, state->cmd->abbr,
|
||||||
|
- state->cmd->usage ? state->cmd->usage : "");
|
||||||
|
+ const char *default_prefixes[] = {
|
||||||
|
+ "",
|
||||||
|
+ NULL,
|
||||||
|
+ };
|
||||||
|
+ const char *vlan_prefixes[] = {
|
||||||
|
+ "vlan <vdev> ",
|
||||||
|
+ "vid <vid> ",
|
||||||
|
+ NULL,
|
||||||
|
+ };
|
||||||
|
+ const char *linestart = "Usage:";
|
||||||
|
+ const char **prefixes;
|
||||||
|
+ const char **prefix;
|
||||||
|
+
|
||||||
|
+ switch (state->cmd->type) {
|
||||||
|
+ case SUBCOMMAND_VID:
|
||||||
|
+ prefixes = vlan_prefixes;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ prefixes = default_prefixes;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (prefix = &prefixes[0]; *prefix; prefix++) {
|
||||||
|
+ fprintf(stderr, "%s batctl [options] %s%s|%s [parameters] %s\n",
|
||||||
|
+ linestart, *prefix, state->cmd->name, state->cmd->abbr,
|
||||||
|
+ state->cmd->usage ? state->cmd->usage : "");
|
||||||
|
+
|
||||||
|
+ linestart = " ";
|
||||||
|
+ }
|
||||||
|
|
||||||
|
fprintf(stderr, "parameters:\n");
|
||||||
|
fprintf(stderr, " \t -h print this help\n");
|
||||||
|
@@ -233,15 +259,19 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* if the specified interface is a VLAN then change the path to point
|
||||||
|
- * to the proper "vlan%{vid}" subfolder in the sysfs tree.
|
||||||
|
- */
|
||||||
|
- if (state->vid >= 0)
|
||||||
|
- snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
|
||||||
|
- state->mesh_iface, state->vid);
|
||||||
|
- else
|
||||||
|
+ switch (state->selector) {
|
||||||
|
+ case SP_NONE_OR_MESHIF:
|
||||||
|
snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT,
|
||||||
|
state->mesh_iface);
|
||||||
|
+ break;
|
||||||
|
+ case SP_VLAN:
|
||||||
|
+ /* if the specified interface is a VLAN then change the path to
|
||||||
|
+ * point to the proper "vlan%{vid}" subfolder in the sysfs tree.
|
||||||
|
+ */
|
||||||
|
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
|
||||||
|
+ state->mesh_iface, state->vid);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
res = sys_read_setting(state, path_buff, settings->sysfs_name);
|
|
@ -0,0 +1,222 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Tue, 9 Jul 2019 19:26:47 +0200
|
||||||
|
Subject: batctl: Integrate hardif setting framework
|
||||||
|
|
||||||
|
batctl currently supports settings which are either mesh interface or vlan
|
||||||
|
specific. But B.A.T.M.A.N. V introduced two additional settings which are
|
||||||
|
hard (slave) interface specific.
|
||||||
|
|
||||||
|
To support these, an additional command prefix called hardif is implemented
|
||||||
|
for some sysfs commands:
|
||||||
|
|
||||||
|
$ batctl hardif eth0 ...
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6ed4dfc5459fd3b9ed221308075db592e538c92f
|
||||||
|
|
||||||
|
diff --git a/functions.c b/functions.c
|
||||||
|
index 61ea4879ebffbdadf8ef5bb12bb737c1ed7ff76f..4ffa86ca7830dea3ed2599656831b56f6fec9e33 100644
|
||||||
|
--- a/functions.c
|
||||||
|
+++ b/functions.c
|
||||||
|
@@ -998,6 +998,28 @@ int translate_vid(struct state *state, const char *vidstr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int translate_hard_iface(struct state *state, const char *hardif)
|
||||||
|
+{
|
||||||
|
+ struct rtnl_link_iface_data link_data;
|
||||||
|
+ unsigned int arg_ifindex;
|
||||||
|
+
|
||||||
|
+ arg_ifindex = if_nametoindex(hardif);
|
||||||
|
+ if (arg_ifindex == 0)
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ query_rtnl_link_single(arg_ifindex, &link_data);
|
||||||
|
+ if (!link_data.master_found)
|
||||||
|
+ return -ENOLINK;
|
||||||
|
+
|
||||||
|
+ if (!if_indextoname(link_data.master, state->mesh_iface))
|
||||||
|
+ return -ENOLINK;
|
||||||
|
+
|
||||||
|
+ state->hif = arg_ifindex;
|
||||||
|
+ state->selector = SP_HARDIF;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int check_mesh_iface_netlink(struct state *state)
|
||||||
|
{
|
||||||
|
struct rtnl_link_iface_data link_data;
|
||||||
|
diff --git a/functions.h b/functions.h
|
||||||
|
index 7474c40bbcdcb8fac8865def2e82514aede62b69..0a08870cee651ee676e67d3e55677c53f59e41c4 100644
|
||||||
|
--- a/functions.h
|
||||||
|
+++ b/functions.h
|
||||||
|
@@ -53,6 +53,7 @@ int netlink_simple_request(struct nl_msg *msg);
|
||||||
|
int translate_mesh_iface_vlan(struct state *state, const char *vlandev);
|
||||||
|
int translate_vlan_iface(struct state *state, const char *vlandev);
|
||||||
|
int translate_vid(struct state *state, const char *vidstr);
|
||||||
|
+int translate_hard_iface(struct state *state, const char *hardif);
|
||||||
|
int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
|
||||||
|
int check_mesh_iface(struct state *state);
|
||||||
|
int check_mesh_iface_ownership(struct state *state, char *hard_iface);
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index 309087799b839848029bd5cbec60cbe1213f9190..3b3a16f4c1caffdd2be897e6bf2a00564e5580f8 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -35,7 +35,8 @@ static void print_usage(void)
|
||||||
|
{
|
||||||
|
.label = "commands:\n",
|
||||||
|
.types = BIT(SUBCOMMAND) |
|
||||||
|
- BIT(SUBCOMMAND_VID),
|
||||||
|
+ BIT(SUBCOMMAND_VID) |
|
||||||
|
+ BIT(SUBCOMMAND_HIF),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "debug tables: \tdisplay the corresponding debug table\n",
|
||||||
|
@@ -51,6 +52,10 @@ static void print_usage(void)
|
||||||
|
"vid <vid> ",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
+ const char *hardif_prefixes[] = {
|
||||||
|
+ "hardif <netdev> ",
|
||||||
|
+ NULL,
|
||||||
|
+ };
|
||||||
|
const struct command **p;
|
||||||
|
const char **prefixes;
|
||||||
|
const char **prefix;
|
||||||
|
@@ -81,6 +86,9 @@ static void print_usage(void)
|
||||||
|
case SUBCOMMAND_VID:
|
||||||
|
prefixes = vlan_prefixes;
|
||||||
|
break;
|
||||||
|
+ case SUBCOMMAND_HIF:
|
||||||
|
+ prefixes = hardif_prefixes;
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
prefixes = default_prefixes;
|
||||||
|
break;
|
||||||
|
@@ -153,6 +161,9 @@ static const struct command *find_command(struct state *state, const char *name)
|
||||||
|
case SP_VLAN:
|
||||||
|
types = BIT(SUBCOMMAND_VID);
|
||||||
|
break;
|
||||||
|
+ case SP_HARDIF:
|
||||||
|
+ types = BIT(SUBCOMMAND_HIF);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -171,6 +182,9 @@ static int detect_selector_prefix(int argc, char *argv[],
|
||||||
|
if (strcmp(argv[0], "vlan") == 0) {
|
||||||
|
*selector = SP_VLAN;
|
||||||
|
return 2;
|
||||||
|
+ } else if (strcmp(argv[0], "hardif") == 0) {
|
||||||
|
+ *selector = SP_HARDIF;
|
||||||
|
+ return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -197,7 +211,17 @@ static int parse_meshif_args(struct state *state, int argc, char *argv[])
|
||||||
|
dev_arg, strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+ return parsed_args;
|
||||||
|
+ case SP_HARDIF:
|
||||||
|
+ ret = translate_hard_iface(state, dev_arg);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ fprintf(stderr, "Error - invalid hardif %s: %s\n",
|
||||||
|
+ dev_arg, strerror(-ret));
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ snprintf(state->hard_iface, sizeof(state->hard_iface), "%s",
|
||||||
|
+ dev_arg);
|
||||||
|
return parsed_args;
|
||||||
|
case SP_NONE_OR_MESHIF:
|
||||||
|
/* not allowed - see detect_selector_prefix */
|
||||||
|
diff --git a/main.h b/main.h
|
||||||
|
index efc277c5465942d7b4dba284d29f653273b42dce..a97b26fe7b969e01cbdb848e58824e36e3d236ab 100644
|
||||||
|
--- a/main.h
|
||||||
|
+++ b/main.h
|
||||||
|
@@ -59,11 +59,13 @@ enum command_flags {
|
||||||
|
enum selector_prefix {
|
||||||
|
SP_NONE_OR_MESHIF,
|
||||||
|
SP_VLAN,
|
||||||
|
+ SP_HARDIF,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum command_type {
|
||||||
|
SUBCOMMAND,
|
||||||
|
SUBCOMMAND_VID,
|
||||||
|
+ SUBCOMMAND_HIF,
|
||||||
|
DEBUGTABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -72,7 +74,11 @@ struct state {
|
||||||
|
enum selector_prefix selector;
|
||||||
|
char mesh_iface[IF_NAMESIZE];
|
||||||
|
unsigned int mesh_ifindex;
|
||||||
|
- int vid;
|
||||||
|
+ char hard_iface[IF_NAMESIZE];
|
||||||
|
+ union {
|
||||||
|
+ unsigned int hif;
|
||||||
|
+ int vid;
|
||||||
|
+ };
|
||||||
|
const struct command *cmd;
|
||||||
|
|
||||||
|
struct nl_sock *sock;
|
||||||
|
diff --git a/sys.c b/sys.c
|
||||||
|
index 61a314d88010ef34507ec9dd6a77b53f318f63a8..b9555ee484f89c1022c0b4e74e18154d18b7af6b 100644
|
||||||
|
--- a/sys.c
|
||||||
|
+++ b/sys.c
|
||||||
|
@@ -150,6 +150,10 @@ static void settings_usage(struct state *state)
|
||||||
|
"vid <vid> ",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
+ const char *hardif_prefixes[] = {
|
||||||
|
+ "hardif <netdev> ",
|
||||||
|
+ NULL,
|
||||||
|
+ };
|
||||||
|
const char *linestart = "Usage:";
|
||||||
|
const char **prefixes;
|
||||||
|
const char **prefix;
|
||||||
|
@@ -158,6 +162,9 @@ static void settings_usage(struct state *state)
|
||||||
|
case SUBCOMMAND_VID:
|
||||||
|
prefixes = vlan_prefixes;
|
||||||
|
break;
|
||||||
|
+ case SUBCOMMAND_HIF:
|
||||||
|
+ prefixes = hardif_prefixes;
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
prefixes = default_prefixes;
|
||||||
|
break;
|
||||||
|
@@ -271,6 +278,14 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
|
||||||
|
snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
|
||||||
|
state->mesh_iface, state->vid);
|
||||||
|
break;
|
||||||
|
+ case SP_HARDIF:
|
||||||
|
+ /* if a hard interface was specified then change the path to
|
||||||
|
+ * point to the proper ${hardif}/batman-adv path in the sysfs
|
||||||
|
+ * tree.
|
||||||
|
+ */
|
||||||
|
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_HARDIF_PATH,
|
||||||
|
+ state->hard_iface);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
diff --git a/sys.h b/sys.h
|
||||||
|
index d4f2fcf542bc66b2b1c6ec55a9ac16e10fdc5cac..b6f0f9043a9af8e3c4d4f8bf7e4af4cab0aa5df9 100644
|
||||||
|
--- a/sys.h
|
||||||
|
+++ b/sys.h
|
||||||
|
@@ -21,8 +21,9 @@
|
||||||
|
#define SYS_BATIF_PATH_FMT "/sys/class/net/%s/mesh/"
|
||||||
|
#define SYS_IFACE_PATH "/sys/class/net"
|
||||||
|
#define SYS_IFACE_DIR SYS_IFACE_PATH"/%s/"
|
||||||
|
-#define SYS_MESH_IFACE_FMT SYS_IFACE_PATH"/%s/batman_adv/mesh_iface"
|
||||||
|
-#define SYS_IFACE_STATUS_FMT SYS_IFACE_PATH"/%s/batman_adv/iface_status"
|
||||||
|
+#define SYS_HARDIF_PATH SYS_IFACE_DIR "batman_adv/"
|
||||||
|
+#define SYS_MESH_IFACE_FMT SYS_HARDIF_PATH "mesh_iface"
|
||||||
|
+#define SYS_IFACE_STATUS_FMT SYS_HARDIF_PATH "iface_status"
|
||||||
|
#define SYS_VLAN_PATH SYS_IFACE_PATH"/%s/mesh/vlan%d/"
|
||||||
|
#define SYS_ROUTING_ALGO_FMT SYS_IFACE_PATH"/%s/mesh/routing_algo"
|
||||||
|
#define VLAN_ID_MAX_LEN 4
|
|
@ -0,0 +1,183 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Tue, 9 Jul 2019 19:26:48 +0200
|
||||||
|
Subject: batctl: Add elp_interval setting command
|
||||||
|
|
||||||
|
B.A.T.M.A.N. V introduced a hard interface specific setting called
|
||||||
|
elp_interval. It defines the interval in milliseconds in which batman-adv
|
||||||
|
emits probing packets for neighbor sensing (ELP).
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/df5c452a446951c5f2fde265d08f3c2809ac2334
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index b7bd545e92963c62128efe60c0dc401bdd9fa023..f071da20f866bff6c162d697d2e43fa9d68ee08d 100755
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -45,6 +45,7 @@ $(eval $(call add_command,bridge_loop_avoidance,y))
|
||||||
|
$(eval $(call add_command,claimtable,y))
|
||||||
|
$(eval $(call add_command,dat_cache,y))
|
||||||
|
$(eval $(call add_command,distributed_arp_table,y))
|
||||||
|
+$(eval $(call add_command,elp_interval,y))
|
||||||
|
$(eval $(call add_command,event,y))
|
||||||
|
$(eval $(call add_command,fragmentation,y))
|
||||||
|
$(eval $(call add_command,gateways,y))
|
||||||
|
diff --git a/README.rst b/README.rst
|
||||||
|
index bc54412bc77dae1889d4f05298c34efc1966776b..92983aa6030e2a890283bca448b9203cd4d56b51 100644
|
||||||
|
--- a/README.rst
|
||||||
|
+++ b/README.rst
|
||||||
|
@@ -386,6 +386,22 @@ Example::
|
||||||
|
1000
|
||||||
|
|
||||||
|
|
||||||
|
+batctl elp interval
|
||||||
|
+===================
|
||||||
|
+
|
||||||
|
+display or modify the elp interval in ms for hard interface
|
||||||
|
+
|
||||||
|
+Usage::
|
||||||
|
+
|
||||||
|
+ batctl hardif $hardif elp_interval|et [interval]
|
||||||
|
+
|
||||||
|
+Example::
|
||||||
|
+
|
||||||
|
+ $ batctl hardif eth0 elp_interval 200
|
||||||
|
+ $ batctl hardif eth0 elp_interval
|
||||||
|
+ 200
|
||||||
|
+
|
||||||
|
+
|
||||||
|
batctl loglevel
|
||||||
|
===============
|
||||||
|
|
||||||
|
diff --git a/elp_interval.c b/elp_interval.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..0a5e98923a622f52e523696b1ec1bfb856eeca9f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elp_interval.c
|
||||||
|
@@ -0,0 +1,111 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
|
+/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
|
||||||
|
+ *
|
||||||
|
+ * Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
+ *
|
||||||
|
+ * License-Filename: LICENSES/preferred/GPL-2.0
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include "main.h"
|
||||||
|
+#include "sys.h"
|
||||||
|
+
|
||||||
|
+static struct elp_interval_data {
|
||||||
|
+ uint32_t elp_interval;
|
||||||
|
+} elp_interval;
|
||||||
|
+
|
||||||
|
+static int parse_elp_interval(struct state *state, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ struct settings_data *settings = state->cmd->arg;
|
||||||
|
+ struct elp_interval_data *data = settings->data;
|
||||||
|
+ char *endptr;
|
||||||
|
+
|
||||||
|
+ if (argc != 2) {
|
||||||
|
+ fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ data->elp_interval = strtoul(argv[1], &endptr, 0);
|
||||||
|
+ if (!endptr || *endptr != '\0') {
|
||||||
|
+ fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int print_elp_interval(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *attrs[BATADV_ATTR_MAX + 1];
|
||||||
|
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
+ struct genlmsghdr *ghdr;
|
||||||
|
+ int *result = arg;
|
||||||
|
+
|
||||||
|
+ if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ ghdr = nlmsg_data(nlh);
|
||||||
|
+
|
||||||
|
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
+ genlmsg_len(ghdr), batadv_netlink_policy)) {
|
||||||
|
+ return NL_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!attrs[BATADV_ATTR_ELP_INTERVAL])
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ printf("%u\n", nla_get_u32(attrs[BATADV_ATTR_ELP_INTERVAL]));
|
||||||
|
+
|
||||||
|
+ *result = 0;
|
||||||
|
+ return NL_STOP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_attrs_elp_interval(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct state *state = arg;
|
||||||
|
+
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_elp_interval(struct state *state)
|
||||||
|
+{
|
||||||
|
+ return sys_simple_nlquery(state, BATADV_CMD_GET_HARDIF,
|
||||||
|
+ get_attrs_elp_interval, print_elp_interval);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_attrs_elp_interval(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct state *state = arg;
|
||||||
|
+ struct settings_data *settings = state->cmd->arg;
|
||||||
|
+ struct elp_interval_data *data = settings->data;
|
||||||
|
+
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, data->elp_interval);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_elp_interval(struct state *state)
|
||||||
|
+{
|
||||||
|
+ return sys_simple_nlquery(state, BATADV_CMD_SET_HARDIF,
|
||||||
|
+ set_attrs_elp_interval, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct settings_data batctl_settings_elp_interval = {
|
||||||
|
+ .sysfs_name = "elp_interval",
|
||||||
|
+ .data = &elp_interval,
|
||||||
|
+ .parse = parse_elp_interval,
|
||||||
|
+ .netlink_get = get_elp_interval,
|
||||||
|
+ .netlink_set = set_elp_interval,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+COMMAND_NAMED(SUBCOMMAND_HIF, elp_interval, "et", handle_sys_setting,
|
||||||
|
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
|
||||||
|
+ &batctl_settings_elp_interval,
|
||||||
|
+ "[interval] \tdisplay or modify elp_interval setting");
|
||||||
|
diff --git a/man/batctl.8 b/man/batctl.8
|
||||||
|
index a5656cf9059bd82c1b85928c22e30d01c56e475f..eef7cd8f1246b83f03627cf307471abcade87cfc 100644
|
||||||
|
--- a/man/batctl.8
|
||||||
|
+++ b/man/batctl.8
|
||||||
|
@@ -97,6 +97,10 @@ the bonding mode.
|
||||||
|
batctl will monitor for events from the netlink kernel interface of batman-adv. The local timestamp of the event will be printed
|
||||||
|
when parameter \fB\-t\fP is specified. Parameter \fB\-r\fP will do the same but with relative timestamps.
|
||||||
|
.br
|
||||||
|
+.IP "\fBhardif <hardif>\fP \fBelp_interval\fP|\fBet\fP [\fBinterval\fP]"
|
||||||
|
+If no parameter is given the current ELP interval setting of the hard interface is displayed otherwise the parameter is used to set the
|
||||||
|
+ELP interval. The interval is in units of milliseconds.
|
||||||
|
+.br
|
||||||
|
.IP "\fBfragmentation\fP|\fBf\fP [\fB0\fP|\fB1\fP]"
|
||||||
|
If no parameter is given the current fragmentation mode setting is displayed. Otherwise the parameter is used to enable or
|
||||||
|
disable fragmentation.
|
|
@ -0,0 +1,189 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Tue, 9 Jul 2019 19:26:49 +0200
|
||||||
|
Subject: batctl: Add throughput_override setting command
|
||||||
|
|
||||||
|
B.A.T.M.A.N. V introduced a hard interface specific setting called
|
||||||
|
throughput. It defines the throughput value to be used by B.A.T.M.A.N. V
|
||||||
|
when estimating the link throughput using this interface. If the value is
|
||||||
|
set to 0 then batman-adv will try to estimate the throughput by itself.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/e5e6560df82813a9aad4a6c958be4d8ea012e909
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index f071da20f866bff6c162d697d2e43fa9d68ee08d..e3747a2a28eb34323e34a1e22f5507dd1d7cd0f6 100755
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -67,6 +67,7 @@ $(eval $(call add_command,ping,y))
|
||||||
|
$(eval $(call add_command,routing_algo,y))
|
||||||
|
$(eval $(call add_command,statistics,y))
|
||||||
|
$(eval $(call add_command,tcpdump,y))
|
||||||
|
+$(eval $(call add_command,throughput_override,y))
|
||||||
|
$(eval $(call add_command,throughputmeter,y))
|
||||||
|
$(eval $(call add_command,traceroute,y))
|
||||||
|
$(eval $(call add_command,transglobal,y))
|
||||||
|
diff --git a/README.rst b/README.rst
|
||||||
|
index 92983aa6030e2a890283bca448b9203cd4d56b51..128f539852fa085d023fb6d26ae436e76b617bb6 100644
|
||||||
|
--- a/README.rst
|
||||||
|
+++ b/README.rst
|
||||||
|
@@ -402,6 +402,23 @@ Example::
|
||||||
|
200
|
||||||
|
|
||||||
|
|
||||||
|
+batctl throughput override
|
||||||
|
+==========================
|
||||||
|
+
|
||||||
|
+display or modify the throughput override in kbit/s for hard interface
|
||||||
|
+
|
||||||
|
+Usage::
|
||||||
|
+
|
||||||
|
+ batctl hardif $hardif throughput_override|to [kbit]
|
||||||
|
+
|
||||||
|
+Example::
|
||||||
|
+
|
||||||
|
+ $ batctl hardif eth0 throughput_override 15000
|
||||||
|
+ $ batctl hardif eth0 throughput_override 15mbit
|
||||||
|
+ $ batctl hardif eth0 throughput_override
|
||||||
|
+ 15.0 MBit
|
||||||
|
+
|
||||||
|
+
|
||||||
|
batctl loglevel
|
||||||
|
===============
|
||||||
|
|
||||||
|
diff --git a/man/batctl.8 b/man/batctl.8
|
||||||
|
index eef7cd8f1246b83f03627cf307471abcade87cfc..d42b6825dd3172009369e370e45ed6e7a9bf9d0d 100644
|
||||||
|
--- a/man/batctl.8
|
||||||
|
+++ b/man/batctl.8
|
||||||
|
@@ -207,6 +207,12 @@ supported routing algorithms are displayed.
|
||||||
|
Otherwise the parameter is used to select the routing algorithm for the following
|
||||||
|
batX interface to be created.
|
||||||
|
.br
|
||||||
|
+.IP "\fBhardif <hardif>\fP \fBthroughput_override|to\fP [\fBbandwidth\fP]\fP"
|
||||||
|
+If no parameter is given the current througput override is displayed otherwise
|
||||||
|
+the parameter is used to set the throughput override for the specified hard
|
||||||
|
+interface.
|
||||||
|
+Just enter any number (optionally followed by "kbit" or "mbit").
|
||||||
|
+.br
|
||||||
|
.IP "\fBisolation_mark\fP|\fBmark\fP"
|
||||||
|
If no parameter is given the current isolation mark value is displayed.
|
||||||
|
Otherwise the parameter is used to set or unset the isolation mark used by the
|
||||||
|
diff --git a/throughput_override.c b/throughput_override.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..28a6588b9417cca213ebde3545a3eb425592ad89
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/throughput_override.c
|
||||||
|
@@ -0,0 +1,113 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
|
+/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
|
||||||
|
+ *
|
||||||
|
+ * Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
+ *
|
||||||
|
+ * License-Filename: LICENSES/preferred/GPL-2.0
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include "functions.h"
|
||||||
|
+#include "main.h"
|
||||||
|
+#include "sys.h"
|
||||||
|
+
|
||||||
|
+static struct throughput_override_data {
|
||||||
|
+ uint32_t throughput_override;
|
||||||
|
+} throughput_override;
|
||||||
|
+
|
||||||
|
+static int parse_throughput_override(struct state *state, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ struct settings_data *settings = state->cmd->arg;
|
||||||
|
+ struct throughput_override_data *data = settings->data;
|
||||||
|
+ bool ret;
|
||||||
|
+
|
||||||
|
+ if (argc != 2) {
|
||||||
|
+ fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = parse_throughput(argv[1], "throughput override",
|
||||||
|
+ &data->throughput_override);
|
||||||
|
+ if (!ret)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int print_throughput_override(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *attrs[BATADV_ATTR_MAX + 1];
|
||||||
|
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
+ struct genlmsghdr *ghdr;
|
||||||
|
+ int *result = arg;
|
||||||
|
+ uint32_t mbit;
|
||||||
|
+
|
||||||
|
+ if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ ghdr = nlmsg_data(nlh);
|
||||||
|
+
|
||||||
|
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
+ genlmsg_len(ghdr), batadv_netlink_policy)) {
|
||||||
|
+ return NL_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE])
|
||||||
|
+ return NL_OK;
|
||||||
|
+
|
||||||
|
+ mbit = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]);
|
||||||
|
+ printf("%u.%u MBit\n", mbit / 10, mbit % 10);
|
||||||
|
+
|
||||||
|
+ *result = 0;
|
||||||
|
+ return NL_STOP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_attrs_elp_isolation(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct state *state = arg;
|
||||||
|
+
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_throughput_override(struct state *state)
|
||||||
|
+{
|
||||||
|
+ return sys_simple_nlquery(state, BATADV_CMD_GET_HARDIF,
|
||||||
|
+ get_attrs_elp_isolation, print_throughput_override);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_attrs_throughput_override(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct state *state = arg;
|
||||||
|
+ struct settings_data *settings = state->cmd->arg;
|
||||||
|
+ struct throughput_override_data *data = settings->data;
|
||||||
|
+
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
|
||||||
|
+ nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE, data->throughput_override);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_throughput_override(struct state *state)
|
||||||
|
+{
|
||||||
|
+ return sys_simple_nlquery(state, BATADV_CMD_SET_HARDIF,
|
||||||
|
+ set_attrs_throughput_override, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct settings_data batctl_settings_throughput_override = {
|
||||||
|
+ .sysfs_name = "throughput_override",
|
||||||
|
+ .data = &throughput_override,
|
||||||
|
+ .parse = parse_throughput_override,
|
||||||
|
+ .netlink_get = get_throughput_override,
|
||||||
|
+ .netlink_set = set_throughput_override,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+COMMAND_NAMED(SUBCOMMAND_HIF, throughput_override, "to", handle_sys_setting,
|
||||||
|
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
|
||||||
|
+ &batctl_settings_throughput_override,
|
||||||
|
+ "[mbit] \tdisplay or modify throughput_override setting");
|
|
@ -0,0 +1,90 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 19 Jun 2019 09:37:50 +0200
|
||||||
|
Subject: batctl: Prefer netlink hardif status retrieval over sysfs
|
||||||
|
|
||||||
|
The sysfs code in batman-adv was changed to print a deprecated warning when
|
||||||
|
sysfs files are accessed. The `batctl if` call would therefore cause
|
||||||
|
warnings like this in the kernel log:
|
||||||
|
|
||||||
|
batman_adv: [Deprecated]: batctl (pid 18540) Use of sysfs file "iface_status".
|
||||||
|
Use batadv genl family instead
|
||||||
|
|
||||||
|
It is now appropriate to try the generic netlink BATADV_CMD_GET_HARDIF
|
||||||
|
request first to get the status of the interface before falling back to
|
||||||
|
sysfs.
|
||||||
|
|
||||||
|
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/ce5f0efb35bff8a80992df63876bcac1d4a94867
|
||||||
|
|
||||||
|
diff --git a/interface.c b/interface.c
|
||||||
|
index 5ff25a7b790d68aa69155f0cc7661080145ac86e..0a694c9f41f71a3dd72ae87b79b28434f7e8918f 100644
|
||||||
|
--- a/interface.c
|
||||||
|
+++ b/interface.c
|
||||||
|
@@ -67,18 +67,18 @@ static int get_iface_status_netlink_parse(struct nl_msg *msg, void *arg)
|
||||||
|
static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
|
||||||
|
char *iface_status)
|
||||||
|
{
|
||||||
|
+ char *ret_status = NULL;
|
||||||
|
struct nl_sock *sock;
|
||||||
|
struct nl_msg *msg;
|
||||||
|
int batadv_family;
|
||||||
|
struct nl_cb *cb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- strncpy(iface_status, "<error reading status>\n", IFACE_STATUS_LEN);
|
||||||
|
- iface_status[IFACE_STATUS_LEN - 1] = '\0';
|
||||||
|
+ iface_status[0] = '\0';
|
||||||
|
|
||||||
|
sock = nl_socket_alloc();
|
||||||
|
if (!sock)
|
||||||
|
- return iface_status;
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
ret = genl_connect(sock);
|
||||||
|
if (ret < 0)
|
||||||
|
@@ -111,6 +111,9 @@ static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
|
||||||
|
|
||||||
|
nl_recvmsgs(sock, cb);
|
||||||
|
|
||||||
|
+ if (strlen(iface_status) > 0)
|
||||||
|
+ ret_status = iface_status;
|
||||||
|
+
|
||||||
|
err_free_msg:
|
||||||
|
nlmsg_free(msg);
|
||||||
|
err_free_cb:
|
||||||
|
@@ -118,7 +121,7 @@ static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
|
||||||
|
err_free_sock:
|
||||||
|
nl_socket_free(sock);
|
||||||
|
|
||||||
|
- return iface_status;
|
||||||
|
+ return ret_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct nla_policy link_policy[IFLA_MAX + 1] = {
|
||||||
|
@@ -161,13 +164,17 @@ static int print_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
|
||||||
|
if (master != print_arg->ifindex)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT, ifname);
|
||||||
|
- ret = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0);
|
||||||
|
- if (ret != EXIT_SUCCESS)
|
||||||
|
- status = get_iface_status_netlink(master, ifm->ifi_index,
|
||||||
|
- iface_status);
|
||||||
|
- else
|
||||||
|
- status = line_ptr;
|
||||||
|
+ status = get_iface_status_netlink(master, ifm->ifi_index, iface_status);
|
||||||
|
+ if (!status) {
|
||||||
|
+ snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT,
|
||||||
|
+ ifname);
|
||||||
|
+ ret = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS,
|
||||||
|
+ 0, 0, 0);
|
||||||
|
+ if (ret != EXIT_SUCCESS)
|
||||||
|
+ status = "<error reading status>\n";
|
||||||
|
+ else
|
||||||
|
+ status = line_ptr;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
printf("%s: %s", ifname, status);
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
From: Leonardo Mörlein <me@irrelefant.net>
|
||||||
|
Date: Wed, 8 Apr 2020 23:49:03 +0200
|
||||||
|
Subject: batctl: Return EXIT_FAILURE when throughputmeter failed
|
||||||
|
|
||||||
|
The command returned a success even an error was shown during the
|
||||||
|
execution.
|
||||||
|
|
||||||
|
$ (sudo batctl tp 77:77:77:77:77:77 && echo true) || echo false
|
||||||
|
Destination unreachable
|
||||||
|
true
|
||||||
|
|
||||||
|
Instead it should indicate a failure when the kernel replied with a
|
||||||
|
non-success return_value:
|
||||||
|
|
||||||
|
$ (sudo ./batctl tp 77:77:77:77:77:77 && echo true) || echo false
|
||||||
|
Destination unreachable
|
||||||
|
false
|
||||||
|
|
||||||
|
Fixes: f109b3473f86 ("batctl: introduce throughput meter support")
|
||||||
|
Signed-off-by: Leonardo Mörlein <me@irrelefant.net>
|
||||||
|
[sven@narfation.org: adjusted commit message]
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/df8bf5164b6904f61ae0b0db090fb5bb41b4f06d
|
||||||
|
|
||||||
|
diff --git a/throughputmeter.c b/throughputmeter.c
|
||||||
|
index f9d98cfcac86d7a9398e2adddd143924b38e50b0..f19d4891981c99b7b9f3fae39c8d59f549243d0a 100644
|
||||||
|
--- a/throughputmeter.c
|
||||||
|
+++ b/throughputmeter.c
|
||||||
|
@@ -465,6 +465,7 @@ static int throughputmeter(struct state *state, int argc, char **argv)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ret = EXIT_FAILURE;
|
||||||
|
switch (result.return_value) {
|
||||||
|
case BATADV_TP_REASON_DST_UNREACHABLE:
|
||||||
|
fprintf(stderr, "Destination unreachable\n");
|
|
@ -0,0 +1,38 @@
|
||||||
|
From: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
Date: Wed, 29 Apr 2020 12:09:44 +0200
|
||||||
|
Subject: batctl: fix endianness when reading radiotap header
|
||||||
|
|
||||||
|
All radiotap header fields are specified in little endian byte-order.
|
||||||
|
Header length conversion is necessary on some platforms.
|
||||||
|
|
||||||
|
Fixes: c6fcdb6dc9a9 ("batctl: add radiotap wifi packet decapsulation support")
|
||||||
|
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/440ae55a6ef96eb73ee628f9237915cf9fb26dee
|
||||||
|
|
||||||
|
diff --git a/tcpdump.c b/tcpdump.c
|
||||||
|
index 8106a6457ac1b000f2f802e4b0a751d783540b69..72c1869eb50d25c1f6b1e1fcae42199b9337cb4e 100644
|
||||||
|
--- a/tcpdump.c
|
||||||
|
+++ b/tcpdump.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
+#include <endian.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
@@ -1034,10 +1035,10 @@ static int monitor_header_length(unsigned char *packet_buff, ssize_t buff_len, i
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
radiotap_hdr = (struct radiotap_header*)packet_buff;
|
||||||
|
- if (buff_len <= radiotap_hdr->it_len)
|
||||||
|
+ if (buff_len <= le16toh(radiotap_hdr->it_len))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
- return radiotap_hdr->it_len;
|
||||||
|
+ return le16toh(radiotap_hdr->it_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
|
@ -0,0 +1,49 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sat, 13 Jun 2020 17:59:34 +0200
|
||||||
|
Subject: batctl: Only remove batadv interface on hardif reduction
|
||||||
|
|
||||||
|
A deletion of a hardif from a batadv meshif will also get a success reply
|
||||||
|
from the kernel when the hardif was never part of the batadv meshif. If the
|
||||||
|
batadv meshif had no attached hardifs before the removal was started, then
|
||||||
|
users are then not expecting that the batadv meshif is removed at all.
|
||||||
|
|
||||||
|
Since the delete operation is not an atomic compare-and-swap operation,
|
||||||
|
just check first the number of attached interfaces and only start the
|
||||||
|
removal of the batadv meshif when the number attached hardifs was reduced.
|
||||||
|
|
||||||
|
Fixes: 25022e0b154d ("batctl: Use rtnl to add/remove interfaces")
|
||||||
|
Reported-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6d49a82cf58ee5ebd6235b6ddaca46febd42f876
|
||||||
|
|
||||||
|
diff --git a/interface.c b/interface.c
|
||||||
|
index 0a694c9f41f71a3dd72ae87b79b28434f7e8918f..138a6cd45744081a04f986fe4be67901b3305b74 100644
|
||||||
|
--- a/interface.c
|
||||||
|
+++ b/interface.c
|
||||||
|
@@ -386,6 +386,7 @@ static int interface(struct state *state, int argc, char **argv)
|
||||||
|
int ret;
|
||||||
|
unsigned int ifindex;
|
||||||
|
unsigned int ifmaster;
|
||||||
|
+ unsigned int pre_cnt;
|
||||||
|
const char *long_op;
|
||||||
|
unsigned int cnt;
|
||||||
|
int rest_argc;
|
||||||
|
@@ -502,6 +503,8 @@ static int interface(struct state *state, int argc, char **argv)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ pre_cnt = count_interfaces(state->mesh_iface);
|
||||||
|
+
|
||||||
|
for (i = 1; i < rest_argc; i++) {
|
||||||
|
ifindex = if_nametoindex(rest_argv[i]);
|
||||||
|
|
||||||
|
@@ -531,7 +534,7 @@ static int interface(struct state *state, int argc, char **argv)
|
||||||
|
/* check if there is no interface left and then destroy mesh_iface */
|
||||||
|
if (!manual_mode && rest_argv[0][0] == 'd') {
|
||||||
|
cnt = count_interfaces(state->mesh_iface);
|
||||||
|
- if (cnt == 0)
|
||||||
|
+ if (cnt == 0 && pre_cnt > 0)
|
||||||
|
destroy_interface(state->mesh_iface);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Sun, 13 Sep 2020 23:30:19 +0200
|
||||||
|
Subject: batctl: tcpdump: Fix endianness in ICMPv6 Echo Request/Reply parsing
|
||||||
|
|
||||||
|
The ICMPv6 Echo Request/Reply sequence number and id as well as the
|
||||||
|
IPv6 header length are two byte long fields and therefore might need a
|
||||||
|
conversion on a little endian system. Otherwise the output will be
|
||||||
|
broken on such a machine.
|
||||||
|
|
||||||
|
Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/e42f73d0d2a04edfbed1b9d0ad9fd57af9e90faf
|
||||||
|
|
||||||
|
diff --git a/tcpdump.c b/tcpdump.c
|
||||||
|
index 72c1869eb50d25c1f6b1e1fcae42199b9337cb4e..f3b1b8bd536e83e583bc535d01630843b80a558d 100644
|
||||||
|
--- a/tcpdump.c
|
||||||
|
+++ b/tcpdump.c
|
||||||
|
@@ -537,13 +537,15 @@ static void dump_ipv6(unsigned char *packet_buff, ssize_t buff_len,
|
||||||
|
break;
|
||||||
|
case ICMP6_ECHO_REQUEST:
|
||||||
|
printf(" echo request, id: %d, seq: %d, length: %hu\n",
|
||||||
|
- icmphdr->icmp6_id, icmphdr->icmp6_seq,
|
||||||
|
- iphdr->ip6_plen);
|
||||||
|
+ ntohs(icmphdr->icmp6_id),
|
||||||
|
+ ntohs(icmphdr->icmp6_seq),
|
||||||
|
+ ntohs(iphdr->ip6_plen));
|
||||||
|
break;
|
||||||
|
case ICMP6_ECHO_REPLY:
|
||||||
|
printf(" echo reply, id: %d, seq: %d, length: %hu\n",
|
||||||
|
- icmphdr->icmp6_id, icmphdr->icmp6_seq,
|
||||||
|
- iphdr->ip6_plen);
|
||||||
|
+ ntohs(icmphdr->icmp6_id),
|
||||||
|
+ ntohs(icmphdr->icmp6_seq),
|
||||||
|
+ ntohs(iphdr->ip6_plen));
|
||||||
|
break;
|
||||||
|
case ICMP6_TIME_EXCEEDED:
|
||||||
|
printf(" time exceeded in-transit, length %zu\n",
|
|
@ -0,0 +1,31 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 15 Jan 2021 23:38:31 +0100
|
||||||
|
Subject: batctl: Don't stop when create_interface detected existing interface
|
||||||
|
|
||||||
|
"batctl meshif bat0 interface add ..." should never be called in parallel.
|
||||||
|
But when something still does this, it could be that the code first detects
|
||||||
|
the missing meshif and then tries to create it - which fails when another
|
||||||
|
process requested the creation of the same interface slightly before batctl
|
||||||
|
did it.
|
||||||
|
|
||||||
|
But this should not prevent batctl to add the lower interface to the
|
||||||
|
meshif. It is not really important that the batctl process was the one
|
||||||
|
which created it - only that it exists is important.
|
||||||
|
|
||||||
|
Fixes: 25022e0b154d ("batctl: Use rtnl to add/remove interfaces")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/5d465bfd9a19c4bda20fb4e36c6e4b22c56ceb17
|
||||||
|
|
||||||
|
diff --git a/interface.c b/interface.c
|
||||||
|
index 138a6cd45744081a04f986fe4be67901b3305b74..2c6a78ad17cb716fbb7f6a1c78e0076494397b01 100644
|
||||||
|
--- a/interface.c
|
||||||
|
+++ b/interface.c
|
||||||
|
@@ -479,7 +479,7 @@ static int interface(struct state *state, int argc, char **argv)
|
||||||
|
ifmaster = if_nametoindex(state->mesh_iface);
|
||||||
|
if (!manual_mode && !ifmaster && rest_argv[0][0] == 'a') {
|
||||||
|
ret = create_interface(state->mesh_iface);
|
||||||
|
- if (ret < 0) {
|
||||||
|
+ if (ret < 0 && ret != -EEXIST) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error - failed to create batman-adv interface: %s\n",
|
||||||
|
strerror(-ret));
|
|
@ -0,0 +1,26 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sat, 31 Oct 2020 18:00:26 +0100
|
||||||
|
Subject: batctl: Fix retrieval of meshif ap_isolation
|
||||||
|
|
||||||
|
The batadv command to retrieve the attributes is called
|
||||||
|
BATADV_CMD_GET_MESH. The used BATADV_CMD_SET_MESH will only return the
|
||||||
|
current settings via the "config" multicast group which is not evaluated by
|
||||||
|
the ap_isolation command.
|
||||||
|
|
||||||
|
Fixes: c56a63a5f12a ("batctl: Support generic netlink for ap_isolation command")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/107cee536a0f8024208923f49a2a548b40bfc432
|
||||||
|
|
||||||
|
diff --git a/ap_isolation.c b/ap_isolation.c
|
||||||
|
index 36fd4d607d03768251150951ebe450740501d446..4854bcd1d6514a02786388dc014966f326818122 100644
|
||||||
|
--- a/ap_isolation.c
|
||||||
|
+++ b/ap_isolation.c
|
||||||
|
@@ -36,7 +36,7 @@ static int get_attrs_ap_isolation(struct nl_msg *msg, void *arg)
|
||||||
|
|
||||||
|
static int get_ap_isolation(struct state *state)
|
||||||
|
{
|
||||||
|
- enum batadv_nl_commands nl_cmd = BATADV_CMD_SET_MESH;
|
||||||
|
+ enum batadv_nl_commands nl_cmd = BATADV_CMD_GET_MESH;
|
||||||
|
|
||||||
|
if (state->selector == SP_VLAN)
|
||||||
|
nl_cmd = BATADV_CMD_GET_VLAN;
|
|
@ -65,6 +65,17 @@ config BATMAN_ADV_MCAST
|
||||||
reduce the air overhead while improving the reliability of
|
reduce the air overhead while improving the reliability of
|
||||||
multicast messages.
|
multicast messages.
|
||||||
|
|
||||||
|
config BATMAN_ADV_DEBUGFS
|
||||||
|
bool "batman-adv debugfs entries"
|
||||||
|
depends on PACKAGE_kmod-batman-adv
|
||||||
|
select KERNEL_DEBUG_FS
|
||||||
|
help
|
||||||
|
Enable this to export routing related debug tables via debugfs.
|
||||||
|
The information for each soft-interface and used hard-interface can be
|
||||||
|
found under batman_adv/
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
config BATMAN_ADV_DEBUG
|
config BATMAN_ADV_DEBUG
|
||||||
bool "B.A.T.M.A.N. debugging"
|
bool "B.A.T.M.A.N. debugging"
|
||||||
depends on PACKAGE_kmod-batman-adv
|
depends on PACKAGE_kmod-batman-adv
|
||||||
|
@ -75,6 +86,18 @@ config BATMAN_ADV_DEBUG
|
||||||
buffer. The output is controlled via the batadv netdev specific
|
buffer. The output is controlled via the batadv netdev specific
|
||||||
log_level setting.
|
log_level setting.
|
||||||
|
|
||||||
|
config BATMAN_ADV_SYSFS
|
||||||
|
bool "batman-adv sysfs entries"
|
||||||
|
depends on PACKAGE_kmod-batman-adv
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Say Y here if you want to enable batman-adv device configuration and
|
||||||
|
status interface through sysfs attributes. It is replaced by the
|
||||||
|
batadv generic netlink family but still used by various userspace
|
||||||
|
tools and scripts.
|
||||||
|
|
||||||
|
If unsure, say Y.
|
||||||
|
|
||||||
config BATMAN_ADV_TRACING
|
config BATMAN_ADV_TRACING
|
||||||
bool "B.A.T.M.A.N. tracing support"
|
bool "B.A.T.M.A.N. tracing support"
|
||||||
depends on PACKAGE_kmod-batman-adv
|
depends on PACKAGE_kmod-batman-adv
|
||||||
|
|
|
@ -1,52 +1,45 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
#
|
||||||
|
# Copyright (C) 2010 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=batman-adv
|
PKG_NAME:=batman-adv
|
||||||
PKG_VERSION:=2024.0
|
|
||||||
PKG_RELEASE:=2
|
PKG_VERSION:=2019.2
|
||||||
|
PKG_RELEASE:=14
|
||||||
|
PKG_HASH:=70c3f6a6cf88d2b25681a76768a52ed92d9fe992ba8e358368b6a8088757adc8
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
PKG_HASH:=61110697b5799f646a2a82a4dcf97faed4bb12a7cc43bf4683d2c4de4f6b40e7
|
PKG_LICENSE:=GPL-2.0
|
||||||
PKG_EXTMOD_SUBDIRS:=net/batman-adv
|
PKG_EXTMOD_SUBDIRS=net/batman-adv
|
||||||
|
|
||||||
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
|
|
||||||
PKG_LICENSE:=GPL-2.0-only MIT
|
|
||||||
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT
|
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
|
||||||
|
|
||||||
STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h
|
STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS += \
|
|
||||||
CONFIG_BATMAN_ADV_BATMAN_V \
|
|
||||||
CONFIG_BATMAN_ADV_BLA \
|
|
||||||
CONFIG_BATMAN_ADV_DAT \
|
|
||||||
CONFIG_BATMAN_ADV_NC \
|
|
||||||
CONFIG_BATMAN_ADV_MCAST \
|
|
||||||
CONFIG_BATMAN_ADV_DEBUG \
|
|
||||||
CONFIG_BATMAN_ADV_TRACING
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define KernelPackage/batman-adv
|
define KernelPackage/batman-adv
|
||||||
SUBMENU:=Network Support
|
|
||||||
TITLE:=B.A.T.M.A.N. Adv
|
|
||||||
URL:=https://www.open-mesh.org/
|
URL:=https://www.open-mesh.org/
|
||||||
|
MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
SUBMENU:=Network Support
|
||||||
DEPENDS:=+BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-lib-crc32c +kmod-cfg80211 +batctl
|
DEPENDS:=+BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-lib-crc32c +kmod-cfg80211 +batctl
|
||||||
|
TITLE:=B.A.T.M.A.N. Adv
|
||||||
FILES:=$(PKG_BUILD_DIR)/net/batman-adv/batman-adv.$(LINUX_KMOD_SUFFIX)
|
FILES:=$(PKG_BUILD_DIR)/net/batman-adv/batman-adv.$(LINUX_KMOD_SUFFIX)
|
||||||
AUTOLOAD:=$(call AutoProbe,batman-adv)
|
AUTOLOAD:=$(call AutoProbe,batman-adv)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define KernelPackage/batman-adv/description
|
define KernelPackage/batman-adv/description
|
||||||
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
||||||
a routing protocol for multi-hop ad-hoc mesh networks. The
|
a routing protocol for multi-hop ad-hoc mesh networks. The
|
||||||
networks may be wired or wireless. See
|
networks may be wired or wireless. See
|
||||||
https://www.open-mesh.org/ for more information and user space
|
https://www.open-mesh.org/ for more information and user space
|
||||||
tools. This package builds version $(PKG_VERSION) of the kernel
|
tools. This package builds version $(PKG_VERSION) of the kernel
|
||||||
module.
|
module.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define KernelPackage/batman-adv/config
|
define KernelPackage/batman-adv/config
|
||||||
|
@ -60,11 +53,13 @@ endef
|
||||||
PKG_EXTRA_KCONFIG:= \
|
PKG_EXTRA_KCONFIG:= \
|
||||||
CONFIG_BATMAN_ADV=m \
|
CONFIG_BATMAN_ADV=m \
|
||||||
CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_BATMAN_ADV_DEBUG),y,n) \
|
CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_BATMAN_ADV_DEBUG),y,n) \
|
||||||
|
CONFIG_BATMAN_ADV_DEBUGFS=$(if $(CONFIG_BATMAN_ADV_DEBUGFS),y,n) \
|
||||||
CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_BATMAN_ADV_BLA),y,n) \
|
CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_BATMAN_ADV_BLA),y,n) \
|
||||||
CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_BATMAN_ADV_DAT),y,n) \
|
CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_BATMAN_ADV_DAT),y,n) \
|
||||||
CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_BATMAN_ADV_MCAST),y,n) \
|
CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_BATMAN_ADV_MCAST),y,n) \
|
||||||
CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_BATMAN_ADV_NC),y,n) \
|
CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_BATMAN_ADV_NC),y,n) \
|
||||||
CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_BATMAN_ADV_BATMAN_V),y,n) \
|
CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_BATMAN_ADV_BATMAN_V),y,n) \
|
||||||
|
CONFIG_BATMAN_ADV_SYSFS=$(if $(CONFIG_BATMAN_ADV_SYSFS),y,n) \
|
||||||
CONFIG_BATMAN_ADV_TRACING=$(if $(CONFIG_BATMAN_ADV_TRACING),y,n) \
|
CONFIG_BATMAN_ADV_TRACING=$(if $(CONFIG_BATMAN_ADV_TRACING),y,n) \
|
||||||
|
|
||||||
PKG_EXTRA_CFLAGS:= \
|
PKG_EXTRA_CFLAGS:= \
|
||||||
|
@ -72,22 +67,27 @@ PKG_EXTRA_CFLAGS:= \
|
||||||
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_EXTRA_KCONFIG)))) \
|
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_EXTRA_KCONFIG)))) \
|
||||||
|
|
||||||
NOSTDINC_FLAGS = \
|
NOSTDINC_FLAGS = \
|
||||||
$(KERNEL_NOSTDINC_FLAGS) \
|
|
||||||
-I$(PKG_BUILD_DIR)/net/batman-adv \
|
-I$(PKG_BUILD_DIR)/net/batman-adv \
|
||||||
-I$(STAGING_DIR)/usr/include/mac80211-backport \
|
-I$(STAGING_DIR)/usr/include/mac80211-backport \
|
||||||
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
|
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
|
||||||
-I$(STAGING_DIR)/usr/include/mac80211 \
|
-I$(STAGING_DIR)/usr/include/mac80211 \
|
||||||
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
|
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
|
||||||
-I$(PKG_BUILD_DIR)/include/ \
|
-I$(PKG_BUILD_DIR)/include/ \
|
||||||
-include backport/autoconf.h \
|
|
||||||
-include backport/backport.h \
|
-include backport/backport.h \
|
||||||
-include $(PKG_BUILD_DIR)/compat-hacks.h \
|
-include $(PKG_BUILD_DIR)/compat-hacks.h \
|
||||||
-DBATADV_SOURCE_VERSION=\\\"$(PKG_VERSION)-openwrt-$(PKG_RELEASE)\\\"
|
-DBATADV_SOURCE_VERSION=\\\"openwrt-$(PKG_VERSION)-$(PKG_RELEASE)\\\"
|
||||||
|
|
||||||
|
COMPAT_SOURCES = \
|
||||||
|
$(if $(CONFIG_BATMAN_ADV_MCAST),../../compat-sources/net/core/skbuff.o,) \
|
||||||
|
$(if $(CONFIG_BATMAN_ADV_MCAST),../../compat-sources/net/ipv4/igmp.o,) \
|
||||||
|
$(if $(CONFIG_BATMAN_ADV_MCAST),../../compat-sources/net/ipv6/mcast_snoop.o,) \
|
||||||
|
|
||||||
define Build/Compile
|
define Build/Compile
|
||||||
|
+env "batman-adv-y=$(COMPAT_SOURCES)" \
|
||||||
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
|
||||||
$(KERNEL_MAKE_FLAGS) \
|
ARCH="$(LINUX_KARCH)" \
|
||||||
M="$(PKG_BUILD_DIR)/net/batman-adv" \
|
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||||
|
SUBDIRS="$(PKG_BUILD_DIR)/net/batman-adv" \
|
||||||
$(PKG_EXTRA_KCONFIG) \
|
$(PKG_EXTRA_KCONFIG) \
|
||||||
EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS)" \
|
EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS)" \
|
||||||
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
|
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
|
||||||
|
|
|
@ -72,42 +72,42 @@ proto_batadv_setup() {
|
||||||
set_default routing_algo 'BATMAN_IV'
|
set_default routing_algo 'BATMAN_IV'
|
||||||
|
|
||||||
batctl routing_algo "$routing_algo"
|
batctl routing_algo "$routing_algo"
|
||||||
batctl meshif "$iface" interface create
|
batctl -m "$iface" interface create
|
||||||
|
|
||||||
[ -n "$aggregated_ogms" ] && batctl meshif "$iface" aggregation "$aggregated_ogms"
|
[ -n "$aggregated_ogms" ] && batctl -m "$iface" aggregation "$aggregated_ogms"
|
||||||
[ -n "$ap_isolation" ] && batctl meshif "$iface" ap_isolation "$ap_isolation"
|
[ -n "$ap_isolation" ] && batctl -m "$iface" ap_isolation "$ap_isolation"
|
||||||
[ -n "$bonding" ] && batctl meshif "$iface" bonding "$bonding"
|
[ -n "$bonding" ] && batctl -m "$iface" bonding "$bonding"
|
||||||
[ -n "$bridge_loop_avoidance" ] && batctl meshif "$iface" bridge_loop_avoidance "$bridge_loop_avoidance" 2>&-
|
[ -n "$bridge_loop_avoidance" ] && batctl -m "$iface" bridge_loop_avoidance "$bridge_loop_avoidance" 2>&-
|
||||||
[ -n "$distributed_arp_table" ] && batctl meshif "$iface" distributed_arp_table "$distributed_arp_table" 2>&-
|
[ -n "$distributed_arp_table" ] && batctl -m "$iface" distributed_arp_table "$distributed_arp_table" 2>&-
|
||||||
[ -n "$fragmentation" ] && batctl meshif "$iface" fragmentation "$fragmentation"
|
[ -n "$fragmentation" ] && batctl -m "$iface" fragmentation "$fragmentation"
|
||||||
|
|
||||||
case "$gw_mode" in
|
case "$gw_mode" in
|
||||||
server)
|
server)
|
||||||
if [ -n "$gw_bandwidth" ]; then
|
if [ -n "$gw_bandwidth" ]; then
|
||||||
batctl meshif "$iface" gw_mode "server" "$gw_bandwidth"
|
batctl -m "$iface" gw_mode "server" "$gw_bandwidth"
|
||||||
else
|
else
|
||||||
batctl meshif "$iface" gw_mode "server"
|
batctl -m "$iface" gw_mode "server"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
client)
|
client)
|
||||||
if [ -n "$gw_sel_class" ]; then
|
if [ -n "$gw_sel_class" ]; then
|
||||||
batctl meshif "$iface" gw_mode "client" "$gw_sel_class"
|
batctl -m "$iface" gw_mode "client" "$gw_sel_class"
|
||||||
else
|
else
|
||||||
batctl meshif "$iface" gw_mode "client"
|
batctl -m "$iface" gw_mode "client"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
batctl meshif "$iface" gw_mode "off"
|
batctl -m "$iface" gw_mode "off"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
[ -n "$hop_penalty" ] && batctl meshif "$iface" hop_penalty "$hop_penalty"
|
[ -n "$hop_penalty" ] && batctl -m "$iface" hop_penalty "$hop_penalty"
|
||||||
[ -n "$isolation_mark" ] && batctl meshif "$iface" isolation_mark "$isolation_mark"
|
[ -n "$isolation_mark" ] && batctl -m "$iface" isolation_mark "$isolation_mark"
|
||||||
[ -n "$multicast_fanout" ] && batctl meshif "$iface" multicast_fanout "$multicast_fanout"
|
[ -n "$multicast_fanout" ] && batctl -m "$iface" multicast_fanout "$multicast_fanout"
|
||||||
[ -n "$multicast_mode" ] && batctl meshif "$iface" multicast_mode "$multicast_mode" 2>&-
|
[ -n "$multicast_mode" ] && batctl -m "$iface" multicast_mode "$multicast_mode" 2>&-
|
||||||
[ -n "$network_coding" ] && batctl meshif "$iface" network_coding "$network_coding" 2>&-
|
[ -n "$network_coding" ] && batctl -m "$iface" network_coding "$network_coding" 2>&-
|
||||||
[ -n "$log_level" ] && batctl meshif "$iface" loglevel "$log_level" 2>&-
|
[ -n "$log_level" ] && batctl -m "$iface" loglevel "$log_level" 2>&-
|
||||||
[ -n "$orig_interval" ] && batctl meshif "$iface" orig_interval "$orig_interval"
|
[ -n "$orig_interval" ] && batctl -m "$iface" orig_interval "$orig_interval"
|
||||||
|
|
||||||
proto_init_update "$iface" 1
|
proto_init_update "$iface" 1
|
||||||
proto_send_update "$config"
|
proto_send_update "$config"
|
||||||
|
@ -117,7 +117,7 @@ proto_batadv_teardown() {
|
||||||
local config="$1"
|
local config="$1"
|
||||||
local iface="$config"
|
local iface="$config"
|
||||||
|
|
||||||
batctl meshif "$iface" interface destroy
|
batctl -m "$iface" interface destroy
|
||||||
}
|
}
|
||||||
|
|
||||||
add_protocol batadv
|
add_protocol batadv
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
proto_batadv_hardif_init_config() {
|
proto_batadv_hardif_init_config() {
|
||||||
proto_config_add_int 'elp_interval'
|
proto_config_add_int 'elp_interval'
|
||||||
proto_config_add_int 'hop_penalty'
|
|
||||||
proto_config_add_string "master"
|
proto_config_add_string "master"
|
||||||
proto_config_add_string 'throughput_override'
|
proto_config_add_string 'throughput_override'
|
||||||
}
|
}
|
||||||
|
@ -18,22 +17,19 @@ proto_batadv_hardif_setup() {
|
||||||
local iface="$2"
|
local iface="$2"
|
||||||
|
|
||||||
local elp_interval
|
local elp_interval
|
||||||
local hop_penalty
|
|
||||||
local master
|
local master
|
||||||
local throughput_override
|
local throughput_override
|
||||||
|
|
||||||
json_get_vars elp_interval
|
json_get_vars elp_interval
|
||||||
json_get_vars hop_penalty
|
|
||||||
json_get_vars master
|
json_get_vars master
|
||||||
json_get_vars throughput_override
|
json_get_vars throughput_override
|
||||||
|
|
||||||
( proto_add_host_dependency "$config" '' "$master" )
|
( proto_add_host_dependency "$config" '' "$master" )
|
||||||
|
|
||||||
batctl meshif "$master" interface -M add "$iface"
|
batctl -m "$master" interface -M add "$iface"
|
||||||
|
|
||||||
[ -n "$elp_interval" ] && batctl hardif "$iface" elp_interval "$elp_interval"
|
[ -n "$elp_interval" ] && batctl -m "$master" hardif "$iface" elp_interval "$elp_interval"
|
||||||
[ -n "$hop_penalty" ] && batctl hardif "$iface" hop_penalty "$hop_penalty"
|
[ -n "$throughput_override" ] && batctl -m "$master" hardif "$iface" throughput_override "$throughput_override"
|
||||||
[ -n "$throughput_override" ] && batctl hardif "$iface" throughput_override "$throughput_override"
|
|
||||||
|
|
||||||
proto_init_update "$iface" 1
|
proto_init_update "$iface" 1
|
||||||
proto_send_update "$config"
|
proto_send_update "$config"
|
||||||
|
@ -47,7 +43,7 @@ proto_batadv_hardif_teardown() {
|
||||||
|
|
||||||
json_get_vars master
|
json_get_vars master
|
||||||
|
|
||||||
batctl meshif "$master" interface -M del "$iface" || true
|
batctl -m "$master" interface -M del "$iface" || true
|
||||||
}
|
}
|
||||||
|
|
||||||
add_protocol batadv_hardif
|
add_protocol batadv_hardif
|
||||||
|
|
|
@ -17,13 +17,9 @@ proto_batadv_vlan_setup() {
|
||||||
|
|
||||||
json_get_vars ap_isolation
|
json_get_vars ap_isolation
|
||||||
|
|
||||||
[ -n "$ap_isolation" ] && batctl vlan "$iface" ap_isolation "$ap_isolation"
|
[ -n "$ap_isolation" ] && batctl -m "$iface" ap_isolation "$ap_isolation"
|
||||||
proto_init_update "$iface" 1
|
proto_init_update "$iface" 1
|
||||||
proto_send_update "$config"
|
proto_send_update "$config"
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_batadv_vlan_teardown() {
|
|
||||||
local cfg="$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
add_protocol batadv_vlan
|
add_protocol batadv_vlan
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Fri, 6 May 2022 22:03:29 +0200
|
|
||||||
Subject: Revert "batman-adv: Migrate to linux/container_of.h"
|
|
||||||
|
|
||||||
The original patch requires Linux 5.16.0 or a mac80211 compat header with this
|
|
||||||
name. But the mac80211 package is currently not providing this header and
|
|
||||||
OpenWrt main is still using older Linux kernel versions for some targets.
|
|
||||||
|
|
||||||
This reverts commit 043ae5634bdfd4c4dd8b95a22890752495080bb5.
|
|
||||||
|
|
||||||
--- a/compat-include/linux/container_of.h
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,20 +0,0 @@
|
|
||||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
-/* Copyright (C) B.A.T.M.A.N. contributors:
|
|
||||||
- *
|
|
||||||
- * Marek Lindner, Simon Wunderlich
|
|
||||||
- *
|
|
||||||
- * This file contains macros for maintaining compatibility with older versions
|
|
||||||
- * of the Linux kernel.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_
|
|
||||||
-#define _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_
|
|
||||||
-
|
|
||||||
-#include <linux/version.h>
|
|
||||||
-#if LINUX_VERSION_IS_GEQ(5, 16, 0)
|
|
||||||
-#include_next <linux/container_of.h>
|
|
||||||
-#else
|
|
||||||
-#include <linux/kernel.h>
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_ */
|
|
||||||
--- a/net/batman-adv/bat_iv_ogm.c
|
|
||||||
+++ b/net/batman-adv/bat_iv_ogm.c
|
|
||||||
@@ -13,13 +13,13 @@
|
|
||||||
#include <linux/bug.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/cache.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/bat_v_elp.c
|
|
||||||
+++ b/net/batman-adv/bat_v_elp.c
|
|
||||||
@@ -10,13 +10,13 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/minmax.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
--- a/net/batman-adv/bat_v_ogm.c
|
|
||||||
+++ b/net/batman-adv/bat_v_ogm.c
|
|
||||||
@@ -9,12 +9,12 @@
|
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/bridge_loop_avoidance.c
|
|
||||||
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
|
||||||
@@ -10,7 +10,6 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/crc16.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
--- a/net/batman-adv/distributed-arp-table.c
|
|
||||||
+++ b/net/batman-adv/distributed-arp-table.c
|
|
||||||
@@ -11,7 +11,6 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
@@ -21,6 +20,7 @@
|
|
||||||
#include <linux/in.h>
|
|
||||||
#include <linux/ip.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
--- a/net/batman-adv/gateway_client.c
|
|
||||||
+++ b/net/batman-adv/gateway_client.c
|
|
||||||
@@ -9,7 +9,6 @@
|
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
--- a/net/batman-adv/hard-interface.c
|
|
||||||
+++ b/net/batman-adv/hard-interface.c
|
|
||||||
@@ -10,12 +10,12 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if.h>
|
|
||||||
#include <linux/if_arp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
--- a/net/batman-adv/main.c
|
|
||||||
+++ b/net/batman-adv/main.c
|
|
||||||
@@ -10,7 +10,6 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/build_bug.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/crc32c.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
--- a/net/batman-adv/multicast.c
|
|
||||||
+++ b/net/batman-adv/multicast.c
|
|
||||||
@@ -11,7 +11,6 @@
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/bug.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
--- a/net/batman-adv/network-coding.c
|
|
||||||
+++ b/net/batman-adv/network-coding.c
|
|
||||||
@@ -11,7 +11,6 @@
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
@@ -20,6 +19,7 @@
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/jhash.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/originator.c
|
|
||||||
+++ b/net/batman-adv/originator.c
|
|
||||||
@@ -8,11 +8,11 @@
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/send.c
|
|
||||||
+++ b/net/batman-adv/send.c
|
|
||||||
@@ -10,13 +10,13 @@
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/bug.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
--- a/net/batman-adv/soft-interface.c
|
|
||||||
+++ b/net/batman-adv/soft-interface.c
|
|
||||||
@@ -11,7 +11,6 @@
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/cache.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
@@ -20,6 +19,7 @@
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/if_vlan.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/tp_meter.c
|
|
||||||
+++ b/net/batman-adv/tp_meter.c
|
|
||||||
@@ -12,13 +12,13 @@
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/cache.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/kthread.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
--- a/net/batman-adv/translation-table.c
|
|
||||||
+++ b/net/batman-adv/translation-table.c
|
|
||||||
@@ -13,7 +13,6 @@
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
#include <linux/cache.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/crc32c.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
@@ -22,6 +21,7 @@
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/jhash.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
--- a/net/batman-adv/tvlv.c
|
|
||||||
+++ b/net/batman-adv/tvlv.c
|
|
||||||
@@ -7,10 +7,10 @@
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
-#include <linux/container_of.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 23 May 2019 19:26:27 +0200
|
||||||
|
Subject: Revert "batman-adv: convert stream-like files from nonseekable_open -> stream_open"
|
||||||
|
|
||||||
|
OpenWrt's mac80211 package is not yet ready to support the generic netlink
|
||||||
|
API of Linux 5.2.
|
||||||
|
|
||||||
|
This reverts commit 337ae19a00d4455cf84afa58abfb432f78c882b9.
|
||||||
|
|
||||||
|
--- a/compat-include/linux/fs.h
|
||||||
|
+++ b/compat-include/linux/fs.h
|
||||||
|
@@ -31,15 +31,4 @@ static inline struct dentry *batadv_file
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 6, 0) */
|
||||||
|
|
||||||
|
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
-
|
||||||
|
-static inline int batadv_stream_open(struct inode *inode, struct file *filp)
|
||||||
|
-{
|
||||||
|
- return nonseekable_open(inode, filp);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#define stream_open batadv_stream_open
|
||||||
|
-
|
||||||
|
-#endif /* < KERNEL_VERSION(5, 2, 0) */
|
||||||
|
-
|
||||||
|
#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_FS_H_ */
|
||||||
|
--- a/net/batman-adv/icmp_socket.c
|
||||||
|
+++ b/net/batman-adv/icmp_socket.c
|
||||||
|
@@ -65,7 +65,7 @@ static int batadv_socket_open(struct ino
|
||||||
|
|
||||||
|
batadv_debugfs_deprecated(file, "");
|
||||||
|
|
||||||
|
- stream_open(inode, file);
|
||||||
|
+ nonseekable_open(inode, file);
|
||||||
|
|
||||||
|
socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
|
||||||
|
if (!socket_client) {
|
||||||
|
--- a/net/batman-adv/log.c
|
||||||
|
+++ b/net/batman-adv/log.c
|
||||||
|
@@ -90,7 +90,7 @@ static int batadv_log_open(struct inode
|
||||||
|
batadv_debugfs_deprecated(file,
|
||||||
|
"Use tracepoint batadv:batadv_dbg instead\n");
|
||||||
|
|
||||||
|
- stream_open(inode, file);
|
||||||
|
+ nonseekable_open(inode, file);
|
||||||
|
file->private_data = inode->i_private;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 23 May 2019 19:26:36 +0200
|
||||||
|
Subject: Revert "batman-adv: compat: Drop support for genl_ops->start"
|
||||||
|
|
||||||
|
OpenWrt's mac80211 package is not yet ready to support the generic netlink
|
||||||
|
API of Linux 5.2.
|
||||||
|
|
||||||
|
This reverts commit 1d30dbe3917d0d6fdb8ba473dfdd6265ac46670b.
|
||||||
|
|
||||||
|
--- a/compat-include/net/genetlink.h
|
||||||
|
+++ b/compat-include/net/genetlink.h
|
||||||
|
@@ -42,6 +42,7 @@ enum genl_validate_flags {
|
||||||
|
struct batadv_genl_ops {
|
||||||
|
int (*doit)(struct sk_buff *skb,
|
||||||
|
struct genl_info *info);
|
||||||
|
+ int (*start)(struct netlink_callback *cb);
|
||||||
|
int (*dumpit)(struct sk_buff *skb,
|
||||||
|
struct netlink_callback *cb);
|
||||||
|
int (*done)(struct netlink_callback *cb);
|
||||||
|
@@ -104,6 +105,7 @@ static inline int batadv_genl_register_f
|
||||||
|
|
||||||
|
for (i = 0; i < family->family.n_ops; i++) {
|
||||||
|
ops[i].doit = family->ops[i].doit;
|
||||||
|
+ ops[i].start = family->ops[i].start;
|
||||||
|
ops[i].dumpit = family->ops[i].dumpit;
|
||||||
|
ops[i].done = family->ops[i].done;
|
||||||
|
ops[i].cmd = family->ops[i].cmd;
|
|
@ -1,19 +0,0 @@
|
||||||
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
|
||||||
Date: Thu, 6 Apr 2023 18:05:50 -0500
|
|
||||||
Subject: fix batadv_is_cfg80211_netdev
|
|
||||||
|
|
||||||
Replace CONFIG_CFG80211 with CPTCFG_CFG80211, which is the correct
|
|
||||||
macro to use when building under backports.
|
|
||||||
|
|
||||||
--- a/net/batman-adv/hard-interface.c
|
|
||||||
+++ b/net/batman-adv/hard-interface.c
|
|
||||||
@@ -308,8 +308,7 @@ static bool batadv_is_cfg80211_netdev(st
|
|
||||||
{
|
|
||||||
if (!net_device)
|
|
||||||
return false;
|
|
||||||
-
|
|
||||||
-#if IS_ENABLED(CONFIG_CFG80211)
|
|
||||||
+#if IS_ENABLED(CPTCFG_CFG80211)
|
|
||||||
/* cfg80211 drivers have to set ieee80211_ptr */
|
|
||||||
if (net_device->ieee80211_ptr)
|
|
||||||
return true;
|
|
|
@ -1,97 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Fri, 2 Feb 2024 22:49:00 +0100
|
|
||||||
Subject: Revert "batman-adv: Switch to linux/sprintf.h"
|
|
||||||
|
|
||||||
The original patch requires Linux 6.6.0 or a mac80211 compat header with this
|
|
||||||
name. But the mac80211 package is currently not providing this header and
|
|
||||||
OpenWrt main is still using older Linux kernel versions for some targets.
|
|
||||||
|
|
||||||
This reverts commit f0fb49c5ab70dfa064f0aa8d1c5d84f65e8cbc86.
|
|
||||||
|
|
||||||
--- a/compat-include/linux/sprintf.h
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,20 +0,0 @@
|
|
||||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
-/* Copyright (C) B.A.T.M.A.N. contributors:
|
|
||||||
- *
|
|
||||||
- * Marek Lindner, Simon Wunderlich
|
|
||||||
- *
|
|
||||||
- * This file contains macros for maintaining compatibility with older versions
|
|
||||||
- * of the Linux kernel.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_
|
|
||||||
-#define _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_
|
|
||||||
-
|
|
||||||
-#include <linux/version.h>
|
|
||||||
-#if LINUX_VERSION_IS_GEQ(6, 6, 0)
|
|
||||||
-#include_next <linux/sprintf.h>
|
|
||||||
-#else
|
|
||||||
-#include <linux/kernel.h>
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_ */
|
|
||||||
--- a/net/batman-adv/bridge_loop_avoidance.c
|
|
||||||
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
#include <linux/if_vlan.h>
|
|
||||||
#include <linux/jhash.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
@@ -29,7 +30,6 @@
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
-#include <linux/sprintf.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/workqueue.h>
|
|
||||||
--- a/net/batman-adv/gateway_client.c
|
|
||||||
+++ b/net/batman-adv/gateway_client.c
|
|
||||||
@@ -17,6 +17,7 @@
|
|
||||||
#include <linux/in.h>
|
|
||||||
#include <linux/ip.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
@@ -27,7 +28,6 @@
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
-#include <linux/sprintf.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/udp.h>
|
|
||||||
#include <net/sock.h>
|
|
||||||
--- a/net/batman-adv/main.c
|
|
||||||
+++ b/net/batman-adv/main.c
|
|
||||||
@@ -32,7 +32,6 @@
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
-#include <linux/sprintf.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/workqueue.h>
|
|
||||||
--- a/net/batman-adv/multicast.c
|
|
||||||
+++ b/net/batman-adv/multicast.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <linux/ip.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/lockdep.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
@@ -34,7 +35,6 @@
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
-#include <linux/sprintf.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/types.h>
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 23 May 2019 19:26:45 +0200
|
||||||
|
Subject: Revert "batman-adv: genetlink: optionally validate strictly/dumps"
|
||||||
|
|
||||||
|
OpenWrt's mac80211 package is not yet ready to support the generic netlink
|
||||||
|
API of Linux 5.2.
|
||||||
|
|
||||||
|
This reverts commit 2ee47abaeb35ca62bb909830e10b0e973393b853.
|
||||||
|
|
||||||
|
--- a/compat-include/net/genetlink.h
|
||||||
|
+++ b/compat-include/net/genetlink.h
|
||||||
|
@@ -33,25 +33,6 @@ void batadv_genl_dump_check_consistent(s
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
|
||||||
|
-enum genl_validate_flags {
|
||||||
|
- GENL_DONT_VALIDATE_STRICT = BIT(0),
|
||||||
|
- GENL_DONT_VALIDATE_DUMP = BIT(1),
|
||||||
|
- GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-struct batadv_genl_ops {
|
||||||
|
- int (*doit)(struct sk_buff *skb,
|
||||||
|
- struct genl_info *info);
|
||||||
|
- int (*start)(struct netlink_callback *cb);
|
||||||
|
- int (*dumpit)(struct sk_buff *skb,
|
||||||
|
- struct netlink_callback *cb);
|
||||||
|
- int (*done)(struct netlink_callback *cb);
|
||||||
|
- u8 cmd;
|
||||||
|
- u8 internal_flags;
|
||||||
|
- u8 flags;
|
||||||
|
- u8 validate;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
struct batadv_genl_family {
|
||||||
|
/* data handled by the actual kernel */
|
||||||
|
struct genl_family family;
|
||||||
|
@@ -69,7 +50,7 @@ struct batadv_genl_family {
|
||||||
|
struct genl_info *info);
|
||||||
|
void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb,
|
||||||
|
struct genl_info *info);
|
||||||
|
- const struct batadv_genl_ops *ops;
|
||||||
|
+ const struct genl_ops *ops;
|
||||||
|
const struct genl_multicast_group *mcgrps;
|
||||||
|
unsigned int n_ops;
|
||||||
|
unsigned int n_mcgrps;
|
||||||
|
@@ -82,6 +63,8 @@ struct batadv_genl_family {
|
||||||
|
struct genl_ops *copy_ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#define genl_family batadv_genl_family
|
||||||
|
+
|
||||||
|
static inline int batadv_genl_register_family(struct batadv_genl_family *family)
|
||||||
|
{
|
||||||
|
struct genl_ops *ops;
|
||||||
|
@@ -99,20 +82,12 @@ static inline int batadv_genl_register_f
|
||||||
|
family->family.n_mcgrps = family->n_mcgrps;
|
||||||
|
family->family.module = family->module;
|
||||||
|
|
||||||
|
- ops = kzalloc(sizeof(*ops) * family->n_ops, GFP_KERNEL);
|
||||||
|
+ ops = kmemdup(family->ops, sizeof(*ops) * family->n_ops, GFP_KERNEL);
|
||||||
|
if (!ops)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- for (i = 0; i < family->family.n_ops; i++) {
|
||||||
|
- ops[i].doit = family->ops[i].doit;
|
||||||
|
- ops[i].start = family->ops[i].start;
|
||||||
|
- ops[i].dumpit = family->ops[i].dumpit;
|
||||||
|
- ops[i].done = family->ops[i].done;
|
||||||
|
- ops[i].cmd = family->ops[i].cmd;
|
||||||
|
- ops[i].internal_flags = family->ops[i].internal_flags;
|
||||||
|
- ops[i].flags = family->ops[i].flags;
|
||||||
|
+ for (i = 0; i < family->family.n_ops; i++)
|
||||||
|
ops[i].policy = family->policy;
|
||||||
|
- }
|
||||||
|
|
||||||
|
family->family.ops = ops;
|
||||||
|
family->copy_ops = ops;
|
||||||
|
@@ -120,17 +95,6 @@ static inline int batadv_genl_register_f
|
||||||
|
return genl_register_family(&family->family);
|
||||||
|
}
|
||||||
|
|
||||||
|
-typedef struct genl_ops batadv_genl_ops_old;
|
||||||
|
-
|
||||||
|
-#define batadv_pre_doit(__x, __y, __z) \
|
||||||
|
- batadv_pre_doit(const batadv_genl_ops_old *ops, __y, __z)
|
||||||
|
-
|
||||||
|
-#define batadv_post_doit(__x, __y, __z) \
|
||||||
|
- batadv_post_doit(const batadv_genl_ops_old *ops, __y, __z)
|
||||||
|
-
|
||||||
|
-#define genl_ops batadv_genl_ops
|
||||||
|
-#define genl_family batadv_genl_family
|
||||||
|
-
|
||||||
|
#define genl_register_family(family) \
|
||||||
|
batadv_genl_register_family((family))
|
||||||
|
|
||||||
|
--- a/net/batman-adv/netlink.c
|
||||||
|
+++ b/net/batman-adv/netlink.c
|
||||||
|
@@ -1343,34 +1343,29 @@ static void batadv_post_doit(const struc
|
||||||
|
static const struct genl_ops batadv_netlink_ops[] = {
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_MESH,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
.doit = batadv_netlink_get_mesh,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.doit = batadv_netlink_tp_meter_start,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER_CANCEL,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.doit = batadv_netlink_tp_meter_cancel,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_algo_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_HARDIF,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
.dumpit = batadv_netlink_dump_hardif,
|
||||||
|
.doit = batadv_netlink_get_hardif,
|
||||||
|
@@ -1379,68 +1374,57 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_tt_local_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_tt_global_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_orig_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_NEIGHBORS,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_hardif_neigh_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_GATEWAYS,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_gw_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_CLAIM,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_bla_claim_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_bla_backbone_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_DAT_CACHE,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_dat_cache_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.dumpit = batadv_mcast_flags_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_MESH,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.doit = batadv_netlink_set_mesh,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_HARDIF,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.doit = batadv_netlink_set_hardif,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
@@ -1448,7 +1432,6 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_VLAN,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
.doit = batadv_netlink_get_vlan,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
@@ -1456,7 +1439,6 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_VLAN,
|
||||||
|
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.doit = batadv_netlink_set_vlan,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
|
@ -1,69 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Fri, 2 Feb 2024 22:49:48 +0100
|
|
||||||
Subject: Revert "batman-adv: Switch to linux/array_size.h"
|
|
||||||
|
|
||||||
The original patch requires Linux 6.7.0 or a mac80211 compat header with this
|
|
||||||
name. But the mac80211 package is currently not providing this header and
|
|
||||||
OpenWrt main is still using older Linux kernel versions for some targets.
|
|
||||||
|
|
||||||
This reverts commit f33d7f724675544a36b24c77f8d4b95d41252ae2.
|
|
||||||
|
|
||||||
--- a/compat-include/linux/array_size.h
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,20 +0,0 @@
|
|
||||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
-/* Copyright (C) B.A.T.M.A.N. contributors:
|
|
||||||
- *
|
|
||||||
- * Marek Lindner, Simon Wunderlich
|
|
||||||
- *
|
|
||||||
- * This file contains macros for maintaining compatibility with older versions
|
|
||||||
- * of the Linux kernel.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_
|
|
||||||
-#define _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_
|
|
||||||
-
|
|
||||||
-#include <linux/version.h>
|
|
||||||
-#if LINUX_VERSION_IS_GEQ(6, 7, 0)
|
|
||||||
-#include_next <linux/array_size.h>
|
|
||||||
-#else
|
|
||||||
-#include <linux/kernel.h>
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_ */
|
|
||||||
--- a/net/batman-adv/main.c
|
|
||||||
+++ b/net/batman-adv/main.c
|
|
||||||
@@ -6,7 +6,6 @@
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
-#include <linux/array_size.h>
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/build_bug.h>
|
|
||||||
#include <linux/byteorder/generic.h>
|
|
||||||
@@ -20,6 +19,7 @@
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/ip.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/kobject.h>
|
|
||||||
#include <linux/kref.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
--- a/net/batman-adv/netlink.c
|
|
||||||
+++ b/net/batman-adv/netlink.c
|
|
||||||
@@ -7,7 +7,6 @@
|
|
||||||
#include "netlink.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
-#include <linux/array_size.h>
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/bug.h>
|
|
||||||
@@ -21,6 +20,7 @@
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/if_vlan.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/minmax.h>
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 23 May 2019 19:26:58 +0200
|
||||||
|
Subject: Revert "batman-adv: genetlink: make policy common to family"
|
||||||
|
|
||||||
|
OpenWrt's mac80211 package is not yet ready to support the generic netlink
|
||||||
|
API of Linux 5.2.
|
||||||
|
|
||||||
|
This reverts commit acfc9a214d01695d1676313ca80cfd2d9309f633.
|
||||||
|
|
||||||
|
--- a/compat-include/linux/cache.h
|
||||||
|
+++ b/compat-include/linux/cache.h
|
||||||
|
@@ -13,8 +13,12 @@
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include_next <linux/cache.h>
|
||||||
|
|
||||||
|
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
|
||||||
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
||||||
|
|
||||||
|
+/* hack for netlink.c which marked the family ops as ro */
|
||||||
|
+#ifdef __ro_after_init
|
||||||
|
+#undef __ro_after_init
|
||||||
|
+#endif
|
||||||
|
#define __ro_after_init
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 6, 0) */
|
||||||
|
--- a/compat-include/net/genetlink.h
|
||||||
|
+++ b/compat-include/net/genetlink.h
|
||||||
|
@@ -30,92 +30,4 @@ void batadv_genl_dump_check_consistent(s
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 15, 0) */
|
||||||
|
|
||||||
|
-
|
||||||
|
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
-
|
||||||
|
-struct batadv_genl_family {
|
||||||
|
- /* data handled by the actual kernel */
|
||||||
|
- struct genl_family family;
|
||||||
|
-
|
||||||
|
- /* data which has to be copied to family by
|
||||||
|
- * batadv_genl_register_family
|
||||||
|
- */
|
||||||
|
- unsigned int hdrsize;
|
||||||
|
- char name[GENL_NAMSIZ];
|
||||||
|
- unsigned int version;
|
||||||
|
- unsigned int maxattr;
|
||||||
|
- const struct nla_policy *policy;
|
||||||
|
- bool netnsok;
|
||||||
|
- int (*pre_doit)(const struct genl_ops *ops, struct sk_buff *skb,
|
||||||
|
- struct genl_info *info);
|
||||||
|
- void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb,
|
||||||
|
- struct genl_info *info);
|
||||||
|
- const struct genl_ops *ops;
|
||||||
|
- const struct genl_multicast_group *mcgrps;
|
||||||
|
- unsigned int n_ops;
|
||||||
|
- unsigned int n_mcgrps;
|
||||||
|
- struct module *module;
|
||||||
|
-
|
||||||
|
- /* allocated by batadv_genl_register_family and free'd by
|
||||||
|
- * batadv_genl_unregister_family. Used to modify the usually read-only
|
||||||
|
- * ops
|
||||||
|
- */
|
||||||
|
- struct genl_ops *copy_ops;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-#define genl_family batadv_genl_family
|
||||||
|
-
|
||||||
|
-static inline int batadv_genl_register_family(struct batadv_genl_family *family)
|
||||||
|
-{
|
||||||
|
- struct genl_ops *ops;
|
||||||
|
- unsigned int i;
|
||||||
|
-
|
||||||
|
- family->family.hdrsize = family->hdrsize;
|
||||||
|
- strncpy(family->family.name, family->name, sizeof(family->family.name));
|
||||||
|
- family->family.version = family->version;
|
||||||
|
- family->family.maxattr = family->maxattr;
|
||||||
|
- family->family.netnsok = family->netnsok;
|
||||||
|
- family->family.pre_doit = family->pre_doit;
|
||||||
|
- family->family.post_doit = family->post_doit;
|
||||||
|
- family->family.mcgrps = family->mcgrps;
|
||||||
|
- family->family.n_ops = family->n_ops;
|
||||||
|
- family->family.n_mcgrps = family->n_mcgrps;
|
||||||
|
- family->family.module = family->module;
|
||||||
|
-
|
||||||
|
- ops = kmemdup(family->ops, sizeof(*ops) * family->n_ops, GFP_KERNEL);
|
||||||
|
- if (!ops)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- for (i = 0; i < family->family.n_ops; i++)
|
||||||
|
- ops[i].policy = family->policy;
|
||||||
|
-
|
||||||
|
- family->family.ops = ops;
|
||||||
|
- family->copy_ops = ops;
|
||||||
|
-
|
||||||
|
- return genl_register_family(&family->family);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#define genl_register_family(family) \
|
||||||
|
- batadv_genl_register_family((family))
|
||||||
|
-
|
||||||
|
-static inline void
|
||||||
|
-batadv_genl_unregister_family(struct batadv_genl_family *family)
|
||||||
|
-{
|
||||||
|
-
|
||||||
|
- genl_unregister_family(&family->family);
|
||||||
|
- kfree(family->copy_ops);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#define genl_unregister_family(family) \
|
||||||
|
- batadv_genl_unregister_family((family))
|
||||||
|
-
|
||||||
|
-#define genlmsg_put(_skb, _pid, _seq, _family, _flags, _cmd) \
|
||||||
|
- genlmsg_put(_skb, _pid, _seq, &(_family)->family, _flags, _cmd)
|
||||||
|
-
|
||||||
|
-#define genlmsg_multicast_netns(_family, _net, _skb, _portid, _group, _flags) \
|
||||||
|
- genlmsg_multicast_netns(&(_family)->family, _net, _skb, _portid, \
|
||||||
|
- _group, _flags)
|
||||||
|
-
|
||||||
|
-#endif /* < KERNEL_VERSION(5, 2, 0) */
|
||||||
|
-
|
||||||
|
#endif /* _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ */
|
||||||
|
--- a/net/batman-adv/netlink.c
|
||||||
|
+++ b/net/batman-adv/netlink.c
|
||||||
|
@@ -1344,29 +1344,34 @@ static const struct genl_ops batadv_netl
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_MESH,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_get_mesh,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_tp_meter_start,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER_CANCEL,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_tp_meter_cancel,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_algo_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_HARDIF,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_netlink_dump_hardif,
|
||||||
|
.doit = batadv_netlink_get_hardif,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
@@ -1375,57 +1380,68 @@ static const struct genl_ops batadv_netl
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_tt_local_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_tt_global_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_orig_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_NEIGHBORS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_hardif_neigh_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_GATEWAYS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_gw_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_CLAIM,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_bla_claim_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_bla_backbone_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_DAT_CACHE,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_dat_cache_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_mcast_flags_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_MESH,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_mesh,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_HARDIF,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_hardif,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
BATADV_FLAG_NEED_HARDIF,
|
||||||
|
@@ -1433,6 +1449,7 @@ static const struct genl_ops batadv_netl
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_VLAN,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_get_vlan,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
BATADV_FLAG_NEED_VLAN,
|
||||||
|
@@ -1440,6 +1457,7 @@ static const struct genl_ops batadv_netl
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_VLAN,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
+ .policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_vlan,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
BATADV_FLAG_NEED_VLAN,
|
||||||
|
@@ -1451,7 +1469,6 @@ struct genl_family batadv_netlink_family
|
||||||
|
.name = BATADV_NL_NAME,
|
||||||
|
.version = 1,
|
||||||
|
.maxattr = BATADV_ATTR_MAX,
|
||||||
|
- .policy = batadv_netlink_policy,
|
||||||
|
.netnsok = true,
|
||||||
|
.pre_doit = batadv_pre_doit,
|
||||||
|
.post_doit = batadv_post_doit,
|
|
@ -0,0 +1,71 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sun, 2 Jun 2019 10:57:31 +0200
|
||||||
|
Subject: batman-adv: Fix duplicated OGMs on NETDEV_UP
|
||||||
|
|
||||||
|
The state of slave interfaces are handled differently depending on whether
|
||||||
|
the interface is up or not. All active interfaces (IFF_UP) will transmit
|
||||||
|
OGMs. But for B.A.T.M.A.N. IV, also non-active interfaces are scheduling
|
||||||
|
(low TTL) OGMs on active interfaces. The code which setups and schedules
|
||||||
|
the OGMs must therefore already be called when the interfaces gets added as
|
||||||
|
slave interface and the transmit function must then check whether it has to
|
||||||
|
send out the OGM or not on the specific slave interface.
|
||||||
|
|
||||||
|
But the commit 0d8468553c3c ("batman-adv: remove ogm_emit and ogm_schedule
|
||||||
|
API calls") moved the setup code from the enable function to the activate
|
||||||
|
function. The latter is called either when the added slave was already up
|
||||||
|
when batadv_hardif_enable_interface processed the new interface or when a
|
||||||
|
NETDEV_UP event was received for this slave interfac. As result, each
|
||||||
|
NETDEV_UP would schedule a new OGM worker for the interface and thus OGMs
|
||||||
|
would be send a lot more than expected.
|
||||||
|
|
||||||
|
Fixes: 0d8468553c3c ("batman-adv: remove ogm_emit and ogm_schedule API calls")
|
||||||
|
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c92331e0df3c0c5645ee5a897eb018c5da5e4aa5
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -2337,7 +2337,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
|
||||||
|
+static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
/* begin scheduling originator messages on that interface */
|
||||||
|
batadv_iv_ogm_schedule(hard_iface);
|
||||||
|
@@ -2683,8 +2683,8 @@ unlock:
|
||||||
|
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
|
||||||
|
.name = "BATMAN_IV",
|
||||||
|
.iface = {
|
||||||
|
- .activate = batadv_iv_iface_activate,
|
||||||
|
.enable = batadv_iv_ogm_iface_enable,
|
||||||
|
+ .enabled = batadv_iv_iface_enabled,
|
||||||
|
.disable = batadv_iv_ogm_iface_disable,
|
||||||
|
.update_mac = batadv_iv_ogm_iface_update_mac,
|
||||||
|
.primary_set = batadv_iv_ogm_primary_iface_set,
|
||||||
|
--- a/net/batman-adv/hard-interface.c
|
||||||
|
+++ b/net/batman-adv/hard-interface.c
|
||||||
|
@@ -795,6 +795,9 @@ int batadv_hardif_enable_interface(struc
|
||||||
|
|
||||||
|
batadv_hardif_recalc_extra_skbroom(soft_iface);
|
||||||
|
|
||||||
|
+ if (bat_priv->algo_ops->iface.enabled)
|
||||||
|
+ bat_priv->algo_ops->iface.enabled(hard_iface);
|
||||||
|
+
|
||||||
|
out:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -2129,6 +2129,9 @@ struct batadv_algo_iface_ops {
|
||||||
|
/** @enable: init routing info when hard-interface is enabled */
|
||||||
|
int (*enable)(struct batadv_hard_iface *hard_iface);
|
||||||
|
|
||||||
|
+ /** @enabled: notification when hard-interface was enabled (optional) */
|
||||||
|
+ void (*enabled)(struct batadv_hard_iface *hard_iface);
|
||||||
|
+
|
||||||
|
/** @disable: de-init routing info when hard-interface is disabled */
|
||||||
|
void (*disable)(struct batadv_hard_iface *hard_iface);
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sun, 7 Jul 2019 22:19:22 +0200
|
||||||
|
Subject: batman-adv: Fix netlink dumping of all mcast_flags buckets
|
||||||
|
|
||||||
|
The bucket variable is only updated outside the loop over the mcast_flags
|
||||||
|
buckets. It will only be updated during a dumping run when the dumping has
|
||||||
|
to be interrupted and a new message has to be started.
|
||||||
|
|
||||||
|
This could result in repeated or missing entries when the multicast flags
|
||||||
|
are dumped to userspace.
|
||||||
|
|
||||||
|
Fixes: 06c82b7b15b1 ("batman-adv: Add inconsistent multicast netlink dump detection")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d1de7f7aa316d6f7b3268f61afa88f5d2c1a5db5
|
||||||
|
|
||||||
|
--- a/net/batman-adv/multicast.c
|
||||||
|
+++ b/net/batman-adv/multicast.c
|
||||||
|
@@ -1653,7 +1653,7 @@ __batadv_mcast_flags_dump(struct sk_buff
|
||||||
|
|
||||||
|
while (bucket_tmp < hash->size) {
|
||||||
|
if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash,
|
||||||
|
- *bucket, &idx_tmp))
|
||||||
|
+ bucket_tmp, &idx_tmp))
|
||||||
|
break;
|
||||||
|
|
||||||
|
bucket_tmp++;
|
|
@ -0,0 +1,56 @@
|
||||||
|
From: Eric Dumazet <edumazet@google.com>
|
||||||
|
Date: Mon, 12 Aug 2019 04:57:27 -0700
|
||||||
|
Subject: batman-adv: fix uninit-value in batadv_netlink_get_ifindex()
|
||||||
|
|
||||||
|
batadv_netlink_get_ifindex() needs to make sure user passed
|
||||||
|
a correct u32 attribute.
|
||||||
|
|
||||||
|
syzbot reported :
|
||||||
|
BUG: KMSAN: uninit-value in batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
|
||||||
|
CPU: 1 PID: 11705 Comm: syz-executor888 Not tainted 5.1.0+ #1
|
||||||
|
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
|
||||||
|
Call Trace:
|
||||||
|
__dump_stack lib/dump_stack.c:77 [inline]
|
||||||
|
dump_stack+0x191/0x1f0 lib/dump_stack.c:113
|
||||||
|
kmsan_report+0x130/0x2a0 mm/kmsan/kmsan.c:622
|
||||||
|
__msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:310
|
||||||
|
batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
|
||||||
|
genl_lock_dumpit+0xc6/0x130 net/netlink/genetlink.c:482
|
||||||
|
netlink_dump+0xa84/0x1ab0 net/netlink/af_netlink.c:2253
|
||||||
|
__netlink_dump_start+0xa3a/0xb30 net/netlink/af_netlink.c:2361
|
||||||
|
genl_family_rcv_msg net/netlink/genetlink.c:550 [inline]
|
||||||
|
genl_rcv_msg+0xfc1/0x1a40 net/netlink/genetlink.c:627
|
||||||
|
netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2486
|
||||||
|
genl_rcv+0x63/0x80 net/netlink/genetlink.c:638
|
||||||
|
netlink_unicast_kernel net/netlink/af_netlink.c:1311 [inline]
|
||||||
|
netlink_unicast+0xf3e/0x1020 net/netlink/af_netlink.c:1337
|
||||||
|
netlink_sendmsg+0x127e/0x12f0 net/netlink/af_netlink.c:1926
|
||||||
|
sock_sendmsg_nosec net/socket.c:651 [inline]
|
||||||
|
sock_sendmsg net/socket.c:661 [inline]
|
||||||
|
___sys_sendmsg+0xcc6/0x1200 net/socket.c:2260
|
||||||
|
__sys_sendmsg net/socket.c:2298 [inline]
|
||||||
|
__do_sys_sendmsg net/socket.c:2307 [inline]
|
||||||
|
__se_sys_sendmsg+0x305/0x460 net/socket.c:2305
|
||||||
|
__x64_sys_sendmsg+0x4a/0x70 net/socket.c:2305
|
||||||
|
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
|
||||||
|
entry_SYSCALL_64_after_hwframe+0x63/0xe7
|
||||||
|
RIP: 0033:0x440209
|
||||||
|
|
||||||
|
Fixes: 55d368c3a57e ("batman-adv: netlink: hardif query")
|
||||||
|
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Reported-by: syzbot <syzkaller@googlegroups.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b470b8a2b9ef4ce68d6e95febd3a0574be1ac14
|
||||||
|
|
||||||
|
--- a/net/batman-adv/netlink.c
|
||||||
|
+++ b/net/batman-adv/netlink.c
|
||||||
|
@@ -164,7 +164,7 @@ batadv_netlink_get_ifindex(const struct
|
||||||
|
{
|
||||||
|
struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
|
||||||
|
|
||||||
|
- return attr ? nla_get_u32(attr) : 0;
|
||||||
|
+ return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
|
@ -0,0 +1,72 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 23 Aug 2019 14:34:27 +0200
|
||||||
|
Subject: batman-adv: Only read OGM tvlv_len after buffer len check
|
||||||
|
|
||||||
|
Multiple batadv_ogm_packet can be stored in an skbuff. The functions
|
||||||
|
batadv_iv_ogm_send_to_if()/batadv_iv_ogm_receive() use
|
||||||
|
batadv_iv_ogm_aggr_packet() to check if there is another additional
|
||||||
|
batadv_ogm_packet in the skb or not before they continue processing the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
The length for such an OGM is BATADV_OGM_HLEN +
|
||||||
|
batadv_ogm_packet->tvlv_len. The check must first check that at least
|
||||||
|
BATADV_OGM_HLEN bytes are available before it accesses tvlv_len (which is
|
||||||
|
part of the header. Otherwise it might try read outside of the currently
|
||||||
|
available skbuff to get the content of tvlv_len.
|
||||||
|
|
||||||
|
Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure")
|
||||||
|
Reported-by: syzbot+355cab184197dbbfa384@syzkaller.appspotmail.com
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Antonio Quartulli <a@unstable.cc>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/07b6051ebcfaa7ea89b4f278eca2ff4070d29e56
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, cons
|
||||||
|
* batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
|
||||||
|
* @buff_pos: current position in the skb
|
||||||
|
* @packet_len: total length of the skb
|
||||||
|
- * @tvlv_len: tvlv length of the previously considered OGM
|
||||||
|
+ * @ogm_packet: potential OGM in buffer
|
||||||
|
*
|
||||||
|
* Return: true if there is enough space for another OGM, false otherwise.
|
||||||
|
*/
|
||||||
|
-static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
|
||||||
|
- __be16 tvlv_len)
|
||||||
|
+static bool
|
||||||
|
+batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
|
||||||
|
+ const struct batadv_ogm_packet *ogm_packet)
|
||||||
|
{
|
||||||
|
int next_buff_pos = 0;
|
||||||
|
|
||||||
|
- next_buff_pos += buff_pos + BATADV_OGM_HLEN;
|
||||||
|
- next_buff_pos += ntohs(tvlv_len);
|
||||||
|
+ /* check if there is enough space for the header */
|
||||||
|
+ next_buff_pos += buff_pos + sizeof(*ogm_packet);
|
||||||
|
+ if (next_buff_pos > packet_len)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ /* check if there is enough space for the optional TVLV */
|
||||||
|
+ next_buff_pos += ntohs(ogm_packet->tvlv_len);
|
||||||
|
|
||||||
|
return (next_buff_pos <= packet_len) &&
|
||||||
|
(next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
|
||||||
|
@@ -315,7 +321,7 @@ static void batadv_iv_ogm_send_to_if(str
|
||||||
|
|
||||||
|
/* adjust all flags and log packets */
|
||||||
|
while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
|
||||||
|
- batadv_ogm_packet->tvlv_len)) {
|
||||||
|
+ batadv_ogm_packet)) {
|
||||||
|
/* we might have aggregated direct link packets with an
|
||||||
|
* ordinary base packet
|
||||||
|
*/
|
||||||
|
@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct
|
||||||
|
|
||||||
|
/* unpack the aggregated packets and process them one by one */
|
||||||
|
while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
|
||||||
|
- ogm_packet->tvlv_len)) {
|
||||||
|
+ ogm_packet)) {
|
||||||
|
batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
|
||||||
|
|
||||||
|
ogm_offset += BATADV_OGM_HLEN;
|
|
@ -0,0 +1,60 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 23 Aug 2019 14:34:28 +0200
|
||||||
|
Subject: batman-adv: Only read OGM2 tvlv_len after buffer len check
|
||||||
|
|
||||||
|
Multiple batadv_ogm2_packet can be stored in an skbuff. The functions
|
||||||
|
batadv_v_ogm_send_to_if() uses batadv_v_ogm_aggr_packet() to check if there
|
||||||
|
is another additional batadv_ogm2_packet in the skb or not before they
|
||||||
|
continue processing the packet.
|
||||||
|
|
||||||
|
The length for such an OGM2 is BATADV_OGM2_HLEN +
|
||||||
|
batadv_ogm2_packet->tvlv_len. The check must first check that at least
|
||||||
|
BATADV_OGM2_HLEN bytes are available before it accesses tvlv_len (which is
|
||||||
|
part of the header. Otherwise it might try read outside of the currently
|
||||||
|
available skbuff to get the content of tvlv_len.
|
||||||
|
|
||||||
|
Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/18f77da3761c5550f42a2d131f0fe5cac62e022d
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_v_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_v_ogm.c
|
||||||
|
@@ -631,17 +631,23 @@ batadv_v_ogm_process_per_outif(struct ba
|
||||||
|
* batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
|
||||||
|
* @buff_pos: current position in the skb
|
||||||
|
* @packet_len: total length of the skb
|
||||||
|
- * @tvlv_len: tvlv length of the previously considered OGM
|
||||||
|
+ * @ogm2_packet: potential OGM2 in buffer
|
||||||
|
*
|
||||||
|
* Return: true if there is enough space for another OGM, false otherwise.
|
||||||
|
*/
|
||||||
|
-static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
|
||||||
|
- __be16 tvlv_len)
|
||||||
|
+static bool
|
||||||
|
+batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
|
||||||
|
+ const struct batadv_ogm2_packet *ogm2_packet)
|
||||||
|
{
|
||||||
|
int next_buff_pos = 0;
|
||||||
|
|
||||||
|
- next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
|
||||||
|
- next_buff_pos += ntohs(tvlv_len);
|
||||||
|
+ /* check if there is enough space for the header */
|
||||||
|
+ next_buff_pos += buff_pos + sizeof(*ogm2_packet);
|
||||||
|
+ if (next_buff_pos > packet_len)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ /* check if there is enough space for the optional TVLV */
|
||||||
|
+ next_buff_pos += ntohs(ogm2_packet->tvlv_len);
|
||||||
|
|
||||||
|
return (next_buff_pos <= packet_len) &&
|
||||||
|
(next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
|
||||||
|
@@ -818,7 +824,7 @@ int batadv_v_ogm_packet_recv(struct sk_b
|
||||||
|
ogm_packet = (struct batadv_ogm2_packet *)skb->data;
|
||||||
|
|
||||||
|
while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
|
||||||
|
- ogm_packet->tvlv_len)) {
|
||||||
|
+ ogm_packet)) {
|
||||||
|
batadv_v_ogm_process(skb, ogm_offset, if_incoming);
|
||||||
|
|
||||||
|
ogm_offset += BATADV_OGM2_HLEN;
|
|
@ -0,0 +1,115 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 3 Oct 2019 17:02:01 +0200
|
||||||
|
Subject: batman-adv: Avoid free/alloc race when handling OGM2 buffer
|
||||||
|
|
||||||
|
A B.A.T.M.A.N. V virtual interface has an OGM2 packet buffer which is
|
||||||
|
initialized using data from the RTNL lock protected netdevice notifier and
|
||||||
|
other rtnetlink related hooks. It is sent regularly via various slave
|
||||||
|
interfaces of the batadv virtual interface and in this process also
|
||||||
|
modified (realloced) to integrate additional state information via TVLV
|
||||||
|
containers.
|
||||||
|
|
||||||
|
It must be avoided that the worker item is executed without a common lock
|
||||||
|
with the netdevice notifier/rtnetlink helpers. Otherwise it can either
|
||||||
|
happen that half modified data is sent out or the functions modifying the
|
||||||
|
OGM2 buffer try to access already freed memory regions.
|
||||||
|
|
||||||
|
Fixes: 632835348e65 ("batman-adv: OGMv2 - add basic infrastructure")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/14ee24576213ff02272b7f8d975c7c61d5448aa2
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_v_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_v_ogm.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
+#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/stddef.h>
|
||||||
|
@@ -116,14 +117,12 @@ static void batadv_v_ogm_send_to_if(stru
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
|
||||||
|
- * @work: work queue item
|
||||||
|
+ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
*/
|
||||||
|
-static void batadv_v_ogm_send(struct work_struct *work)
|
||||||
|
+static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
struct batadv_hard_iface *hard_iface;
|
||||||
|
- struct batadv_priv_bat_v *bat_v;
|
||||||
|
- struct batadv_priv *bat_priv;
|
||||||
|
struct batadv_ogm2_packet *ogm_packet;
|
||||||
|
struct sk_buff *skb, *skb_tmp;
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
@@ -131,8 +130,7 @@ static void batadv_v_ogm_send(struct wor
|
||||||
|
u16 tvlv_len = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
|
||||||
|
- bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
|
||||||
|
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||||
|
goto out;
|
||||||
|
@@ -224,6 +222,22 @@ out:
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
|
||||||
|
+ * @work: work queue item
|
||||||
|
+ */
|
||||||
|
+static void batadv_v_ogm_send(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct batadv_priv_bat_v *bat_v;
|
||||||
|
+ struct batadv_priv *bat_priv;
|
||||||
|
+
|
||||||
|
+ rtnl_lock();
|
||||||
|
+ bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
|
||||||
|
+ bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
|
||||||
|
+ batadv_v_ogm_send_softif(bat_priv);
|
||||||
|
+ rtnl_unlock();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
* batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V
|
||||||
|
* @hard_iface: the interface to prepare
|
||||||
|
*
|
||||||
|
@@ -249,6 +263,8 @@ void batadv_v_ogm_primary_iface_set(stru
|
||||||
|
struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
|
||||||
|
struct batadv_ogm2_packet *ogm_packet;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
if (!bat_priv->bat_v.ogm_buff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -857,6 +873,8 @@ int batadv_v_ogm_init(struct batadv_priv
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
u32 random_seqno;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
|
||||||
|
ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
|
||||||
|
if (!ogm_buff)
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -1477,10 +1477,10 @@ struct batadv_softif_vlan {
|
||||||
|
* struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
|
||||||
|
*/
|
||||||
|
struct batadv_priv_bat_v {
|
||||||
|
- /** @ogm_buff: buffer holding the OGM packet */
|
||||||
|
+ /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
|
||||||
|
- /** @ogm_buff_len: length of the OGM packet buffer */
|
||||||
|
+ /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
|
||||||
|
int ogm_buff_len;
|
||||||
|
|
||||||
|
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
|
@ -0,0 +1,39 @@
|
||||||
|
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
|
||||||
|
Date: Mon, 5 Apr 2021 19:16:50 +0900
|
||||||
|
Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field
|
||||||
|
|
||||||
|
KMSAN found uninitialized value at batadv_tt_prepare_tvlv_local_data()
|
||||||
|
[1], for commit ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16
|
||||||
|
in TT code") inserted 'reserved' field into "struct batadv_tvlv_tt_data"
|
||||||
|
and commit 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN
|
||||||
|
specific") moved that field to "struct batadv_tvlv_tt_vlan_data" but left
|
||||||
|
that field uninitialized.
|
||||||
|
|
||||||
|
[1] https://syzkaller.appspot.com/bug?id=07f3e6dba96f0eb3cabab986adcd8a58b9bdbe9d
|
||||||
|
|
||||||
|
Reported-by: syzbot <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
|
||||||
|
Tested-by: syzbot <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
|
||||||
|
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
|
||||||
|
Fixes: c5e7a06a2961 ("batman-adv: use CRC32C instead of CRC16 in TT code")
|
||||||
|
Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fe8bf38f47a0c1a0e53c487228e3f5a44c86939f
|
||||||
|
|
||||||
|
--- a/net/batman-adv/translation-table.c
|
||||||
|
+++ b/net/batman-adv/translation-table.c
|
||||||
|
@@ -891,6 +891,7 @@ batadv_tt_prepare_tvlv_global_data(struc
|
||||||
|
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
|
||||||
|
tt_vlan->vid = htons(vlan->vid);
|
||||||
|
tt_vlan->crc = htonl(vlan->tt.crc);
|
||||||
|
+ tt_vlan->reserved = 0;
|
||||||
|
|
||||||
|
tt_vlan++;
|
||||||
|
}
|
||||||
|
@@ -974,6 +975,7 @@ batadv_tt_prepare_tvlv_local_data(struct
|
||||||
|
|
||||||
|
tt_vlan->vid = htons(vlan->vid);
|
||||||
|
tt_vlan->crc = htonl(vlan->tt.crc);
|
||||||
|
+ tt_vlan->reserved = 0;
|
||||||
|
|
||||||
|
tt_vlan++;
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 3 Oct 2019 17:02:01 +0200
|
||||||
|
Subject: batman-adv: Avoid free/alloc race when handling OGM buffer
|
||||||
|
|
||||||
|
Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM
|
||||||
|
packet buffer which is initialized using data from the RTNL lock protected
|
||||||
|
netdevice notifier and other rtnetlink related hooks. It is sent regularly
|
||||||
|
via various slave interfaces of the batadv virtual interface and in this
|
||||||
|
process also modified (realloced) to integrate additional state information
|
||||||
|
via TVLV containers.
|
||||||
|
|
||||||
|
It must be avoided that the worker item is executed without a common lock
|
||||||
|
with the netdevice notifier/rtnetlink helpers. Otherwise it can either
|
||||||
|
happen that half modified/freed data is sent out or functions modifying the
|
||||||
|
OGM buffer try to access already freed memory regions.
|
||||||
|
|
||||||
|
Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com
|
||||||
|
Fixes: ea6f8d42a595 ("batman-adv: move /proc interface handling to /sys")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b8ceef26c697d0c8319748428944c3339a498dc
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -29,6 +29,7 @@
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
+#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
@@ -193,6 +194,8 @@ static int batadv_iv_ogm_iface_enable(st
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
u32 random_seqno;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
/* randomize initial seqno to avoid collision */
|
||||||
|
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
||||||
|
atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
|
||||||
|
@@ -217,6 +220,8 @@ static int batadv_iv_ogm_iface_enable(st
|
||||||
|
|
||||||
|
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
kfree(hard_iface->bat_iv.ogm_buff);
|
||||||
|
hard_iface->bat_iv.ogm_buff = NULL;
|
||||||
|
}
|
||||||
|
@@ -226,6 +231,8 @@ static void batadv_iv_ogm_iface_update_m
|
||||||
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
|
ether_addr_copy(batadv_ogm_packet->orig,
|
||||||
|
hard_iface->net_dev->dev_addr);
|
||||||
|
@@ -239,6 +246,8 @@ batadv_iv_ogm_primary_iface_set(struct b
|
||||||
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
|
batadv_ogm_packet->ttl = BATADV_TTL;
|
||||||
|
}
|
||||||
|
@@ -753,6 +762,8 @@ static void batadv_iv_ogm_schedule(struc
|
||||||
|
u16 tvlv_len = 0;
|
||||||
|
unsigned long send_time;
|
||||||
|
|
||||||
|
+ ASSERT_RTNL();
|
||||||
|
+
|
||||||
|
if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
|
||||||
|
hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
|
||||||
|
return;
|
||||||
|
@@ -1643,16 +1654,12 @@ static void batadv_iv_ogm_process(const
|
||||||
|
batadv_orig_node_put(orig_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
|
||||||
|
+static void
|
||||||
|
+batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet)
|
||||||
|
{
|
||||||
|
- struct delayed_work *delayed_work;
|
||||||
|
- struct batadv_forw_packet *forw_packet;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
bool dropped = false;
|
||||||
|
|
||||||
|
- delayed_work = to_delayed_work(work);
|
||||||
|
- forw_packet = container_of(delayed_work, struct batadv_forw_packet,
|
||||||
|
- delayed_work);
|
||||||
|
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
|
||||||
|
|
||||||
|
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||||
|
@@ -1681,6 +1688,20 @@ out:
|
||||||
|
batadv_forw_packet_free(forw_packet, dropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct delayed_work *delayed_work;
|
||||||
|
+ struct batadv_forw_packet *forw_packet;
|
||||||
|
+
|
||||||
|
+ delayed_work = to_delayed_work(work);
|
||||||
|
+ forw_packet = container_of(delayed_work, struct batadv_forw_packet,
|
||||||
|
+ delayed_work);
|
||||||
|
+
|
||||||
|
+ rtnl_lock();
|
||||||
|
+ batadv_iv_send_outstanding_forw_packet(forw_packet);
|
||||||
|
+ rtnl_unlock();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int batadv_iv_ogm_receive(struct sk_buff *skb,
|
||||||
|
struct batadv_hard_iface *if_incoming)
|
||||||
|
{
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -71,10 +71,10 @@ enum batadv_dhcp_recipient {
|
||||||
|
* struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data
|
||||||
|
*/
|
||||||
|
struct batadv_hard_iface_bat_iv {
|
||||||
|
- /** @ogm_buff: buffer holding the OGM packet */
|
||||||
|
+ /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
|
||||||
|
- /** @ogm_buff_len: length of the OGM packet buffer */
|
||||||
|
+ /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
|
||||||
|
int ogm_buff_len;
|
||||||
|
|
||||||
|
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
|
@ -0,0 +1,134 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sun, 13 Oct 2019 21:03:06 +0200
|
||||||
|
Subject: batman-adv: Introduce own OGM2 buffer mutex
|
||||||
|
|
||||||
|
Only a single function is currently automatically locked by the rtnl_lock
|
||||||
|
because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard
|
||||||
|
interfaces on which it will be transmitted. A private mutex can be used
|
||||||
|
instead to avoid unnecessary delays which would have been introduced by the
|
||||||
|
global lock.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_v_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_v_ogm.c
|
||||||
|
@@ -17,11 +17,12 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kref.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
+#include <linux/lockdep.h>
|
||||||
|
+#include <linux/mutex.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
-#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/stddef.h>
|
||||||
|
@@ -130,7 +131,7 @@ static void batadv_v_ogm_send_softif(str
|
||||||
|
u16 tvlv_len = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
+ lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
|
||||||
|
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||||
|
goto out;
|
||||||
|
@@ -230,11 +231,12 @@ static void batadv_v_ogm_send(struct wor
|
||||||
|
struct batadv_priv_bat_v *bat_v;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
|
||||||
|
- rtnl_lock();
|
||||||
|
bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
|
||||||
|
bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
|
||||||
|
+
|
||||||
|
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
batadv_v_ogm_send_softif(bat_priv);
|
||||||
|
- rtnl_unlock();
|
||||||
|
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -263,13 +265,15 @@ void batadv_v_ogm_primary_iface_set(stru
|
||||||
|
struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
|
||||||
|
struct batadv_ogm2_packet *ogm_packet;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
-
|
||||||
|
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
if (!bat_priv->bat_v.ogm_buff)
|
||||||
|
- return;
|
||||||
|
+ goto unlock;
|
||||||
|
|
||||||
|
ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
|
||||||
|
ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
|
||||||
|
+
|
||||||
|
+unlock:
|
||||||
|
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -873,8 +877,6 @@ int batadv_v_ogm_init(struct batadv_priv
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
u32 random_seqno;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
-
|
||||||
|
bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
|
||||||
|
ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
|
||||||
|
if (!ogm_buff)
|
||||||
|
@@ -893,6 +895,8 @@ int batadv_v_ogm_init(struct batadv_priv
|
||||||
|
atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
|
||||||
|
INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
|
||||||
|
|
||||||
|
+ mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -904,7 +908,11 @@ void batadv_v_ogm_free(struct batadv_pri
|
||||||
|
{
|
||||||
|
cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
|
||||||
|
|
||||||
|
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
+
|
||||||
|
kfree(bat_priv->bat_v.ogm_buff);
|
||||||
|
bat_priv->bat_v.ogm_buff = NULL;
|
||||||
|
bat_priv->bat_v.ogm_buff_len = 0;
|
||||||
|
+
|
||||||
|
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/kref.h>
|
||||||
|
+#include <linux/mutex.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/sched.h> /* for linux/wait.h */
|
||||||
|
@@ -1477,15 +1478,18 @@ struct batadv_softif_vlan {
|
||||||
|
* struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
|
||||||
|
*/
|
||||||
|
struct batadv_priv_bat_v {
|
||||||
|
- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
|
||||||
|
+ /** @ogm_buff: buffer holding the OGM packet */
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
|
||||||
|
- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
|
||||||
|
+ /** @ogm_buff_len: length of the OGM packet buffer */
|
||||||
|
int ogm_buff_len;
|
||||||
|
|
||||||
|
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
||||||
|
atomic_t ogm_seqno;
|
||||||
|
|
||||||
|
+ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
|
||||||
|
+ struct mutex ogm_buff_mutex;
|
||||||
|
+
|
||||||
|
/** @ogm_wq: workqueue used to schedule OGM transmissions */
|
||||||
|
struct delayed_work ogm_wq;
|
||||||
|
};
|
|
@ -0,0 +1,257 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sun, 13 Oct 2019 21:03:07 +0200
|
||||||
|
Subject: batman-adv: Avoid OGM workqueue synchronous cancel deadlock
|
||||||
|
|
||||||
|
batadv_forw_packet_list_free can be called when an interface is being
|
||||||
|
disabled. Under this circumstance, the rntl_lock will be held and while it
|
||||||
|
calls cancel_delayed_work_sync.
|
||||||
|
|
||||||
|
cancel_delayed_work_sync will stop the execution of the current context
|
||||||
|
when the work item is currently processed. It can now happen that the
|
||||||
|
cancel_delayed_work_sync was called when rtnl_lock was already called in
|
||||||
|
batadv_iv_send_outstanding_bat_ogm_packet or when it was in the process of
|
||||||
|
calling it. In this case, batadv_iv_send_outstanding_bat_ogm_packet waits
|
||||||
|
for the lock and cancel_delayed_work_sync (which holds the rtnl_lock) is
|
||||||
|
waiting for batadv_iv_send_outstanding_bat_ogm_packet to finish.
|
||||||
|
|
||||||
|
This can only be avoided by not using (conflicting) blocking locks while
|
||||||
|
cancel_delayed_work_sync is called. It also has the benefit that the
|
||||||
|
ogm scheduling functionality can avoid unnecessary delays which can be
|
||||||
|
introduced by a global lock.
|
||||||
|
|
||||||
|
Fixes: 9b8ceef26c69 ("batman-adv: Avoid free/alloc race when handling OGM buffer")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d3be478f1aa27b47f61c4a62e18eb063d47c9168
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -22,6 +22,8 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kref.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
+#include <linux/lockdep.h>
|
||||||
|
+#include <linux/mutex.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/pkt_sched.h>
|
||||||
|
@@ -29,7 +31,6 @@
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
-#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
@@ -194,7 +195,7 @@ static int batadv_iv_ogm_iface_enable(st
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
u32 random_seqno;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
/* randomize initial seqno to avoid collision */
|
||||||
|
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
||||||
|
@@ -202,8 +203,10 @@ static int batadv_iv_ogm_iface_enable(st
|
||||||
|
|
||||||
|
hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
|
||||||
|
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
|
||||||
|
- if (!ogm_buff)
|
||||||
|
+ if (!ogm_buff) {
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
hard_iface->bat_iv.ogm_buff = ogm_buff;
|
||||||
|
|
||||||
|
@@ -215,41 +218,59 @@ static int batadv_iv_ogm_iface_enable(st
|
||||||
|
batadv_ogm_packet->reserved = 0;
|
||||||
|
batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
|
||||||
|
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
kfree(hard_iface->bat_iv.ogm_buff);
|
||||||
|
hard_iface->bat_iv.ogm_buff = NULL;
|
||||||
|
+
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
+ void *ogm_buff;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
|
+ ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
+ if (!ogm_buff)
|
||||||
|
+ goto unlock;
|
||||||
|
+
|
||||||
|
+ batadv_ogm_packet = ogm_buff;
|
||||||
|
ether_addr_copy(batadv_ogm_packet->orig,
|
||||||
|
hard_iface->net_dev->dev_addr);
|
||||||
|
ether_addr_copy(batadv_ogm_packet->prev_sender,
|
||||||
|
hard_iface->net_dev->dev_addr);
|
||||||
|
+
|
||||||
|
+unlock:
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
+ void *ogm_buff;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
|
+ ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
+ if (!ogm_buff)
|
||||||
|
+ goto unlock;
|
||||||
|
+
|
||||||
|
+ batadv_ogm_packet = ogm_buff;
|
||||||
|
batadv_ogm_packet->ttl = BATADV_TTL;
|
||||||
|
+
|
||||||
|
+unlock:
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when do we schedule our own ogm to be sent */
|
||||||
|
@@ -751,7 +772,11 @@ batadv_iv_ogm_slide_own_bcast_window(str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
||||||
|
+/**
|
||||||
|
+ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
|
||||||
|
+ * @hard_iface: interface whose ogm buffer should be transmitted
|
||||||
|
+ */
|
||||||
|
+static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
||||||
|
{
|
||||||
|
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||||
|
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
|
||||||
|
@@ -762,11 +787,7 @@ static void batadv_iv_ogm_schedule(struc
|
||||||
|
u16 tvlv_len = 0;
|
||||||
|
unsigned long send_time;
|
||||||
|
|
||||||
|
- ASSERT_RTNL();
|
||||||
|
-
|
||||||
|
- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
|
||||||
|
- hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
|
||||||
|
- return;
|
||||||
|
+ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
/* the interface gets activated here to avoid race conditions between
|
||||||
|
* the moment of activating the interface in
|
||||||
|
@@ -834,6 +855,17 @@ out:
|
||||||
|
batadv_hardif_put(primary_if);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
||||||
|
+{
|
||||||
|
+ if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
|
||||||
|
+ hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
+ batadv_iv_ogm_schedule_buff(hard_iface);
|
||||||
|
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface
|
||||||
|
* @orig_node: originator which reproadcasted the OGMs directly
|
||||||
|
@@ -1654,12 +1686,16 @@ static void batadv_iv_ogm_process(const
|
||||||
|
batadv_orig_node_put(orig_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet)
|
||||||
|
+static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
|
||||||
|
{
|
||||||
|
+ struct delayed_work *delayed_work;
|
||||||
|
+ struct batadv_forw_packet *forw_packet;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
bool dropped = false;
|
||||||
|
|
||||||
|
+ delayed_work = to_delayed_work(work);
|
||||||
|
+ forw_packet = container_of(delayed_work, struct batadv_forw_packet,
|
||||||
|
+ delayed_work);
|
||||||
|
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
|
||||||
|
|
||||||
|
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||||
|
@@ -1688,20 +1724,6 @@ out:
|
||||||
|
batadv_forw_packet_free(forw_packet, dropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
|
||||||
|
-{
|
||||||
|
- struct delayed_work *delayed_work;
|
||||||
|
- struct batadv_forw_packet *forw_packet;
|
||||||
|
-
|
||||||
|
- delayed_work = to_delayed_work(work);
|
||||||
|
- forw_packet = container_of(delayed_work, struct batadv_forw_packet,
|
||||||
|
- delayed_work);
|
||||||
|
-
|
||||||
|
- rtnl_lock();
|
||||||
|
- batadv_iv_send_outstanding_forw_packet(forw_packet);
|
||||||
|
- rtnl_unlock();
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int batadv_iv_ogm_receive(struct sk_buff *skb,
|
||||||
|
struct batadv_hard_iface *if_incoming)
|
||||||
|
{
|
||||||
|
--- a/net/batman-adv/hard-interface.c
|
||||||
|
+++ b/net/batman-adv/hard-interface.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kref.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
+#include <linux/mutex.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/printk.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
@@ -930,6 +931,7 @@ batadv_hardif_add_interface(struct net_d
|
||||||
|
INIT_LIST_HEAD(&hard_iface->list);
|
||||||
|
INIT_HLIST_HEAD(&hard_iface->neigh_list);
|
||||||
|
|
||||||
|
+ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
spin_lock_init(&hard_iface->neigh_list_lock);
|
||||||
|
kref_init(&hard_iface->refcount);
|
||||||
|
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -72,14 +72,17 @@ enum batadv_dhcp_recipient {
|
||||||
|
* struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data
|
||||||
|
*/
|
||||||
|
struct batadv_hard_iface_bat_iv {
|
||||||
|
- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
|
||||||
|
+ /** @ogm_buff: buffer holding the OGM packet */
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
|
||||||
|
- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
|
||||||
|
+ /** @ogm_buff_len: length of the OGM packet buffer */
|
||||||
|
int ogm_buff_len;
|
||||||
|
|
||||||
|
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
||||||
|
atomic_t ogm_seqno;
|
||||||
|
+
|
||||||
|
+ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
|
||||||
|
+ struct mutex ogm_buff_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
|
@ -0,0 +1,41 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 28 Nov 2019 12:43:49 +0100
|
||||||
|
Subject: batman-adv: Fix DAT candidate selection on little endian systems
|
||||||
|
|
||||||
|
The distributed arp table is using a DHT to store and retrieve MAC address
|
||||||
|
information for an IP address. This is done using unicast messages to
|
||||||
|
selected peers. The potential peers are looked up using the IP address and
|
||||||
|
the VID.
|
||||||
|
|
||||||
|
While the IP address is always stored in big endian byte order, it is not
|
||||||
|
the case of the VID. It can (depending on the host system) either be big
|
||||||
|
endian or little endian. The host must therefore always convert it to big
|
||||||
|
endian to ensure that all devices calculate the same peers for the same
|
||||||
|
lookup data.
|
||||||
|
|
||||||
|
Fixes: 3e26722bc9f2 ("batman-adv: make the Distributed ARP Table vlan aware")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Antonio Quartulli <a@unstable.cc>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/728aea06f38e0e4d70f4f7d43698187f7f7055c5
|
||||||
|
|
||||||
|
--- a/net/batman-adv/distributed-arp-table.c
|
||||||
|
+++ b/net/batman-adv/distributed-arp-table.c
|
||||||
|
@@ -285,6 +285,7 @@ static u32 batadv_hash_dat(const void *d
|
||||||
|
u32 hash = 0;
|
||||||
|
const struct batadv_dat_entry *dat = data;
|
||||||
|
const unsigned char *key;
|
||||||
|
+ __be16 vid;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
key = (const unsigned char *)&dat->ip;
|
||||||
|
@@ -294,7 +295,8 @@ static u32 batadv_hash_dat(const void *d
|
||||||
|
hash ^= (hash >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
- key = (const unsigned char *)&dat->vid;
|
||||||
|
+ vid = htons(dat->vid);
|
||||||
|
+ key = (__force const unsigned char *)&vid;
|
||||||
|
for (i = 0; i < sizeof(dat->vid); i++) {
|
||||||
|
hash += key[i];
|
||||||
|
hash += (hash << 10);
|
|
@ -0,0 +1,35 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sun, 16 Feb 2020 13:02:06 +0100
|
||||||
|
Subject: batman-adv: Don't schedule OGM for disabled interface
|
||||||
|
|
||||||
|
A transmission scheduling for an interface which is currently dropped by
|
||||||
|
batadv_iv_ogm_iface_disable could still be in progress. The B.A.T.M.A.N. V
|
||||||
|
is simply cancelling the workqueue item in an synchronous way but this is
|
||||||
|
not possible with B.A.T.M.A.N. IV because the OGM submissions are
|
||||||
|
intertwined.
|
||||||
|
|
||||||
|
Instead it has to stop submitting the OGM when it detect that the buffer
|
||||||
|
pointer is set to NULL.
|
||||||
|
|
||||||
|
Reported-by: syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com
|
||||||
|
Reported-by: syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com
|
||||||
|
Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Cc: Hillf Danton <hdanton@sina.com>
|
||||||
|
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/a089c55ca004b396d340baae58abe9a79f32cc0f
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -789,6 +789,10 @@ static void batadv_iv_ogm_schedule_buff(
|
||||||
|
|
||||||
|
lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||||
|
|
||||||
|
+ /* interface already disabled by batadv_iv_ogm_iface_disable */
|
||||||
|
+ if (!*ogm_buff)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
/* the interface gets activated here to avoid race conditions between
|
||||||
|
* the moment of activating the interface in
|
||||||
|
* hardif_activate_interface() where the originator mac is set and
|
|
@ -0,0 +1,57 @@
|
||||||
|
From: George Spelvin <lkml@sdf.org>
|
||||||
|
Date: Sun, 8 Mar 2020 09:44:59 -0400
|
||||||
|
Subject: batman-adv: fix batadv_nc_random_weight_tq
|
||||||
|
|
||||||
|
and change to pseudorandom numbers, as this is a traffic dithering
|
||||||
|
operation that doesn't need crypto-grade.
|
||||||
|
|
||||||
|
The previous code operated in 4 steps:
|
||||||
|
|
||||||
|
1. Generate a random byte 0 <= rand_tq <= 255
|
||||||
|
2. Multiply it by BATADV_TQ_MAX_VALUE - tq
|
||||||
|
3. Divide by 255 (= BATADV_TQ_MAX_VALUE)
|
||||||
|
4. Return BATADV_TQ_MAX_VALUE - rand_tq
|
||||||
|
|
||||||
|
This would apperar to scale (BATADV_TQ_MAX_VALUE - tq) by a random
|
||||||
|
value between 0/255 and 255/255.
|
||||||
|
|
||||||
|
But! The intermediate value between steps 3 and 4 is stored in a u8
|
||||||
|
variable. So it's truncated, and most of the time, is less than 255, after
|
||||||
|
which the division produces 0. Specifically, if tq is odd, the product is
|
||||||
|
always even, and can never be 255. If tq is even, there's exactly one
|
||||||
|
random byte value that will produce a product byte of 255.
|
||||||
|
|
||||||
|
Thus, the return value is 255 (511/512 of the time) or 254 (1/512
|
||||||
|
of the time).
|
||||||
|
|
||||||
|
If we assume that the truncation is a bug, and the code is meant to scale
|
||||||
|
the input, a simpler way of looking at it is that it's returning a random
|
||||||
|
value between tq and BATADV_TQ_MAX_VALUE, inclusive.
|
||||||
|
|
||||||
|
Well, we have an optimized function for doing just that.
|
||||||
|
|
||||||
|
Fixes: c3289f3650d3 ("batman-adv: network coding - code and transmit packets if possible")
|
||||||
|
Signed-off-by: George Spelvin <lkml@sdf.org>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/db48c60b0edb995450ee846157364bd09bb23762
|
||||||
|
|
||||||
|
--- a/net/batman-adv/network-coding.c
|
||||||
|
+++ b/net/batman-adv/network-coding.c
|
||||||
|
@@ -1009,15 +1009,8 @@ static struct batadv_nc_path *batadv_nc_
|
||||||
|
*/
|
||||||
|
static u8 batadv_nc_random_weight_tq(u8 tq)
|
||||||
|
{
|
||||||
|
- u8 rand_val, rand_tq;
|
||||||
|
-
|
||||||
|
- get_random_bytes(&rand_val, sizeof(rand_val));
|
||||||
|
-
|
||||||
|
/* randomize the estimated packet loss (max TQ - estimated TQ) */
|
||||||
|
- rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq);
|
||||||
|
-
|
||||||
|
- /* normalize the randomized packet loss */
|
||||||
|
- rand_tq /= BATADV_TQ_MAX_VALUE;
|
||||||
|
+ u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq);
|
||||||
|
|
||||||
|
/* convert to (randomized) estimated tq again */
|
||||||
|
return BATADV_TQ_MAX_VALUE - rand_tq;
|
|
@ -0,0 +1,36 @@
|
||||||
|
From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Date: Wed, 15 Apr 2020 16:31:50 +0800
|
||||||
|
Subject: batman-adv: Fix refcnt leak in batadv_show_throughput_override
|
||||||
|
|
||||||
|
batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(),
|
||||||
|
which gets a batadv_hard_iface object from net_dev with increased refcnt
|
||||||
|
and its reference is assigned to a local pointer 'hard_iface'.
|
||||||
|
|
||||||
|
When batadv_show_throughput_override() returns, "hard_iface" becomes
|
||||||
|
invalid, so the refcount should be decreased to keep refcount balanced.
|
||||||
|
|
||||||
|
The issue happens in the normal path of
|
||||||
|
batadv_show_throughput_override(), which forgets to decrease the refcnt
|
||||||
|
increased by batadv_hardif_get_by_netdev() before the function returns,
|
||||||
|
causing a refcnt leak.
|
||||||
|
|
||||||
|
Fix this issue by calling batadv_hardif_put() before the
|
||||||
|
batadv_show_throughput_override() returns in the normal path.
|
||||||
|
|
||||||
|
Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
|
||||||
|
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f301bfed59b146a63471d0f147b767d7cafede6f
|
||||||
|
|
||||||
|
--- a/net/batman-adv/sysfs.c
|
||||||
|
+++ b/net/batman-adv/sysfs.c
|
||||||
|
@@ -1189,6 +1189,7 @@ static ssize_t batadv_show_throughput_ov
|
||||||
|
|
||||||
|
tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
|
||||||
|
|
||||||
|
+ batadv_hardif_put(hard_iface);
|
||||||
|
return sprintf(buff, "%u.%u MBit\n", tp_override / 10,
|
||||||
|
tp_override % 10);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Date: Wed, 15 Apr 2020 16:35:21 +0800
|
||||||
|
Subject: batman-adv: Fix refcnt leak in batadv_store_throughput_override
|
||||||
|
|
||||||
|
batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(),
|
||||||
|
which gets a batadv_hard_iface object from net_dev with increased refcnt
|
||||||
|
and its reference is assigned to a local pointer 'hard_iface'.
|
||||||
|
|
||||||
|
When batadv_store_throughput_override() returns, "hard_iface" becomes
|
||||||
|
invalid, so the refcount should be decreased to keep refcount balanced.
|
||||||
|
|
||||||
|
The issue happens in one error path of
|
||||||
|
batadv_store_throughput_override(). When batadv_parse_throughput()
|
||||||
|
returns NULL, the refcnt increased by batadv_hardif_get_by_netdev() is
|
||||||
|
not decreased, causing a refcnt leak.
|
||||||
|
|
||||||
|
Fix this issue by jumping to "out" label when batadv_parse_throughput()
|
||||||
|
returns NULL.
|
||||||
|
|
||||||
|
Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
|
||||||
|
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/b69cd8bdbfd6fa7e61878c2fa9e6637406f40dd9
|
||||||
|
|
||||||
|
--- a/net/batman-adv/sysfs.c
|
||||||
|
+++ b/net/batman-adv/sysfs.c
|
||||||
|
@@ -1149,7 +1149,7 @@ static ssize_t batadv_store_throughput_o
|
||||||
|
ret = batadv_parse_throughput(net_dev, buff, "throughput_override",
|
||||||
|
&tp_override);
|
||||||
|
if (!ret)
|
||||||
|
- return count;
|
||||||
|
+ goto out;
|
||||||
|
|
||||||
|
old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
|
||||||
|
if (old_tp_override == tp_override)
|
|
@ -0,0 +1,37 @@
|
||||||
|
From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Date: Mon, 20 Apr 2020 13:37:20 +0800
|
||||||
|
Subject: batman-adv: Fix refcnt leak in batadv_v_ogm_process
|
||||||
|
|
||||||
|
batadv_v_ogm_process() invokes batadv_hardif_neigh_get(), which returns
|
||||||
|
a reference of the neighbor object to "hardif_neigh" with increased
|
||||||
|
refcount.
|
||||||
|
|
||||||
|
When batadv_v_ogm_process() returns, "hardif_neigh" becomes invalid, so
|
||||||
|
the refcount should be decreased to keep refcount balanced.
|
||||||
|
|
||||||
|
The reference counting issue happens in one exception handling paths of
|
||||||
|
batadv_v_ogm_process(). When batadv_v_ogm_orig_get() fails to get the
|
||||||
|
orig node and returns NULL, the refcnt increased by
|
||||||
|
batadv_hardif_neigh_get() is not decreased, causing a refcnt leak.
|
||||||
|
|
||||||
|
Fix this issue by jumping to "out" label when batadv_v_ogm_orig_get()
|
||||||
|
fails to get the orig node.
|
||||||
|
|
||||||
|
Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic")
|
||||||
|
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
|
||||||
|
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/4515f5e6a4ccbe1c563b05f2d487eb9eef3c9740
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_v_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_v_ogm.c
|
||||||
|
@@ -723,7 +723,7 @@ static void batadv_v_ogm_process(const s
|
||||||
|
|
||||||
|
orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
|
||||||
|
if (!orig_node)
|
||||||
|
- return;
|
||||||
|
+ goto out;
|
||||||
|
|
||||||
|
neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
|
||||||
|
ethhdr->h_source);
|
|
@ -0,0 +1,72 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 25 Nov 2019 10:46:50 +0100
|
||||||
|
Subject: batman-adv: Revert "disable ethtool link speed detection when auto negotiation off"
|
||||||
|
|
||||||
|
The commit d60b8fc69ef2 ("batman-adv: disable ethtool link speed detection
|
||||||
|
when auto negotiation off") disabled the usage of ethtool's link_ksetting
|
||||||
|
when auto negotation was enabled due to invalid values when used with
|
||||||
|
tun/tap virtual net_devices. According to the patch, automatic measurements
|
||||||
|
should be used for these kind of interfaces.
|
||||||
|
|
||||||
|
But there are major flaws with this argumentation:
|
||||||
|
|
||||||
|
* automatic measurements are not implemented
|
||||||
|
* auto negotiation has nothing to do with the validity of the retrieved
|
||||||
|
values
|
||||||
|
|
||||||
|
The first point has to be fixed by a longer patch series. The "validity"
|
||||||
|
part of the second point must be addressed in the same patch series by
|
||||||
|
dropping the usage of ethtool's link_ksetting (thus always doing automatic
|
||||||
|
measurements over ethernet).
|
||||||
|
|
||||||
|
Drop the patch again to have more default values for various net_device
|
||||||
|
types/configurations. The user can still overwrite them using the
|
||||||
|
batadv_hardif's BATADV_ATTR_THROUGHPUT_OVERRIDE.
|
||||||
|
|
||||||
|
Reported-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e860b3d5e4147bafcda32bf9b3e769926f232c5
|
||||||
|
|
||||||
|
--- a/compat-include/linux/ethtool.h
|
||||||
|
+++ b/compat-include/linux/ethtool.h
|
||||||
|
@@ -21,7 +21,6 @@ struct batadv_ethtool_link_ksettings {
|
||||||
|
struct {
|
||||||
|
__u32 speed;
|
||||||
|
__u8 duplex;
|
||||||
|
- __u8 autoneg;
|
||||||
|
} base;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -42,7 +41,6 @@ batadv_ethtool_get_link_ksettings(struct
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
link_ksettings->base.duplex = cmd.duplex;
|
||||||
|
- link_ksettings->base.autoneg = cmd.autoneg;
|
||||||
|
link_ksettings->base.speed = ethtool_cmd_speed(&cmd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
--- a/net/batman-adv/bat_v_elp.c
|
||||||
|
+++ b/net/batman-adv/bat_v_elp.c
|
||||||
|
@@ -120,20 +120,7 @@ static u32 batadv_v_elp_get_throughput(s
|
||||||
|
rtnl_lock();
|
||||||
|
ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings);
|
||||||
|
rtnl_unlock();
|
||||||
|
-
|
||||||
|
- /* Virtual interface drivers such as tun / tap interfaces, VLAN, etc
|
||||||
|
- * tend to initialize the interface throughput with some value for the
|
||||||
|
- * sake of having a throughput number to export via ethtool. This
|
||||||
|
- * exported throughput leaves batman-adv to conclude the interface
|
||||||
|
- * throughput is genuine (reflecting reality), thus no measurements
|
||||||
|
- * are necessary.
|
||||||
|
- *
|
||||||
|
- * Based on the observation that those interface types also tend to set
|
||||||
|
- * the link auto-negotiation to 'off', batman-adv shall check this
|
||||||
|
- * setting to differentiate between genuine link throughput information
|
||||||
|
- * and placeholders installed by virtual interfaces.
|
||||||
|
- */
|
||||||
|
- if (ret == 0 && link_settings.base.autoneg == AUTONEG_ENABLE) {
|
||||||
|
+ if (ret == 0) {
|
||||||
|
/* link characteristics might change over time */
|
||||||
|
if (link_settings.base.duplex == DUPLEX_FULL)
|
||||||
|
hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
|
|
@ -0,0 +1,40 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 22 Jul 2020 20:49:23 +0200
|
||||||
|
Subject: batman-adv: Avoid uninitialized chaddr when handling DHCP
|
||||||
|
|
||||||
|
The gateway client code can try to optimize the delivery of DHCP packets to
|
||||||
|
avoid broadcasting them through the whole mesh. But also transmissions to
|
||||||
|
the client can be optimized by looking up the destination via the chaddr of
|
||||||
|
the DHCP packet.
|
||||||
|
|
||||||
|
But the chaddr is currently only done when chaddr is fully inside the
|
||||||
|
non-paged area of the skbuff. Otherwise it will not be initialized and the
|
||||||
|
unoptimized path should have been taken.
|
||||||
|
|
||||||
|
But the implementation didn't handle this correctly. It didn't retrieve the
|
||||||
|
correct chaddr but still tried to perform the TT lookup with this
|
||||||
|
uninitialized memory.
|
||||||
|
|
||||||
|
Reported-by: syzbot+ab16e463b903f5a37036@syzkaller.appspotmail.com
|
||||||
|
Fixes: 2d5b555644b2 ("batman-adv: send every DHCP packet as bat-unicast")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Antonio Quartulli <a@unstable.cc>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fcdf008ffd749246632d1f9423163af5dc3f8c7f
|
||||||
|
|
||||||
|
--- a/net/batman-adv/gateway_client.c
|
||||||
|
+++ b/net/batman-adv/gateway_client.c
|
||||||
|
@@ -703,8 +703,10 @@ batadv_gw_dhcp_recipient_get(struct sk_b
|
||||||
|
|
||||||
|
chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET;
|
||||||
|
/* store the client address if the message is going to a client */
|
||||||
|
- if (ret == BATADV_DHCP_TO_CLIENT &&
|
||||||
|
- pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) {
|
||||||
|
+ if (ret == BATADV_DHCP_TO_CLIENT) {
|
||||||
|
+ if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN))
|
||||||
|
+ return BATADV_DHCP_NO;
|
||||||
|
+
|
||||||
|
/* check if the DHCP packet carries an Ethernet DHCP */
|
||||||
|
p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET;
|
||||||
|
if (*p != BATADV_DHCP_HTYPE_ETHERNET)
|
|
@ -0,0 +1,57 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Fri, 31 Jul 2020 00:22:55 +0200
|
||||||
|
Subject: batman-adv: Fix own OGM check in aggregated OGMs
|
||||||
|
|
||||||
|
The own OGM check is currently misplaced and can lead to the following
|
||||||
|
issues:
|
||||||
|
|
||||||
|
For one thing we might receive an aggregated OGM from a neighbor node
|
||||||
|
which has our own OGM in the first place. We would then not only skip
|
||||||
|
our own OGM but erroneously also any other, following OGM in the
|
||||||
|
aggregate.
|
||||||
|
|
||||||
|
For another, we might receive an OGM aggregate which has our own OGM in
|
||||||
|
a place other then the first one. Then we would wrongly not skip this
|
||||||
|
OGM, leading to populating the orginator and gateway table with ourself.
|
||||||
|
|
||||||
|
The latter seems to not only be a cosmetic issue, but there were reports
|
||||||
|
that this causes issues with various subsystems of batman-adv, too. For
|
||||||
|
instance there were reports about issues with DAT and either disabling
|
||||||
|
DAT or aggregation seemed to solve it.
|
||||||
|
|
||||||
|
Fixing these issues by applying the own OGM check not on the first OGM
|
||||||
|
in an aggregate but for each OGM in an aggregate instead.
|
||||||
|
|
||||||
|
Fixes: 667996ebeab ("batman-adv: OGMv2 - implement originators logic")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d41cc7cb62c184b2fb8ab97fda45815918200001
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_v_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_v_ogm.c
|
||||||
|
@@ -704,6 +704,12 @@ static void batadv_v_ogm_process(const s
|
||||||
|
ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl,
|
||||||
|
ogm_packet->version, ntohs(ogm_packet->tvlv_len));
|
||||||
|
|
||||||
|
+ if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) {
|
||||||
|
+ batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||||
|
+ "Drop packet: originator packet from ourself\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* If the throughput metric is 0, immediately drop the packet. No need
|
||||||
|
* to create orig_node / neigh_node for an unusable route.
|
||||||
|
*/
|
||||||
|
@@ -831,11 +837,6 @@ int batadv_v_ogm_packet_recv(struct sk_b
|
||||||
|
if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
|
||||||
|
goto free_skb;
|
||||||
|
|
||||||
|
- ogm_packet = (struct batadv_ogm2_packet *)skb->data;
|
||||||
|
-
|
||||||
|
- if (batadv_is_my_mac(bat_priv, ogm_packet->orig))
|
||||||
|
- goto free_skb;
|
||||||
|
-
|
||||||
|
batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
|
||||||
|
batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
|
||||||
|
skb->len + ETH_HLEN);
|
|
@ -0,0 +1,29 @@
|
||||||
|
From: Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||||
|
Date: Tue, 18 Aug 2020 17:46:10 +0300
|
||||||
|
Subject: batman-adv: bla: use netif_rx_ni when not in interrupt context
|
||||||
|
|
||||||
|
batadv_bla_send_claim() gets called from worker thread context through
|
||||||
|
batadv_bla_periodic_work(), thus netif_rx_ni needs to be used in that
|
||||||
|
case. This fixes "NOHZ: local_softirq_pending 08" log messages seen
|
||||||
|
when batman-adv is enabled.
|
||||||
|
|
||||||
|
Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code")
|
||||||
|
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3747f81a1380b65740fc52fc71c7a3af4c6e49de
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -437,7 +437,10 @@ static void batadv_bla_send_claim(struct
|
||||||
|
batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
|
||||||
|
skb->len + ETH_HLEN);
|
||||||
|
|
||||||
|
- netif_rx(skb);
|
||||||
|
+ if (in_interrupt())
|
||||||
|
+ netif_rx(skb);
|
||||||
|
+ else
|
||||||
|
+ netif_rx_ni(skb);
|
||||||
|
out:
|
||||||
|
if (primary_if)
|
||||||
|
batadv_hardif_put(primary_if);
|
|
@ -0,0 +1,39 @@
|
||||||
|
From: Linus Lüssing <ll@simonwunderlich.de>
|
||||||
|
Date: Thu, 27 Aug 2020 17:34:48 +0200
|
||||||
|
Subject: batman-adv: bla: fix type misuse for backbone_gw hash indexing
|
||||||
|
|
||||||
|
It seems that due to a copy & paste error the void pointer
|
||||||
|
in batadv_choose_backbone_gw() is cast to the wrong type.
|
||||||
|
|
||||||
|
Fixing this by using "struct batadv_bla_backbone_gw" instead of "struct
|
||||||
|
batadv_bla_claim" which better matches the caller's side.
|
||||||
|
|
||||||
|
For now it seems that we were lucky because the two structs both have
|
||||||
|
their orig/vid and addr/vid in the beginning. However I stumbled over
|
||||||
|
this issue when I was trying to add some debug variables in front of
|
||||||
|
"orig" in batadv_backbone_gw, which caused hash lookups to fail.
|
||||||
|
|
||||||
|
Fixes: 7e15c9305ce0 ("batman-adv: don't rely on positions in struct for hashing")
|
||||||
|
Signed-off-by: Linus Lüssing <ll@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/398a706cd46c1fc085aef56ae8ed11f76e182bd1
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -83,11 +83,12 @@ static inline u32 batadv_choose_claim(co
|
||||||
|
*/
|
||||||
|
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
|
||||||
|
{
|
||||||
|
- const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
|
||||||
|
+ const struct batadv_bla_backbone_gw *gw;
|
||||||
|
u32 hash = 0;
|
||||||
|
|
||||||
|
- hash = jhash(&claim->addr, sizeof(claim->addr), hash);
|
||||||
|
- hash = jhash(&claim->vid, sizeof(claim->vid), hash);
|
||||||
|
+ gw = (struct batadv_bla_backbone_gw *)data;
|
||||||
|
+ hash = jhash(&gw->orig, sizeof(gw->orig), hash);
|
||||||
|
+ hash = jhash(&gw->vid, sizeof(gw->vid), hash);
|
||||||
|
|
||||||
|
return hash % size;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Fri, 4 Sep 2020 20:28:00 +0200
|
||||||
|
Subject: batman-adv: mcast/TT: fix wrongly dropped or rerouted packets
|
||||||
|
|
||||||
|
The unicast packet rerouting code makes several assumptions. For
|
||||||
|
instance it assumes that there is always exactly one destination in the
|
||||||
|
TT. This breaks for multicast frames in a unicast packets in several ways:
|
||||||
|
|
||||||
|
For one thing if there is actually no TT entry and the destination node
|
||||||
|
was selected due to the multicast tvlv flags it announced. Then an
|
||||||
|
intermediate node will wrongly drop the packet.
|
||||||
|
|
||||||
|
For another thing if there is a TT entry but the TTVN of this entry is
|
||||||
|
newer than the originally addressed destination node: Then the
|
||||||
|
intermediate node will wrongly redirect the packet, leading to
|
||||||
|
duplicated multicast packets at a multicast listener and missing
|
||||||
|
packets at other multicast listeners or multicast routers.
|
||||||
|
|
||||||
|
Fixing this by not applying the unicast packet rerouting to batman-adv
|
||||||
|
unicast packets with a multicast payload. We are not able to detect a
|
||||||
|
roaming multicast listener at the moment and will just continue to send
|
||||||
|
the multicast frame to both the new and old destination for a while in
|
||||||
|
case of such a roaming multicast listener.
|
||||||
|
|
||||||
|
Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22e740c5e6c9342e0f5028beb3d14b84a018d113
|
||||||
|
|
||||||
|
--- a/net/batman-adv/routing.c
|
||||||
|
+++ b/net/batman-adv/routing.c
|
||||||
|
@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(st
|
||||||
|
vid = batadv_get_vid(skb, hdr_len);
|
||||||
|
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
|
||||||
|
|
||||||
|
+ /* do not reroute multicast frames in a unicast header */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
/* check if the destination client was served by this node and it is now
|
||||||
|
* roaming. In this case, it means that the node has got a ROAM_ADV
|
||||||
|
* message and that it knows the new destination in the mesh to re-route
|
|
@ -0,0 +1,24 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 14 Sep 2020 13:58:16 +0200
|
||||||
|
Subject: batman-adv: Add missing include for in_interrupt()
|
||||||
|
|
||||||
|
The fix for receiving (internally generated) bla packets outside the
|
||||||
|
interrupt context introduced the usage of in_interrupt(). But this
|
||||||
|
functionality is only defined in linux/preempt.h which was not included
|
||||||
|
with the same patch.
|
||||||
|
|
||||||
|
Fixes: 3747f81a1380 ("batman-adv: bla: use netif_rx_ni when not in interrupt context")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6ea99cd9c82b2d1bc4a313fe9006bcf5d956380e
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
#include <linux/lockdep.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
+#include <linux/preempt.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
#include <linux/seq_file.h>
|
|
@ -0,0 +1,164 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:08 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from a BLA backbone (multiple nodes with
|
||||||
|
their bat0 bridged together, with BLA enabled)
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* BLA backbone nodes receive the frame multiple times on bat0
|
||||||
|
|
||||||
|
For multicast frames received via batman-adv broadcast packets the
|
||||||
|
originator of the broadcast packet is checked before decapsulating and
|
||||||
|
forwarding the frame to bat0 (batadv_bla_is_backbone_gw()->
|
||||||
|
batadv_recv_bcast_packet()). If it came from a node which shares the
|
||||||
|
same BLA backbone with us then it is not forwarded to bat0 to avoid a
|
||||||
|
loop.
|
||||||
|
|
||||||
|
When sending a multicast frame in a non-4-address batman-adv unicast
|
||||||
|
packet we are currently missing this check - and cannot do so because
|
||||||
|
the batman-adv unicast packet has no originator address field.
|
||||||
|
|
||||||
|
However, we can simply fix this on the sender side by only sending the
|
||||||
|
multicast frame via unicasts to interested nodes which do not share the
|
||||||
|
same BLA backbone with us. This also nicely avoids some unnecessary
|
||||||
|
transmissions on mesh side.
|
||||||
|
|
||||||
|
Note that no infinite loop was observed, probably because of dropping
|
||||||
|
via batadv_interface_tx()->batadv_bla_tx(). However the duplicates still
|
||||||
|
utterly confuse switches/bridges, ICMPv6 duplicate address detection and
|
||||||
|
neighbor discovery and therefore leads to long delays before being able
|
||||||
|
to establish TCP connections, for instance. And it also leads to the Linux
|
||||||
|
bridge printing messages like:
|
||||||
|
"br-lan: received packet on eth1 with own address as source address ..."
|
||||||
|
|
||||||
|
Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/3c39a2455a5be02ecceeaf1a15976bddd611392e
|
||||||
|
|
||||||
|
--- a/net/batman-adv/multicast.c
|
||||||
|
+++ b/net/batman-adv/multicast.c
|
||||||
|
@@ -50,6 +50,7 @@
|
||||||
|
#include <uapi/linux/batadv_packet.h>
|
||||||
|
#include <uapi/linux/batman_adv.h>
|
||||||
|
|
||||||
|
+#include "bridge_loop_avoidance.h"
|
||||||
|
#include "hard-interface.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "log.h"
|
||||||
|
@@ -1020,6 +1021,35 @@ batadv_mcast_forw_mode(struct batadv_pri
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: the multicast packet to send
|
||||||
|
+ * @vid: the vlan identifier
|
||||||
|
+ * @orig_node: the originator to send the packet to
|
||||||
|
+ *
|
||||||
|
+ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
|
||||||
|
+ */
|
||||||
|
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node)
|
||||||
|
+{
|
||||||
|
+ /* Avoid sending multicast-in-unicast packets to other BLA
|
||||||
|
+ * gateways - they already got the frame from the LAN side
|
||||||
|
+ * we share with them.
|
||||||
|
+ * TODO: Refactor to take BLA into account earlier, to avoid
|
||||||
|
+ * reducing the mcast_fanout count.
|
||||||
|
+ */
|
||||||
|
+ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
|
||||||
|
+ dev_kfree_skb(skb);
|
||||||
|
+ return NET_XMIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
|
||||||
|
+ orig_node, vid);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
* batadv_mcast_forw_tt() - forwards a packet to multicast listeners
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the multicast packet to transmit
|
||||||
|
@@ -1056,8 +1086,8 @@ batadv_mcast_forw_tt(struct batadv_priv
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||||
|
- orig_entry->orig_node, vid);
|
||||||
|
+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
|
||||||
|
+ orig_entry->orig_node);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
@@ -1098,8 +1128,7 @@ batadv_mcast_forw_want_all_ipv4(struct b
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||||
|
- orig_node, vid);
|
||||||
|
+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
|
@@ -1136,8 +1165,7 @@ batadv_mcast_forw_want_all_ipv6(struct b
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||||
|
- orig_node, vid);
|
||||||
|
+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
|
--- a/net/batman-adv/multicast.h
|
||||||
|
+++ b/net/batman-adv/multicast.h
|
||||||
|
@@ -46,6 +46,11 @@ enum batadv_forw_mode
|
||||||
|
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node **mcast_single_orig);
|
||||||
|
|
||||||
|
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node);
|
||||||
|
+
|
||||||
|
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
unsigned short vid);
|
||||||
|
|
||||||
|
@@ -72,6 +77,16 @@ batadv_mcast_forw_mode(struct batadv_pri
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
+batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node)
|
||||||
|
+{
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return NET_XMIT_DROP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline int
|
||||||
|
batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
unsigned short vid)
|
||||||
|
{
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -363,9 +363,8 @@ send:
|
||||||
|
goto dropped;
|
||||||
|
ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
|
||||||
|
} else if (mcast_single_orig) {
|
||||||
|
- ret = batadv_send_skb_unicast(bat_priv, skb,
|
||||||
|
- BATADV_UNICAST, 0,
|
||||||
|
- mcast_single_orig, vid);
|
||||||
|
+ ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
|
||||||
|
+ mcast_single_orig);
|
||||||
|
} else if (forw_mode == BATADV_FORW_SOME) {
|
||||||
|
ret = batadv_mcast_forw_send(bat_priv, skb, vid);
|
||||||
|
} else {
|
|
@ -0,0 +1,150 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:09 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from mesh to a BLA backbone (multiple nodes
|
||||||
|
with their bat0 bridged together, with BLA enabled)
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* BLA backbone nodes receive the frame multiple times on bat0,
|
||||||
|
once from mesh->bat0 and once from each backbone_gw from LAN
|
||||||
|
|
||||||
|
For unicast, a node will send only to the best backbone gateway
|
||||||
|
according to the TQ. However for multicast we currently cannot determine
|
||||||
|
if multiple destination nodes share the same backbone if they don't share
|
||||||
|
the same backbone with us. So we need to keep sending the unicasts to
|
||||||
|
all backbone gateways and let the backbone gateways decide which one
|
||||||
|
will forward the frame. We can use the CLAIM mechanism to make this
|
||||||
|
decision.
|
||||||
|
|
||||||
|
One catch: The batman-adv gateway feature for DHCP packets potentially
|
||||||
|
sends multicast packets in the same batman-adv unicast header as the
|
||||||
|
multicast optimizations code. And we are not allowed to drop those even
|
||||||
|
if we did not claim the source address of the sender, as for such
|
||||||
|
packets there is only this one multicast-in-unicast packet.
|
||||||
|
|
||||||
|
How can we distinguish the two cases?
|
||||||
|
|
||||||
|
The gateway feature uses a batman-adv unicast 4 address header. While
|
||||||
|
the multicast-to-unicasts feature uses a simple, 3 address batman-adv
|
||||||
|
unicast header. So let's use this to distinguish.
|
||||||
|
|
||||||
|
Fixes: e32470167379 ("batman-adv: check incoming packet type for bla")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d7665cf8a824c41c61c6e2110ab63d37eb7a8ef7
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1814,7 +1814,7 @@ batadv_bla_loopdetect_check(struct batad
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the frame to be checked
|
||||||
|
* @vid: the VLAN ID of the frame
|
||||||
|
- * @is_bcast: the packet came in a broadcast packet type.
|
||||||
|
+ * @packet_type: the batman packet type this frame came in
|
||||||
|
*
|
||||||
|
* batadv_bla_rx avoidance checks if:
|
||||||
|
* * we have to race for a claim
|
||||||
|
@@ -1826,7 +1826,7 @@ batadv_bla_loopdetect_check(struct batad
|
||||||
|
* further process the skb.
|
||||||
|
*/
|
||||||
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
- unsigned short vid, bool is_bcast)
|
||||||
|
+ unsigned short vid, int packet_type)
|
||||||
|
{
|
||||||
|
struct batadv_bla_backbone_gw *backbone_gw;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
@@ -1848,9 +1848,24 @@ bool batadv_bla_rx(struct batadv_priv *b
|
||||||
|
goto handled;
|
||||||
|
|
||||||
|
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
|
||||||
|
- /* don't allow broadcasts while requests are in flight */
|
||||||
|
- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
|
||||||
|
- goto handled;
|
||||||
|
+ /* don't allow multicast packets while requests are in flight */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
+ /* Both broadcast flooding or multicast-via-unicasts
|
||||||
|
+ * delivery might send to multiple backbone gateways
|
||||||
|
+ * sharing the same LAN and therefore need to coordinate
|
||||||
|
+ * which backbone gateway forwards into the LAN,
|
||||||
|
+ * by claiming the payload source address.
|
||||||
|
+ *
|
||||||
|
+ * Broadcast flooding and multicast-via-unicasts
|
||||||
|
+ * delivery use the following two batman packet types.
|
||||||
|
+ * Note: explicitly exclude BATADV_UNICAST_4ADDR,
|
||||||
|
+ * as the DHCP gateway feature will send explicitly
|
||||||
|
+ * to only one BLA gateway, so the claiming process
|
||||||
|
+ * should be avoided there.
|
||||||
|
+ */
|
||||||
|
+ if (packet_type == BATADV_BCAST ||
|
||||||
|
+ packet_type == BATADV_UNICAST)
|
||||||
|
+ goto handled;
|
||||||
|
|
||||||
|
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||||
|
search_claim.vid = vid;
|
||||||
|
@@ -1885,13 +1900,14 @@ bool batadv_bla_rx(struct batadv_priv *b
|
||||||
|
goto allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* if it is a broadcast ... */
|
||||||
|
- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
|
||||||
|
+ /* if it is a multicast ... */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
+ (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
|
||||||
|
/* ... drop it. the responsible gateway is in charge.
|
||||||
|
*
|
||||||
|
- * We need to check is_bcast because with the gateway
|
||||||
|
+ * We need to check packet type because with the gateway
|
||||||
|
* feature, broadcasts (like DHCP requests) may be sent
|
||||||
|
- * using a unicast packet type.
|
||||||
|
+ * using a unicast 4 address packet type. See comment above.
|
||||||
|
*/
|
||||||
|
goto handled;
|
||||||
|
} else {
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.h
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.h
|
||||||
|
@@ -36,7 +36,7 @@ static inline bool batadv_bla_is_loopdet
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
- unsigned short vid, bool is_bcast);
|
||||||
|
+ unsigned short vid, int packet_type);
|
||||||
|
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
unsigned short vid);
|
||||||
|
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
|
||||||
|
@@ -67,7 +67,7 @@ bool batadv_bla_check_claim(struct batad
|
||||||
|
|
||||||
|
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, unsigned short vid,
|
||||||
|
- bool is_bcast)
|
||||||
|
+ int packet_type)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -423,10 +423,10 @@ void batadv_interface_rx(struct net_devi
|
||||||
|
struct vlan_ethhdr *vhdr;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
unsigned short vid;
|
||||||
|
- bool is_bcast;
|
||||||
|
+ int packet_type;
|
||||||
|
|
||||||
|
batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
- is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
|
||||||
|
+ packet_type = batadv_bcast_packet->packet_type;
|
||||||
|
|
||||||
|
skb_pull_rcsum(skb, hdr_size);
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
|
@@ -469,7 +469,7 @@ void batadv_interface_rx(struct net_devi
|
||||||
|
/* Let the bridge loop avoidance check the packet. If will
|
||||||
|
* not handle it, we can safely push it up.
|
||||||
|
*/
|
||||||
|
- if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
|
||||||
|
+ if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (orig_node)
|
|
@ -0,0 +1,189 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:10 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from BLA backbone gateways (multiple nodes
|
||||||
|
with their bat0 bridged together, with BLA enabled) sharing the same
|
||||||
|
LAN to nodes in the mesh
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* Nodes receive the frame multiple times on bat0 from the mesh,
|
||||||
|
once from each foreign BLA backbone gateway which shares the same LAN
|
||||||
|
with another
|
||||||
|
|
||||||
|
For multicast frames via batman-adv broadcast packets coming from the
|
||||||
|
same BLA backbone but from different backbone gateways duplicates are
|
||||||
|
currently detected via a CRC history of previously received packets.
|
||||||
|
|
||||||
|
However this CRC so far was not performed for multicast frames received
|
||||||
|
via batman-adv unicast packets. Fixing this by appyling the same check
|
||||||
|
for such packets, too.
|
||||||
|
|
||||||
|
Room for improvements in the future: Ideally we would introduce the
|
||||||
|
possibility to not only claim a client, but a complete originator, too.
|
||||||
|
This would allow us to only send a multicast-in-unicast packet from a BLA
|
||||||
|
backbone gateway claiming the node and by that avoid potential redundant
|
||||||
|
transmissions in the first place.
|
||||||
|
|
||||||
|
Fixes: e5cf86d30a9b ("batman-adv: add broadcast duplicate check")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c5cb6a670cc3070d9d5c5562f95fa75faac767ba
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1581,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
- * @skb: contains the bcast_packet to be checked
|
||||||
|
- *
|
||||||
|
- * check if it is on our broadcast list. Another gateway might
|
||||||
|
- * have sent the same packet because it is connected to the same backbone,
|
||||||
|
- * so we have to remove this duplicate.
|
||||||
|
+ * @skb: contains the multicast packet to be checked
|
||||||
|
+ * @payload_ptr: pointer to position inside the head buffer of the skb
|
||||||
|
+ * marking the start of the data to be CRC'ed
|
||||||
|
+ * @orig: originator mac address, NULL if unknown
|
||||||
|
+ *
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
*
|
||||||
|
* This is performed by checking the CRC, which will tell us
|
||||||
|
* with a good chance that it is the same packet. If it is furthermore
|
||||||
|
@@ -1596,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv *
|
||||||
|
*
|
||||||
|
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
*/
|
||||||
|
-bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
- struct sk_buff *skb)
|
||||||
|
+static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb, u8 *payload_ptr,
|
||||||
|
+ const u8 *orig)
|
||||||
|
{
|
||||||
|
- int i, curr;
|
||||||
|
- __be32 crc;
|
||||||
|
- struct batadv_bcast_packet *bcast_packet;
|
||||||
|
struct batadv_bcast_duplist_entry *entry;
|
||||||
|
bool ret = false;
|
||||||
|
-
|
||||||
|
- bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
+ int i, curr;
|
||||||
|
+ __be32 crc;
|
||||||
|
|
||||||
|
/* calculate the crc ... */
|
||||||
|
- crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
|
||||||
|
+ crc = batadv_skb_crc32(skb, payload_ptr);
|
||||||
|
|
||||||
|
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
||||||
|
|
||||||
|
@@ -1627,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(stru
|
||||||
|
if (entry->crc != crc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (batadv_compare_eth(entry->orig, bcast_packet->orig))
|
||||||
|
- continue;
|
||||||
|
+ /* are the originators both known and not anonymous? */
|
||||||
|
+ if (orig && !is_zero_ether_addr(orig) &&
|
||||||
|
+ !is_zero_ether_addr(entry->orig)) {
|
||||||
|
+ /* If known, check if the new frame came from
|
||||||
|
+ * the same originator:
|
||||||
|
+ * We are safe to take identical frames from the
|
||||||
|
+ * same orig, if known, as multiplications in
|
||||||
|
+ * the mesh are detected via the (orig, seqno) pair.
|
||||||
|
+ * So we can be a bit more liberal here and allow
|
||||||
|
+ * identical frames from the same orig which the source
|
||||||
|
+ * host might have sent multiple times on purpose.
|
||||||
|
+ */
|
||||||
|
+ if (batadv_compare_eth(entry->orig, orig))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* this entry seems to match: same crc, not too old,
|
||||||
|
* and from another gw. therefore return true to forbid it.
|
||||||
|
@@ -1644,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(stru
|
||||||
|
entry = &bat_priv->bla.bcast_duplist[curr];
|
||||||
|
entry->crc = crc;
|
||||||
|
entry->entrytime = jiffies;
|
||||||
|
- ether_addr_copy(entry->orig, bcast_packet->orig);
|
||||||
|
+
|
||||||
|
+ /* known originator */
|
||||||
|
+ if (orig)
|
||||||
|
+ ether_addr_copy(entry->orig, orig);
|
||||||
|
+ /* anonymous originator */
|
||||||
|
+ else
|
||||||
|
+ eth_zero_addr(entry->orig);
|
||||||
|
+
|
||||||
|
bat_priv->bla.bcast_duplist_curr = curr;
|
||||||
|
|
||||||
|
out:
|
||||||
|
@@ -1654,6 +1675,48 @@ out:
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: contains the multicast packet to be checked, decapsulated from a
|
||||||
|
+ * unicast_packet
|
||||||
|
+ *
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: contains the bcast_packet to be checked
|
||||||
|
+ *
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ struct batadv_bcast_packet *bcast_packet;
|
||||||
|
+ u8 *payload_ptr;
|
||||||
|
+
|
||||||
|
+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
+ payload_ptr = (u8 *)(bcast_packet + 1);
|
||||||
|
+
|
||||||
|
+ return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
|
||||||
|
+ bcast_packet->orig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
|
||||||
|
* the VLAN identified by vid.
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
@@ -1867,6 +1930,14 @@ bool batadv_bla_rx(struct batadv_priv *b
|
||||||
|
packet_type == BATADV_UNICAST)
|
||||||
|
goto handled;
|
||||||
|
|
||||||
|
+ /* potential duplicates from foreign BLA backbone gateways via
|
||||||
|
+ * multicast-in-unicast packets
|
||||||
|
+ */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
+ packet_type == BATADV_UNICAST &&
|
||||||
|
+ batadv_bla_check_ucast_duplist(bat_priv, skb))
|
||||||
|
+ goto handled;
|
||||||
|
+
|
||||||
|
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||||
|
search_claim.vid = vid;
|
||||||
|
claim = batadv_claim_hash_find(bat_priv, &search_claim);
|
|
@ -0,0 +1,23 @@
|
||||||
|
From: Taehee Yoo <ap420073@gmail.com>
|
||||||
|
Date: Sun, 15 Nov 2020 10:30:04 +0000
|
||||||
|
Subject: batman-adv: set .owner to THIS_MODULE
|
||||||
|
|
||||||
|
If THIS_MODULE is not set, the module would be removed while debugfs is
|
||||||
|
being used.
|
||||||
|
It eventually makes kernel panic.
|
||||||
|
|
||||||
|
Fixes: 24571be14371 ("batman-adv: add routing debug log accessible via debugfs")
|
||||||
|
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e2937539a2c9f8a8536515258bc1f08bed19a06
|
||||||
|
|
||||||
|
--- a/net/batman-adv/log.c
|
||||||
|
+++ b/net/batman-adv/log.c
|
||||||
|
@@ -180,6 +180,7 @@ static const struct file_operations bata
|
||||||
|
.read = batadv_log_read,
|
||||||
|
.poll = batadv_log_poll,
|
||||||
|
.llseek = no_llseek,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
|
@ -0,0 +1,28 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 26 Nov 2020 18:15:06 +0100
|
||||||
|
Subject: batman-adv: Consider fragmentation for needed_headroom
|
||||||
|
|
||||||
|
If a batman-adv packets has to be fragmented, then the original batman-adv
|
||||||
|
packet header is not stripped away. Instead, only a new header is added in
|
||||||
|
front of the packet after it was split.
|
||||||
|
|
||||||
|
This size must be considered to avoid cost intensive reallocations during
|
||||||
|
the transmission through the various device layers.
|
||||||
|
|
||||||
|
Fixes: e2b4301f4e2d ("batman-adv: Add lower layer needed_(head|tail)room to own ones")
|
||||||
|
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/92064deda9b063ca2d5a53b307c6127a9453357c
|
||||||
|
|
||||||
|
--- a/net/batman-adv/hard-interface.c
|
||||||
|
+++ b/net/batman-adv/hard-interface.c
|
||||||
|
@@ -553,6 +553,9 @@ static void batadv_hardif_recalc_extra_s
|
||||||
|
needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
|
||||||
|
needed_headroom += batadv_max_header_len();
|
||||||
|
|
||||||
|
+ /* fragmentation headers don't strip the unicast/... header */
|
||||||
|
+ needed_headroom += sizeof(struct batadv_frag_packet);
|
||||||
|
+
|
||||||
|
soft_iface->needed_headroom = needed_headroom;
|
||||||
|
soft_iface->needed_tailroom = lower_tailroom;
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 25 Nov 2020 13:16:43 +0100
|
||||||
|
Subject: batman-adv: Reserve needed_*room for fragments
|
||||||
|
|
||||||
|
The batadv net_device is trying to propagate the needed_headroom and
|
||||||
|
needed_tailroom from the lower devices. This is needed to avoid cost
|
||||||
|
intensive reallocations using pskb_expand_head during the transmission.
|
||||||
|
|
||||||
|
But the fragmentation code split the skb's without adding extra room at the
|
||||||
|
end/beginning of the various fragments. This reduced the performance of
|
||||||
|
transmissions over complex scenarios (batadv on vxlan on wireguard) because
|
||||||
|
the lower devices had to perform the reallocations at least once.
|
||||||
|
|
||||||
|
Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0966d5424bb87e863037301488519ccdd69e4d26
|
||||||
|
|
||||||
|
--- a/net/batman-adv/fragmentation.c
|
||||||
|
+++ b/net/batman-adv/fragmentation.c
|
||||||
|
@@ -391,6 +391,7 @@ out:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_frag_create() - create a fragment from skb
|
||||||
|
+ * @net_dev: outgoing device for fragment
|
||||||
|
* @skb: skb to create fragment from
|
||||||
|
* @frag_head: header to use in new fragment
|
||||||
|
* @fragment_size: size of new fragment
|
||||||
|
@@ -401,22 +402,25 @@ out:
|
||||||
|
*
|
||||||
|
* Return: the new fragment, NULL on error.
|
||||||
|
*/
|
||||||
|
-static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
|
||||||
|
+static struct sk_buff *batadv_frag_create(struct net_device *net_dev,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
struct batadv_frag_packet *frag_head,
|
||||||
|
unsigned int fragment_size)
|
||||||
|
{
|
||||||
|
+ unsigned int ll_reserved = LL_RESERVED_SPACE(net_dev);
|
||||||
|
+ unsigned int tailroom = net_dev->needed_tailroom;
|
||||||
|
struct sk_buff *skb_fragment;
|
||||||
|
unsigned int header_size = sizeof(*frag_head);
|
||||||
|
unsigned int mtu = fragment_size + header_size;
|
||||||
|
|
||||||
|
- skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
|
||||||
|
+ skb_fragment = dev_alloc_skb(ll_reserved + mtu + tailroom);
|
||||||
|
if (!skb_fragment)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
skb_fragment->priority = skb->priority;
|
||||||
|
|
||||||
|
/* Eat the last mtu-bytes of the skb */
|
||||||
|
- skb_reserve(skb_fragment, header_size + ETH_HLEN);
|
||||||
|
+ skb_reserve(skb_fragment, ll_reserved + header_size);
|
||||||
|
skb_split(skb, skb_fragment, skb->len - fragment_size);
|
||||||
|
|
||||||
|
/* Add the header */
|
||||||
|
@@ -439,11 +443,12 @@ int batadv_frag_send_packet(struct sk_bu
|
||||||
|
struct batadv_orig_node *orig_node,
|
||||||
|
struct batadv_neigh_node *neigh_node)
|
||||||
|
{
|
||||||
|
+ struct net_device *net_dev = neigh_node->if_incoming->net_dev;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
|
struct batadv_frag_packet frag_header;
|
||||||
|
struct sk_buff *skb_fragment;
|
||||||
|
- unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
|
||||||
|
+ unsigned int mtu = net_dev->mtu;
|
||||||
|
unsigned int header_size = sizeof(frag_header);
|
||||||
|
unsigned int max_fragment_size, num_fragments;
|
||||||
|
int ret;
|
||||||
|
@@ -503,7 +508,7 @@ int batadv_frag_send_packet(struct sk_bu
|
||||||
|
goto put_primary_if;
|
||||||
|
}
|
||||||
|
|
||||||
|
- skb_fragment = batadv_frag_create(skb, &frag_header,
|
||||||
|
+ skb_fragment = batadv_frag_create(net_dev, skb, &frag_header,
|
||||||
|
max_fragment_size);
|
||||||
|
if (!skb_fragment) {
|
||||||
|
ret = -ENOMEM;
|
|
@ -0,0 +1,39 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 26 Nov 2020 18:24:49 +0100
|
||||||
|
Subject: batman-adv: Don't always reallocate the fragmentation skb head
|
||||||
|
|
||||||
|
When a packet is fragmented by batman-adv, the original batman-adv header
|
||||||
|
is not modified. Only a new fragmentation is inserted between the original
|
||||||
|
one and the ethernet header. The code must therefore make sure that it has
|
||||||
|
a writable region of this size in the skbuff head.
|
||||||
|
|
||||||
|
But it is not useful to always reallocate the skbuff by this size even when
|
||||||
|
there would be more than enough headroom still in the skb. The reallocation
|
||||||
|
is just to costly during in this codepath.
|
||||||
|
|
||||||
|
Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3e3ff987876d3be70d928561acbefe5a48ab1654
|
||||||
|
|
||||||
|
--- a/net/batman-adv/fragmentation.c
|
||||||
|
+++ b/net/batman-adv/fragmentation.c
|
||||||
|
@@ -527,13 +527,14 @@ int batadv_frag_send_packet(struct sk_bu
|
||||||
|
frag_header.no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Make room for the fragment header. */
|
||||||
|
- if (batadv_skb_head_push(skb, header_size) < 0 ||
|
||||||
|
- pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0) {
|
||||||
|
- ret = -ENOMEM;
|
||||||
|
+ /* make sure that there is at least enough head for the fragmentation
|
||||||
|
+ * and ethernet headers
|
||||||
|
+ */
|
||||||
|
+ ret = skb_cow_head(skb, ETH_HLEN + header_size);
|
||||||
|
+ if (ret < 0)
|
||||||
|
goto put_primary_if;
|
||||||
|
- }
|
||||||
|
|
||||||
|
+ skb_push(skb, header_size);
|
||||||
|
memcpy(skb->data, &frag_header, header_size);
|
||||||
|
|
||||||
|
/* Send the last fragment */
|
|
@ -0,0 +1,31 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Tue, 18 May 2021 21:00:27 +0200
|
||||||
|
Subject: batman-adv: Avoid WARN_ON timing related checks
|
||||||
|
|
||||||
|
The soft/batadv interface for a queued OGM can be changed during the time
|
||||||
|
the OGM was queued for transmission and when the OGM is actually
|
||||||
|
transmitted by the worker.
|
||||||
|
|
||||||
|
But WARN_ON must be used to denote kernel bugs and not to print simple
|
||||||
|
warnings. A warning can simply be printed using pr_warn.
|
||||||
|
|
||||||
|
Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
|
||||||
|
Reported-by: syzbot+c0b807de416427ff3dd1@syzkaller.appspotmail.com
|
||||||
|
Fixes: 29b9256e6631 ("batman-adv: consider outgoing interface in OGM sending")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/5061f9c502d7101912089d8f4a7866e0a926a49a
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -409,8 +409,10 @@ static void batadv_iv_ogm_emit(struct ba
|
||||||
|
if (WARN_ON(!forw_packet->if_outgoing))
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface))
|
||||||
|
+ if (forw_packet->if_outgoing->soft_iface != soft_iface) {
|
||||||
|
+ pr_warn("%s: soft interface switch for queued OGM\n", __func__);
|
||||||
|
return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
|
||||||
|
return;
|
162
batman-adv/patches/0036-batman-adv-fix-error-handling.patch
Normal file
162
batman-adv/patches/0036-batman-adv-fix-error-handling.patch
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
From: Pavel Skripkin <paskripkin@gmail.com>
|
||||||
|
Date: Sun, 24 Oct 2021 16:13:56 +0300
|
||||||
|
Subject: batman-adv: fix error handling
|
||||||
|
|
||||||
|
Syzbot reported ODEBUG warning in batadv_nc_mesh_free(). The problem was
|
||||||
|
in wrong error handling in batadv_mesh_init().
|
||||||
|
|
||||||
|
Before this patch batadv_mesh_init() was calling batadv_mesh_free() in case
|
||||||
|
of any batadv_*_init() calls failure. This approach may work well, when
|
||||||
|
there is some kind of indicator, which can tell which parts of batadv are
|
||||||
|
initialized; but there isn't any.
|
||||||
|
|
||||||
|
All written above lead to cleaning up uninitialized fields. Even if we hide
|
||||||
|
ODEBUG warning by initializing bat_priv->nc.work, syzbot was able to hit
|
||||||
|
GPF in batadv_nc_purge_paths(), because hash pointer in still NULL. [1]
|
||||||
|
|
||||||
|
To fix these bugs we can unwind batadv_*_init() calls one by one.
|
||||||
|
It is good approach for 2 reasons: 1) It fixes bugs on error handling
|
||||||
|
path 2) It improves the performance, since we won't call unneeded
|
||||||
|
batadv_*_free() functions.
|
||||||
|
|
||||||
|
So, this patch makes all batadv_*_init() clean up all allocated memory
|
||||||
|
before returning with an error to no call correspoing batadv_*_free()
|
||||||
|
and open-codes batadv_mesh_free() with proper order to avoid touching
|
||||||
|
uninitialized fields.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/netdev/000000000000c87fbd05cef6bcb0@google.com/ [1]
|
||||||
|
Reported-and-tested-by: syzbot+28b0702ada0bf7381f58@syzkaller.appspotmail.com
|
||||||
|
Fixes: 21e838760727 ("[batman-adv] fix various race conditions during startup & shutdown")
|
||||||
|
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0631e0825c8129cd3896926da62a09ac00bf13a0
|
||||||
|
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1561,10 +1561,14 @@ int batadv_bla_init(struct batadv_priv *
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bat_priv->bla.claim_hash = batadv_hash_new(128);
|
||||||
|
- bat_priv->bla.backbone_hash = batadv_hash_new(32);
|
||||||
|
+ if (!bat_priv->bla.claim_hash)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
|
||||||
|
- if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
|
||||||
|
+ bat_priv->bla.backbone_hash = batadv_hash_new(32);
|
||||||
|
+ if (!bat_priv->bla.backbone_hash) {
|
||||||
|
+ batadv_hash_destroy(bat_priv->bla.claim_hash);
|
||||||
|
return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
|
||||||
|
&batadv_claim_hash_lock_class_key);
|
||||||
|
--- a/net/batman-adv/main.c
|
||||||
|
+++ b/net/batman-adv/main.c
|
||||||
|
@@ -197,29 +197,41 @@ int batadv_mesh_init(struct net_device *
|
||||||
|
|
||||||
|
bat_priv->gw.generation = 0;
|
||||||
|
|
||||||
|
- ret = batadv_v_mesh_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
-
|
||||||
|
ret = batadv_originator_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_orig;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = batadv_tt_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_tt;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = batadv_v_mesh_init(bat_priv);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_v;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = batadv_bla_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_bla;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = batadv_dat_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_dat;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = batadv_nc_mesh_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto err;
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||||
|
+ goto err_nc;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
batadv_gw_init(bat_priv);
|
||||||
|
batadv_mcast_init(bat_priv);
|
||||||
|
@@ -229,8 +241,20 @@ int batadv_mesh_init(struct net_device *
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
-err:
|
||||||
|
- batadv_mesh_free(soft_iface);
|
||||||
|
+err_nc:
|
||||||
|
+ batadv_dat_free(bat_priv);
|
||||||
|
+err_dat:
|
||||||
|
+ batadv_bla_free(bat_priv);
|
||||||
|
+err_bla:
|
||||||
|
+ batadv_v_mesh_free(bat_priv);
|
||||||
|
+err_v:
|
||||||
|
+ batadv_tt_free(bat_priv);
|
||||||
|
+err_tt:
|
||||||
|
+ batadv_originator_free(bat_priv);
|
||||||
|
+err_orig:
|
||||||
|
+ batadv_purge_outstanding_packets(bat_priv, NULL);
|
||||||
|
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/batman-adv/network-coding.c
|
||||||
|
+++ b/net/batman-adv/network-coding.c
|
||||||
|
@@ -155,8 +155,10 @@ int batadv_nc_mesh_init(struct batadv_pr
|
||||||
|
&batadv_nc_coding_hash_lock_class_key);
|
||||||
|
|
||||||
|
bat_priv->nc.decoding_hash = batadv_hash_new(128);
|
||||||
|
- if (!bat_priv->nc.decoding_hash)
|
||||||
|
+ if (!bat_priv->nc.decoding_hash) {
|
||||||
|
+ batadv_hash_destroy(bat_priv->nc.coding_hash);
|
||||||
|
goto err;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
batadv_hash_set_lock_class(bat_priv->nc.decoding_hash,
|
||||||
|
&batadv_nc_decoding_hash_lock_class_key);
|
||||||
|
--- a/net/batman-adv/translation-table.c
|
||||||
|
+++ b/net/batman-adv/translation-table.c
|
||||||
|
@@ -4405,8 +4405,10 @@ int batadv_tt_init(struct batadv_priv *b
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = batadv_tt_global_init(bat_priv);
|
||||||
|
- if (ret < 0)
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ batadv_tt_local_table_free(bat_priv);
|
||||||
|
return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
|
||||||
|
batadv_tt_tvlv_unicast_handler_v1,
|
|
@ -0,0 +1,182 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Mon, 1 Nov 2021 21:46:17 +0100
|
||||||
|
Subject: batman-adv: allow netlink usage in unprivileged containers
|
||||||
|
|
||||||
|
Currently, creating a batman-adv interface in an unprivileged LXD
|
||||||
|
container and attaching secondary interfaces to it with "ip" or "batctl"
|
||||||
|
works fine. However all batctl debug and configuration commands
|
||||||
|
fail:
|
||||||
|
|
||||||
|
root@container:~# batctl originators
|
||||||
|
Error received: Operation not permitted
|
||||||
|
root@container:~# batctl orig_interval
|
||||||
|
1000
|
||||||
|
root@container:~# batctl orig_interval 2000
|
||||||
|
root@container:~# batctl orig_interval
|
||||||
|
1000
|
||||||
|
|
||||||
|
To fix this change the generic netlink permissions from GENL_ADMIN_PERM
|
||||||
|
to GENL_UNS_ADMIN_PERM. This way a batman-adv interface is fully
|
||||||
|
maintainable as root from within a user namespace, from an unprivileged
|
||||||
|
container.
|
||||||
|
|
||||||
|
All except one batman-adv netlink setting are per interface and do not
|
||||||
|
leak information or change settings from the host system and are
|
||||||
|
therefore save to retrieve or modify as root from within an unprivileged
|
||||||
|
container.
|
||||||
|
|
||||||
|
"batctl routing_algo" / BATADV_CMD_GET_ROUTING_ALGOS is the only
|
||||||
|
exception: It provides the batman-adv kernel module wide default routing
|
||||||
|
algorithm. However it is read-only from netlink and an unprivileged
|
||||||
|
container is still not allowed to modify
|
||||||
|
/sys/module/batman_adv/parameters/routing_algo. Instead it is advised to
|
||||||
|
use the newly introduced "batctl if create routing_algo RA_NAME" /
|
||||||
|
IFLA_BATADV_ALGO_NAME to set the routing algorithm on interface
|
||||||
|
creation, which already works fine in an unprivileged container.
|
||||||
|
|
||||||
|
Cc: Tycho Andersen <tycho@tycho.pizza>
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/055fa41b73ca8dae1c1ed41777e32a8f02e80c82
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/compat-include/uapi/linux/genetlink.h
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+/* Copyright (C) B.A.T.M.A.N. contributors:
|
||||||
|
+ *
|
||||||
|
+ * Marek Lindner, Simon Wunderlich
|
||||||
|
+ *
|
||||||
|
+ * This file contains macros for maintaining compatibility with older versions
|
||||||
|
+ * of the Linux kernel.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_
|
||||||
|
+#define _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_
|
||||||
|
+
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include_next <uapi/linux/genetlink.h>
|
||||||
|
+
|
||||||
|
+#if LINUX_VERSION_IS_LESS(4, 6, 0)
|
||||||
|
+
|
||||||
|
+#define GENL_UNS_ADMIN_PERM GENL_ADMIN_PERM
|
||||||
|
+
|
||||||
|
+#endif /* LINUX_VERSION_IS_LESS(4, 6, 0) */
|
||||||
|
+
|
||||||
|
+#endif /* _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_ */
|
||||||
|
--- a/net/batman-adv/netlink.c
|
||||||
|
+++ b/net/batman-adv/netlink.c
|
||||||
|
@@ -1350,21 +1350,21 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_tp_meter_start,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_TP_METER_CANCEL,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_tp_meter_cancel,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_algo_dump,
|
||||||
|
},
|
||||||
|
@@ -1379,68 +1379,68 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_tt_local_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_tt_global_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_orig_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_NEIGHBORS,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_hardif_neigh_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_GATEWAYS,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_gw_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_CLAIM,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_bla_claim_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_bla_backbone_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_DAT_CACHE,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_dat_cache_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_mcast_flags_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_MESH,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_mesh,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_HARDIF,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_hardif,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
||||||
|
@@ -1456,7 +1456,7 @@ static const struct genl_ops batadv_netl
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_SET_VLAN,
|
||||||
|
- .flags = GENL_ADMIN_PERM,
|
||||||
|
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.doit = batadv_netlink_set_vlan,
|
||||||
|
.internal_flags = BATADV_FLAG_NEED_MESH |
|
|
@ -5,45 +5,202 @@
|
||||||
#include <linux/version.h> /* LINUX_VERSION_CODE */
|
#include <linux/version.h> /* LINUX_VERSION_CODE */
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#if LINUX_VERSION_IS_LESS(6, 0, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
|
||||||
|
|
||||||
#define __vstring(item, fmt, ap) __dynamic_array(char, item, 256)
|
#define dev_get_iflink(_net_dev) ((_net_dev)->iflink)
|
||||||
#define __assign_vstr(dst, fmt, va) \
|
|
||||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(dst), 256, fmt, *va) >= 256)
|
|
||||||
|
|
||||||
#endif /* LINUX_VERSION_IS_LESS(6, 0, 0) */
|
#endif /* < KERNEL_VERSION(4, 1, 0) */
|
||||||
|
|
||||||
#if LINUX_VERSION_IS_LESS(6, 2, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
|
||||||
|
|
||||||
#include <linux/random.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
#define genl_split_ops genl_ops
|
#define netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info, extack) ({\
|
||||||
|
BUILD_BUG_ON(upper_priv != NULL); \
|
||||||
|
BUILD_BUG_ON(upper_info != NULL); \
|
||||||
|
BUILD_BUG_ON(extack != NULL); \
|
||||||
|
netdev_master_upper_dev_link(dev, upper_dev); \
|
||||||
|
})
|
||||||
|
|
||||||
static inline u32 batadv_get_random_u32_below(u32 ep_ro)
|
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||||
|
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
#define netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info, extack) ({\
|
||||||
|
BUILD_BUG_ON(extack != NULL); \
|
||||||
|
netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 5, 0) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
/* wild hack for batadv_getlink_net only */
|
||||||
|
#define get_link_net get_xstats_size || 1 ? fallback_net : (struct net*)netdev->rtnl_link_ops->get_xstats_size
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 0, 0) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||||
|
|
||||||
|
struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb,
|
||||||
|
unsigned int transport_len,
|
||||||
|
__sum16(*skb_chkf)(struct sk_buff *skb));
|
||||||
|
|
||||||
|
int ip_mc_check_igmp(struct sk_buff *skb);
|
||||||
|
int ipv6_mc_check_mld(struct sk_buff *skb);
|
||||||
|
|
||||||
|
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
|
||||||
|
|
||||||
|
#include_next <linux/igmp.h>
|
||||||
|
#include_next <net/addrconf.h>
|
||||||
|
|
||||||
|
static inline int batadv_ipv6_mc_check_mld1(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return prandom_u32_max(ep_ro);
|
return ipv6_mc_check_mld(skb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define get_random_u32_below batadv_get_random_u32_below
|
static inline int batadv_ipv6_mc_check_mld2(struct sk_buff *skb,
|
||||||
|
struct sk_buff **skb_trimmed)
|
||||||
|
{
|
||||||
|
return ipv6_mc_check_mld(skb, skb_trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LINUX_VERSION_IS_LESS(6, 2, 0) */
|
#define ipv6_mc_check_mld_get(_1, _2, ipv6_mc_check_mld_name, ...) ipv6_mc_check_mld_name
|
||||||
|
#define ipv6_mc_check_mld(...) \
|
||||||
|
ipv6_mc_check_mld_get(__VA_ARGS__, batadv_ipv6_mc_check_mld2, batadv_ipv6_mc_check_mld1)(__VA_ARGS__)
|
||||||
|
|
||||||
#if LINUX_VERSION_IS_LESS(6, 4, 0) && \
|
static inline int batadv_ip_mc_check_igmp1(struct sk_buff *skb)
|
||||||
!(LINUX_VERSION_IS_GEQ(5, 10, 205) && LINUX_VERSION_IS_LESS(5, 11, 0)) && \
|
{
|
||||||
!(LINUX_VERSION_IS_GEQ(5, 15, 144) && LINUX_VERSION_IS_LESS(5, 16, 0)) && \
|
return ip_mc_check_igmp(skb, NULL);
|
||||||
!(LINUX_VERSION_IS_GEQ(6, 1, 69) && LINUX_VERSION_IS_LESS(6, 2, 0))
|
}
|
||||||
|
|
||||||
#include <linux/if_vlan.h>
|
static inline int batadv_ip_mc_check_igmp2(struct sk_buff *skb,
|
||||||
|
struct sk_buff **skb_trimmed)
|
||||||
|
{
|
||||||
|
return ip_mc_check_igmp(skb, skb_trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prefer this version in TX path, instead of
|
#define ip_mc_check_igmp_get(_1, _2, ip_mc_check_igmp_name, ...) ip_mc_check_igmp_name
|
||||||
* skb_reset_mac_header() + vlan_eth_hdr()
|
#define ip_mc_check_igmp(...) \
|
||||||
|
ip_mc_check_igmp_get(__VA_ARGS__, batadv_ip_mc_check_igmp2, batadv_ip_mc_check_igmp1)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 2, 0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
|
||||||
|
|
||||||
|
#define IFF_NO_QUEUE 0; dev->tx_queue_len = 0
|
||||||
|
|
||||||
|
static inline bool hlist_fake(struct hlist_node *h)
|
||||||
|
{
|
||||||
|
return h->pprev == &h->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 3, 0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
|
||||||
|
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
|
||||||
|
#define ethtool_link_ksettings batadv_ethtool_link_ksettings
|
||||||
|
|
||||||
|
struct batadv_ethtool_link_ksettings {
|
||||||
|
struct {
|
||||||
|
__u32 speed;
|
||||||
|
__u8 duplex;
|
||||||
|
__u8 autoneg;
|
||||||
|
} base;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __ethtool_get_link_ksettings(__dev, __link_settings) \
|
||||||
|
batadv_ethtool_get_link_ksettings(__dev, __link_settings)
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
batadv_ethtool_get_link_ksettings(struct net_device *dev,
|
||||||
|
struct ethtool_link_ksettings *link_ksettings)
|
||||||
|
{
|
||||||
|
struct ethtool_cmd cmd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
ret = __ethtool_get_settings(dev, &cmd);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
link_ksettings->base.duplex = cmd.duplex;
|
||||||
|
link_ksettings->base.speed = ethtool_cmd_speed(&cmd);
|
||||||
|
link_ksettings->base.autoneg = cmd.autoneg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 6, 0) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
||||||
|
|
||||||
|
#include_next <linux/cache.h>
|
||||||
|
|
||||||
|
/* hack for netlink.c which marked the family ops as ro */
|
||||||
|
#ifdef __ro_after_init
|
||||||
|
#undef __ro_after_init
|
||||||
|
#endif
|
||||||
|
#define __ro_after_init
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 10, 0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 9)
|
||||||
|
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
/* work around missing attribute needs_free_netdev and priv_destructor in
|
||||||
|
* net_device
|
||||||
*/
|
*/
|
||||||
static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb)
|
#define ether_setup(dev) \
|
||||||
|
void batadv_softif_free2(struct net_device *dev) \
|
||||||
|
{ \
|
||||||
|
batadv_softif_free(dev); \
|
||||||
|
free_netdev(dev); \
|
||||||
|
} \
|
||||||
|
void (*t1)(struct net_device *dev) __attribute__((unused)); \
|
||||||
|
bool t2 __attribute__((unused)); \
|
||||||
|
ether_setup(dev)
|
||||||
|
#define needs_free_netdev destructor = batadv_softif_free2; t2
|
||||||
|
#define priv_destructor destructor = batadv_softif_free2; t1
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 11, 9) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||||
|
|
||||||
|
#define batadv_softif_slave_add(__dev, __slave_dev, __extack) \
|
||||||
|
batadv_softif_slave_add(__dev, __slave_dev)
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 15, 0) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
|
||||||
|
|
||||||
|
static inline int batadv_access_ok(int type, const void __user *p,
|
||||||
|
unsigned long size)
|
||||||
{
|
{
|
||||||
return (struct vlan_ethhdr *)skb->data;
|
return access_ok(type, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LINUX_VERSION_IS_LESS(6, 4, 0) */
|
#ifdef access_ok
|
||||||
|
#undef access_ok
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define access_ok_get(_1, _2, _3 , access_ok_name, ...) access_ok_name
|
||||||
|
#define access_ok(...) \
|
||||||
|
access_ok_get(__VA_ARGS__, access_ok3, access_ok2)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define access_ok2(addr, size) batadv_access_ok(VERIFY_WRITE, (addr), (size))
|
||||||
|
#define access_ok3(type, addr, size) batadv_access_ok((type), (addr), (size))
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(5, 0, 0) */
|
||||||
|
|
||||||
/* <DECLARE_EWMA> */
|
/* <DECLARE_EWMA> */
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
PKG_NAME:=batmand
|
PKG_NAME:=batmand
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL:=https://git.open-mesh.org/batmand.git
|
PKG_SOURCE_URL:=https://git.open-mesh.org/batmand.git
|
||||||
PKG_REV:=b67a7087b51d7a5e90d27ac39116d1f57257c86e
|
PKG_REV:=b67a7087b51d7a5e90d27ac39116d1f57257c86e
|
||||||
PKG_VERSION:=1440
|
PKG_VERSION:=1440
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=0
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
PKG_SOURCE_VERSION:=$(PKG_REV)
|
PKG_SOURCE_VERSION:=$(PKG_REV)
|
||||||
|
@ -22,13 +23,19 @@ PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
|
||||||
PKG_MIRROR_HASH:=ceb8e0e399f79b1b663594fcf9642e1efc40e696a7604daf709c77da9b6ec52f
|
PKG_MIRROR_HASH:=ceb8e0e399f79b1b663594fcf9642e1efc40e696a7604daf709c77da9b6ec52f
|
||||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_EXTRA_CFLAGS=-DDEBUG_MALLOC -DMEMORY_USAGE -DPROFILE_DATA -DREVISION_VERSION=\"\ rv$(PKG_REV)\" -D_GNU_SOURCE
|
||||||
|
|
||||||
|
PKG_KMOD_BUILD_DIR:=$(PKG_BUILD_DIR)/linux/modules
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define Package/batmand
|
define Package/batmand/Default
|
||||||
URL:=https://www.open-mesh.org/
|
URL:=https://www.open-mesh.org/
|
||||||
MAINTAINER:=Corinna "Elektra" Aichele <onelektra@gmx.net>
|
MAINTAINER:=Corinna "Elektra" Aichele <onelektra@gmx.net>
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/batmand
|
||||||
|
$(call Package/batmand/Default)
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
SUBMENU:=Routing and Redirection
|
SUBMENU:=Routing and Redirection
|
||||||
|
@ -40,16 +47,61 @@ define Package/batmand/description
|
||||||
B.A.T.M.A.N. layer 3 routing daemon
|
B.A.T.M.A.N. layer 3 routing daemon
|
||||||
endef
|
endef
|
||||||
|
|
||||||
MAKE_FLAGS += \
|
define KernelPackage/batgat
|
||||||
EXTRA_CFLAGS='-DDEBUG_MALLOC -DMEMORY_USAGE -DPROFILE_DATA -DREVISION_VERSION=\"\ rv$(PKG_REV)\" -D_GNU_SOURCE' \
|
$(call Package/batmand/Default)
|
||||||
|
SUBMENU:=Network Support
|
||||||
|
DEPENDS:=+batmand @BROKEN
|
||||||
|
TITLE:=B.A.T.M.A.N. gateway module
|
||||||
|
FILES:=$(PKG_KMOD_BUILD_DIR)/batgat.$(LINUX_KMOD_SUFFIX)
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,batgat)
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
define KernelPackage/batgat/description
|
||||||
|
Kernel gateway module for B.A.T.M.A.N. for better tunnel performance
|
||||||
|
endef
|
||||||
|
|
||||||
|
MAKE_BATMAND_ARGS += \
|
||||||
|
EXTRA_CFLAGS='$(TARGET_CFLAGS) $(PKG_EXTRA_CFLAGS)' \
|
||||||
|
CCFLAGS="$(TARGET_CFLAGS)" \
|
||||||
|
OFLAGS="$(TARGET_CFLAGS)" \
|
||||||
REVISION="$(PKG_REV)" \
|
REVISION="$(PKG_REV)" \
|
||||||
CC="$(TARGET_CC)" \
|
CC="$(TARGET_CC)" \
|
||||||
|
NODEBUG=1 \
|
||||||
UNAME="Linux" \
|
UNAME="Linux" \
|
||||||
batmand
|
INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \
|
||||||
|
STRIP="/bin/true" \
|
||||||
|
batmand install
|
||||||
|
|
||||||
|
MAKE_BATGAT_ARGS += \
|
||||||
|
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||||
|
ARCH="$(LINUX_KARCH)" \
|
||||||
|
PATH="$(TARGET_PATH)" \
|
||||||
|
SUBDIRS="$(PKG_KMOD_BUILD_DIR)" \
|
||||||
|
LINUX_VERSION="$(LINUX_VERSION)" \
|
||||||
|
REVISION="$(PKG_REV)" modules
|
||||||
|
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
endef
|
||||||
|
|
||||||
|
ifneq ($(DEVELOPER)$(CONFIG_PACKAGE_batmand),)
|
||||||
|
BUILD_BATMAND := $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_BATMAND_ARGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(DEVELOPER)$(CONFIG_PACKAGE_kmod-batgat),)
|
||||||
|
BUILD_BATGAT := $(MAKE) -C "$(LINUX_DIR)" $(MAKE_BATGAT_ARGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(BUILD_BATMAND)
|
||||||
|
cp $(PKG_KMOD_BUILD_DIR)/Makefile.kbuild $(PKG_KMOD_BUILD_DIR)/Makefile
|
||||||
|
$(BUILD_BATGAT)
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/batmand/install
|
define Package/batmand/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
|
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batmand $(1)/usr/sbin/
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/batmand $(1)/usr/sbin/
|
||||||
$(INSTALL_BIN) ./files/etc/init.d/batmand $(1)/etc/init.d
|
$(INSTALL_BIN) ./files/etc/init.d/batmand $(1)/etc/init.d
|
||||||
$(INSTALL_DATA) ./files/etc/config/batmand $(1)/etc/config
|
$(INSTALL_DATA) ./files/etc/config/batmand $(1)/etc/config
|
||||||
endef
|
endef
|
||||||
|
@ -59,3 +111,4 @@ define Package/batmand/conffiles
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,batmand))
|
$(eval $(call BuildPackage,batmand))
|
||||||
|
$(eval $(call KernelPackage,batgat))
|
||||||
|
|
|
@ -1,39 +1,21 @@
|
||||||
#!/bin/sh /etc/rc.common
|
#!/bin/sh /etc/rc.common
|
||||||
START=90
|
START=90
|
||||||
USE_PROCD=1
|
|
||||||
|
|
||||||
batmand_start() {
|
start () {
|
||||||
local config="$1"
|
interface=$(uci get batmand.general.interface)
|
||||||
local batman_args
|
|
||||||
local interface
|
|
||||||
local hnas
|
|
||||||
local gateway_class
|
|
||||||
local originator_interval
|
|
||||||
local preferred_gateway
|
|
||||||
local routing_class
|
|
||||||
local visualisation_srv
|
|
||||||
local local policy_routing_script
|
|
||||||
local disable_client_nat
|
|
||||||
local disable_aggregation
|
|
||||||
|
|
||||||
[ "$config" = "general" ] || return 1
|
|
||||||
|
|
||||||
config_get interface "$config" interface
|
|
||||||
if [ "$interface" = "" ]; then
|
if [ "$interface" = "" ]; then
|
||||||
echo $1 Error, you must specify at least a network interface
|
echo $1 Error, you must specify at least a network interface
|
||||||
return 1
|
exit
|
||||||
fi
|
fi
|
||||||
|
hnas=$(uci get batmand.general.hna)
|
||||||
config_get hnas "$config" hna
|
gateway_class=$(uci get batmand.general.gateway_class)
|
||||||
config_get gateway_class "$config" gateway_class
|
originator_interval=$(uci get batmand.general.originator_interval)
|
||||||
config_get originator_interval "$config" originator_interval
|
preferred_gateway=$(uci get batmand.general.preferred_gateway)
|
||||||
config_get preferred_gateway "$config" preferred_gateway
|
routing_class=$(uci get batmand.general.routing_class)
|
||||||
config_get routing_class "$config" routing_class
|
visualisation_srv=$(uci get batmand.general.visualisation_srv)
|
||||||
config_get visualisation_srv "$config" visualisation_srv
|
policy_routing_script=$(uci get batmand.general.policy_routing_script)
|
||||||
config_get policy_routing_script "$config" policy_routing_script
|
disable_client_nat=$(uci get batmand.general.disable_client_nat)
|
||||||
config_get disable_client_nat "$config" disable_client_nat
|
disable_aggregation=$(uci get batmand.general.disable_aggregation)
|
||||||
config_get disable_aggregation "$config" disable_aggregation
|
|
||||||
|
|
||||||
batman_args=""
|
batman_args=""
|
||||||
|
|
||||||
for hna in $hnas; do
|
for hna in $hnas; do
|
||||||
|
@ -72,20 +54,10 @@ batmand_start() {
|
||||||
batman_args=${batman_args}'--disable-aggregation '
|
batman_args=${batman_args}'--disable-aggregation '
|
||||||
fi
|
fi
|
||||||
|
|
||||||
procd_open_instance "${config}"
|
batman_args=${batman_args}$interface
|
||||||
procd_set_param command /usr/sbin/batmand
|
batmand $batman_args >/dev/null 2>&1
|
||||||
procd_append_param command --no-detach
|
|
||||||
procd_append_param command ${batman_args}
|
|
||||||
procd_append_param command ${interface}
|
|
||||||
procd_set_param netdev ${interface}
|
|
||||||
procd_close_instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start_service() {
|
stop () {
|
||||||
config_load "batmand"
|
killall batmand
|
||||||
config_foreach batmand_start batmand
|
|
||||||
}
|
|
||||||
|
|
||||||
service_triggers() {
|
|
||||||
procd_add_reload_trigger "batmand"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Sun, 1 Dec 2013 14:39:00 +0100
|
|
||||||
Subject: Allow one to disable forking to background in debug_mode 0
|
|
||||||
|
|
||||||
---
|
|
||||||
posix/init.c | 19 ++++++++++++++-----
|
|
||||||
1 file changed, 14 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
--- a/posix/init.c
|
|
||||||
+++ b/posix/init.c
|
|
||||||
@@ -44,6 +44,7 @@
|
|
||||||
#define IOCSETDEV 1
|
|
||||||
|
|
||||||
int8_t stop;
|
|
||||||
+int no_detach = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -159,6 +160,7 @@ void apply_init_args( int argc, char *ar
|
|
||||||
{"purge-timeout", required_argument, 0, 'q'},
|
|
||||||
{"disable-aggregation", no_argument, 0, 'x'},
|
|
||||||
{"disable-client-nat", no_argument, 0, 'z'},
|
|
||||||
+ {"no-detach", no_argument, 0, 'D'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -169,7 +171,7 @@ void apply_init_args( int argc, char *ar
|
|
||||||
if ( strstr( SOURCE_VERSION, "-" ) != NULL )
|
|
||||||
printf( "WARNING: You are using the unstable batman branch. If you are interested in *using* batman get the latest stable release !\n" );
|
|
||||||
|
|
||||||
- while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vV", long_options, &option_index ) ) != -1 ) {
|
|
||||||
+ while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vVD", long_options, &option_index ) ) != -1 ) {
|
|
||||||
|
|
||||||
switch ( optchar ) {
|
|
||||||
|
|
||||||
@@ -381,6 +383,11 @@ void apply_init_args( int argc, char *ar
|
|
||||||
found_args++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
+ case 'D':
|
|
||||||
+ no_detach = 1;
|
|
||||||
+ found_args++;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
case 'h':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
@@ -539,12 +546,14 @@ void apply_init_args( int argc, char *ar
|
|
||||||
/* daemonize */
|
|
||||||
if (debug_level == 0) {
|
|
||||||
|
|
||||||
- if (my_daemon() < 0) {
|
|
||||||
+ if (!no_detach) {
|
|
||||||
+ if (my_daemon() < 0) {
|
|
||||||
|
|
||||||
- printf("Error - can't fork to background: %s\n", strerror(errno));
|
|
||||||
- restore_defaults();
|
|
||||||
- exit(EXIT_FAILURE);
|
|
||||||
+ printf("Error - can't fork to background: %s\n", strerror(errno));
|
|
||||||
+ restore_defaults();
|
|
||||||
+ exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
openlog("batmand", LOG_PID, LOG_DAEMON);
|
|
47
batmand/patches/100-2.6.36.patch
Normal file
47
batmand/patches/100-2.6.36.patch
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
batman/linux/modules/gateway.c | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
--- batmand-r1439.orig/linux/modules/gateway.c
|
||||||
|
+++ batmand-r1439/linux/modules/gateway.c
|
||||||
|
@@ -29,6 +29,7 @@ static struct class *batman_class;
|
||||||
|
static int batgat_open(struct inode *inode, struct file *filp);
|
||||||
|
static int batgat_release(struct inode *inode, struct file *file);
|
||||||
|
static int batgat_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg );
|
||||||
|
+static long batgat_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg );
|
||||||
|
|
||||||
|
|
||||||
|
static void udp_data_ready(struct sock *sk, int len);
|
||||||
|
@@ -53,7 +54,11 @@ static int proc_clients_read(char *buf,
|
||||||
|
static struct file_operations fops = {
|
||||||
|
.open = batgat_open,
|
||||||
|
.release = batgat_release,
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
|
||||||
|
+ .unlocked_ioctl = batgat_ioctl_unlocked,
|
||||||
|
+#else
|
||||||
|
.ioctl = batgat_ioctl,
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -166,6 +171,20 @@ static int batgat_release(struct inode *
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
|
||||||
|
+#include <linux/smp_lock.h>
|
||||||
|
+static long batgat_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg )
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ lock_kernel();
|
||||||
|
+ ret = batgat_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
|
||||||
|
+ unlock_kernel();
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int batgat_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg )
|
||||||
|
{
|
||||||
|
uint8_t tmp_ip[4];
|
342
bird1-openwrt/LUCI-DOCUMENTATION.md
Normal file
342
bird1-openwrt/LUCI-DOCUMENTATION.md
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
<!--
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(C) 2014 - 2017 Eloi Carbo <eloicaso@openmailbox.org>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
-->
|
||||||
|
|
||||||
|
# LUCI Bird{4|6} v0.3 Packages Documentation
|
||||||
|
* BIRD Daemon's official documentation: http://bird.network.cz/?get_doc
|
||||||
|
* Extra documentation in English & Catalan: https://github.com/eloicaso/bgp-bmx6-bird-docn
|
||||||
|
* If you want to add new options to bird*-openwrt packages add a pull request or issue in: https://github.com/eloicaso/bird-openwrt
|
||||||
|
|
||||||
|
> *Clarification*: This documentation covers luci-app-bird{4|6} as both are completely aligned and only those IPv4/6-specific options will be covered separately.
|
||||||
|
>
|
||||||
|
> Bird v1.6.3 has been used to test luci-app-bird{4|6}. Using newer versions of the Daemon might change the behaviour or messages documented here. Create an issue or pull request if you spot any mismatch in this document to address it.
|
||||||
|
|
||||||
|
# Table of contents
|
||||||
|
1. [Status Page](#status)
|
||||||
|
2. [Log Page](#log)
|
||||||
|
3. [Overview Page](#overview)
|
||||||
|
4. [General Protocols Page](#general)
|
||||||
|
5. [BGP Portocol](#bgp)
|
||||||
|
6. [Filters and Functions](#fnf)
|
||||||
|
|
||||||
|
|
||||||
|
## Status Page <a name="status"></a>
|
||||||
|
The Status Page allows you to Start, Stop and restart the service as well as to check the result of these operations.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Button* **Start**: Execute a Bird Daemon Service Start call. Operation's result is shown in the *Service Status* Text Box.
|
||||||
|
- *Button* **Stop**: Execute a Bird Daemon Service Stop call. Operation's result is shown in the *Service Status* Text Box.
|
||||||
|
- *Button* **Restart**: Execute a Bird Daemon Service Restart call. Operation's result is shown in the *Service Status* Text Box.
|
||||||
|
- *Text Box* **Service Status**: Executes a Bird Daemon Service Status call. Operation's result is shown as plain text.
|
||||||
|
|
||||||
|
#### Service Status common messages
|
||||||
|
* *Running*: Service is running with no issues
|
||||||
|
* *Already started*: You have clicked *Start* when the service was already running. No action taken.
|
||||||
|
* *Stopped*: You have clicked *Stop* when the service was running. Service has been stopped.
|
||||||
|
* *Already stopped*: You have clicked *Stop* when the service was already stopped. No action taken.
|
||||||
|
* *Stopped ... Started*: You have pressed *Restart* when the service was running. The service has been restarted.
|
||||||
|
* *Already stopped .. Started*: You have pressed *Restart* when the service was already stopped. The service has been started.
|
||||||
|
* *Failed - ERROR MESSAGE*: There is a configuration or validation issue that prevents Bird to start. Check the *Error Message* and the Log Page to debug it and fix it.
|
||||||
|
|
||||||
|
#### Error Examples
|
||||||
|
1. Validation issues:
|
||||||
|
`bird4: Failed - bird: /tmp/bird4.conf, line 65: syntax error`
|
||||||
|
|
||||||
|
If we check the file shown: `/tmp/bird4.conf` :
|
||||||
|
```
|
||||||
|
protocol bgp BGPExample {
|
||||||
|
import Filter NonExistingFilter;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
We have entered an invalid (non-existent in this case) filter name. In order to fix this, write the correct Filter Name or remove its reference from the BGP Protocol Configuration Page and start the service again.
|
||||||
|
|
||||||
|
2. Configuration issues:
|
||||||
|
` bird4: Failed - bird: /tmp/bird4.conf, line 76: Only internal neighbor can be RR client`
|
||||||
|
|
||||||
|
In this case, it is easy to spot that we have incorrectly selected the *Route Reflector Server* option incorrectly and we only need to untick it and start the service to solve it.
|
||||||
|
|
||||||
|
Usuarlly, any configuration issue will be flagged appropiately through Bird service messages. However, in the event where you do not have enough information, please look for advice in either Bird's documentation or in the affected Protocol's documentation.
|
||||||
|
|
||||||
|
## Log Page <a name="log"></a>
|
||||||
|
The Log Page shows the last 30 lines of the configured Bird Daemon Log file. This information is automatically refreshed each second.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Text Area* **Log File**: 30 lines text area that shows the Log file information
|
||||||
|
- *Text* **Using Log File** and **File Size**: The first line of the Text Area is fixed and shows the file being used and its current size. **Please**, check this size information regularly to avoid letting the Log information overflow your Storage as it will make your service stop and prevent it to start until you fix it.
|
||||||
|
- *Text* **File Contents**: The next 30 lines show information about the events and debug information happening live. Main information are state changes and *info, warning, fatal or trace*. If you hit any issue starting the service, you can investigate the issue from this page.
|
||||||
|
|
||||||
|
|
||||||
|
## Overview Page <a name="overview"></a>
|
||||||
|
The Overview Page includes the configuration of basic Bird Daemon settings such as UCI usage, Routing Tables definition and Global Options.
|
||||||
|
|
||||||
|
### Bird File Settings (UCI Usage)
|
||||||
|
This section enables/disables the use of this package's capabilities.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Use UCI configuration**:
|
||||||
|
- If enabled, the package will use the UCI configuration generated by this web settings and translate it into a Bird Daemon configuration file.
|
||||||
|
- If disabled, the package will do nothing and you will have to manually edit a Bird Daemon configuration file.
|
||||||
|
- *Text Box* **UCI File**: This file specifies the selected location for the translated Bird Daemon configuration file. Do not leave blank.
|
||||||
|
|
||||||
|
### Tables Configuration
|
||||||
|
This section allows you to set the Routing tables that will be used later in the different protocols. You can *Add* as many instances as required.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Text Box* **Table Name**: Set an unique (meaningful) routing table name.
|
||||||
|
> In some instances or protocols, you may want or be required to set a specific ID to a Table. In order to do this, please, follow this -right now- [manual procedure](https://github.com/eloicaso/bgp-bmx6-bird-docn/blob/master/EN/manual_procedures.md).
|
||||||
|
|
||||||
|
|
||||||
|
### Global Options
|
||||||
|
This section allows you to configure basic Bird Daemon settings.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Text Box* **Router ID**: Set the Identificator to be used in this Bird Daemon instance. This option must be:
|
||||||
|
> IPv4, this option will be set by default to the lowest IP Address configured. Otherwise, the identificator must be an IPv4 address.
|
||||||
|
|
||||||
|
> IPv6, this option is **mandatory** and must be a HEX value (Hexadecimal). This package (bird6-uci), provides the HEX value *0xCAFEBABE* as a default value to avoid initial crashes.
|
||||||
|
|
||||||
|
- *Text Box* **Log File**: Set the Name and Location of the Log file. By default, its location will be /tmp/bird{4|6}.log as the non-persistent partition.
|
||||||
|
- *Mutiple Value* **Log**: Set which elements you want Bird Daemon to log in the configured file.
|
||||||
|
> *Caution I*: if you select *All*, the other selected options will have no validity as, by definition, they are already included.
|
||||||
|
> *Caution II*: Take into consideration that the more elements Bird has to log, the more space you will require to store this log file. If your storage is full, Bird will fail to start until you free some space to store its Log data.
|
||||||
|
|
||||||
|
- *Multi Value* **Debug**: Set which Debug information elements you want Bird Daemon to log in the configured file.
|
||||||
|
> *Caution I*: if you select *All*, the other selected options will have no validity as, by definition, they are already included.
|
||||||
|
> *Caution II*: Take into consideration that the more elements Bird has to log, the more space you will require to store this log file (this is particularly critical in Debug as it can log MegaBytes of data quickly). If your storage is full, Bird will fail to start until you free some space to store its Log data.
|
||||||
|
|
||||||
|
## General Protocols <a name="general"></a>
|
||||||
|
The General Protocols Page includes the configuration of key OS Protocols or Network Basic Settings such as Kernel, Device or Static Routes.
|
||||||
|
|
||||||
|
### Kernel Options
|
||||||
|
This section allows you to set all the Kernel Protocols required to do Networking.
|
||||||
|
> The first Kernel instance is the Primary one and must be left by default for OS usage. Do not set its "Table" or "Kernel Table" options.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *List Value* **Table**: Select the Routing Table to be used in the Kernel Protocol instance.
|
||||||
|
> The Primary Kernel Protocol cannot be empty.
|
||||||
|
|
||||||
|
- *Text Box* **Import**: Set if the protocol must import routes and which ones.
|
||||||
|
- **all**: Accept all the incoming routes.
|
||||||
|
- **none**: Reject all the incoming routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which incoming routes will be accepted or rejected.
|
||||||
|
- *Text Box* **Export**: Set if the protocol must export routes and which ones.
|
||||||
|
- **all**: Accept all the outgoing routes.
|
||||||
|
- **none**: Reject all the outgoing routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which outgoing routes will be accepted or rejected.
|
||||||
|
- *Text Box* **Scan time**: Set the time between Kernel Routing Table scans. This value must be the same for all the Kernel Protocols.
|
||||||
|
- *Check Box* **Learn**: Set this option to allow the Kernel Protocol to learn Routes form other routing daemons or manually added by an admin.
|
||||||
|
- *Check Box* **Persist**: Set this option to store the routes learnt in the table until it is removed. Unset this option if you want to clean the routes on the fly.
|
||||||
|
- *Text Box* **Kernel Table**: Select the specific exitisting Routing Table for this Protocol instance.
|
||||||
|
> The Kernel Table ID must be previously set by the administrator during the Routing Table configuration. Currently (v0.3), this process is done manually. Please, follow this [manual procedure](https://github.com/eloicaso/bgp-bmx6-bird-docn/blob/master/EN/manual_procedures.md).
|
||||||
|
|
||||||
|
### Device Options
|
||||||
|
This section allows you to set all the Device *Protocol*. The Device *Protocol* is just a mechanism to bound the interfaces and Kernel tables in order to get its information.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *Text Box* **Scan Time**: Set the time between Kernel Routing Table scans. This value must be the same for all the Kernel Protocols.
|
||||||
|
|
||||||
|
### Static Options
|
||||||
|
This section allows you to create the container for Routes definition. Static protocol instances allows you to manually create Routes that Bird will use and which Routing Table should hold this information. It also helps to manage routes by marking them (i.e. *Unreachable*, *Blocked*, ...).
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *List Value* **Table**: Select the Routing Table to be used in the Static Protocol instance.
|
||||||
|
|
||||||
|
### Routes
|
||||||
|
This section allows to set which Routes will be set in a specific Static Protocol and how these should be handled.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *List Value* **Route Instance**: Set which Static Protocol instance will contain this route infromation.
|
||||||
|
> Routes require an existing Static Protocol as parent.
|
||||||
|
|
||||||
|
- *Text Box* **Route Prefix**: Set the Route instance to be defined.
|
||||||
|
> Examples of routes are:. 10.0.0.0/8 (IPv4) or 2001:DB8:3000:0/16 (IPv6)
|
||||||
|
|
||||||
|
- *List Value* **Type Of Route**: This value will set the conditional settings. Options are:
|
||||||
|
- **Router**: Classic routes going through specific IP Addresses.
|
||||||
|
- *Text Box* **Via**: Set the target IP Address to be used for Routing
|
||||||
|
> I.e. 10.0.0.0/8 via 10.1.1.1
|
||||||
|
|
||||||
|
- **MultiPath**: Multiple paths Route.
|
||||||
|
- *List of Text Box* **Via**: Set the target Route to be used for Routing. This option allows several instances of **Via** elements.
|
||||||
|
> I.e. 10.0.0.0/8 via 10.1.1.1
|
||||||
|
> via 10.1.1.100
|
||||||
|
> via 10.1.1.200
|
||||||
|
|
||||||
|
- **Special**: Special treated Route.
|
||||||
|
- *Text Box* **Attribute**: Block special consideration of routes.
|
||||||
|
> **unreachable**: Return route cannot be reached.
|
||||||
|
> **prohibit**: Return route has been administratively blocked.
|
||||||
|
> **blackhole**: Silently drop the route.
|
||||||
|
|
||||||
|
- **Iface**: Classic routes going through specific interfaces.
|
||||||
|
- *List Value* **Interface**: Select the target interface to route.
|
||||||
|
|
||||||
|
- **Recursive**: Set a static recursive route. Its next hope will depen on the table's lookup for each target IP Address.
|
||||||
|
|
||||||
|
### Direct Protocol
|
||||||
|
This section allows to set pools of *directly* connected interfaces. Direct Protocol instances will make use of the *Device* Protocol in order to generate routes between the selected interfaces.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *Text Box* **Interfaces**: This is the key option allowing to *tie* the interfaces and create direct routes between different sides. Enter each interface's name you want to couple.
|
||||||
|
- If you leave this option empty, it will tie all the interfaces together.
|
||||||
|
- Each interface must be quoted: i.e. `"eth0"`
|
||||||
|
- Several interfaces must be entered comma-separated: i.e. `"eth0", "wlan0"`
|
||||||
|
- If you want to restrict this to specific interfaces, you have to enter them using its name or a pattern: i.e. All the ethernet interfaces `"eth*"`
|
||||||
|
- You are allowed to **exclude** specific interfaces by adding `-` before the interface name: i.e. Exclude all the Wireless interfaces `"-wlan*"`
|
||||||
|
> Example: All the wired interfaces (eth and em) but exclude all the wireless and point-to-point interfaces: `"eth*", "em*", "-wlan*", "-ptp_*"`
|
||||||
|
|
||||||
|
> Current version 0.3 requires you to enter each interface you want to **include** or **exclude** manually. This will be enhanced in future versions.
|
||||||
|
|
||||||
|
### Pipe Protocol
|
||||||
|
This section allows to set instances of *linked* routing tables. Each instance will allow you to share the routes from a primary table to a secondary one.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *List Value* **Table**: Select the **Primary** Routing Table to be used.
|
||||||
|
- *List Value* **Peer Table**: Select the **Secondary** Routing Table to be used.
|
||||||
|
- *List Value* **Mode**: Set if you want to work in *transparent* or *opaque* mode.
|
||||||
|
- **Transparent**: Retransmits all the routes and its attributes. Therefore, you get two identical routing tables. This is the default behaviour.
|
||||||
|
- **Opaque**: This mode is not recommended for new configurations and it is not recommended. Tables will only share the optimal routes and overwrite route's attributes with new ones (Pipe).
|
||||||
|
- *Text Box* **Import**: Set if the protocol must import routes and which ones.
|
||||||
|
- **all**: Accept all the incoming routes.
|
||||||
|
- **none**: Reject all the incoming routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which incoming routes will be accepted or rejected.
|
||||||
|
- *Text Box* **Export**: Set if the protocol must export routes and which ones.
|
||||||
|
- **all**: Accept all the outgoing routes.
|
||||||
|
- **none**: Reject all the outgoing routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which outgoing routes will be accepted or rejected.
|
||||||
|
|
||||||
|
|
||||||
|
## BGP Protocol<a name="bgp"></a>
|
||||||
|
The BGP Protocol Page includes all the settings to configure BGP Templates and BGP instances.
|
||||||
|
BGP Templates and Instances share most of the options as Templates are meant to diminish the requirements on Instances.
|
||||||
|
> An extreme example case could be the Template holding all the options and the Instance only referencing to the Template as the only option..
|
||||||
|
|
||||||
|
### BGP Templates
|
||||||
|
This section allows you to set BGP Templates, which are commonly used BGP configuration*themes* to reduce the number of repeated settings while adding BGP Instances.
|
||||||
|
|
||||||
|
### BGP Instances
|
||||||
|
This section allows you to set BGP Instances. The Instances are the ones starting the BGP Protocol and can, or not, use a BGP Template to re-use the common properties.
|
||||||
|
> **Caution**: Any duplicated option between an Instance and a Template will resolve by using the Instance option and dismissing the Template one. **Instance** > *Template*.
|
||||||
|
|
||||||
|
#### BGP Instance Specific Option
|
||||||
|
- *List Value* **Templates**: Set the BGP Template that will feed the instance. Any option in the Template will be inherited.
|
||||||
|
|
||||||
|
#### Common Options
|
||||||
|
- *Check Box* **Disabled**: Set this Check Box if you do not want to configure and use this Protocol.
|
||||||
|
- *Text Area* **Description**: Set a descriptive text to identify this protocol and what it does.
|
||||||
|
- *Text Box* **Import**: Set if the protocol must import routes and which ones.
|
||||||
|
- **all**: Accept all the incoming routes.
|
||||||
|
- **none**: Reject all the incoming routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which incoming routes will be accepted or rejected.
|
||||||
|
- *Text Box* **Export**: Set if the protocol must export routes and which ones.
|
||||||
|
- **all**: Accept all the outgoing routes.
|
||||||
|
- **none**: Reject all the outgoing routes.
|
||||||
|
- **filter filterName**: Call an existing filter to define which outgoing routes will be accepted or rejected.
|
||||||
|
- *List Value* **Table**: Select the Routing Table to be used.
|
||||||
|
- *List Value* **IGP Table**: Set the IGP Routing Table (Internal BGP). Bird uses the same Routing Table for both External BGP and Internal BGP by default.
|
||||||
|
- *Text Area* **Source Address**: Set the local IP Address. By default the Router ID will be used.
|
||||||
|
- *Text Area* **Local AS**: Set the local BGP Autonomous System ID.
|
||||||
|
- *Text Area* **Local BGP Address**: Set the local BGP Autonomous System IP Address.
|
||||||
|
- *Text Area* **Neighbor IP Address**: Set BGP neighbour's IP Address.
|
||||||
|
- *Text Area* **Neighbor AS**: Set BGP neighbour's Autonomous System ID.
|
||||||
|
- *Check Box* **Next Hop Self**: Overwrite Next Hop cost attributes with its own source address as next hop. Disabled by default as it is only used in some specific instances.
|
||||||
|
- *Check Box* **Next Hop Keep**: Forward the same Next Hop information even in situations where the system would use its own source address instead. Disabled by default.
|
||||||
|
- *Check Box* **Route Reflector Server**: Set if BGP instance must act as a Route Reflector Server and expect neighbours AS to act as clients
|
||||||
|
- *Text Value* **Route Reflector Cluster ID**: Route Reflector service ID to avoid loops. This options is only allowed in the Server (not clients) and it is Router's ID by default.
|
||||||
|
- *Text Box* **Routes Import Limit**: Set the maximum number of routes the protocol will import.
|
||||||
|
- *List Value* **Routes Import Limit Action**: Set the action to apply if the *Routes Import Limit* is exceeded. Options are:
|
||||||
|
- **block**: Block any route exceeding the limit.
|
||||||
|
- **disable**: Stop the protocol.
|
||||||
|
- **warn**: Print Log warnings.
|
||||||
|
- **restart**: Restart the protocol.
|
||||||
|
- *Text Box* **Routes Export Limit**: Set the maximum number of routes the protocol will export.
|
||||||
|
- *List Value* **Routes Export Limit Action**: Set the action to apply if the *Routes Export Limit* is exceeded. Options are:
|
||||||
|
- **block**: Block any route exceeding the limit.
|
||||||
|
- **disable**: Stop BGP protocol.
|
||||||
|
- **warn**: Print Log warnings.
|
||||||
|
- **restart**: Restart BGP protocol.
|
||||||
|
- *Text Box* **Routes Received Limit**: Set the maximum number of shared routes the Protocol must accept and remember (the **number** of imported routes is not affected by this option).
|
||||||
|
- *List Value* **Routes Received Limit Action**: Set the action to apply if the *Routes Received Limit* is exceeded. Options are:
|
||||||
|
- **block**: Block any route exceeding the limit.
|
||||||
|
- **disable**: Stop BGP protocol.
|
||||||
|
- **warn**: Print Log warnings.
|
||||||
|
- **restart**: Restart BGP protocol.
|
||||||
|
|
||||||
|
|
||||||
|
## Filters and Functions<a name="fnf"></a>
|
||||||
|
The Filters and the Functions Page allows you to edit Bird Daemon Filter and Functions files without requiring you to go to command line. Both Pages share the same code base and the only main change is where they are getting the files from. Therefore, and for documentation simplicity sake, both pages will be covered in this section.
|
||||||
|
> From version 0.3 onwards:
|
||||||
|
> The default and supported place to store filter files is under `/etc/bird{4|6}/filters`.
|
||||||
|
> The default and supported place to store function files is under `/etc/bird{4|6}/functions`.
|
||||||
|
|
||||||
|
> Current version 0.3 does not allow changing file names. You will have to change the default filenames through SSH. This will be enhanced in future versions.
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- *List Value* **Filter Files** / **Function Files**: Set the Filter or Function file to edit from the ones under `/etc/bird{4|6}/filters` / `/etc/bird{4|6}/functions`.
|
||||||
|
> If you want to create a new Filter or Function file, use the **New File** element in the list.
|
||||||
|
|
||||||
|
> The default behaviour is to allow administrators to create new files using this scheme:
|
||||||
|
> */etc/bird{4|6}/filters/filter*-**TIMESTAMP**. *Timestamp* is: YYYYMMDD-HHMM. I.e. */etc/bird4/filters/filter-20170705-2030*
|
||||||
|
> */etc/bird{4|6}/functions/function*-**TIMESTAMP**. *Timestamp* is: YYYYMMDD-HHMM. I.e. */etc/bird4/functions/function-20170705-2030*
|
||||||
|
|
||||||
|
- *Button* **Load File**: Click this button to Load the file selected in the *{filter|function} Files* list. This button **must** be pressed in order to edit the target file.
|
||||||
|
- *Read Only Text Box* **Editing File**: This Read-Only field is empty by default. It will get populated with the target file to edit.
|
||||||
|
> **Caution**: Only if this field shows a file path, the contents of the target file can be edited and saved.
|
||||||
|
|
||||||
|
- *Text Area* **File Contents**: This text area will show the contents of the file shown in the *Editting File*. Save the contents of this text area by pressing the Button **Submit**
|
||||||
|
> Use **spaces** instead of **tabs** for indentation.
|
||||||
|
|
||||||
|
> **Caveat**: If you save your filter or function using the *New File* option, until you refresh the page, the **saved** file will still appear as *New File*. However, the file will be created and correctly stored and you will be able to edit it with no problems.
|
||||||
|
> After refreshing the page, your file will appear normally together with a new *New File* option.
|
||||||
|
> This behaviour will be enhanced in future versions.
|
||||||
|
|
||||||
|
#### Common Errors
|
||||||
|
Most common errors produced by Filters and Functions are:
|
||||||
|
|
||||||
|
- Syntax errors: `bird: /etc/bird4/filters/filter-20170507-0951, line 4: syntax error`
|
||||||
|
> This instances require you to check where your errors is following Bird's hints.
|
||||||
|
|
||||||
|
- Non-existing filter: `bird: /tmp/bird4.conf, line 71: No such filter.`
|
||||||
|
> Check your Filter name or define it in the **Filters Page**
|
||||||
|
|
||||||
|
- Calls to functions not defined in the Functions files or not part of the Bird filter/function definition *language*: `, line 4: You can't call something which is not a function. Really.`
|
||||||
|
> Check you Function definition, your call name or Bird's official documentation to get the right reference.
|
||||||
|
|
||||||
|
#### Critical Errors
|
||||||
|
There are some critical errors that could escape from first sight as Bird Daemon will start working *correctly*.
|
||||||
|
|
||||||
|
If you set your Filter **without** *accept* or *reject* calls, your filter will fail to work and let all the routes pass by as accepted. This will be shown in the **Log Page**:
|
||||||
|
|
||||||
|
Example: **Filter "doNothing"**
|
||||||
|
```
|
||||||
|
filter doNothing
|
||||||
|
{
|
||||||
|
print "HelloWorld";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This *wrong* filter has been used in our BGP instance and Bird Daemon runs correctly. However, if we check the **Log Page** we find:
|
||||||
|
```
|
||||||
|
2017-05-07 10:18:49 <ERR> Filter doNothing did not return accept nor reject. Make up your mind
|
||||||
|
2017-05-07 10:18:49 <INFO> HelloWorld
|
||||||
|
```
|
||||||
|
> Do not leave any filter without *accept* or *reject* calls to avoid this wrong behaviour that will incurr in a waste of resources.
|
80
bird1-openwrt/README.md
Normal file
80
bird1-openwrt/README.md
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# bird-openwrt
|
||||||
|
|
||||||
|
Package for OpenWRT to bring integration with UCI and LUCI to Bird4 and Bird6 daemon.
|
||||||
|
|
||||||
|
This repository contains an UCI module adding support for an user-friendly configuration of the BIRD daemon in OpenWRT systems and a LuCI application to control this UCI configuration using the web-based OpenWRT configuration system.
|
||||||
|
|
||||||
|
**Package Names**: luci-app-bird{4|6} and bird{4|6}-uci
|
||||||
|
|
||||||
|
**Dependences**: +bird{4|6} +libuci +luci-base +uci +libuci-lua
|
||||||
|
|
||||||
|
**Last Version**: 0.3
|
||||||
|
|
||||||
|
**Terminal (UCI) Documentation**: [Link](https://github.com/eloicaso/bird-openwrt/blob/master/UCI-DOCUMENTATION.md)
|
||||||
|
|
||||||
|
**Web (LUCI) Documentation**: [Link](https://github.com/eloicaso/bird-openwrt/blob/master/LUCI-DOCUMENTATION.md)
|
||||||
|
|
||||||
|
|
||||||
|
## Known issues (v0.3):
|
||||||
|
* There is an issue with pre-built images. It seems that the UCI-Default Scripts are not applied for some reason. If you face this situation, just copy both packages in your /tmp and and execute "opkg install PackageName.ipk --force-reinstall". It will overwrite your /etc/config/bird{4|6}, create a backup of this configuration.
|
||||||
|
|
||||||
|
* LUCI Material Design Theme shows a "Loading page" in **Logs Page** preventing it to load. Moreover, the OpenWRT Theme crashes loading the **Log Page**.
|
||||||
|
Please, go to `System -> Language and Style -> Design` and change it to any other avaiable Theme (*Bootstrap* or *Freifunk_Generic* are recommended).
|
||||||
|
|
||||||
|
* There is a manual procedure to designate custom Routing Table IDs created through this package's UI. Please, visit [this page](https://github.com/eloicaso/bgp-bmx6-bird-docn/blob/master/EN/manual_procedures.md) for more details.
|
||||||
|
|
||||||
|
## How to compile:
|
||||||
|
Due to the existence of Routing's bird-openwrt packages, if you want to build your system using this repo's bird packages, you need to proceed as follows:
|
||||||
|
|
||||||
|
|
||||||
|
* Add this github as a repository in feeds.conf. Alternatively, you could use a local git clone)
|
||||||
|
```
|
||||||
|
src-git birdwrt https://github.com/eloicaso/bird-openwrt.git
|
||||||
|
|
||||||
|
```
|
||||||
|
OR
|
||||||
|
```
|
||||||
|
src-link birdwrt /path/to/your/git/clone/bird-openwrt
|
||||||
|
```
|
||||||
|
|
||||||
|
* Disable OpenWRT-Routing repository to avoid getting the outdated package
|
||||||
|
```
|
||||||
|
# src-git routing https://github.com/openwrt-routing/packages.git
|
||||||
|
```
|
||||||
|
|
||||||
|
* Update and install all packages in feeds
|
||||||
|
```
|
||||||
|
./scripts/feeds update -a; ./scripts/feeds install -a
|
||||||
|
```
|
||||||
|
|
||||||
|
* Enable OpenWRT-Routing repository to fulfill bird{4/6} dependencies
|
||||||
|
```
|
||||||
|
src-git routing https://github.com/openwrt-routing/packages.git
|
||||||
|
./scripts/feeds update routing; ./scripts/feeds install bird4 bird6
|
||||||
|
```
|
||||||
|
|
||||||
|
* Compile (Option 1) the whole OpenWRT image with the package included
|
||||||
|
```
|
||||||
|
make menuconfig -> Network -> Routing and Redirection -> Select bird*-uci
|
||||||
|
-> LuCI -> 3. Applications -> Select luci-app-bird*
|
||||||
|
make V=99
|
||||||
|
```
|
||||||
|
|
||||||
|
* Compile (Option 2) the packet ( ! this method requires to compile its dependeces before using Option 1)
|
||||||
|
```
|
||||||
|
make package/feeds/birdwrt/bird{4/6}-openwrt/compile V=99
|
||||||
|
```
|
||||||
|
|
||||||
|
* Find your package in
|
||||||
|
```
|
||||||
|
[OpenWRT_folder]/bin/packages/{Architecture}/routing/bird{4/6}-uci_{Version}_{Architecture}.ipk
|
||||||
|
[OpenWRT_folder]/bin/packages/{Architecture}/routing/luci-app-bird{4/6}_{Version}_{Architecture}.ipk
|
||||||
|
```
|
||||||
|
|
||||||
|
* Install your .ipk in your dev-environment (avoid CheckSum Missmatch issues)
|
||||||
|
```
|
||||||
|
scp bird{4/6}-uci_{Version}_{Architecture}.ipk user@IPAddres:/tmp
|
||||||
|
|
||||||
|
On your Dev-Environment:
|
||||||
|
opkg install bird{4/6}-uci_{Version}_{Architecture}.ipk --force-checksum
|
||||||
|
```
|
345
bird1-openwrt/UCI-DOCUMENTATION.md
Normal file
345
bird1-openwrt/UCI-DOCUMENTATION.md
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
<!--
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(C) 2014 - 2017 Eloi Carbo <eloicaso@openmailbox.org>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Bird{4|6} UCI Packages Documentation
|
||||||
|
* BIRD Daemon's original documentation: http://bird.network.cz/?get_doc
|
||||||
|
* Usage examples (Gitlab): https://gitlab.labs.nic.cz/labs/bird/wikis/home
|
||||||
|
* Extra documentation in English & Catalan: https://github.com/eloicaso/bgp-bmx6-bird-docn
|
||||||
|
* If you want to add new options to bird*-openwrt packages add a pull request or issue in: https://github.com/eloicaso/bird-openwrt
|
||||||
|
|
||||||
|
### Options used in /etc/config/bird{4|6}
|
||||||
|
> *Clarification*: Any reference to **{4|6}** in this document means that it applies to both Bird4 and Bird6 packages and configurations. Otherwise, the text will clarify which specific package is affected by it.
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 1: 'bird'
|
||||||
|
Usage example :
|
||||||
|
``` Bash
|
||||||
|
config bird 'bird'
|
||||||
|
option use_UCI_config '1'
|
||||||
|
option UCI_config_file '/tmp/bird4.conf'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **use_UCI_config**: *Boolean*
|
||||||
|
This option allows you to use package's UCI configuration translation instead of using the original Bird config file (hand-edited). If true/1, birdX init.d script will use the translation placed in "UCI_config_file". Otherwise, it will use the default "/etc/birdX.conf" configuration.
|
||||||
|
**\[HINT**\] This could be used to allow multiple configurations and swap them easily.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
* **UCI_config_file**: *String* File_path
|
||||||
|
This option sets where will be placed the translation of the UCI configuration file.
|
||||||
|
*Default: /tmp/birdX.conf*
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 2: 'global NAME'
|
||||||
|
Usage example:
|
||||||
|
```Bash
|
||||||
|
config global 'global'
|
||||||
|
option log_file '/tmp/bird4.log'
|
||||||
|
option log 'all'
|
||||||
|
option debug 'off'
|
||||||
|
option router_id '172.16.1.6'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **log_file**: *String* File_path
|
||||||
|
This option sets the path of the file used to save Bird Log and Debug's information.
|
||||||
|
*Default: /tmp/bird{4|6}.log*
|
||||||
|
|
||||||
|
* **log**: *String/Enumeration* (all/off, info, warning, error, fatal, debug, trace, remote, auth, bug)
|
||||||
|
This option allows you to set which information you want to save in the Log file.
|
||||||
|
**\[HINT\]** Use the enumeration like: { info, waning, error }. Do not enter any extra option if you select "all" (Bird will fail to start).
|
||||||
|
*Default: all*
|
||||||
|
|
||||||
|
* **debug**: *String/Enumeration* ( all/off, states, routes, filters, interfaces, events, packets)
|
||||||
|
This option allows you to set which **extra** debug information will be saved in the "log_file" file.
|
||||||
|
**\[HINT\]** Use the enumeration like: { info, waning, error }. Do not enter any extra option if you select "all" (Bird will fail to start).
|
||||||
|
*Default: off*
|
||||||
|
|
||||||
|
* **router_id**: IP Address
|
||||||
|
This option sets which will be the Router ID.
|
||||||
|
**\[HINT\]** In **Bird4** this field is the lowest IP address (not loopback) among the existing interfaces by default (Optional property).
|
||||||
|
In **Bird6** there is no default value and it is mandatory.
|
||||||
|
|
||||||
|
* **listen_bgp_addr**: IP Address
|
||||||
|
This option sets the IP address that Bird BGP instances will listen by default.
|
||||||
|
*Default: 0.0.0.0*
|
||||||
|
|
||||||
|
* **listen_bgp_port**: *Integer* Port
|
||||||
|
This option sets the port that Bird BGP instances will listen by default.
|
||||||
|
*Default: IP 0.0.0.0 and Port 179*
|
||||||
|
|
||||||
|
* **listen_bgp_dual**: *Boolean*
|
||||||
|
**\[Bird6\]** This option configures Bird6 BGP instances to listen only IPv6 or IPv4/6 BGP routes.
|
||||||
|
|
||||||
|
|
||||||
|
#### <a name="table"></a>CONFIGURATION SECTION 3: 'table'
|
||||||
|
Usage example:
|
||||||
|
``` Bash
|
||||||
|
config table
|
||||||
|
option name 'aux'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **name**: *String*
|
||||||
|
This option allows you to set the name of the auxiliar kernel tables used for Bird. This option is mandatory for most of the protocols.
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 4: 'kernel NAME'
|
||||||
|
Usage example:
|
||||||
|
``` Bash
|
||||||
|
config kernel kernel1
|
||||||
|
option table 'aux'
|
||||||
|
option import 'all'
|
||||||
|
option export 'all'
|
||||||
|
option kernel_table '100'
|
||||||
|
option scan_time '10'
|
||||||
|
option learn '1'
|
||||||
|
option persist '0'
|
||||||
|
option disabled '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **table**: *String*
|
||||||
|
Set an auxiliary table for the current kernel routing instance. This table **MUST** exist as a [table](#table) instance.
|
||||||
|
**\[HINT\]** If there is an Kernel protocol instance that uses the "main" kernel table, not using table/kernel_table options, this should be included before the rest of Kernel instances (which will use auxiliary tables).
|
||||||
|
|
||||||
|
* **import**: *String/Filter* function
|
||||||
|
This option delimits which routes coming from other protocols will be accepted.
|
||||||
|
Options are:
|
||||||
|
**All/none**: allows to import all the routes or none of them.
|
||||||
|
**Filter name**: \[import 'bgp_filter_in'\] the protocol will use the filter with the given name (Specified filter **must** exists in any file under /etc/bird{4|6}/filters/ folder).
|
||||||
|
|
||||||
|
* export: String/Filter function
|
||||||
|
This option delimits which routes going out from the protocol. This option allows filters in different manners:
|
||||||
|
**All/none**: allows to export all the routes or none of them.
|
||||||
|
**Filter name**: \[export 'bgp_filter_out'\] the protocol will use the filter with the given name(Specified filter **must** exists in any file under /etc/bird{4|6}/filters/ folder).
|
||||||
|
|
||||||
|
* **kernel_table**: *Integer*
|
||||||
|
This option sets the identification number of the Kernel table that will be used instead of the main one.
|
||||||
|
*Default: main table (254)*
|
||||||
|
|
||||||
|
* **scan_time**: *Integer*
|
||||||
|
This option sets the time between checks to target kernel table.
|
||||||
|
|
||||||
|
* **learn**: *Boolean*
|
||||||
|
Set if kernel table will add the routes from other routing protocols or the system administrator.
|
||||||
|
|
||||||
|
* **persist**: *Boolean*
|
||||||
|
Set if Bird Daemon will save the known routes when exiting or if it will clean the routing table.
|
||||||
|
|
||||||
|
* **disable**: *Boolean*
|
||||||
|
This option sets if the protocol will be used or dismissed.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 5: 'device NAME'
|
||||||
|
Usage example:
|
||||||
|
``` Bash
|
||||||
|
config device device1
|
||||||
|
option scan_time '10'
|
||||||
|
option disabled '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **scan_time***: *Integer*
|
||||||
|
This option sets the time between checks to the selected kernel table.
|
||||||
|
|
||||||
|
* **disable**: *Boolean*
|
||||||
|
This option sets if the protocol will be used or dismissed.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 6: 'static NAME'
|
||||||
|
Usage example:
|
||||||
|
``` Bash
|
||||||
|
config static static1
|
||||||
|
option table 'aux'
|
||||||
|
option disabled '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **table**: *String*
|
||||||
|
Set an auxiliary table for the current static instance. This table **MUST** exist as a [table](#table) instance.
|
||||||
|
**\[HINT\]** If there is an static instance that uses the "main" kernel table (not using table/kernel_table options), this should be included before the rest of static instances (which will use auxiliary tables).
|
||||||
|
|
||||||
|
* **disable**: *Boolean*
|
||||||
|
This option sets if the protocol will be used or dismissed.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 7 & 8: 'bgp NAME' & 'bgp_template NAME'
|
||||||
|
This section merges two different configuration sections: BGP *instances* and *templates*. The first one is the basic BGP configuration part and the second one is the template used to minimize the number of options written in the configuration file for each unique instance. Both configuration sections have the same options but, when Bird finds duplicities, the instance will overwrite the template options.
|
||||||
|
|
||||||
|
Usage examples:
|
||||||
|
``` Bash
|
||||||
|
# instance
|
||||||
|
config bgp bgp1
|
||||||
|
option template 'bgp_common'
|
||||||
|
option description 'Description of the BGP instance'
|
||||||
|
option neighbor_address '172.16.1.5'
|
||||||
|
option neighbor_as '65530'
|
||||||
|
option source_address '172.16.1.6'
|
||||||
|
option next_hop_self '0'
|
||||||
|
option next_hop_keep '0'
|
||||||
|
option rr_client '1'
|
||||||
|
option rr_cluster_id '172.16.1.6'
|
||||||
|
```
|
||||||
|
|
||||||
|
``` Bash
|
||||||
|
# template
|
||||||
|
config bgp_template bgp_common
|
||||||
|
option table 'aux'
|
||||||
|
option import 'all'
|
||||||
|
option export 'all'
|
||||||
|
option local_address '172.16.1.6'
|
||||||
|
option local_as '65001'
|
||||||
|
option import_limit '100'
|
||||||
|
option import_limit_action 'warn'
|
||||||
|
option export_limit '100'
|
||||||
|
option export_limit_action 'warn'
|
||||||
|
option receive_limit '100'
|
||||||
|
option receive_limit_action 'warn'
|
||||||
|
option disabled '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **template**: *String*
|
||||||
|
This option states the template used for current BGP instance. This template MUST exist.
|
||||||
|
|
||||||
|
* **description**: *String*
|
||||||
|
This option allows to add a description of the bgp instance and its function.
|
||||||
|
|
||||||
|
* **local_addr**: IP address
|
||||||
|
This option allows to set the IP source of our Autonomous System (AS).
|
||||||
|
|
||||||
|
* **local_as**: *Integer*
|
||||||
|
This option allows to set the identification number of our AS number. This option is mandatory for each BGP instance.
|
||||||
|
|
||||||
|
* **neighbor_addr**: IP address
|
||||||
|
Each BGP instance has a neighbor connected to. This option allows to set its IP address.
|
||||||
|
|
||||||
|
* **neighbor_as**: *Integer*
|
||||||
|
Each BGP instance has a neighbor connected to. This option allows to set its AS ID.
|
||||||
|
|
||||||
|
* **next_hop_self**: *Boolean*
|
||||||
|
If this option is true, BGP protocol will avoid to calculate the next hop and always advertise own "Router id" IP.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
* **next_hop_keep**: *Boolean*
|
||||||
|
If this option is true, BGP will always use the received next_hop information to redirect the route.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
* **rr_client**: *Boolean*
|
||||||
|
IF this option is true, the router will be set as Route Reflector and will treat the rest of the routers as RR clients.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
* **rr_cluster_id**: *Integer*
|
||||||
|
This option sets the identification number of the RR cluster. All the nodes in a cluster needs this option and share the same number.
|
||||||
|
*Default: Router id*
|
||||||
|
|
||||||
|
* **import_limit**: *Integer*
|
||||||
|
This option sets the limit of routes that a protocol can import until take the action indicated in the import_limit_action.
|
||||||
|
import_limit also counts filtered routes (even dropped ones).
|
||||||
|
*Default: 0 (no limit)*
|
||||||
|
|
||||||
|
* **import_limit_action**: *String*
|
||||||
|
This option allows to decide the action to take when reached the limit of imported routes.
|
||||||
|
Actions are: warn, block, restart, disable
|
||||||
|
|
||||||
|
* **export_limit**: *Integer*
|
||||||
|
This option sets the limit of routes that a protocol can export until take the action indicated in the export_limit_action.
|
||||||
|
*Default: 0 (no limit)*
|
||||||
|
|
||||||
|
* **export_limit_action**: *String*
|
||||||
|
This option allows to decide the action to take when reached the limit of exported routes.
|
||||||
|
Actions are: warn, block, restart, disable
|
||||||
|
|
||||||
|
* **receive_limit**: *Integer*
|
||||||
|
This option sets the limit of routes that a protocol can receive until take the action indicated in the receive_limit_action. receive_limit only counts accepted routes from the protocol.
|
||||||
|
*Default: 0 (no limit)*
|
||||||
|
|
||||||
|
* **receive_limit_action**: *String*
|
||||||
|
This option allows to decide the action to take when reached the limit of received routes.
|
||||||
|
Actions are: warn, block, restart, disable
|
||||||
|
|
||||||
|
* **disable**: *Boolean*
|
||||||
|
This option sets if the protocol will be used or dismissed.
|
||||||
|
*Default: 0*
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 9: 'route'
|
||||||
|
Usage example:
|
||||||
|
``` Bash
|
||||||
|
config route
|
||||||
|
option instance 'static1'
|
||||||
|
option type 'router'
|
||||||
|
option prefix '192.168.9.0/24'
|
||||||
|
option via '10.99.105.159'
|
||||||
|
|
||||||
|
config route
|
||||||
|
option instance 'static1'
|
||||||
|
option type 'special'
|
||||||
|
option prefix '192.168.2.0/24'
|
||||||
|
option attribute 'unreachable'
|
||||||
|
|
||||||
|
config route
|
||||||
|
option instance 'static1'
|
||||||
|
option type 'iface'
|
||||||
|
option prefix '192.168.3.0/24'
|
||||||
|
option iface 'mgmt0'
|
||||||
|
|
||||||
|
config route
|
||||||
|
option instance 'static1'
|
||||||
|
option type 'recursive'
|
||||||
|
option prefix '192.168.4.0/24'
|
||||||
|
option ip '192.168.1.1'
|
||||||
|
|
||||||
|
config route
|
||||||
|
option instance 'static1'
|
||||||
|
option type 'multipath'
|
||||||
|
option prefix '192.168.30.0/24'
|
||||||
|
list l_via '172.16.1.5'
|
||||||
|
list l_via '172.16.1.6'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **instance**: *String*
|
||||||
|
This option indicates the route that the static protocol instance will apply.
|
||||||
|
|
||||||
|
* **type**: *String*
|
||||||
|
This option states the type of route that will be applied. Also defines the options available for it.
|
||||||
|
Types are: 'router', 'special', 'iface', 'recursive' or 'multipath'.
|
||||||
|
|
||||||
|
* **prefix**: IP address/network
|
||||||
|
This option allows to define the network that you want to define.
|
||||||
|
**\[router only\]**
|
||||||
|
**via**: IP Address
|
||||||
|
This option indicates the IP address of the neighbor router where the routes will pass through.
|
||||||
|
**\[special only\]**
|
||||||
|
**attribute**: *String*
|
||||||
|
This option will mark the behaviour of the route.
|
||||||
|
Attribures are: 'blackhole', 'unreachable' or 'prohibit'.
|
||||||
|
**\[iface only\]**
|
||||||
|
**iface**: *String*
|
||||||
|
This option indicates the interface used to redirect the BGP routes. Careful, the interface MUST exist, or Bird will fail to start.
|
||||||
|
**\[recursive only\]**
|
||||||
|
**ip**: IP address
|
||||||
|
This option states the IP address which the next hop will depend on.
|
||||||
|
**\[multipath only\]**
|
||||||
|
This is a list, not an option. Use it as in the example, or check the UCI configuration documentation.
|
||||||
|
**l_via**: IP address
|
||||||
|
This list of IPs specifies the list (following the sequence) of routers that the route will follow as next hops.
|
||||||
|
|
||||||
|
|
||||||
|
#### CONFIGURATION SECTION 10 & 11: 'filter NAME' & 'function Name'
|
||||||
|
Filters are written in separated files under **/etc/bird{4|6}/filters/** and **/etc/bird{4|6}/functions/**. Their syntax can be found [here.](http://bird.network.cz/?get_doc&f=bird-5.html)
|
||||||
|
The content of each filter and file file will be included in the resulting bird{4|6}.conf file without checking its syntax, so you could find errors during start time.
|
||||||
|
|
||||||
|
* Clarification for any existing **v0.2** user: an automated upgrade path has been added to switch your old "filter" or "function" sections. It is safe to upgrade, but doing regular backups of your key files is always a good practise to avoid frustration.
|
103
bird1-openwrt/bird1-ipv4-openwrt/Makefile
Normal file
103
bird1-openwrt/bird1-ipv4-openwrt/Makefile
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# Copyright (C) 2014-2017 Eloi Carbo <eloicaso@openmailbox.org>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
|
BIRD := bird4
|
||||||
|
BIRD_PKG := bird1-ipv4
|
||||||
|
PKG_NAME := $(BIRD_PKG)-openwrt
|
||||||
|
PKG_VERSION := 0.3
|
||||||
|
PKG_RELEASE := 1
|
||||||
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
PKG_LICENSE := GPL-3.0+
|
||||||
|
uci := $(BIRD_PKG)-uci
|
||||||
|
luci := luci-app-$(BIRD_PKG)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
endef
|
||||||
|
define Build/Compile
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(uci)
|
||||||
|
TITLE:=The BIRD UCI module (v1.6) (IPv4)
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
SUBMENU:=Routing and Redirection
|
||||||
|
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
|
||||||
|
URL:=https://github.com/eloicaso/bird-openwrt/
|
||||||
|
DEPENDS:=+$(BIRD_PKG) +libuci +uci
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(uci)/description
|
||||||
|
$(BIRD_PKG) UCI integration module
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(uci)/conffiles
|
||||||
|
/etc/config/$(BIRD)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(uci)/install
|
||||||
|
$(INSTALL_DIR) $(1)/etc/$(BIRD)/init.d
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_DIR) $(1)/etc/$(BIRD)/filters
|
||||||
|
$(INSTALL_DIR) $(1)/etc/$(BIRD)/functions
|
||||||
|
$(INSTALL_BIN) ./src/init.d/$(BIRD)* $(1)/etc/$(BIRD)/init.d/
|
||||||
|
$(CP) ./src/uci-defaults/* $(1)/etc/$(BIRD)/init.d/
|
||||||
|
$(INSTALL_CONF) ./src/config/$(BIRD) $(1)/etc/config/
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(uci)/postinst
|
||||||
|
#!/bin/sh
|
||||||
|
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||||
|
( . /etc/$(BIRD)/init.d/bird-uci-install-init.d $(BIRD) ) && rm -f /etc/$(BIRD)/init.d/bird-uci-install-init.d
|
||||||
|
( . /etc/$(BIRD)/init.d/99-relocate-filters $(BIRD) ) && rm -f /etc/$(BIRD)/init.d/99-relocate-filters
|
||||||
|
if [ -f /etc/sysupgrade.conf ] && ! grep $(BIRD) /etc/sysupgrade.conf; then
|
||||||
|
echo /etc/config/$(BIRD) >> /etc/sysupgrade.conf
|
||||||
|
echo /etc/$(BIRD)/filters/ >> /etc/sysupgrade.conf
|
||||||
|
echo /etc/$(BIRD)/functions/ >> /etc/sysupgrade.conf
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,$(uci)))
|
||||||
|
|
||||||
|
define Package/$(luci)
|
||||||
|
TITLE:=LuCI support for $(BIRD_PKG)
|
||||||
|
SECTION:=luci
|
||||||
|
CATEGORY:=LuCI
|
||||||
|
SUBMENU:=3. Applications
|
||||||
|
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
|
||||||
|
URL:=https://github.com/eloicaso/bird-openwrt/
|
||||||
|
DEPENDS:=+$(BIRD_PKG)-uci +luci-base
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(luci)/description
|
||||||
|
$(BIRD) application for LuCI
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/$(luci)/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/$(BIRD)/
|
||||||
|
$(CP) ./src/model/* $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
|
||||||
|
$(CP) ./src/controller/* $(1)/usr/lib/lua/luci/controller/
|
||||||
|
$(CP) ./src/view/* $(1)/usr/lib/lua/luci/view/$(BIRD)/
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,$(luci)))
|
33
bird1-openwrt/bird1-ipv4-openwrt/src/config/bird4
Normal file
33
bird1-openwrt/bird1-ipv4-openwrt/src/config/bird4
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
config bird 'bird'
|
||||||
|
option use_UCI_config '1'
|
||||||
|
#Caution! Enabling this option, Bird will translate this
|
||||||
|
#UCI file and use it instead of /etc/bird4.conf
|
||||||
|
option UCI_config_file '/tmp/bird4.conf'
|
||||||
|
#If you enable useUCIconfig, UCIconfigFile will be Bird's
|
||||||
|
#configuration file location.
|
||||||
|
|
||||||
|
config global 'global'
|
||||||
|
option log_file '/tmp/bird4.log'
|
||||||
|
option log 'all'
|
||||||
|
option debug 'off'
|
||||||
|
|
||||||
|
config table
|
||||||
|
option name 'aux'
|
||||||
|
|
||||||
|
config kernel kernel1
|
||||||
|
option table 'aux'
|
||||||
|
option import 'all'
|
||||||
|
option export 'all'
|
||||||
|
option kernel_table '100'
|
||||||
|
option scan_time '10'
|
||||||
|
option learn '1'
|
||||||
|
option persist '0'
|
||||||
|
option disabled '0'
|
||||||
|
|
||||||
|
config device device1
|
||||||
|
option scan_time '10'
|
||||||
|
option disabled '0'
|
||||||
|
|
||||||
|
config static static1
|
||||||
|
option table 'aux'
|
||||||
|
option disabled '0'
|
52
bird1-openwrt/bird1-ipv4-openwrt/src/controller/bird4.lua
Normal file
52
bird1-openwrt/bird1-ipv4-openwrt/src/controller/bird4.lua
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
module("luci.controller.bird4", package.seeall)
|
||||||
|
|
||||||
|
function index()
|
||||||
|
entry({"admin", "network", "bird4",},
|
||||||
|
alias("admin", "network", "bird4", "status"),
|
||||||
|
_("Bird4"), 0)
|
||||||
|
|
||||||
|
entry({"admin", "network", "bird4", "status"},
|
||||||
|
cbi("bird4/status"),
|
||||||
|
_("Status"), 0).leaf = true
|
||||||
|
|
||||||
|
entry({"admin","network","bird4","log"},
|
||||||
|
template("bird4/log"),
|
||||||
|
_("Log"), 1).leaf = true
|
||||||
|
|
||||||
|
entry({"admin", "network", "bird4", "overview"},
|
||||||
|
cbi("bird4/overview"),
|
||||||
|
_("Overview"), 2).leaf = true
|
||||||
|
|
||||||
|
entry({"admin","network","bird4","proto_general"},
|
||||||
|
cbi("bird4/gen_proto"),
|
||||||
|
_("General protocols"), 3).leaf = true
|
||||||
|
|
||||||
|
entry({"admin","network","bird4","proto_bgp"},
|
||||||
|
cbi("bird4/bgp_proto"),
|
||||||
|
_("BGP Protocol"), 4).leaf = true
|
||||||
|
|
||||||
|
entry({"admin","network","bird4","filters"},
|
||||||
|
cbi("bird4/filters"),
|
||||||
|
_("Filters"), 5).leaf = true
|
||||||
|
|
||||||
|
entry({"admin","network","bird4","functions"},
|
||||||
|
cbi("bird4/functions"),
|
||||||
|
_("Functions"), 6).leaf = true
|
||||||
|
end
|
233
bird1-openwrt/bird1-ipv4-openwrt/src/init.d/bird4
Executable file
233
bird1-openwrt/bird1-ipv4-openwrt/src/init.d/bird4
Executable file
|
@ -0,0 +1,233 @@
|
||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
# Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Extra Service Function to get the Status of the Service
|
||||||
|
# This complements /etc/rc.common functions
|
||||||
|
# Commands ending with *_quiet are meant to be ran in Luci. These
|
||||||
|
# scripts' return minimal output.
|
||||||
|
EXTRA_COMMANDS="status start_quiet stop_quiet restart_quiet status_quiet"
|
||||||
|
EXTRA_HELP=" status Returns service status"
|
||||||
|
|
||||||
|
BIRD="bird4"
|
||||||
|
BIRD_CONFIG="/etc/${BIRD}.conf"
|
||||||
|
BIRD_LOG="/var/log/${BIRD}.log"
|
||||||
|
BIRD_ERR="/tmp/${BIRD}.err"
|
||||||
|
|
||||||
|
START=99
|
||||||
|
STOP=10
|
||||||
|
|
||||||
|
SERVICE_DAEMONIZE=1
|
||||||
|
SERVICE_USE_PID=1
|
||||||
|
SERVICE_PID_FILE="/var/run/${BIRD}.pid"
|
||||||
|
|
||||||
|
BIRD_BIN="/usr/sbin/${BIRD}"
|
||||||
|
# Special non-terminal-rich output for Luci calls
|
||||||
|
LUCI="false"
|
||||||
|
|
||||||
|
. /etc/${BIRD}/init.d/${BIRD}-lib.sh
|
||||||
|
|
||||||
|
start() {
|
||||||
|
config_load ${BIRD}
|
||||||
|
local use_UCI_config
|
||||||
|
get use_UCI_config 'bird'
|
||||||
|
|
||||||
|
#Start the service
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo "Starting ${BIRD} Service [ ... ]"
|
||||||
|
fi
|
||||||
|
if [ -f ${BIRD_ERR} ]; then
|
||||||
|
echo -n "" > ${BIRD_ERR}
|
||||||
|
else
|
||||||
|
touch ${BIRD_ERR}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${use_UCI_config}" -o "${use_UCI_config}" = "0" ]; then
|
||||||
|
# Disable Custom bird-openwrt settings.
|
||||||
|
# Use default behaviour and files
|
||||||
|
${BIRD_BIN} -d -c ${BIRD_CONFIG} -P ${SERVICE_PID_FILE} -D ${BIRD_LOG} &> ${BIRD_ERR} &
|
||||||
|
else
|
||||||
|
#Set Bird4 configuration location:
|
||||||
|
local UCI_config_file
|
||||||
|
local log_file
|
||||||
|
get UCI_config_file 'bird'
|
||||||
|
get log_file 'global'
|
||||||
|
BIRD_CONFIG="${UCI_config_file:-$BIRD_CONFIG}"
|
||||||
|
BIRD_LOG="${log_file:-$BIRD_LOG}"
|
||||||
|
#Backup previous configuration
|
||||||
|
[ -f ${BIRD_CONFIG} ] && cp ${BIRD_CONFIG} ${BIRD_CONFIG}.bak
|
||||||
|
#Setup the basic configuration
|
||||||
|
prepare_global 'global'
|
||||||
|
|
||||||
|
# Gather and set all Functions
|
||||||
|
gather_functions
|
||||||
|
# Gather and set all Filters
|
||||||
|
gather_filters
|
||||||
|
|
||||||
|
# Setup Main Protocols
|
||||||
|
config_foreach prepare_kernel 'kernel'
|
||||||
|
config_foreach prepare_static 'static'
|
||||||
|
config_foreach prepare_device 'device'
|
||||||
|
config_foreach prepare_direct 'direct'
|
||||||
|
config_foreach prepare_pipe 'pipe'
|
||||||
|
|
||||||
|
#Setup protocol's configuration: BGP
|
||||||
|
config_foreach prepare_bgp_template 'bgp_template'
|
||||||
|
config_foreach prepare_bgp 'bgp'
|
||||||
|
|
||||||
|
#Setup protocol's configuration: OSPF
|
||||||
|
config_foreach prepare_ospf_instance 'ospf'
|
||||||
|
|
||||||
|
#Start the service
|
||||||
|
${BIRD_BIN} -d -c ${BIRD_CONFIG} -P ${SERVICE_PID_FILE} -D ${BIRD_LOG} &>${BIRD_ERR} &
|
||||||
|
fi
|
||||||
|
while [ ! -s ${SERVICE_PID_FILE} ]; do
|
||||||
|
sleep 1
|
||||||
|
if [ -s ${BIRD_ERR} ]; then
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon Start Status: \033[0;31m[ FAILED ]\e[m"
|
||||||
|
cat ${BIRD_ERR}
|
||||||
|
cat ${BIRD_ERR} >> ${BIRD_LOG}
|
||||||
|
else
|
||||||
|
echo "${BIRD} - Failed: $(cat ${BIRD_ERR})"
|
||||||
|
cat ${BIRD_ERR} >> ${BIRD_LOG}
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# PID & ERROR contents are read from their files to avoid an issue
|
||||||
|
# where if [ -s ${SERVICE_PID_FILE} ] and if [ -s ${BIRD_ERR} ]
|
||||||
|
# fails unless a previous command reads its contents making its
|
||||||
|
# behaviour unreliable.
|
||||||
|
SVC_PID="$(cat ${SERVICE_PID_FILE})"
|
||||||
|
BRDERR_TXT="$(cat ${BIRD_ERR})"
|
||||||
|
if [ -n "${SVC_PID}" ]; then
|
||||||
|
if [ -n "${BRDERR_TXT}" ]; then
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon already started. Status \033[0;32m[ RUNNING ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD} already started"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon Start Status: \033[0;32m[ STARTED ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD} - Started"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# PID File found (service started correctly)
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# PID File not found (error while starting service)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if [ -s ${SERVICE_PID_FILE} ]; then
|
||||||
|
config_load ${BIRD}
|
||||||
|
local log_file
|
||||||
|
get log_file 'global'
|
||||||
|
BIRD_LOG="${log_file:-$BIRD_LOG}"
|
||||||
|
start-stop-daemon -p ${SERVICE_PID_FILE} -K 2>&1 >> ${BIRD_LOG}
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon Stop Status: \033[0;32m[ OK ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD} - Stopped"
|
||||||
|
fi
|
||||||
|
echo -n "" > ${BIRD_ERR}
|
||||||
|
else
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon Stop Status: \033[0;31m[ FAILED ]\e[m"
|
||||||
|
echo "Check ${BIRD_LOG} file for more information."
|
||||||
|
else
|
||||||
|
echo "${BIRD} Failed to Stop. See Log file: ${BIRD_LOG}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} Daemon Service already stopped. \033[0;31m[ FAILED ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD} already stopped"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
stop
|
||||||
|
sleep 1
|
||||||
|
if [ "${LUCI}" == "true" ]; then
|
||||||
|
echo " ... "
|
||||||
|
fi
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
service_reload ${BIRD_BIN}
|
||||||
|
}
|
||||||
|
|
||||||
|
status() {
|
||||||
|
if [ -s ${SERVICE_PID_FILE} ]; then
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} start status: \033[0;32m[ RUNNING ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD}: Running"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if [ -s ${BIRD_ERR} ]; then
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} service status: \033[0;31m[ STOPPED ]\e[m"
|
||||||
|
cat ${BIRD_ERR}
|
||||||
|
else
|
||||||
|
echo "${BIRD}: Failed - $(cat ${BIRD_ERR})"
|
||||||
|
fi
|
||||||
|
return 2
|
||||||
|
else
|
||||||
|
if [ "${LUCI}" == "false" ]; then
|
||||||
|
echo -e "${BIRD} service status: \033[0;31m[ STOPPED ]\e[m"
|
||||||
|
else
|
||||||
|
echo "${BIRD}: Stopped"
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Luci-specific calls (stripped output).
|
||||||
|
# The following scripts are not meant to be ran using Ash Terminal
|
||||||
|
# Used in: LUCI/model/cbi/bird4/status.lua
|
||||||
|
start_quiet() {
|
||||||
|
LUCI="true"
|
||||||
|
start
|
||||||
|
}
|
||||||
|
stop_quiet() {
|
||||||
|
LUCI="true"
|
||||||
|
stop
|
||||||
|
}
|
||||||
|
restart_quiet() {
|
||||||
|
LUCI="true"
|
||||||
|
restart
|
||||||
|
}
|
||||||
|
status_quiet() {
|
||||||
|
LUCI="true"
|
||||||
|
status
|
||||||
|
}
|
587
bird1-openwrt/bird1-ipv4-openwrt/src/init.d/bird4-lib.sh
Normal file
587
bird1-openwrt/bird1-ipv4-openwrt/src/init.d/bird4-lib.sh
Normal file
|
@ -0,0 +1,587 @@
|
||||||
|
# Bird4-OpenWRT Library - Functions used in /etc/init.d/bird4 script.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
# Function: writeToConfig $1
|
||||||
|
# $1 string.
|
||||||
|
# Allows to write in the $BIRD_CONFIG file, the string $1. This function does not check the $1 string.
|
||||||
|
# Example: writeToConfig "value: $N"
|
||||||
|
writeToConfig() {
|
||||||
|
echo "$1" >> ${BIRD_CONFIG}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: write $1 $2
|
||||||
|
# $1 string. $2 string.
|
||||||
|
# This function checks if $2 is empty. If not, it writes the string $1 in the $BIRD_CONFIG file.
|
||||||
|
# Use write function to check if $1, value found inside $2, is not empty and can be written in the configuration file.
|
||||||
|
# Example: N=""; write "value: $N" $N;
|
||||||
|
write() {
|
||||||
|
[ -n "$2" ] && writeToConfig "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#Function: write_bool $1 $2
|
||||||
|
# $1 string; $2 boolean
|
||||||
|
# This function checks if $2 is true and write the $1 string into $BIRD_CONFIG file.
|
||||||
|
# Example: local N=0; write_bool $N
|
||||||
|
write_bool() {
|
||||||
|
[ "$2" == 1 ] && writeToConfig " $1;"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: get $1 $2
|
||||||
|
# $1 string. $2 string
|
||||||
|
# This function uses the external UCI function "config_get $result $section $option" to obtain a string value from UCI config file.
|
||||||
|
# To use this function, use the same name of the UCI option for the variable.
|
||||||
|
# Example: UCI (option id 'abcd'); local id; get id $section
|
||||||
|
get() {
|
||||||
|
config_get $1 $2 $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: get_bool $1 $2
|
||||||
|
# $1 boolean. $2 string
|
||||||
|
# This function uses the external UCI function "config_get_bool $result $section $option" to obtain a boolean value from UCI config file.
|
||||||
|
# To use this function, use the same name of the UCI option for the variable $1.
|
||||||
|
# Example: UCI (option use_ipv6 '1'); local use_ipv6; get use_ipv6 $section
|
||||||
|
get_bool() {
|
||||||
|
config_get_bool $1 $2 $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: multipath_list $1
|
||||||
|
# $1 string
|
||||||
|
# This function writes the $1 string in the multipath routes.
|
||||||
|
multipath_list() {
|
||||||
|
write " via $1" $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: range_list $1
|
||||||
|
# $1 string
|
||||||
|
# This function writes the $1 string in the OSPF networks.
|
||||||
|
range_list(){
|
||||||
|
write " $1;" $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: hidden_range_list $1
|
||||||
|
# $1 string
|
||||||
|
# This function writes the $1 string in the OSPF networks as hidden.
|
||||||
|
hidden_range_list(){
|
||||||
|
write " $1 hidden;" $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_tables $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "table" section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI table section
|
||||||
|
prepare_tables() {
|
||||||
|
local section="$1"; local name
|
||||||
|
|
||||||
|
get name ${section}
|
||||||
|
|
||||||
|
write "table ${name};" ${name}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_global $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "global" section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI global section. prepare_global is the first configuration set in the bird4.conf and removes the old file.
|
||||||
|
prepare_global () {
|
||||||
|
local section="$1"
|
||||||
|
local log_file; local log; local debug; local router_id; local table
|
||||||
|
|
||||||
|
# Remove old configuration file
|
||||||
|
rm -f "${BIRD_CONFIG}"
|
||||||
|
|
||||||
|
get log_file ${section}
|
||||||
|
get log ${section}
|
||||||
|
get debug ${section}
|
||||||
|
get router_id ${section}
|
||||||
|
get table ${section}
|
||||||
|
|
||||||
|
# First line of the NEW configuration file
|
||||||
|
echo "#Bird4 configuration using UCI:" > ${BIRD_CONFIG}
|
||||||
|
writeToConfig " "
|
||||||
|
#TODO: Set Syslog as receiver if empty
|
||||||
|
# LOGF="${log_file:-syslog]}"
|
||||||
|
#TODO: If $log/$debug are empty, set to off
|
||||||
|
if [ -n "${log_file}" -a -n "${log}" ]; then
|
||||||
|
firstEntry="${log:0:3}"
|
||||||
|
if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
|
||||||
|
writeToConfig 'log "'${log_file}'" '${firstEntry}';'
|
||||||
|
else
|
||||||
|
logEntries=$(echo ${log} | tr " " ",")
|
||||||
|
writeToConfig "log \"${log_file}\" { ${logEntries} };"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${debug}" ]; then
|
||||||
|
firstEntry="${debug:0:3}"
|
||||||
|
if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
|
||||||
|
writeToConfig "debug protocols ${firstEntry};"
|
||||||
|
else
|
||||||
|
debugEntries=$(echo ${debug} | tr " " ",")
|
||||||
|
writeToConfig "debug protocols { ${debugEntries} };"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
writeToConfig " "
|
||||||
|
writeToConfig "#Router ID"
|
||||||
|
write "router id ${router_id};" ${router_id}
|
||||||
|
writeToConfig " "
|
||||||
|
writeToConfig "#Secondary tables"
|
||||||
|
config_foreach prepare_tables 'table'
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_routes $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "route" section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI route section. Each type of route has its own treatment.
|
||||||
|
prepare_routes() {
|
||||||
|
local instance; local prefix; local via; local type; local attribute; local iface
|
||||||
|
local section="$1"
|
||||||
|
local protoInstance="$2"
|
||||||
|
|
||||||
|
get instance ${section}
|
||||||
|
get type ${section}
|
||||||
|
get prefix ${section}
|
||||||
|
|
||||||
|
if [ "${instance}" = "${protoInstance}" ]; then
|
||||||
|
case "${type}" in
|
||||||
|
"router")
|
||||||
|
get via ${section}
|
||||||
|
[ -n "${prefix}" -a -n "${via}" ] && writeToConfig " route ${prefix} via ${via};"
|
||||||
|
;;
|
||||||
|
"special")
|
||||||
|
get attribute ${section}
|
||||||
|
[ -n "${prefix}" -a -n "${attribute}" ] && writeToConfig " route ${prefix} ${attribute};"
|
||||||
|
;;
|
||||||
|
"iface")
|
||||||
|
get iface ${section}
|
||||||
|
[ -n "${prefix}" -a -n "${iface}" ] && writeToConfig ' route '${prefix}' via "'${iface}'";'
|
||||||
|
;;
|
||||||
|
"multipath")
|
||||||
|
write " route ${prefix} multipath" ${prefix}
|
||||||
|
config_list_foreach ${section} l_via multipath_list
|
||||||
|
writeToConfig " ;"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_kernel $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "kernel" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI kernel section.
|
||||||
|
prepare_kernel() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local table; local kernel_table; local import; local export
|
||||||
|
local scan_time; local persist; local learn
|
||||||
|
|
||||||
|
get_bool disabled ${section}
|
||||||
|
get table ${section}
|
||||||
|
get import ${section}
|
||||||
|
get export ${section}
|
||||||
|
get scan_time ${section}
|
||||||
|
get kernel_table ${section}
|
||||||
|
get learn ${section}
|
||||||
|
get persist ${section}
|
||||||
|
|
||||||
|
write "#${section} configuration:" ${section}
|
||||||
|
writeToConfig "protocol kernel ${section} {" ${section}
|
||||||
|
write_bool disabled ${disabled}
|
||||||
|
write " table ${table};" ${table}
|
||||||
|
write " kernel table ${kernel_table};" ${kernel_table}
|
||||||
|
write_bool learn ${learn}
|
||||||
|
write_bool persist ${persist}
|
||||||
|
write " scan time ${scan_time};" ${scan_time}
|
||||||
|
write " import ${import};" ${import}
|
||||||
|
write " export ${export};" ${export}
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_static $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "static" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI static section.
|
||||||
|
prepare_static() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local table
|
||||||
|
|
||||||
|
get disabled ${section}
|
||||||
|
get table ${section}
|
||||||
|
|
||||||
|
if [ "${disabled}" -eq 0 ]; then
|
||||||
|
writeToConfig "#${section} configration:" ${section}
|
||||||
|
writeToConfig "protocol static {"
|
||||||
|
write " table ${table};" ${table}
|
||||||
|
config_foreach prepare_routes 'route' ${section}
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_direct $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "direct" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI direct section.
|
||||||
|
prepare_direct() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local interface
|
||||||
|
|
||||||
|
get disabled ${section}
|
||||||
|
get interface ${section}
|
||||||
|
|
||||||
|
write "#${section} configuration:" ${section}
|
||||||
|
writeToConfig "protocol direct {"
|
||||||
|
write_bool disabled ${disabled}
|
||||||
|
write " interface ${interface};" ${interface}
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_pipe $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "pipe" protocol section in the UCI configuration an
|
||||||
|
# $1 is set as the ID of the current UCI direct section.
|
||||||
|
prepare_pipe() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local table; local peer_table; local mode; local import; local export
|
||||||
|
|
||||||
|
get disabled $section
|
||||||
|
get peer_table $section
|
||||||
|
get mode $section
|
||||||
|
get table $section
|
||||||
|
get import $section
|
||||||
|
get export $section
|
||||||
|
|
||||||
|
write "#$section configuration:" $section
|
||||||
|
writeToConfig "protocol pipe $section {" $section
|
||||||
|
write_bool disabled $disabled
|
||||||
|
write " table $table;" $table
|
||||||
|
write " peer table $peer_table;" $peer_table
|
||||||
|
write " mode $mode;" $mode
|
||||||
|
write " import $import;" $import
|
||||||
|
write " export $export;" $export
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_device $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "device" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI device section.
|
||||||
|
prepare_device() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local scan_time
|
||||||
|
|
||||||
|
get disabled ${section}
|
||||||
|
get scan_time ${section}
|
||||||
|
|
||||||
|
write "#${section} configuration:" ${section}
|
||||||
|
writeToConfig "protocol device {"
|
||||||
|
write_bool disabled ${disabled}
|
||||||
|
write " scan time ${scan_time};" ${scan_time}
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_bgp_template $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "bgp_template" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI bgp_template section.
|
||||||
|
# Careful! Template options will be replaced by "instance" options if there is any match.
|
||||||
|
prepare_bgp_template() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local table; local import; local export
|
||||||
|
local local_as; local neighbor_address; local neighbor_as; local source_address
|
||||||
|
local next_hop_self; local next_hop_keep; local rr_client; local rr_cluster_id
|
||||||
|
local import_limit; local import_limit_action; local export_limit; local export_limit_action
|
||||||
|
local receive_limit; local receive_limit_action; local igp_table
|
||||||
|
|
||||||
|
get_bool disabled ${section}
|
||||||
|
get table ${section}
|
||||||
|
get import ${section}
|
||||||
|
get export ${section}
|
||||||
|
get source_address ${section}
|
||||||
|
|
||||||
|
get local_as ${section}
|
||||||
|
get neighbor_address ${section}
|
||||||
|
get neighbor_as ${section}
|
||||||
|
|
||||||
|
get_bool next_hop_self ${section}
|
||||||
|
get_bool next_hop_keep ${section}
|
||||||
|
get rr_client ${section}
|
||||||
|
get rr_cluster_id ${section}
|
||||||
|
|
||||||
|
get import_limit ${section}
|
||||||
|
get import_limit_action ${section}
|
||||||
|
get export_limit ${section}
|
||||||
|
get export_limit_action ${section}
|
||||||
|
|
||||||
|
get receive_limit ${section}
|
||||||
|
get receive_limit_action ${section}
|
||||||
|
get igp_table ${section}
|
||||||
|
|
||||||
|
writeToConfig "#${section} template:"
|
||||||
|
writeToConfig "template bgp ${section} {"
|
||||||
|
[ -n "${disabled}" ] && write_bool disabled ${disabled}
|
||||||
|
[ -n "${table}" ] && writeToConfig " table ${table};"
|
||||||
|
[ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
|
||||||
|
[ -n "${local_as}" ] && writeToConfig " local as ${local_as};"
|
||||||
|
[ -n "${source_address}" ] && writeToConfig " source address ${source_address};"
|
||||||
|
[ -n "${import}" ] && writeToConfig " import ${import};"
|
||||||
|
[ -n "${export}" ] && writeToConfig " export ${export};"
|
||||||
|
[ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
|
||||||
|
if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
|
||||||
|
[ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
|
||||||
|
writeToConfig " import limit ${import_limit} action ${import_limit_action};"
|
||||||
|
fi
|
||||||
|
if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
|
||||||
|
[ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
|
||||||
|
writeToConfig " export limit ${export_limit} action ${export_limit_action};"
|
||||||
|
fi
|
||||||
|
if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
|
||||||
|
[ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
|
||||||
|
writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
|
||||||
|
fi
|
||||||
|
[ -n "${next_hop_self}" ] && write_bool " next hop self;" ${next_hop_self}
|
||||||
|
[ -n "${next_hop_keep}" ] && write_bool " next hop keep;" ${next_hop_keep}
|
||||||
|
[ -n "${rr_client}" ] && write_bool " rr client;" ${rr_client}
|
||||||
|
[ -n "${rr_cluster_id}" ] && writeToConfig " rr cluster id ${rr_cluster_id};"
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_bgp $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "bgp" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI bgp section.
|
||||||
|
# Careful! The options set in bgp instances overlap bgp_template ones.
|
||||||
|
prepare_bgp() {
|
||||||
|
local section="$1"
|
||||||
|
local disabled; local table; local template; local description; local igp_table; local passive
|
||||||
|
local import; local export; local source_address; local local_as; local neighbor_address
|
||||||
|
local neighbor_as; local rr_client; local rr_cluster_id; local import_limit
|
||||||
|
local import_limit_action; local export_limit; local export_limit_action
|
||||||
|
local receive_limit; local receive_limit_action; local igp_table
|
||||||
|
|
||||||
|
get disabled ${section}
|
||||||
|
get table ${section}
|
||||||
|
get igp_table ${section}
|
||||||
|
get template ${section}
|
||||||
|
get description ${section}
|
||||||
|
get passive ${section}
|
||||||
|
|
||||||
|
get import ${section}
|
||||||
|
get export ${section}
|
||||||
|
get source_address ${section}
|
||||||
|
get local_as ${section}
|
||||||
|
get neighbor_address ${section}
|
||||||
|
|
||||||
|
get neighbor_as ${section}
|
||||||
|
get import_limit ${section}
|
||||||
|
get import_limit_action ${section}
|
||||||
|
get export_limit ${section}
|
||||||
|
get export_limit_action ${section}
|
||||||
|
|
||||||
|
get receive_limit ${section}
|
||||||
|
get receive_limit_action ${section}
|
||||||
|
get_bool next_hop_self ${section}
|
||||||
|
get_bool next_hop_keep ${section}
|
||||||
|
get rr_client ${section}
|
||||||
|
get rr_cluster_id ${section}
|
||||||
|
|
||||||
|
writeToConfig "#${section} configuration:"
|
||||||
|
[ -n "${template}" ] && writeToConfig "protocol bgp ${section} from ${template} {" \
|
||||||
|
|| writeToConfig "protocol bgp ${section} {"
|
||||||
|
[ -n "${disabled}" ] && write_bool disabled ${disabled}
|
||||||
|
[ -n "${table}" ] && writeToConfig " table ${table};"
|
||||||
|
[ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
|
||||||
|
[ -n "${passive}" ] && writeToConfig " passive;" ${passive}
|
||||||
|
[ -n "${local_as}" ] && writeToConfig " local as ${local_as};"
|
||||||
|
[ -n "${source_address}" ] && writeToConfig " source address ${source_address};"
|
||||||
|
[ -n "${import}" ] && writeToConfig " import ${import};"
|
||||||
|
[ -n "${export}" ] && writeToConfig " export ${export};"
|
||||||
|
[ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
|
||||||
|
if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
|
||||||
|
[ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
|
||||||
|
writeToConfig " import limit ${import_limit} action ${import_limit_action};"
|
||||||
|
fi
|
||||||
|
if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
|
||||||
|
[ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
|
||||||
|
writeToConfig " export limit ${export_limit} action ${export_limit_action};"
|
||||||
|
fi
|
||||||
|
if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
|
||||||
|
[ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
|
||||||
|
writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
|
||||||
|
fi
|
||||||
|
[ -n "${next_hop_self}" ] && write_bool " next hop self;" ${next_hop_self}
|
||||||
|
[ -n "${next_hop_keep}" ] && write_bool " next hop keep;" ${next_hop_keep}
|
||||||
|
[ -n "${rr_client}" ] && write_bool " rr client;" ${rr_client}
|
||||||
|
[ -n "${rr_cluster_id}" ] && writeToConfig " rr cluster id ${rr_cluster_id};"
|
||||||
|
writeToConfig "}"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#Function: prepare_ospf_network $1
|
||||||
|
# $1 string $2 string
|
||||||
|
# This function gets each "ospf_network" protocol section in the UCI configuration, checks if its Area ID is the same as the one
|
||||||
|
# being configurated and finally sets the list of network ranges to be propagated, or not, by the OSPF protocol
|
||||||
|
# $1 is set as the ID of the action area of the internal networks.
|
||||||
|
# $2 is set as the ID of the current area being configurated.
|
||||||
|
prepare_ospf_networks() {
|
||||||
|
local section="$1"
|
||||||
|
local current_area="$2"
|
||||||
|
|
||||||
|
if [ "${section}" = "${current_area}" ]; then
|
||||||
|
writeToConfig " networks {"
|
||||||
|
config_list_foreach ${section} range range_list
|
||||||
|
config_list_foreach ${section} hidden_range hidden_range_list
|
||||||
|
writeToConfig " };"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_ospf_password $1 $2
|
||||||
|
prepare_ospf_passwords() {
|
||||||
|
local section="$1"
|
||||||
|
local current_interface="$2"
|
||||||
|
local interface; local passphrase
|
||||||
|
|
||||||
|
get interface $section
|
||||||
|
get passphrase $section
|
||||||
|
|
||||||
|
[ "current_interface" = "${interface}" ] && write ' password "$passphrase";' ${passphrase}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_ospf_neighbors $1 $2
|
||||||
|
#prepare_ospf_neighbors() {
|
||||||
|
#}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_ospf_interface $1 $2
|
||||||
|
prepare_ospf_interface() {
|
||||||
|
local section="$1"
|
||||||
|
local current_area="$2"
|
||||||
|
local area; local cost; local type; local hello; local priority; local retransmit; local authentication
|
||||||
|
|
||||||
|
get area ${section}
|
||||||
|
get cost ${section}
|
||||||
|
get type ${section}
|
||||||
|
get hello ${section}
|
||||||
|
get priority ${section}
|
||||||
|
get retransmit ${section}
|
||||||
|
|
||||||
|
if [ "${current_area}" = "${area}" ]; then
|
||||||
|
writeToConfig ' interface "$section" {'
|
||||||
|
write " cost ${cost};" ${cost}
|
||||||
|
write " hello ${hello};" ${hello}
|
||||||
|
write " type ${type};" ${type}
|
||||||
|
write " retransmit ${retransmit};" ${retransmit}
|
||||||
|
write " authentication ${authentication};" ${authentication}
|
||||||
|
config_foreach prepare_ospf_passwords "ospf_password" ${section}
|
||||||
|
# config_foreach prepare_ospf_neighbors "ospf_neighbor" $section
|
||||||
|
writeToConfig " };"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_ospf_area $1
|
||||||
|
prepare_ospf_area() {
|
||||||
|
local section="$1"
|
||||||
|
local instance; local stub; local default_cost
|
||||||
|
|
||||||
|
get instance ${section}
|
||||||
|
get stub ${section}
|
||||||
|
get default_cost ${section}
|
||||||
|
|
||||||
|
writeToConfig " area ${section} {"
|
||||||
|
if [ -n "${instance}" -a "${instance}" = "${section}" ]; then
|
||||||
|
[ -n "${stub}" -a "${stub}" = "1" ] && writeToConfig " stub yes;"
|
||||||
|
[ -n "${default_cost}" ] && writeToConfig " default cost ${default_cost};"
|
||||||
|
config_foreach prepare_ospf_networks "ospf_networks" ${section}
|
||||||
|
config_foreach prepare_ospf_interface "ospf_interface" ${section}
|
||||||
|
writeToConfig " };"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: prepare_ospf_instance $1
|
||||||
|
# $1 string
|
||||||
|
# This function gets each "ospf_area" protocol section in the UCI configuration and sets each option in the bird4.conf file.
|
||||||
|
# $1 is set as the ID of the current UCI ospf_area section.
|
||||||
|
prepare_ospf_instance() {
|
||||||
|
local section="$1"
|
||||||
|
local cfg1583compat; local tick
|
||||||
|
|
||||||
|
get cfg1583compat ${section}
|
||||||
|
get tick ${section}
|
||||||
|
|
||||||
|
writeToConfig "protocol ospf ${section} {"
|
||||||
|
[ -n "${cfg1583compat}" ] && cfg1583State="yes" || cfg1583State="no"
|
||||||
|
writeToConfig " rfc1583compat ${cfg1583State};"
|
||||||
|
[ -n "${tick}" ] && writeToConfig " tick ${tick};"
|
||||||
|
config_foreach prepare_ospf_area 'ospf_area'
|
||||||
|
writeToConfig "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: gather_filters
|
||||||
|
# This function gets all the FILES under /filters folder and adds
|
||||||
|
# them into the config as %include elements on top of the file
|
||||||
|
# If there are no filters, the section will remain empty.
|
||||||
|
gather_filters() {
|
||||||
|
writeToConfig "#Filters Section:"
|
||||||
|
for filter in $(find /etc/${BIRD}/filters -type f); do
|
||||||
|
writeToConfig "include \"${filter}\";"
|
||||||
|
done
|
||||||
|
writeToConfig "#End of Filters --"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Function: gather_functions
|
||||||
|
# This function gets all the FILES under /functions folder and adds
|
||||||
|
# them into the config as %include elements on top of the file
|
||||||
|
# If there are no filters, the section will remain empty.
|
||||||
|
gather_functions() {
|
||||||
|
writeToConfig "#Functions Section:"
|
||||||
|
for func in $(find /etc/${BIRD}/functions -type f); do
|
||||||
|
writeToConfig "include \"${func}\";"
|
||||||
|
done
|
||||||
|
writeToConfig "#End of Functions --"
|
||||||
|
writeToConfig " "
|
||||||
|
}
|
282
bird1-openwrt/bird1-ipv4-openwrt/src/model/bgp_proto.lua
Normal file
282
bird1-openwrt/bird1-ipv4-openwrt/src/model/bgp_proto.lua
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require("luci.sys")
|
||||||
|
local http = require "luci.http"
|
||||||
|
local uci = luci.model.uci.cursor()
|
||||||
|
|
||||||
|
-- Repeated Strings
|
||||||
|
local common_string = "Valid options are:<br />" .. "1. all (All the routes)<br />" .. "2. none (No routes)<br />" .. "3. filter <b>Your_Filter_Name</b> (Call a specific filter from any of the available in the filters files)"
|
||||||
|
local imp_string = "Set if the protocol must import routes.<br />" .. common_string
|
||||||
|
local exp_string = "Set if the protocol must export routes.<br />" .. common_string
|
||||||
|
|
||||||
|
m=Map("bird4", "Bird4 BGP protocol's configuration")
|
||||||
|
|
||||||
|
tab_templates = {}
|
||||||
|
uci:foreach('bird4', 'bgp_template', function (s)
|
||||||
|
local name = s[".name"]
|
||||||
|
if (name ~= nil) then
|
||||||
|
table.insert(tab_templates, name)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- BGP TEMPLATES
|
||||||
|
--
|
||||||
|
sect_templates = m:section(TypedSection, "bgp_template", "BGP Templates", "Configuration of the templates used in BGP instances.")
|
||||||
|
sect_templates.addremove = true
|
||||||
|
sect_templates.anonymous = false
|
||||||
|
|
||||||
|
disabled = sect_templates:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
|
||||||
|
disabled.optional=true
|
||||||
|
|
||||||
|
table = sect_templates:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
|
||||||
|
table.optional=true
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
table:value(s.name)
|
||||||
|
end)
|
||||||
|
table:value("")
|
||||||
|
table.default = ""
|
||||||
|
|
||||||
|
igp_table = sect_templates:option(ListValue, "igp_table", "IGP Table", "Select the IGP Routing Table to use. Hint: usually the same table as BGP.")
|
||||||
|
igp_table.optional = true
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function(s)
|
||||||
|
igp_table:value(s.name)
|
||||||
|
end)
|
||||||
|
igp_table:value("")
|
||||||
|
igp_table.default = ""
|
||||||
|
|
||||||
|
import = sect_templates:option(Value, "import", "Import", imp_string)
|
||||||
|
import.optional=true
|
||||||
|
|
||||||
|
export = sect_templates:option(Value, "export", "Export", exp_string)
|
||||||
|
export.optional=true
|
||||||
|
|
||||||
|
source_addr = sect_templates:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
|
||||||
|
source_addr.optional = true
|
||||||
|
|
||||||
|
local_as = sect_templates:option(Value, "local_as", "Local AS", "")
|
||||||
|
local_as.optional = false
|
||||||
|
|
||||||
|
next_hop_self = sect_templates:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
|
||||||
|
next_hop_self.default = nil
|
||||||
|
next_hop_self.optional = true
|
||||||
|
|
||||||
|
next_hop_keep = sect_templates:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
|
||||||
|
next_hop_keep.default = nil
|
||||||
|
next_hop_keep.optional = true
|
||||||
|
|
||||||
|
rr_client = sect_templates:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
|
||||||
|
rr_client.default = nil
|
||||||
|
rr_client.optional = true
|
||||||
|
|
||||||
|
rr_cluster_id = sect_templates:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
|
||||||
|
rr_cluster_id.optional = true
|
||||||
|
|
||||||
|
import_trigger = sect_templates:option(Flag, "import_trigger", "Import Limit", "Enable Routes Import limit settings")
|
||||||
|
import_trigger.default = 0
|
||||||
|
import_trigger.rmempty = false
|
||||||
|
import_trigger.optional = false
|
||||||
|
|
||||||
|
import_limit = sect_templates:option(Value, "import_limit", "Routes import limit", "Specify an import route limit.")
|
||||||
|
import_limit:depends({import_trigger = "1"})
|
||||||
|
import_limit.rmempty = true
|
||||||
|
|
||||||
|
import_limit_action = sect_templates:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
|
||||||
|
import_limit_action:depends({import_trigger = "1"})
|
||||||
|
import_limit_action:value("warn")
|
||||||
|
import_limit_action:value("block")
|
||||||
|
import_limit_action:value("disable")
|
||||||
|
import_limit_action:value("restart")
|
||||||
|
import_limit_action.default = "warn"
|
||||||
|
import_limit_action.rmempty = true
|
||||||
|
|
||||||
|
export_trigger = sect_templates:option(Flag, "export_trigger", "Export Limit", "Enable Routes Export limit settings")
|
||||||
|
export_trigger.default = 0
|
||||||
|
export_trigger.rmempty = false
|
||||||
|
export_trigger.optional = false
|
||||||
|
|
||||||
|
export_limit = sect_templates:option(Value, "export_limit", "Routes export limit", "Specify an export route limit.")
|
||||||
|
export_limit:depends({export_trigger = "1"})
|
||||||
|
export_limit.rmempty = true
|
||||||
|
|
||||||
|
export_limit_action = sect_templates:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
|
||||||
|
export_limit_action:depends({export_trigger = "1"})
|
||||||
|
export_limit_action.rmempty = true
|
||||||
|
export_limit_action:value("warn")
|
||||||
|
export_limit_action:value("block")
|
||||||
|
export_limit_action:value("disable")
|
||||||
|
export_limit_action:value("restart")
|
||||||
|
export_limit_action.default = "warn"
|
||||||
|
|
||||||
|
receive_trigger = sect_templates:option(Flag, "receive_trigger", "Received Limit", "Enable Routes Received Limit settings")
|
||||||
|
receive_trigger.default = 0
|
||||||
|
receive_trigger.rmempty = false
|
||||||
|
receive_trigger.optional = false
|
||||||
|
|
||||||
|
receive_limit = sect_templates:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit.")
|
||||||
|
receive_limit:depends({receive_trigger = "1"})
|
||||||
|
receive_limit.rmempty = true
|
||||||
|
|
||||||
|
receive_limit_action = sect_templates:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
|
||||||
|
receive_limit_action:depends({receive_trigger = "1"})
|
||||||
|
receive_limit_action:value("warn")
|
||||||
|
receive_limit_action:value("block")
|
||||||
|
receive_limit_action:value("disable")
|
||||||
|
receive_limit_action:value("restart")
|
||||||
|
receive_limit_action.default = "warn"
|
||||||
|
receive_limit_action.rmempty= true
|
||||||
|
|
||||||
|
--
|
||||||
|
-- BGP INSTANCES
|
||||||
|
--
|
||||||
|
sect_instances = m:section(TypedSection, "bgp", "BGP Instances", "Configuration of the BGP protocol instances")
|
||||||
|
sect_instances.addremove = true
|
||||||
|
sect_instances.anonymous = false
|
||||||
|
|
||||||
|
disabled = sect_instances:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
|
||||||
|
disabled.optional = false
|
||||||
|
disabled.rmempty = false
|
||||||
|
disabled.default = nil
|
||||||
|
|
||||||
|
templates = sect_instances:option(ListValue, "template", "Templates", "Available BGP templates")
|
||||||
|
uci:foreach("bird4", "bgp_template",
|
||||||
|
function(s)
|
||||||
|
templates:value(s[".name"])
|
||||||
|
end)
|
||||||
|
templates:value("")
|
||||||
|
|
||||||
|
description = sect_instances:option(TextValue, "description", "Description", "Description of the current BGP instance")
|
||||||
|
description.optional = true
|
||||||
|
|
||||||
|
table = sect_instances:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
|
||||||
|
table.optional=true
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
table:value(s.name)
|
||||||
|
end)
|
||||||
|
table:value("")
|
||||||
|
table.default = ""
|
||||||
|
|
||||||
|
igp_table = sect_instances:option(ListValue, "igp_table", "IGP Table", "Select the IGP Routing Table to use. Hint: usually the same table as BGP.")
|
||||||
|
igp_table.optional = true
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function(s)
|
||||||
|
igp_table:value(s.name)
|
||||||
|
end)
|
||||||
|
igp_table:value("")
|
||||||
|
igp_table.default = ""
|
||||||
|
|
||||||
|
passive = sect_instances:option(Flag, "passive", "Passive", "Disable automatic initialization of outgoing connections.")
|
||||||
|
passive.optional=true
|
||||||
|
passive.rmempty = false
|
||||||
|
passive.default = nil
|
||||||
|
|
||||||
|
import = sect_instances:option(Value, "import", "Import", imp_string)
|
||||||
|
import.optional=true
|
||||||
|
|
||||||
|
export = sect_instances:option(Value, "export", "Export", exp_string)
|
||||||
|
export.optional=true
|
||||||
|
|
||||||
|
source_address = sect_instances:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
|
||||||
|
source_address.optional = true
|
||||||
|
|
||||||
|
local_as = sect_instances:option(Value, "local_as", "Local AS", "")
|
||||||
|
local_as.optional=true
|
||||||
|
|
||||||
|
neighbor_address = sect_instances:option(Value, "neighbor_address", "Neighbor IP Address", "")
|
||||||
|
neighbor_address.optional = false
|
||||||
|
|
||||||
|
neighbor_as = sect_instances:option(Value, "neighbor_as", "Neighbor AS", "")
|
||||||
|
neighbor_as.optional = false
|
||||||
|
|
||||||
|
next_hop_self = sect_instances:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
|
||||||
|
next_hop_self.default = nil
|
||||||
|
next_hop_self.optional = true
|
||||||
|
|
||||||
|
next_hop_keep = sect_instances:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
|
||||||
|
next_hop_keep.default = nil
|
||||||
|
next_hop_keep.optional = true
|
||||||
|
|
||||||
|
rr_client = sect_instances:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
|
||||||
|
rr_client.default = nil
|
||||||
|
rr_client.optional = true
|
||||||
|
|
||||||
|
rr_cluster_id = sect_instances:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
|
||||||
|
rr_cluster_id.optional = true
|
||||||
|
|
||||||
|
import_trigger = sect_instances:option(Flag, "import_trigger", "Import Limit", "Enable Routes Import limit settings")
|
||||||
|
import_trigger.default = 0
|
||||||
|
import_trigger.rmempty = false
|
||||||
|
import_trigger.optional = false
|
||||||
|
|
||||||
|
import_limit = sect_instances:option(Value, "import_limit", "Routes import limit", "Specify an import route limit.")
|
||||||
|
import_limit:depends({import_trigger = "1"})
|
||||||
|
import_limit.rmempty = true
|
||||||
|
|
||||||
|
import_limit_action = sect_instances:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
|
||||||
|
import_limit_action:depends({import_trigger = "1"})
|
||||||
|
import_limit_action:value("warn")
|
||||||
|
import_limit_action:value("block")
|
||||||
|
import_limit_action:value("disable")
|
||||||
|
import_limit_action:value("restart")
|
||||||
|
import_limit_action.default = "warn"
|
||||||
|
import_limit_action.rmempty = true
|
||||||
|
|
||||||
|
export_trigger = sect_instances:option(Flag, "export_trigger", "Export Limit", "Enable Routes Export limit settings")
|
||||||
|
export_trigger.default = 0
|
||||||
|
export_trigger.rmempty = false
|
||||||
|
export_trigger.optional = false
|
||||||
|
|
||||||
|
export_limit = sect_instances:option(Value, "export_limit", "Routes export limit", "Specify an export route limit.")
|
||||||
|
export_limit:depends({export_trigger = "1"})
|
||||||
|
export_limit.rmempty = true
|
||||||
|
|
||||||
|
export_limit_action = sect_instances:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
|
||||||
|
export_limit_action:depends({export_trigger = "1"})
|
||||||
|
export_limit_action:value("warn")
|
||||||
|
export_limit_action:value("block")
|
||||||
|
export_limit_action:value("disable")
|
||||||
|
export_limit_action:value("restart")
|
||||||
|
export_limit_action.default = "warn"
|
||||||
|
export_limit_action.rmempty= true
|
||||||
|
|
||||||
|
receive_trigger = sect_instances:option(Flag, "receive_trigger", "Received Limit", "Enable Routes Received Limit settings")
|
||||||
|
receive_trigger.default = 0
|
||||||
|
receive_trigger.rmempty = false
|
||||||
|
receive_trigger.optional = false
|
||||||
|
|
||||||
|
receive_limit = sect_instances:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit.")
|
||||||
|
receive_limit:depends({receive_trigger = "1"})
|
||||||
|
receive_limit.rmempty = true
|
||||||
|
|
||||||
|
receive_limit_action = sect_instances:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
|
||||||
|
receive_limit_action:depends({receive_trigger = "1"})
|
||||||
|
receive_limit_action:value("warn")
|
||||||
|
receive_limit_action:value("block")
|
||||||
|
receive_limit_action:value("disable")
|
||||||
|
receive_limit_action:value("restart")
|
||||||
|
receive_limit_action.default = "warn"
|
||||||
|
receive_limit_action.rmempty= true
|
||||||
|
|
||||||
|
|
||||||
|
function m.on_commit(self,map)
|
||||||
|
luci.sys.exec('/etc/init.d/bird4 restart')
|
||||||
|
end
|
||||||
|
return m
|
77
bird1-openwrt/bird1-ipv4-openwrt/src/model/filters.lua
Normal file
77
bird1-openwrt/bird1-ipv4-openwrt/src/model/filters.lua
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
local filters_dir = "/etc/bird4/filters/"
|
||||||
|
local lock_file = "/etc/bird4/filter_lock"
|
||||||
|
|
||||||
|
m = SimpleForm("bird4", "Bird4 Filters", "<b>INFO:</b> New files are created using Timestamps.<br />In order to make it easier to handle, use SSH to connect to your terminal and rename those files.<br />If your file is not correctly shown in the list, please, refresh your browser.")
|
||||||
|
|
||||||
|
s = m:section(SimpleSection)
|
||||||
|
files = s:option(ListValue, "Files", "Filter Files:")
|
||||||
|
local new_filter = filters_dir .. os.date("filter-%Y%m%d-%H%M")
|
||||||
|
|
||||||
|
-- New File Entry
|
||||||
|
files:value(new_filter, "New File (".. new_filter .. ")")
|
||||||
|
files.default = new_filter
|
||||||
|
|
||||||
|
local i, file_list = 0, { }
|
||||||
|
for filename in io.popen("find " .. filters_dir .. " -type f"):lines() do
|
||||||
|
i = i + 1
|
||||||
|
files:value(filename, filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
ld = s:option(Button, "_load", "Load File")
|
||||||
|
ld.inputstyle = "reload"
|
||||||
|
|
||||||
|
st_file = s:option(DummyValue, "_stfile", "Editing file:")
|
||||||
|
function st_file.cfgvalue(self, section)
|
||||||
|
if ld:formvalue(section) then
|
||||||
|
fs.writefile(lock_file, files:formvalue(section))
|
||||||
|
return files:formvalue(section)
|
||||||
|
else
|
||||||
|
fs.writefile(lock_file, "")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
area = s:option(Value, "_filters")
|
||||||
|
area.template = "bird4/tvalue"
|
||||||
|
area.rows = 30
|
||||||
|
function area.cfgvalue(self,section)
|
||||||
|
if ld:formvalue(section) then
|
||||||
|
local contents = fs.readfile(files:formvalue(section))
|
||||||
|
if contents then
|
||||||
|
return contents
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function area.write(self, section)
|
||||||
|
local locked_file = fs.readfile(lock_file)
|
||||||
|
if locked_file and not ld:formvalue(section) then
|
||||||
|
local text = self:formvalue(section):gsub("\r\n?", "\n")
|
||||||
|
fs.writefile(locked_file, text)
|
||||||
|
fs.writefile(lock_file, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
77
bird1-openwrt/bird1-ipv4-openwrt/src/model/functions.lua
Normal file
77
bird1-openwrt/bird1-ipv4-openwrt/src/model/functions.lua
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
local functions_dir = "/etc/bird4/functions/"
|
||||||
|
local lock_file = "/etc/bird4/function_lock"
|
||||||
|
|
||||||
|
m = SimpleForm("bird4", "Bird4 Functions", "<b>INFO:</b> New files are created using Timestamps.<br />In order to make it easier to handle, use SSH to connect to your terminal and rename those files.<br />If your file is not correctly shown in the list, please, refresh your browser.")
|
||||||
|
|
||||||
|
s = m:section(SimpleSection)
|
||||||
|
files = s:option(ListValue, "Files", "Function Files:")
|
||||||
|
local new_function = functions_dir .. os.date("function-%Y%m%d-%H%M")
|
||||||
|
|
||||||
|
-- New File Entry
|
||||||
|
files:value(new_function, "New File (".. new_function .. ")")
|
||||||
|
files.default = new_function
|
||||||
|
|
||||||
|
local i, file_list = 0, { }
|
||||||
|
for filename in io.popen("find " .. functions_dir .. " -type f"):lines() do
|
||||||
|
i = i + 1
|
||||||
|
files:value(filename, filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
ld = s:option(Button, "_load", "Load File")
|
||||||
|
ld.inputstyle = "reload"
|
||||||
|
|
||||||
|
st_file = s:option(DummyValue, "_stfile", "Editing file:")
|
||||||
|
function st_file.cfgvalue(self, section)
|
||||||
|
if ld:formvalue(section) then
|
||||||
|
fs.writefile(lock_file, files:formvalue(section))
|
||||||
|
return files:formvalue(section)
|
||||||
|
else
|
||||||
|
fs.writefile(lock_file, "")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
area = s:option(Value, "_functions")
|
||||||
|
area.template = "bird4/tvalue"
|
||||||
|
area.rows = 30
|
||||||
|
function area.cfgvalue(self,section)
|
||||||
|
if ld:formvalue(section) then
|
||||||
|
local contents = fs.readfile(files:formvalue(section))
|
||||||
|
if contents then
|
||||||
|
return contents
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function area.write(self, section)
|
||||||
|
local locked_file = fs.readfile(lock_file)
|
||||||
|
if locked_file and not ld:formvalue(section) then
|
||||||
|
local text = self:formvalue(section):gsub("\r\n?", "\n")
|
||||||
|
fs.writefile(locked_file, text)
|
||||||
|
fs.writefile(lock_file, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
263
bird1-openwrt/bird1-ipv4-openwrt/src/model/gen_proto.lua
Normal file
263
bird1-openwrt/bird1-ipv4-openwrt/src/model/gen_proto.lua
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require("luci.sys")
|
||||||
|
local http = require "luci.http"
|
||||||
|
local uci = luci.model.uci.cursor()
|
||||||
|
|
||||||
|
-- Repeated Strings
|
||||||
|
local common_string = "Valid options are:<br />" .. "1. all (All the routes)<br />" .. "2. none (No routes)<br />" .. "3. filter <b>Your_Filter_Name</b> (Call a specific filter from any of the available in the filters files)"
|
||||||
|
local imp_string = "Set if the protocol must import routes.<br />" .. common_string
|
||||||
|
local exp_string = "Set if the protocol must export routes.<br />" .. common_string
|
||||||
|
|
||||||
|
m=Map("bird4", "Bird4 general protocol's configuration.")
|
||||||
|
|
||||||
|
-- Optional parameters lists
|
||||||
|
local protoptions = {
|
||||||
|
{["name"]="table", ["help"]="Auxiliar table for routing", ["depends"]={"static","kernel"}},
|
||||||
|
{["name"]="import", ["help"]=imp_string, ["depends"]={"kernel"}},
|
||||||
|
{["name"]="export", ["help"]=exp_string, ["depends"]={"kernel"}},
|
||||||
|
{["name"]="scan_time", ["help"]="Time between scans", ["depends"]={"kernel","device"}},
|
||||||
|
{["name"]="kernel_table", ["help"]="Set which table must be used as auxiliar kernel table", ["depends"]={"kernel"}},
|
||||||
|
{["name"]="learn", ["help"]="Learn routes", ["depends"]={"kernel"}},
|
||||||
|
{["name"]="persist", ["help"]="Store routes. After a restart, routes willstill be configured", ["depends"]={"kernel"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
local routeroptions = {
|
||||||
|
{["name"]="prefix",["help"]="",["depends"]={"router","special","iface","multipath","recursive"}},
|
||||||
|
{["name"]="via",["help"]="",["depends"]={"router","multipath"}},
|
||||||
|
{["name"]="attribute",["help"]="",["depends"]={"special"}},
|
||||||
|
{["name"]="iface",["help"]="",["depends"]={"iface"}},
|
||||||
|
{["name"]="ip",["help"]="",["depends"]={"recursive"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- KERNEL PROTOCOL
|
||||||
|
--
|
||||||
|
sect_kernel_protos = m:section(TypedSection, "kernel", "Kernel options", "Configuration of the kernel protocols. First Instance MUST be Primary table (no table or kernel_table fields).")
|
||||||
|
sect_kernel_protos.addremove = true
|
||||||
|
sect_kernel_protos.anonymous = false
|
||||||
|
|
||||||
|
-- Default kernel parameters
|
||||||
|
disabled = sect_kernel_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
|
||||||
|
disabled.default=0
|
||||||
|
|
||||||
|
-- Optional parameters
|
||||||
|
for _,o in ipairs(protoptions) do
|
||||||
|
if o.name ~= nil then
|
||||||
|
for _, d in ipairs(o.depends) do
|
||||||
|
if d == "kernel" then
|
||||||
|
if o.name == "learn" or o.name == "persist" then
|
||||||
|
value = sect_kernel_protos:option(Flag, o.name, translate(o.name), translate(o.help))
|
||||||
|
elseif o.name == "table" then
|
||||||
|
value = sect_kernel_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
value:value(s.name)
|
||||||
|
end)
|
||||||
|
value:value("")
|
||||||
|
value.default = ""
|
||||||
|
else
|
||||||
|
value = sect_kernel_protos:option(Value, o.name, translate(o.name), translate(o.help))
|
||||||
|
end
|
||||||
|
value.optional = true
|
||||||
|
value.rmempty = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- DEVICE PROTOCOL
|
||||||
|
--
|
||||||
|
sect_device_protos = m:section(TypedSection, "device", "Device options", "Configuration of the device protocols.")
|
||||||
|
sect_device_protos.addremove = true
|
||||||
|
sect_device_protos.anonymous = false
|
||||||
|
|
||||||
|
-- Default kernel parameters
|
||||||
|
|
||||||
|
disabled = sect_device_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
|
||||||
|
disabled.default=0
|
||||||
|
|
||||||
|
-- Optional parameters
|
||||||
|
for _,o in ipairs(protoptions) do
|
||||||
|
if o.name ~= nil then
|
||||||
|
for _, d in ipairs(o.depends) do
|
||||||
|
if d == "device" then
|
||||||
|
value = sect_device_protos:option(Value, o.name, translate(o.name), translate(o.help))
|
||||||
|
value.optional = true
|
||||||
|
value.rmempty = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PIPE PROTOCOL
|
||||||
|
--
|
||||||
|
sect_pipe_protos = m:section(TypedSection, "pipe", "Pipe options", "Configuration of the Pipe protocols.")
|
||||||
|
sect_pipe_protos.addremove = true
|
||||||
|
sect_pipe_protos.anonymous = false
|
||||||
|
|
||||||
|
-- Default Pipe parameters
|
||||||
|
disabled = sect_pipe_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured. This protocol will connect the configured 'Table' to the 'Peer Table'.")
|
||||||
|
disabled.default=0
|
||||||
|
|
||||||
|
table = sect_pipe_protos:option(ListValue, "table", "Table", "Select the Primary Table to connect.")
|
||||||
|
table.optional = false
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
table:value(s.name)
|
||||||
|
end)
|
||||||
|
table:value("")
|
||||||
|
table.default = ""
|
||||||
|
|
||||||
|
peer_table = sect_pipe_protos:option(ListValue, "peer_table", "Peer Table", "Select the Secondary Table to connect.")
|
||||||
|
table.optional = false
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
peer_table:value(s.name)
|
||||||
|
end)
|
||||||
|
peer_table:value("")
|
||||||
|
peer_table.default = ""
|
||||||
|
|
||||||
|
mode = sect_pipe_protos:option(ListValue, "mode", "Mode", "Select <b>transparent</b> to retransmit all routes and their attributes<br />Select <b>opaque</b> to retransmit optimal routes (similar to what other protocols do)")
|
||||||
|
mode.optional = false
|
||||||
|
mode:value("transparent")
|
||||||
|
mode:value("opaque")
|
||||||
|
mode.default = "transparent"
|
||||||
|
|
||||||
|
import = sect_pipe_protos:option(Value, "import", "Import",imp_string)
|
||||||
|
import.optional=true
|
||||||
|
|
||||||
|
export = sect_pipe_protos:option(Value, "export", "Export", exp_string)
|
||||||
|
export.optional=true
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- DIRECT PROTOCOL
|
||||||
|
--
|
||||||
|
sect_direct_protos = m:section(TypedSection, "direct", "Direct options", "Configuration of the Direct protocols.")
|
||||||
|
sect_direct_protos.addremove = true
|
||||||
|
sect_direct_protos.anonymous = false
|
||||||
|
|
||||||
|
-- Default Direct parameters
|
||||||
|
disabled = sect_direct_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured. This protocol will connect the configured 'Table' to the 'Peer Table'.")
|
||||||
|
disabled.optional = false
|
||||||
|
disabled.default = 0
|
||||||
|
|
||||||
|
interface = sect_direct_protos:option(Value, "interface", "Interfaces", "By default Direct will generate device routes for all the interfaces. To restrict this behaviour, select a number of patterns to match your desired interfaces:" .. "<br />" .. "1. All the strings <b>MUST</b> be quoted: \"pattern\"" .. "<br />" .. "2. Use * (star) to match patterns: \"eth*\" (<b>include</b> all eth... interfaces)" .. "<br />" .. "3. You can add \"-\" (minus) to exclude patterns: \"-em*\" (<b>exclude</b> all em... interfaces)." .. "<br />" .. "4. Separate several patterns using , (coma): \"-em*\", \"eth*\" (<b>exclude</b> em... and <b>include</b> all eth... interfaces).")
|
||||||
|
interface.optional = false
|
||||||
|
interface.default = "\"*\""
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- STATIC PROTOCOL
|
||||||
|
--
|
||||||
|
sect_static_protos = m:section(TypedSection, "static", "Static options", "Configuration of the static protocols.")
|
||||||
|
sect_static_protos.addremove = true
|
||||||
|
sect_static_protos.anonymous = false
|
||||||
|
|
||||||
|
-- Default kernel parameters
|
||||||
|
disabled = sect_static_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
|
||||||
|
disabled.default=0
|
||||||
|
|
||||||
|
-- Optional parameters
|
||||||
|
for _,o in ipairs(protoptions) do
|
||||||
|
if o.name ~= nil then
|
||||||
|
for _, d in ipairs(o.depends) do
|
||||||
|
if d == "static" then
|
||||||
|
if o.name == "table" then
|
||||||
|
value = sect_static_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
|
||||||
|
uci:foreach("bird4", "table",
|
||||||
|
function (s)
|
||||||
|
value:value(s.name)
|
||||||
|
end)
|
||||||
|
value:value("")
|
||||||
|
value.default = ""
|
||||||
|
else
|
||||||
|
value = sect_static_protos:option(Value, o.name, translate(o.name), translate(o.help))
|
||||||
|
end
|
||||||
|
value.optional = true
|
||||||
|
value.rmempty = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- ROUTES FOR STATIC PROTOCOL
|
||||||
|
--
|
||||||
|
sect_routes = m:section(TypedSection, "route", "Routes configuration", "Configuration of the routes used in static protocols.")
|
||||||
|
sect_routes.addremove = true
|
||||||
|
sect_routes.anonymous = true
|
||||||
|
|
||||||
|
instance = sect_routes:option(ListValue, "instance", "Route instance", "")
|
||||||
|
i = 0
|
||||||
|
uci:foreach("bird4", "static",
|
||||||
|
function (s)
|
||||||
|
instance:value(s[".name"])
|
||||||
|
end)
|
||||||
|
|
||||||
|
prefix = sect_routes:option(Value, "prefix", "Route prefix", "")
|
||||||
|
|
||||||
|
type = sect_routes:option(ListValue, "type", "Type of route", "")
|
||||||
|
type:value("router")
|
||||||
|
type:value("special")
|
||||||
|
type:value("iface")
|
||||||
|
type:value("recursive")
|
||||||
|
type:value("multipath")
|
||||||
|
|
||||||
|
valueVia = sect_routes:option(Value, "via", "Via", "")
|
||||||
|
valueVia.optional = false
|
||||||
|
valueVia:depends("type", "router")
|
||||||
|
valueVia.datatype = "ip4addr"
|
||||||
|
|
||||||
|
listVia = sect_routes:option(DynamicList, "l_via", "Via", "")
|
||||||
|
listVia:depends("type", "multipath")
|
||||||
|
listVia.optional=false
|
||||||
|
listVia.datatype = "ip4addr"
|
||||||
|
|
||||||
|
attribute = sect_routes:option(ListValue, "attribute", "Attribute", "")
|
||||||
|
attribute:depends("type", "special")
|
||||||
|
attribute:value("unreachable")
|
||||||
|
attribute:value("prohibit")
|
||||||
|
attribute:value("blackhole")
|
||||||
|
|
||||||
|
iface = sect_routes:option(ListValue, "iface", "Interface", "")
|
||||||
|
iface:depends("type", "iface")
|
||||||
|
uci:foreach("network", "interface",
|
||||||
|
function(section)
|
||||||
|
if section[".name"] ~= "loopback" then
|
||||||
|
iface:value(section[".name"])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
ip = sect_routes:option(Value, "ip", "IP address", "")
|
||||||
|
ip:depends("type", "ip")
|
||||||
|
ip.datatype = [[ or"ip4addr", "ip6addr" ]]
|
||||||
|
|
||||||
|
function m.on_commit(self,map)
|
||||||
|
luci.sys.exec('/etc/init.d/bird4 restart')
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
76
bird1-openwrt/bird1-ipv4-openwrt/src/model/overview.lua
Normal file
76
bird1-openwrt/bird1-ipv4-openwrt/src/model/overview.lua
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
require("luci.sys")
|
||||||
|
local http = require "luci.http"
|
||||||
|
local uci = require "luci.model.uci"
|
||||||
|
local uciout = uci.cursor()
|
||||||
|
|
||||||
|
m=Map("bird4", "Bird4 UCI configuration helper", "")
|
||||||
|
|
||||||
|
-- Named section: "bird"
|
||||||
|
|
||||||
|
s_bird_uci = m:section(NamedSection, "bird", "bird", "Bird4 file settings", "")
|
||||||
|
s_bird_uci.addremove = False
|
||||||
|
|
||||||
|
uuc = s_bird_uci:option(Flag, "use_UCI_config", "Use UCI configuration", "Use UCI configuration instead of the /etc/bird4.conf file")
|
||||||
|
|
||||||
|
ucf = s_bird_uci:option(Value, "UCI_config_file", "UCI File", "Specify the file to place the UCI-translated configuration")
|
||||||
|
ucf.default = "/tmp/bird4.conf"
|
||||||
|
|
||||||
|
-- Named Section: "table"
|
||||||
|
|
||||||
|
s_bird_table = m:section(TypedSection, "table", "Tables configuration", "Configuration of the tables used in the protocols")
|
||||||
|
s_bird_table.addremove = true
|
||||||
|
s_bird_table.anonymous = true
|
||||||
|
|
||||||
|
name = s_bird_table:option(Value, "name", "Table name", "Descriptor ID of the table")
|
||||||
|
|
||||||
|
-- Named section: "global"
|
||||||
|
|
||||||
|
s_bird_global = m:section(NamedSection, "global", "global", "Global options", "Basic Bird4 settings")
|
||||||
|
s_bird_global.addremove = False
|
||||||
|
|
||||||
|
id = s_bird_global:option(Value, "router_id", "Router ID", "Identification number of the router. By default, is the router's IP.")
|
||||||
|
|
||||||
|
lf = s_bird_global:option(Value, "log_file", "Log File", "File used to store log related data.")
|
||||||
|
|
||||||
|
l = s_bird_global:option(MultiValue, "log", "Log", "Set which elements do you want to log.")
|
||||||
|
l:value("all", "All")
|
||||||
|
l:value("info", "Info")
|
||||||
|
l:value("warning","Warning")
|
||||||
|
l:value("error","Error")
|
||||||
|
l:value("fatal","Fatal")
|
||||||
|
l:value("debug","Debug")
|
||||||
|
l:value("trace","Trace")
|
||||||
|
l:value("remote","Remote")
|
||||||
|
l:value("auth","Auth")
|
||||||
|
|
||||||
|
d = s_bird_global:option(MultiValue, "debug", "Debug", "Set which elements do you want to debug.")
|
||||||
|
d:value("all", "All")
|
||||||
|
d:value("states","States")
|
||||||
|
d:value("routes","Routes")
|
||||||
|
d:value("filters","Filters")
|
||||||
|
d:value("interfaces","Interfaces")
|
||||||
|
d:value("events","Events")
|
||||||
|
d:value("packets","Packets")
|
||||||
|
|
||||||
|
function m.on_commit(self,map)
|
||||||
|
luci.sys.exec('/etc/init.d/bird4 restart')
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
53
bird1-openwrt/bird1-ipv4-openwrt/src/model/status.lua
Normal file
53
bird1-openwrt/bird1-ipv4-openwrt/src/model/status.lua
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
--[[
|
||||||
|
Copyright (C) 2014-2017 - Eloi Carbo
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local sys = require "luci.sys"
|
||||||
|
|
||||||
|
m = SimpleForm("bird4", "Bird4 Daemon Status Page", "This page let you Start, Stop, Restart and check Bird4 Service Status.")
|
||||||
|
m.reset = false
|
||||||
|
m.submit = false
|
||||||
|
|
||||||
|
s = m:section(SimpleSection)
|
||||||
|
|
||||||
|
start = s:option(Button, "_start", "Start Bird4 Daemon:")
|
||||||
|
start.inputtitle = " Start "
|
||||||
|
start.inputstyle = "apply"
|
||||||
|
|
||||||
|
stop = s:option(Button, "_stop", "Stop Bird4 Daemon:")
|
||||||
|
stop.inputtitle = " Stop "
|
||||||
|
stop.inputstyle = "remove"
|
||||||
|
|
||||||
|
restart = s:option(Button, "_restart", "Restart Bird4 Daemon:")
|
||||||
|
restart.inputtitle = "Restart"
|
||||||
|
restart.inputstyle = "reload"
|
||||||
|
|
||||||
|
output = s:option(DummyValue, "_value", "Service Status")
|
||||||
|
function output.cfgvalue(self, section)
|
||||||
|
local ret = ""
|
||||||
|
if start:formvalue(section) then
|
||||||
|
ret = sys.exec("/etc/init.d/bird4 start_quiet")
|
||||||
|
elseif stop:formvalue(section) then
|
||||||
|
ret = sys.exec("/etc/init.d/bird4 stop_quiet")
|
||||||
|
elseif restart:formvalue(section) then
|
||||||
|
ret = sys.exec("/etc/init.d/bird4 restart_quiet")
|
||||||
|
else
|
||||||
|
ret = sys.exec("/etc/init.d/bird4 status_quiet")
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This UCI-Defaults script will MOVE any pre-existing filter
|
||||||
|
# stored in a file and configured as an UCI item (deprecated)
|
||||||
|
# The script will try to match any "filter" Section, get its
|
||||||
|
# "file_path" property and move the file (if exists) to the
|
||||||
|
# new (v0.3+) default location: /etc/bird{4|6}/filters
|
||||||
|
|
||||||
|
[ $# -ne 1 ] && exit 1
|
||||||
|
BIRD="$1"
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
# This function will move an existing folder configured on
|
||||||
|
# Bird as a "filter" to filters' folder.
|
||||||
|
mv_filter() {
|
||||||
|
local section="$1"
|
||||||
|
local file_path
|
||||||
|
config_get file_path ${section} file_path
|
||||||
|
|
||||||
|
if [ -f ${file_path} ]; then
|
||||||
|
mv ${file_path} /etc/${BIRD}/filters/
|
||||||
|
fi
|
||||||
|
uci delete ${BIRD}.${section}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -f /etc/config/${BIRD} ]; then
|
||||||
|
config_load ${BIRD}
|
||||||
|
config_foreach mv_filter 'filter'
|
||||||
|
uci commit ${BIRD}
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ $# -ne 1 ] && exit 1
|
||||||
|
|
||||||
|
BIRD=$1
|
||||||
|
|
||||||
|
EXC=`mount -t overlayfs | grep overlayfs -c`
|
||||||
|
|
||||||
|
[ $EXC > 0 ] && rm -r /etc/init.d/${BIRD} || mv /etc/init.d/${BIRD} /etc/${BIRD}/init.d/${BIRD}.orig
|
||||||
|
|
||||||
|
ln -s /etc/${BIRD}/init.d/${BIRD} /etc/init.d/${BIRD}
|
||||||
|
|
||||||
|
exit 0
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue