Snap for 10453563 from 65a8683b07ce5587dd2e3c9d0cdb40c40e6f7687 to mainline-extservices-release
Change-Id: I51266444ff946617c52329ec68f9fe89c845127b
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..bed344c
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# clang-format configuration file. Intended for clang-format >= 4.
+#
+# For more information, see:
+#
+# Documentation/process/clang-format.rst
+# https://clang.llvm.org/docs/ClangFormat.html
+# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+#
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ #AfterExternBlock: false # Unknown to clang-format-5.0
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+ #SplitEmptyFunction: true # Unknown to clang-format-4.0
+ #SplitEmptyRecord: true # Unknown to clang-format-4.0
+ #SplitEmptyNamespace: true # Unknown to clang-format-4.0
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+#CompactNamespaces: false # Unknown to clang-format-4.0
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+#FixNamespaceComments: false # Unknown to clang-format-4.0
+
+# Taken from:
+# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \
+# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
+# | sort | uniq
+ForEachMacros:
+ - 'list_for_each_safe'
+ - 'nl_list_for_each_entry'
+ - 'nla_for_each_attr'
+ - 'nla_for_each_nested'
+ - 'nlmsg_for_each'
+ - 'nlmsg_for_each_attr'
+ - 'nlmsg_for_each_msg'
+
+#IncludeBlocks: Preserve # Unknown to clang-format-5.0
+IncludeCategories:
+ - Regex: '.*'
+ Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+#IndentPPDirectives: None # Unknown to clang-format-5.0
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
+ObjCBlockIndentWidth: 8
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+
+# Taken from git's rules
+#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakString: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: false
+#SortUsingDeclarations: false # Unknown to clang-format-4.0
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
+#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
+SpaceBeforeParens: ControlStatements
+#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp03
+TabWidth: 8
+UseTab: Always
+...
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..ef0afad
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,112 @@
+name: libnl3-ci
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ ci:
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ - cc: clang
+ runs-on: ubuntu-latest
+ steps:
+
+ - name: Install packages
+ run: |
+ sudo apt-get update
+ sudo apt-get -y --no-install-recommends install \
+ check \
+ valgrind \
+ libtool-bin
+
+ - name: Check out repository code
+ uses: actions/checkout@v3
+
+ - name: Setup Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: 3.x
+
+ - name: Lint Python
+ run: |
+ python3 -m pip install flake8
+ flake8 . --count --select=E703,E9,F63,F7,F82,Y --show-source --statistics
+
+ - name: Build
+ run: |
+ set -x
+
+ export CC="${{ matrix.cc }}"
+ export CFLAGS="-DNL_MORE_ASSERTS=1000 -O2 -Werror -Wall -Wdeclaration-after-statement -Wvla -std=gnu11"
+ if [ "$CC" = "clang" ]; then
+ CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument -Wno-error=unused-function"
+ fi
+
+ ./autogen.sh
+ ./configure
+ make -j 5
+ shell: bash
+ - name: Build Unit Tests
+ run: make -j 5 check-progs
+
+ - name: Run Unit Tests
+ run: |
+ set -x
+ export NLTST_SEED_RAND=
+ for i in `seq 1 5`; do
+ tests/check-all
+ tests/check-direct
+ make -j check
+ done
+
+ - name: Run Unit Tests w/Valgrind
+ run: |
+ set -x
+ export NLTST_SEED_RAND=
+ CK_FORK=no libtool --mode=execute valgrind --error-exitcode=66 --leak-check=full -s --show-leak-kinds=all ./tests/check-all
+ CK_FORK=no libtool --mode=execute valgrind --error-exitcode=66 --leak-check=full -s --show-leak-kinds=all ./tests/check-direct
+ shell: bash
+
+ - name: Install packages for Release
+ run: |
+ test "${{ matrix.cc }}" == gcc || exit 0
+ sudo apt-get -y --no-install-recommends install \
+ asciidoc \
+ doxygen \
+ graphviz \
+ mscgen \
+ source-highlight \
+ python3-pygments
+
+ - name: Build Release
+ run: |
+ test "${{ matrix.cc }}" == gcc || exit 0
+ set -x
+ git clean -fdx
+ NO_GPG_SIGN=1 ./tools/build_release.sh BuildAll
+
+ - name: Build out-of-tree and disable-static
+ run: |
+ set -x
+
+ git clean -fdx
+
+ export CC="${{ matrix.cc }}"
+ export CFLAGS="-Werror -Wall -Wdeclaration-after-statement -Wvla -std=gnu11"
+ if [ "$CC" = "clang" ]; then
+ CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument -Wno-error=unused-function"
+ fi
+
+ ./autogen.sh
+ mkdir build
+ cd build
+ ../configure --disable-static
+ make -j 5
+ make -j 5 check-progs
+ export NLTST_SEED_RAND=
+ make -j 5 check
+
+ - run: echo "🍏 This job's status is ${{ job.status }}."
diff --git a/.gitignore b/.gitignore
index c22a603..da3eb81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,18 +10,137 @@
Makefile.in
defs.h.in
defs.h.in~
-/lib/stamp-h1
+cscope.*
test-suite.log
-/libnl-1.pc
-/lib/defs.h
-cscope.*
-/tags
-
+/*.pc
/aclocal.m4
/autom4te.cache
/build-aux/
/config.*
/configure
+/doc/*.html
+/doc/Doxyfile
+/doc/aclocal.m4
+/doc/api/*.css
+/doc/api/*.html
+/doc/api/*.js
+/doc/api/*.map
+/doc/api/*.md5
+/doc/api/*.png
+/doc/api/*.tag
+/doc/api/formula.repository
+/doc/api/jquery.js
+/doc/asciidoc.tmp
+/doc/autom4te.cache/
+/doc/build-aux/
+/doc/config.*
+/doc/configure
+/doc/images/*.odg
+/doc/images/asciidoc__*.png
+/doc/images/core__*
+/doc/libnl.dict
+/include/netlink/version.h
+/lib/defs.h
+/lib/lex.yy.c
+/lib/libnl-*.so*
+/lib/libnl.so*
+/lib/route/cls/ematch_grammar.[ch]
+/lib/route/cls/ematch_syntax.[ch]
+/lib/route/pktloc_grammar.c
+/lib/route/pktloc_grammar.h
+/lib/route/pktloc_syntax.c
+/lib/route/pktloc_syntax.h
+/lib/stamp-h1
+/libnl-1.pc
/libtool
-/*.pc
+/m4/libtool.m4
+/m4/lt*.m4
+/python/build
+/python/capi.py
+/python/capi_wrap.c
+/python/setup.py
+/src/genl-ctrl-list
+/src/idiag-socket-details
+/src/nf-ct-add
+/src/nf-ct-events
+/src/nf-ct-list
+/src/nf-exp-add
+/src/nf-exp-delete
+/src/nf-exp-list
+/src/nf-log
+/src/nf-monitor
+/src/nf-queue
+/src/nl-addr-add
+/src/nl-addr-delete
+/src/nl-addr-list
+/src/nl-class-add
+/src/nl-class-delete
+/src/nl-class-list
+/src/nl-classid-lookup
+/src/nl-cls-add
+/src/nl-cls-delete
+/src/nl-cls-list
+/src/nl-fib-lookup
+/src/nl-link-enslave
+/src/nl-link-ifindex2name
+/src/nl-link-list
+/src/nl-link-name2ifindex
+/src/nl-link-release
+/src/nl-link-set
+/src/nl-link-stats
+/src/nl-list-caches
+/src/nl-list-sockets
+/src/nl-monitor
+/src/nl-neigh-add
+/src/nl-neigh-delete
+/src/nl-neigh-list
+/src/nl-neightbl-list
+/src/nl-pktloc-lookup
+/src/nl-qdisc-add
+/src/nl-qdisc-delete
+/src/nl-qdisc-list
+/src/nl-route-add
+/src/nl-route-delete
+/src/nl-route-get
+/src/nl-route-list
+/src/nl-rule-list
+/src/nl-tctree-list
+/src/nl-util-addr
+/tags
+/tests/check-all
+/tests/check-all.log
+/tests/check-all.trs
+/tests/check-direct
+/tests/check-direct.log
+/tests/check-direct.trs
+/tests/test-*.log
+/tests/test-*.trs
+/tests/test-cache-mngr
+/tests/test-complex-HTB-with-hash-filters
+/tests/test-create-bond
+/tests/test-create-bridge
+/tests/test-create-geneve
+/tests/test-create-ifb
+/tests/test-create-ip6tnl
+/tests/test-create-ipgre
+/tests/test-create-ipgretap
+/tests/test-create-ipip
+/tests/test-create-ipvlan
+/tests/test-create-ipvti
+/tests/test-create-macsec
+/tests/test-create-macvlan
+/tests/test-create-macvtap
+/tests/test-create-sit
+/tests/test-create-veth
+/tests/test-create-vlan
+/tests/test-create-vrf
+/tests/test-create-vxlan
+/tests/test-create-xfrmi
+/tests/test-delete-link
+/tests/test-genl
+/tests/test-loopback-up-down
+/tests/test-nf-cache-mngr
+/tests/test-socket-creation
+/tests/test-suite.log
+/tests/test-u32-filter-with-actions
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index efc8ae5..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: c
-compiler:
- - gcc
- - clang
-
-before_install:
-
-script: ./.travis/run.sh
diff --git a/.travis/run.sh b/.travis/run.sh
deleted file mode 100755
index afa1702..0000000
--- a/.travis/run.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-set -e
-
-CFLAGS="-Werror -Wall -Wdeclaration-after-statement -Wvla"
-
-if [ "$CC" = "clang" ]; then
- CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument -Wno-error=unused-function"
-fi
-
-CFLAGS="$CFLAGS -DNL_MORE_ASSERTS=1000"
-
-export CFLAGS
-./autogen.sh
-./configure
-make -j 5
-make -j 5 check
diff --git a/Android.bp b/Android.bp
index 9b01e6f..efd663e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -55,10 +55,7 @@
},
host: {
srcs: [
- "lib/route/link.c",
- "lib/route/link/api.c",
"lib/route/link/macvlan.c",
- "lib/route/link/sriov.c",
],
},
},
@@ -72,6 +69,16 @@
"lib/genl/genl.c",
"lib/genl/mngt.c",
"lib/netfilter/nfnl.c",
+ "lib/route/link.c",
+ "lib/route/link/api.c",
+ "lib/route/link/macsec.c",
+ "lib/route/link/sriov.c",
+ "lib/route/link/vlan.c",
+ "lib/route/nexthop.c",
+ "lib/route/nexthop_encap.c",
+ "lib/route/nh_encap_mpls.c",
+ "lib/route/route.c",
+ "lib/route/route_obj.c",
"lib/route/route_utils.c",
"lib/route/rtnl.c",
],
diff --git a/ChangeLog b/ChangeLog
index cdd78a8..3d93d1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,5 @@
ChangeLog discontinued, git history can be found here:
-http://git.infradead.org/users/tgr/libnl.git
+https://github.com/thom311/libnl
Summary of Changes from 1.0-pre6 to 1.0-pre7
================================================
@@ -42,7 +42,7 @@
NL_SKIP
o Fixed nl_recvmsgs() to stop reading after parsing if not in the
middle of a multipart message.
- o Fixed nl_recvmsgs() to not stop after receving an ACK
+ o Fixed nl_recvmsgs() to not stop after receiving an ACK
o Fixed nl_recvmsgs() to not blindly discard remaining messages
if a NLMSG_DONE message is received.
@@ -205,7 +205,7 @@
o Removed non-reentrant translation routines, only bloating
the code and too risky.
o Fixed wrong version number from 1.0-pre1.
- o Reenabled unfinished policer module.
+ o Re-enabled unfinished policer module.
o Reworked TBF module, automatic caluclation of transmit times,
limit setable via latency, automatic cell size calculation,
options TLV generation. (untested)
@@ -219,7 +219,7 @@
o Add empty install target to src/Makefile
Simon Stelling <blubb@gentoo.org>
- o Use LIBDIR instead of $(prefix)/lib for users to alllow librariers
+ o Use LIBDIR instead of $(prefix)/lib for users to allow librariers
into $(prefix)/lib64.
Summary of Changes from 0.5.0 to 1.0-pre1
@@ -231,7 +231,7 @@
Petr Gotthard <petr.gotthard@siemens.com>,
Siemens AG Oesterreich
o added class_build, rtnl_class_build_add_request, rtnl_class_add
- o added HTB (Hierachical Token Bucket) class support
+ o added HTB (Hierarchical Token Bucket) class support
o added nl_xmittime, nl_build_rtable
o added nl_data_append to realloc a nl_data structure
o added rtnl_rcopy_ratespec as reverse to rtnl_copy_ratespec
@@ -248,9 +248,9 @@
o nl_cache_filter to manually filter on a object
o partial routing support
o routing rules support
- o Propely set address family when setting addresses
+ o Properly set address family when setting addresses
o debug flag and some rare messages, more to come
- o make error mesage verboseness configureable
+ o make error message verboseness configurable
o tc fixes to wait for ack
o cleanup and adaption of address code to latest internal API
o various cleanups
diff --git a/METADATA b/METADATA
index 536465d..cb610c1 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update libnl
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "libnl"
description: "Netlink Library Suite"
third_party {
@@ -9,11 +13,11 @@
type: GIT
value: "https://github.com/thom311/libnl.git"
}
- version: "libnl3_5_0"
+ version: "libnl3_7_0"
license_type: RESTRICTED
last_upgrade_date {
- year: 2020
- month: 3
- day: 10
+ year: 2023
+ month: 1
+ day: 9
}
}
diff --git a/Makefile.am b/Makefile.am
index b2e8737..ef0f82d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -105,6 +105,7 @@
include/netlink/route/class.h \
include/netlink/route/classifier.h \
include/netlink/route/link.h \
+ include/netlink/route/mdb.h \
include/netlink/route/neighbour.h \
include/netlink/route/neightbl.h \
include/netlink/route/netconf.h \
@@ -121,6 +122,7 @@
libnlinclude_netlink_route_act_HEADERS = \
include/netlink/route/act/gact.h \
include/netlink/route/act/mirred.h \
+ include/netlink/route/act/nat.h \
include/netlink/route/act/skbedit.h \
include/netlink/route/act/vlan.h \
$(NULL)
@@ -129,6 +131,7 @@
include/netlink/route/cls/basic.h \
include/netlink/route/cls/cgroup.h \
include/netlink/route/cls/ematch.h \
+ include/netlink/route/cls/flower.h \
include/netlink/route/cls/fw.h \
include/netlink/route/cls/matchall.h \
include/netlink/route/cls/police.h \
@@ -151,7 +154,9 @@
include/netlink/route/link/inet.h \
include/netlink/route/link/inet6.h \
include/netlink/route/link/info-api.h \
+ include/netlink/route/link/ip6gre.h \
include/netlink/route/link/ip6tnl.h \
+ include/netlink/route/link/ip6vti.h \
include/netlink/route/link/ipgre.h \
include/netlink/route/link/ipip.h \
include/netlink/route/link/ipvlan.h \
@@ -162,6 +167,7 @@
include/netlink/route/link/ppp.h \
include/netlink/route/link/sit.h \
include/netlink/route/link/sriov.h \
+ include/netlink/route/link/team.h \
include/netlink/route/link/veth.h \
include/netlink/route/link/vlan.h \
include/netlink/route/link/vrf.h \
@@ -203,6 +209,7 @@
include/netlink/cli/ct.h \
include/netlink/cli/exp.h \
include/netlink/cli/link.h \
+ include/netlink/cli/mdb.h \
include/netlink/cli/neigh.h \
include/netlink/cli/qdisc.h \
include/netlink/cli/route.h \
@@ -253,6 +260,7 @@
include/linux-private/linux/socket.h \
include/linux-private/linux/tc_act/tc_gact.h \
include/linux-private/linux/tc_act/tc_mirred.h \
+ include/linux-private/linux/tc_act/tc_nat.h \
include/linux-private/linux/tc_act/tc_skbedit.h \
include/linux-private/linux/tc_act/tc_vlan.h \
include/linux-private/linux/tc_ematch/tc_em_meta.h \
@@ -261,12 +269,14 @@
include/netlink-private/cache-api.h \
include/netlink-private/genl.h \
include/netlink-private/netlink.h \
+ include/netlink-private/nl-auto.h \
include/netlink-private/object-api.h \
include/netlink-private/route/link/api.h \
include/netlink-private/route/link/sriov.h \
include/netlink-private/route/mpls.h \
include/netlink-private/route/nexthop-encap.h \
include/netlink-private/route/tc-api.h \
+ include/netlink-private/route/utils.h \
include/netlink-private/socket.h \
include/netlink-private/tc.h \
include/netlink-private/types.h \
@@ -371,6 +381,7 @@
lib/route/act.c \
lib/route/act/gact.c \
lib/route/act/mirred.c \
+ lib/route/act/nat.c \
lib/route/act/skbedit.c \
lib/route/act/vlan.c \
lib/route/addr.c \
@@ -385,6 +396,7 @@
lib/route/cls/ematch/meta.c \
lib/route/cls/ematch/nbyte.c \
lib/route/cls/ematch/text.c \
+ lib/route/cls/flower.c \
lib/route/cls/fw.c \
lib/route/cls/mall.c \
lib/route/cls/police.c \
@@ -399,7 +411,9 @@
lib/route/link/ifb.c \
lib/route/link/inet.c \
lib/route/link/inet6.c \
+ lib/route/link/ip6gre.c \
lib/route/link/ip6tnl.c \
+ lib/route/link/ip6vti.c \
lib/route/link/ipgre.c \
lib/route/link/ipip.c \
lib/route/link/ipvlan.c \
@@ -409,11 +423,13 @@
lib/route/link/ppp.c \
lib/route/link/sit.c \
lib/route/link/sriov.c \
+ lib/route/link/team.c \
lib/route/link/veth.c \
lib/route/link/vlan.c \
lib/route/link/vrf.c \
lib/route/link/vxlan.c \
lib/route/link/xfrmi.c \
+ lib/route/mdb.c \
lib/route/neigh.c \
lib/route/neightbl.c \
lib/route/netconf.c \
@@ -832,7 +848,25 @@
lib/libnl-3.la \
lib/libnl-nf-3.la \
lib/libnl-genl-3.la \
- lib/libnl-route-3.la
+ lib/libnl-route-3.la \
+ $(NULL)
+
+if WITH_CHECK
+check_LTLIBRARIES += tests/libnl-test-util.la
+endif
+
+tests_libnl_test_util_la_SOURCES = \
+ tests/nl-test-util.h \
+ tests/nl-test-util.c \
+ $(NULL)
+tests_libnl_test_util_la_CPPFLAGS = \
+ $(tests_cppflags) \
+ $(CHECK_CFLAGS) \
+ $(NULL)
+tests_libnl_test_util_la_LIBADD = \
+ $(tests_ldadd) \
+ $(CHECK_LIBS) \
+ $(NULL)
check_PROGRAMS += \
tests/test-complex-HTB-with-hash-filters \
@@ -913,11 +947,13 @@
check_PROGRAMS += \
tests/test-cache-mngr \
tests/test-genl \
- tests/test-nf-cache-mngr
+ tests/test-nf-cache-mngr \
+ $(NULL)
tests_cli_ldadd = \
$(tests_ldadd) \
- src/lib/libnl-cli-3.la
+ src/lib/libnl-cli-3.la \
+ $(NULL)
tests_test_cache_mngr_CPPFLAGS = $(tests_cppflags)
tests_test_cache_mngr_LDADD = $(tests_cli_ldadd)
@@ -932,11 +968,12 @@
endif
tests_check_all_SOURCES = \
- tests/check-addr.c \
tests/check-all.c \
- tests/check-attr.c \
- tests/check-ematch-tree-clone.c \
- tests/util.h \
+ tests/cksuite-all-addr.c \
+ tests/cksuite-all-attr.c \
+ tests/cksuite-all-ematch-tree-clone.c \
+ tests/cksuite-all-netns.c \
+ tests/cksuite-all.h \
$(NULL)
tests_check_all_CPPFLAGS = \
@@ -945,7 +982,34 @@
tests_check_all_LDADD = \
$(tests_ldadd) \
- $(CHECK_LIBS)
+ tests/libnl-test-util.la \
+ $(CHECK_LIBS) \
+ $(NULL)
+
+if WITH_CHECK
+if ENABLE_STATIC
+check_programs += tests/check-direct
+endif
+endif
+
+tests_check_direct_SOURCES = \
+ tests/check-direct.c \
+ $(NULL)
+
+tests_check_direct_CPPFLAGS = \
+ $(tests_cppflags) \
+ $(CHECK_CFLAGS) \
+ $(NULL)
+
+tests_check_direct_LDFLAGS = \
+ -static \
+ $(NULL)
+
+tests_check_direct_LDADD = \
+ $(tests_ldadd) \
+ tests/libnl-test-util.la \
+ $(CHECK_LIBS) \
+ $(NULL)
###############################################################################
@@ -1021,3 +1085,11 @@
libnl-route-3.sym \
libnl-xfrm-3.sym \
$(NULL)
+
+###############################################################################
+
+check-progs: all $(check_PROGRAMS) $(check_LTLIBRARIES)
+
+###############################################################################
+
+.PHONY = check-progs
diff --git a/configure.ac b/configure.ac
index ee44d89..b6bdcec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,18 +1,12 @@
-#
-# configure.in
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation version 2.1
-# of the License.
+# SPDX-License-Identifier: LGPL-2.1-only
+
#
# Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
#
-
# copied from glib
m4_define([libnl_major_version], [3])
-m4_define([libnl_minor_version], [5])
+m4_define([libnl_minor_version], [7])
m4_define([libnl_micro_version], [0])
m4_define([libnl_git_sha], [m4_esyscmd([ ( [ -d ./.git/ ] && [ "$(readlink -f ./.git/)" = "$(readlink -f "$(git rev-parse --git-dir 2>/dev/null)" 2>/dev/null)" ] && git rev-parse --verify -q HEAD 2>/dev/null ) || true ])])
@@ -113,6 +107,8 @@
AC_CHECK_LIB([pthread], [pthread_mutex_lock], [], AC_MSG_ERROR([libpthread is required]))
fi
+AM_CONDITIONAL([ENABLE_STATIC], [test "$enable_static" != "no"])
+
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--disable-debug], [Do not include debugging statements]),
[enable_debug="$enableval"], [enable_debug="yes"])
diff --git a/doc/.gitignore b/doc/.gitignore
deleted file mode 100644
index f7cb70d..0000000
--- a/doc/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.html
-libnl.dict
-Doxyfile
-/aclocal.m4
-/autom4te.cache/
-/build-aux/
-/config.*
-/configure
diff --git a/doc/COPYING b/doc/COPYING
index 94a9ed0..f288702 100644
--- a/doc/COPYING
+++ b/doc/COPYING
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@
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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/doc/README b/doc/README
index ddcdf14..dbca8f5 100644
--- a/doc/README
+++ b/doc/README
@@ -4,7 +4,7 @@
http://www.mcternan.me.uk/mscgen/
mscgen-filter-1.2
- http://code.google.com/p/asciidoc-mscgen-filter/
+ https://github.com/hwmaier/asciidoc-mscgen-filter
asciidoc > 8.6.x
doxygen > 1.8.0
diff --git a/doc/api/.gitignore b/doc/api/.gitignore
index cdef49d..e69de29 100644
--- a/doc/api/.gitignore
+++ b/doc/api/.gitignore
@@ -1,9 +0,0 @@
-*.html
-*.png
-*.css
-*.map
-*.md5
-*.js
-*.tag
-formula.repository
-jquery.js
diff --git a/doc/configure.ac b/doc/configure.ac
index 187447c..4fb3cc3 100644
--- a/doc/configure.ac
+++ b/doc/configure.ac
@@ -1,15 +1,9 @@
-#
-# configure.in
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation version 2.1
-# of the License.
+# SPDX-License-Identifier: LGPL-2.1-only
#
# Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
#
-AC_INIT(libnl-doc, [3.5.0], [http://www.infradead.org/~tgr/libnl/])
+AC_INIT(libnl-doc, [3.7.0], [http://www.infradead.org/~tgr/libnl/])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign])
diff --git a/doc/core.txt b/doc/core.txt
index 042369d..56d8749 100644
--- a/doc/core.txt
+++ b/doc/core.txt
@@ -13,10 +13,10 @@
== Introduction
The core library contains the fundamentals required to communicate
-over netlink sockets. It deals with connecting and disconnectng of
+over netlink sockets. It deals with connecting and disconnecting of
sockets, sending and receiving of data, construction and parsing of
-messages, provides a customizeable receiving state machine, and
-provides a abstract data type framework which eases the implementation
+messages, provides a customizable receiving state machine, and
+provides an abstract data type framework which eases the implementation
of object based netlink protocols where objects are added, removed, or
modified using a netlink based protocol.
@@ -385,8 +385,8 @@
--------
The configuration may be changed by sending a +MSG_SETCFG+ which will
-be responded to with either a ACK (see <<core_msg_ack>>)
-or a error message (see <<core_errmsg>>).
+be responded to with either an ACK (see <<core_msg_ack>>)
+or an error message (see <<core_errmsg>>).
["mscgen"]
--------
@@ -423,7 +423,7 @@
receiver is expected to continue receiving and parsing until the special
message type +NLMSG_DONE+ is received.
-Multipart messages unlike fragmented ip packets must not be reassmbled
+Multipart messages unlike fragmented ip packets must not be reassembled
even though it is perfectly legal to do so if the protocols wishes to
work this way. Often multipart message are used to send lists or trees
of objects were each multipart message simply carries multiple objects
@@ -552,7 +552,7 @@
Netlink allows the use of sequence numbers to help relate replies to
requests. It should be noted that unlike in protocols such as TCP
-there is no strict enforcment of the sequence number. The sole purpose
+there is no strict enforcement of the sequence number. The sole purpose
of sequence numbers is to assist a sender in relating replies to the
corresponding requests. See <<core_msg_types>> for more information.
@@ -733,7 +733,7 @@
void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb);
--------
-Additionaly a shortcut exists to modify the callback configuration
+Additionally a shortcut exists to modify the callback configuration
assigned to a socket directly:
[source,c]
@@ -930,7 +930,7 @@
dislike then you must overwrite the nl_send() function via
nl_cb_overwrite_send()
-The purpose of nl_send() is to embed the netlink message into a iovec
+The purpose of nl_send() is to embed the netlink message into an iovec
structure and pass it on to nl_send_iovec().
[source,c]
@@ -1117,8 +1117,8 @@
This may be useful if the netlink byte stream is in fact not received
from a socket directly but is read from a file or another source.
-If data has been read, it will be attemped to parse the data. This
-will be done repeately until the parser returns NL_STOP, an error was
+If data has been read, it will be attempted to parse the data. This
+will be done repeatedly until the parser returns NL_STOP, an error was
returned or all data has been parsed.
In case the last message parsed successfully was a multipart message
@@ -1200,7 +1200,7 @@
.Alignment
Most netlink protocols enforce a strict alignment policy for all
-boundries. The alignment value is defined by NLMSG_ALIGNTO and is
+boundaries. The alignment value is defined by NLMSG_ALIGNTO and is
fixed to 4 bytes. Therefore all netlink message headers, begin of
payload sections, protocol specific headers, and attribute sections
must start at an offset which is a multiple of NLMSG_ALIGNTO.
@@ -1321,7 +1321,7 @@
.Message Payload
-The message payload is appended to the message header and is guranteed
+The message payload is appended to the message header and is guaranteed
to start at a multiple of +NLMSG_ALIGNTO+. Padding at the end of the
message header is added if necessary to ensure this. The function
nlmsg_data() will calculate the necessary offset based on the message
@@ -1348,8 +1348,8 @@
nlmsg_tail(nlh) --------------------------------------------------^
--------
-The payload may consist of arbitary data but may have strict alignment
-and formatting rules depening on the actual netlink protocol.
+The payload may consist of arbitrary data but may have strict alignment
+and formatting rules depending on the actual netlink protocol.
[[core_msg_attr]]
.Message Attributes
@@ -1401,7 +1401,7 @@
The function nlmsg_validate() is based on nla_validate() and behaves
exactly the same as nlmsg_parse() except that it only validates and
-will not fill a array with pointers to each attribute.
+will not fill anarray with pointers to each attribute.
[source,c]
--------
@@ -1470,7 +1470,7 @@
--------
Instead of changing the default message size, the function
-nlmsg_alloc_size() can be used to allocate a message with a individual
+nlmsg_alloc_size() can be used to allocate a message with an individual
maximum message size.
@@ -1514,7 +1514,7 @@
The function nlmsg_put() will build a netlink message header out of
+nlmsg_type+, +nlmsg_flags+, +seqnr+, and +port+ and copy it into the
-netlink message. +seqnr+ can be set to +NL_AUTO_SEQ+ to indiciate
+netlink message. +seqnr+ can be set to +NL_AUTO_SEQ+ to indicate
that the next possible sequence number should be used automatically.
To use this feature, the message must be sent using the function
nl_send_auto(). Like +port+, the argument +seqnr+ can be set to
@@ -1538,7 +1538,7 @@
struct nl_msg *msg;
struct myhdr {
uint32_t foo1, foo2;
-} hdr = { 10, 20 };
+} shdr = { 10, 20 };
/* Allocate a message with the default maximum message size */
msg = nlmsg_alloc();
@@ -1548,10 +1548,10 @@
* let library fill port and sequence number, and reserve room for
* struct myhdr
*/
-hdr = nlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, MY_MSGTYPE, sizeof(hdr), NLM_F_CREATE);
+hdr = nlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, MY_MSGTYPE, sizeof(shdr), NLM_F_CREATE);
/* Copy own header into newly reserved payload section */
-memcpy(nlmsg_data(hdr), &hdr, sizeof(hdr));
+memcpy(nlmsg_data(hdr), &shdr, sizeof(shdr));
/*
* The message will now look like this:
@@ -1570,7 +1570,7 @@
Most functions described later on will automatically take care of
reserving room for the data that is added to the end of the netlink
-message. In some situations it may be requried for the application
+message. In some situations it may be required for the application
to reserve room directly though.
[source,c]
@@ -1619,10 +1619,10 @@
alignment requirements must be provided by the owner of the
previous message section.
-.Adding attribtues to a message
+.Adding attributes to a message
-Construction of attributes and addition of attribtues to the message is
-covereted in section <<core_attr>>.
+Construction of attributes and addition of attributes to the message is
+covered in section <<core_attr>>.
[[core_attr]]
== Attributes
@@ -1654,7 +1654,7 @@
[[core_attr_format]]
=== Attribute Format
-Netlink attributes allow for any number of data chunks of arbitary
+Netlink attributes allow for any number of data chunks of arbitrary
length to be attached to a netlink message. See <<core_msg_attr>>
for more information on where attributes are stored in the message.
@@ -1791,10 +1791,10 @@
[[core_attr_validation]]
.Attribute Validation
-When receiving netlink attributes, the receiver has certain expections
+When receiving netlink attributes, the receiver has certain expectations
on how the attributes should look like. These expectations must be
-defined to make sure the sending side meets our expecations. For this
-purpose, a attribute validation interface exists which must be used
+defined to make sure the sending side meets our expectations. For this
+purpose, an attribute validation interface exists which must be used
prior to accessing any payload.
All functions providing attribute validation functionality are based
@@ -1817,7 +1817,7 @@
member can be used to define a maximum payload length for an
attribute to still be considered valid.
-NOTE: Specyfing a maximum payload length is not recommended when
+NOTE: Specifying a maximum payload length is not recommended when
encoding structures in an attribute as it will prevent any
extension of the structure in the future. Something that is
frequently done in netlink protocols and does not break
@@ -1883,7 +1883,7 @@
The following example demonstrates how to parse a netlink message sent
over a netlink protocol which does not use protocol headers. The example
-does enforce a attribute policy however, the attribute MY_ATTR_FOO must
+does enforce an attribute policy however, the attribute MY_ATTR_FOO must
be a 32 bit integer, and the attribute MY_ATTR_BAR must be a string with
a maximum length of 16 characters.
@@ -1948,7 +1948,7 @@
In some situations it does not make sense to assign a unique attribute
type to each attribute in the attribute stream. For example a list may
-be transferd using a stream of attributes and even if the attribute type
+be transferred using a stream of attributes and even if the attribute type
is incremented for each attribute it may not make sense to use the
nlmsg_parse() or nla_parse() function to fill an array.
@@ -2003,7 +2003,7 @@
int nla_put(struct nl_msg *msg, int attrtype, int attrlen, const void *data);
--------
-The function nla_put() is base don nla_reserve() but takes an additional
+The function nla_put() is based on nla_reserve() but takes an additional
pointer +data+ pointing to a buffer containing the attribute payload.
It will copy the buffer into the message automatically.
@@ -2065,7 +2065,7 @@
A number of basic data types have been defined to simplify access and
validation of attributes. The datatype is not encoded in the
-attribute, therefore bthe sender and receiver are required to use the
+attribute, therefore the sender and receiver are required to use the
same definition on what attribute is of what type.
[options="header", cols="1m,5"]
@@ -2095,7 +2095,7 @@
NLA_U64:: 64bit integer
Note that due to the alignment requirements of attributes the integer
-attribtue +NLA_u8+ and +NLA_U16+ will not result in space savings in
+attribute +NLA_u8+ and +NLA_U16+ will not result in space savings in
the netlink message. Their use is intended to limit the range of
values.
@@ -2148,7 +2148,7 @@
automatically enforce the correct minimum payload length policy.
Validation does not differ between signed and unsigned integers, only
-the size matters. If the appliaction wishes to enforce particular value
+the size matters. If the application wishes to enforce particular value
ranges it must do so itself.
[source,c]
@@ -2252,13 +2252,13 @@
nlmsg_parse(), nla_validate(), or nla_parse() only the
attributes on the first level are being validated. None of these
functions will validate attributes recursively. Therefore you
- must explicitely call nla_validate() or use nla_parse_nested()
+ must explicitly call nla_validate() or use nla_parse_nested()
for each level of nested attributes.
The type +NLA_NESTED+ should be used when defining nested attributes
in a struct nla_policy definition. It will not enforce any minimum
-payload length unless +minlen+ is specified explicitely. This is
-because some netlink protocols implicitely allow empty container
+payload length unless +minlen+ is specified explicitly. This is
+because some netlink protocols implicitly allow empty container
attributes.
[source,c]
@@ -2294,7 +2294,7 @@
.Construction of Nested Attributes
Attributes are nested by surrounding them with calls to nla_nest_start()
-and nla_nest_end(). nla_nest_start() will add a attribute header to
+and nla_nest_end(). nla_nest_start() will add an attribute header to
the message but no actual payload. All data added to the message from
this point on will be part of the container attribute until nla_nest_end()
is called which "closes" the attribute, correcting its payload length to
@@ -2324,7 +2324,7 @@
==== Unspecified Attribute
This is the default attribute type and used when none of the basic
-datatypes is suitable. It represents data of arbitary type and length.
+datatypes is suitable. It represents data of arbitrary type and length.
See <<core_addr_alloc, Address Allocation>> for a more information on
a special interface allowing the allocation of abstract address object
@@ -2363,7 +2363,7 @@
/* Append a 32 bit integer attribute to carry the MTU */
NLA_PUT_U32(msg, IFLA_MTU, mtu);
- /* Append a unspecific attribute to carry the link layer address */
+ /* Append an unspecific attribute to carry the link layer address */
NLA_PUT_ADDR(msg, IFLA_ADDRESS, lladdr);
/* Append a container for nested attributes to carry link information */
@@ -2417,7 +2417,7 @@
* The nlmsg_parse() function will make sure that the message contains
* enough payload to hold the header (struct my_hdr), validates any
* attributes attached to the messages and stores a pointer to each
- * attribute in the attrs[] array accessable by attribute type.
+ * attribute in the attrs[] array accessible by attribute type.
*/
if ((err = nlmsg_parse(hdr, sizeof(struct my_hdr), attrs, ATTR_MAX,
attr_policy)) < 0)
@@ -2456,7 +2456,7 @@
== Callback Configurations
Callback hooks and overwriting capabilities are provided in various places
-inside library to control the behaviour of several functions. All the
+inside the library to control the behaviour of several functions. All the
callback and overwrite functions are packed together in struct nl_cb which
is attached to a netlink socket or passed on to functions directly.
@@ -2479,7 +2479,7 @@
.Default Callback Implementations
The library provides three sets of default callback implementations:
-* +NL_CB_DEFAULT+ This is the default set. It implets the default behaviour.
+* +NL_CB_DEFAULT+ This is the default set. It implements the default behaviour.
See the table below for more information on the return codes of each
function.
* +NL_CB_VERBOSE+ This set is based on the default set but will cause an
@@ -2583,7 +2583,7 @@
int (*func)(struct nl_sock *sk, struct nl_cb *cb));
--------
-The following criteras must be met if a recvmsgs() implementation is
+The following criterias must be met if a recvmsgs() implementation is
supposed to work with high level interfaces:
- MUST respect the callback configuration +cb+, therefore:
@@ -2618,14 +2618,14 @@
implementation:
- *MUST* return the number of bytes read or a negative error code if
- an error occured. The function may also return 0 to indicate that
+ an error occurred. The function may also return 0 to indicate that
no data has been read.
- *MUST* set `*buf` to a buffer containing the data read. It must be
safe for the caller to access the number of bytes read returned as
return code.
- *MAY* fill out `*addr` with the netlink address of the peer the
data has been received from.
- - *MAY* set `*cred` to a newly allocated struct ucred containg
+ - *MAY* set `*cred` to a newly allocated struct ucred containing
credentials.
.Overwriting nl_send()
@@ -2829,7 +2829,7 @@
a particular address. After the last user has returned the reference
the address is freed.
-If you pass on a address object to another function and you are not
+If you pass on an address object to another function and you are not
sure how long it will be used, make sure to call nl_addr_get() to
acquire an additional reference and have that function or code path
call nl_addr_put() as soon as it has finished using the address.
@@ -2926,7 +2926,7 @@
If an abstract address needs to presented to the user it should be
done in a human readable format which differs depending on the address
family. The function `nl_addr2str()` takes care of this by calling the
-appropriate conversion functions internaly. It expects a `buf` of
+appropriate conversion functions internally. It expects a `buf` of
length `size` to write the character string into and returns a pointer
to `buf` for easy `printf()` usage.
@@ -2955,9 +2955,9 @@
Before allocating an address you may want to check if the character
string actually represents a valid address of the address family you
are expecting. The function `nl_addr_valid()` can be used for that, it
-returns 1 if the supplised `addr` is a valid address in the context of
+returns 1 if the supplied `addr` is a valid address in the context of
`family`. See `inet_pton(3)`, `dnet_pton(3)` for more information on
-valid adddress formats.
+valid address formats.
[source,c]
--------
@@ -2969,12 +2969,12 @@
=== Abstract Data
The abstract data type is a trivial datatype with the primary purpose
-to simplify usage of netlink attributes of arbitary length.
+to simplify usage of netlink attributes of arbitrary length.
[[core_data_alloc]]
.Allocation of a Data Object
The function `nl_data_alloc()` alloctes a new abstract data object and
-fill it with the provided data. `nl_data_alloc_attr()` does the same
+fills it with the provided data. `nl_data_alloc_attr()` does the same
but bases the data on the payload of a netlink attribute. New data
objects can also be allocated by cloning existing ones by using
`nl_data_clone()`.
diff --git a/doc/doxygen-link.py b/doc/doxygen-link.py
index 910b8f8..1f3f67c 100755
--- a/doc/doxygen-link.py
+++ b/doc/doxygen-link.py
@@ -11,7 +11,7 @@
def parse_dict(filename):
links = {}
for line in open(filename, 'r'):
- m = re.match('^([^=]+)=([^\n]+)$', line);
+ m = re.match('^([^=]+)=([^\n]+)$', line)
if not m:
continue
name = m.group(1)
diff --git a/doc/images/.gitignore b/doc/images/.gitignore
deleted file mode 100644
index efcc7e2..0000000
--- a/doc/images/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-core__*
-asciidoc__*.png
-*.odg
diff --git a/doc/resolve-asciidoc-refs.py b/doc/resolve-asciidoc-refs.py
index 5418747..7999156 100755
--- a/doc/resolve-asciidoc-refs.py
+++ b/doc/resolve-asciidoc-refs.py
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+from __future__ import print_function
+
import fileinput
import re
import sys
@@ -22,4 +24,4 @@
rc = re.compile('|'.join(map(re.escape, sorted(refs, reverse=True))))
for line in open(sys.argv[1], 'r'):
- print rc.sub(translate, line),
+ print(rc.sub(translate, line), end='')
diff --git a/doc/route.txt b/doc/route.txt
index 9d4c23a..cd3ea8f 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -138,7 +138,7 @@
*Returns:*
- +EINVAL+ malformed message or invalid configuration parameters
-- +EAFNOSUPPORT+ if a address family specific configuration (+IFLA_AF_SPEC+)
+- +EAFNOSUPPORT+ if an address family specific configuration (+IFLA_AF_SPEC+)
is not supported.
- +EOPNOTSUPP+ if the link does not support modification of parameters
- +EEXIST+ if +NLM_F_EXCL+ was set and the link exists alraedy
@@ -195,7 +195,7 @@
The cache will contain link objects (+struct rtnl_link+, see <<link_object>>)
and can be accessed using the standard cache functions. By setting the
-+family+ parameter to an address familly other than +AF_UNSPEC+, the resulting
++family+ parameter to an address family other than +AF_UNSPEC+, the resulting
cache will only contain links supporting the specified address family.
The following direct search functions are provided to search by interface
@@ -268,7 +268,7 @@
==== Translating interface index to link name
Applications which require to translate interface index to a link name or
-vice verase may use the following functions to do so. Both functions require
+vice versa may use the following functions to do so. Both functions require
a filled link cache to work with.
[source,c]
@@ -447,7 +447,7 @@
IFF_LOOPBACK:: Link loopback network
IFF_POINTOPOINT:: Point-to-point link
IFF_NOARP:: ARP is not supported
-IFF_PROMISC:: Status of promiscious mode
+IFF_PROMISC:: Status of promiscuous mode
IFF_MASTER:: Master of a load balancer (bonding)
IFF_SLAVE:: Slave to a master link
IFF_PORTSEL:: Driver supports setting media type (only used by ARM ethernet)
@@ -941,9 +941,12 @@
extern int rtnl_link_ipip_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
extern uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link);
+extern int rtnl_link_ipip_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ipip_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
-----
-.Example: Add a ipip tunnel device
+.Example: Add an ipip tunnel device
[source,c]
-----
struct rtnl_link *link
@@ -1019,9 +1022,12 @@
extern int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
extern uint8_t rtnl_link_ipgre_get_pmtudisc(struct rtnl_link *link);
+extern int rtnl_link_ipgre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ipgre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
-----
-.Example: Add a ipgre tunnel device
+.Example: Add an ipgre tunnel device
[source,c]
-----
struct rtnl_link *link
@@ -1097,6 +1103,9 @@
extern int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
extern uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link);
+extern int rtnl_link_sit_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_sit_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
-----
.Example: Add a sit tunnel device
@@ -1161,9 +1170,12 @@
extern int rtnl_link_ipvti_set_remote(struct rtnl_link *link, uint32_t addr);
extern uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link);
+extern int rtnl_link_ipvti_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ipvti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
-----
-.Example: Add a ipvti tunnel device
+.Example: Add an ipvti tunnel device
[source,c]
-----
struct rtnl_link *link
@@ -1232,9 +1244,12 @@
extern int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto);
extern uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link);
+extern int rtnl_link_ip6_tnl_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ip6_tnl_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
-----
-.Example: Add a ip6tnl tunnel device
+.Example: Add an ip6tnl tunnel device
[source,c]
-----
struct rtnl_link *link
@@ -1256,6 +1271,127 @@
-----
+[[link_ip6gre]]
+==== IP6GRE
+
+[source,c]
+----
+extern int rtnl_link_is_ip6gre(struct rtnl_link *link);
+
+extern struct rtnl_link *rtnl_link_ip6gre_alloc(void);
+extern int rtnl_link_ip6gre_add(struct nl_sock *sk, const char *name);
+
+extern int rtnl_link_ip6gre_set_link(struct rtnl_link *link, uint32_t index);
+extern int rtnl_link_ip6gre_get_link(struct rtnl_link *link, uint32_t *index);
+
+extern int rtnl_link_ip6gre_set_iflags(struct rtnl_link *link, uint16_t iflags);
+extern int rtnl_link_ip6gre_get_iflags(struct rtnl_link *link, uint16_t *iflags);
+
+extern int rtnl_link_ip6gre_set_oflags(struct rtnl_link *link, uint16_t oflags);
+extern int rtnl_link_ip6gre_get_oflags(struct rtnl_link *link, uint16_t *oflags);
+
+extern int rtnl_link_ip6gre_set_ikey(struct rtnl_link *link, uint32_t ikey);
+extern int rtnl_link_ip6gre_get_ikey(struct rtnl_link *link, uint32_t *ikey);
+
+extern int rtnl_link_ip6gre_set_okey(struct rtnl_link *link, uint32_t okey);
+extern int rtnl_link_ip6gre_get_okey(struct rtnl_link *link, uint32_t *okey);
+
+extern int rtnl_link_ip6gre_set_local(struct rtnl_link *link, struct in6_addr *local);
+extern int rtnl_link_ip6gre_get_local(struct rtnl_link *link, struct in6_addr *local);
+
+extern int rtnl_link_ip6gre_set_remote(struct rtnl_link *link, struct in6_addr *remote);
+extern int rtnl_link_ip6gre_get_remote(struct rtnl_link *link, struct in6_addr *remote);
+
+extern int rtnl_link_ip6gre_set_ttl(struct rtnl_link *link, uint8_t ttl);
+extern int rtnl_link_ip6gre_get_ttl(struct rtnl_link *link, uint8_t *ttl);
+
+extern int rtnl_link_ip6gre_set_encaplimit(struct rtnl_link *link, uint8_t encaplimit);
+extern int rtnl_link_ip6gre_get_encaplimit(struct rtnl_link *link, uint8_t *encaplimit);
+
+extern int rtnl_link_ip6gre_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo);
+extern int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowinfo);
+
+extern int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags);
+extern int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags);
+
+extern int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
+----
+
+.Example: Add an ip6gre tunnel device
+[source,c]
+----
+struct rtnl_link *link
+struct in6_addr addr
+
+link = rtnl_link_ip6gre_alloc();
+
+rtnl_link_set_name(link, "ip6gre-tun");
+rtnl_link_ip6gre_set_link(link, if_index);
+
+inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr);
+rtnl_link_ip6gre_set_local(link, &addr);
+
+inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr);
+rtnl_link_ip6gre_set_remote(link, &addr);
+
+rtnl_link_add(sk, link, NLM_F_CREATE);
+rtnl_link_put(link);
+
+-----
+
+[[link_ip6vti]]
+==== IP6VTI
+
+[source,c]
+----
+int rtnl_link_is_ip6vti(struct rtnl_link *link);
+
+extern struct rtnl_link *rtnl_link_ip6vti_alloc(void);
+extern int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name);
+
+extern int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index);
+extern int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index);
+
+extern int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey);
+extern int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey);
+
+extern int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey);
+extern int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey);
+
+extern int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local);
+extern int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *remote);
+
+extern int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote);
+extern int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote);
+
+extern int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
+----
+
+.Example: Add an ip6vti tunnel device
+[source,c]
+----
+struct rtnl_link *link
+struct in6_addr addr
+
+link = rtnl_link_ip6vti_alloc();
+
+rtnl_link_set_name(link, "ip6vti-tun");
+rtnl_link_ip6vti_set_link(link, if_index);
+
+inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr);
+rtnl_link_ip6vti_set_local(link, &addr);
+
+inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr);
+rtnl_link_ip6vti_set_remote(link, &addr);
+
+rtnl_link_add(sk, link, NLM_F_CREATE);
+rtnl_link_put(link);
+
+-----
[[link_xfrmi]]
==== XFRMI
@@ -1490,7 +1626,7 @@
-----
Parent::
-Specifies the parent traffic control object. The parent is identifier
+Specifies the parent traffic control object. The parent is identified
by its handle. Special values are:
- `TC_H_ROOT`: attach tc object directly to network device (root
qdisc, root classifier)
@@ -1527,7 +1663,7 @@
| RTNL_TC_RATE_BPS | Rate | Current bytes/s rate
| RTNL_TC_RATE_PPS | Rate | Current packets/s rate
| RTNL_TC_QLEN | Rate | Current length of the queue
-| RTNL_TC_BACKLOG | Rate | # of packets currently backloged
+| RTNL_TC_BACKLOG | Rate | # of packets currently backlogged
| RTNL_TC_DROPS | Counter | # of packets dropped
| RTNL_TC_REQUEUES | Counter | # of packets requeued
| RTNL_TC_OVERLIMITS | Counter | # of packets that exceeded the limit
@@ -1548,6 +1684,7 @@
-------
==== Rate Table Calculations
+TODO
[[tc_qdisc]]
=== Queueing Discipline (qdisc)
@@ -1555,7 +1692,7 @@
.Classless Qdisc
The queueing discipline (qdisc) is used to implement fair queueing,
-priorization or rate control. It provides a _enqueue()_ and
+prioritization or rate control. It provides a _enqueue()_ and
_dequeue()_ operation. Whenever a network packet leaves the networking
stack over a network device, be it a physical or virtual device, it
will be enqueued to a qdisc unless the device is queueless. The
@@ -1607,7 +1744,7 @@
class.
| DRR | Yes |
The DRR (Deficit Round Robin) scheduler is a classful qdisc
-impelemting fair queueing. Each class is assigned a quantum specyfing
+implementing fair queueing. Each class is assigned a quantum specifying
the maximum number of bytes that can be served per round. Unused
quantum at the end of the round is carried over to the next round.
| DSMARK | Yes | FIXME
@@ -1771,7 +1908,7 @@
rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
-----
-After specyfing the qdisc kind (rtnl_tc_set_kind()) the qdisc type
+After specifying the qdisc kind (rtnl_tc_set_kind()) the qdisc type
specific interface can be used to set attributes which are specific
to the respective qdisc implementations:
@@ -1880,7 +2017,7 @@
-----
Rate::
-The rate (bytes/s) specifies the maximum bandwidth an invidivual class
+The rate (bytes/s) specifies the maximum bandwidth an individual class
can use without borrowing. The rate of a class should always be greater
or erqual than the rate of its children.
+
@@ -1891,7 +2028,7 @@
-----
Ceil Rate::
-The ceil rate specifies the maximum bandwidth an invidivual class
+The ceil rate specifies the maximum bandwidth an individual class
can use. This includes bandwidth that is being borrowed from other
classes. Ceil defaults to the class rate implying that by default
the class will not borrow. The ceil rate of a class should always
@@ -1917,8 +2054,8 @@
+
[source,c]
-----
-uint32_t rtnl_htb_get_bbuffer(struct rtnl_class *class);
-int rtnl_htb_set_bbuffer(struct rtnl_class *class, uint32_t burst);
+uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *);
+int rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t);
-----
Quantum::
@@ -1926,13 +2063,10 @@
+
[source,c]
-----
+uint32_t rtnl_htb_get_quantum(struct rtnl_class *class);
int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum);
-----
-extern int rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t);
-
-
-
[[tc_class]]
=== Class
diff --git a/include/linux-private/linux/if_bridge.h b/include/linux-private/linux/if_bridge.h
index bdfecf9..e206aa8 100644
--- a/include/linux-private/linux/if_bridge.h
+++ b/include/linux-private/linux/if_bridge.h
@@ -243,6 +243,7 @@
union {
__be32 ip4;
struct in6_addr ip6;
+ unsigned char mac_addr[ETH_ALEN];
} u;
__be16 proto;
} addr;
diff --git a/include/linux-private/linux/if_link.h b/include/linux-private/linux/if_link.h
index f4a9715..47ccf7f 100644
--- a/include/linux-private/linux/if_link.h
+++ b/include/linux-private/linux/if_link.h
@@ -455,6 +455,7 @@
IFLA_MACSEC_REPLAY_PROTECT,
IFLA_MACSEC_VALIDATION,
IFLA_MACSEC_PAD,
+ IFLA_MACSEC_OFFLOAD,
__IFLA_MACSEC_MAX,
};
diff --git a/include/linux-private/linux/if_vlan.h b/include/linux-private/linux/if_vlan.h
index 18a15da..04bca79 100644
--- a/include/linux-private/linux/if_vlan.h
+++ b/include/linux-private/linux/if_vlan.h
@@ -32,10 +32,11 @@
};
enum vlan_flags {
- VLAN_FLAG_REORDER_HDR = 0x1,
- VLAN_FLAG_GVRP = 0x2,
- VLAN_FLAG_LOOSE_BINDING = 0x4,
- VLAN_FLAG_MVRP = 0x8,
+ VLAN_FLAG_REORDER_HDR = 0x1,
+ VLAN_FLAG_GVRP = 0x2,
+ VLAN_FLAG_LOOSE_BINDING = 0x4,
+ VLAN_FLAG_MVRP = 0x8,
+ VLAN_FLAG_BRIDGE_BINDING = 0x10,
};
enum vlan_name_types {
diff --git a/include/linux-private/linux/netfilter/nfnetlink_log.h b/include/linux-private/linux/netfilter/nfnetlink_log.h
index 20983cb..45c8d3b 100644
--- a/include/linux-private/linux/netfilter/nfnetlink_log.h
+++ b/include/linux-private/linux/netfilter/nfnetlink_log.h
@@ -33,6 +33,15 @@
__aligned_be64 usec;
};
+enum nfulnl_vlan_attr {
+ NFULA_VLAN_UNSPEC,
+ NFULA_VLAN_PROTO, /* __be16 skb vlan_proto */
+ NFULA_VLAN_TCI, /* __be16 skb htons(vlan_tci) */
+ __NFULA_VLAN_MAX,
+};
+
+#define NFULA_VLAN_MAX (__NFULA_VLAN_MAX + 1)
+
enum nfulnl_attr_type {
NFULA_UNSPEC,
NFULA_PACKET_HDR,
@@ -54,6 +63,8 @@
NFULA_HWLEN, /* hardware header length */
NFULA_CT, /* nf_conntrack_netlink.h */
NFULA_CT_INFO, /* enum ip_conntrack_info */
+ NFULA_VLAN, /* nested attribute: packet vlan info */
+ NFULA_L2HDR, /* full L2 header */
__NFULA_MAX
};
diff --git a/include/linux-private/linux/tc_act/tc_nat.h b/include/linux-private/linux/tc_act/tc_nat.h
new file mode 100644
index 0000000..21399c2
--- /dev/null
+++ b/include/linux-private/linux/tc_act/tc_nat.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_TC_NAT_H
+#define __LINUX_TC_NAT_H
+
+#include <linux/pkt_cls.h>
+#include <linux/types.h>
+
+enum {
+ TCA_NAT_UNSPEC,
+ TCA_NAT_PARMS,
+ TCA_NAT_TM,
+ TCA_NAT_PAD,
+ __TCA_NAT_MAX
+};
+#define TCA_NAT_MAX (__TCA_NAT_MAX - 1)
+
+#define TCA_NAT_FLAG_EGRESS 1
+
+struct tc_nat {
+ tc_gen;
+ __be32 old_addr;
+ __be32 new_addr;
+ __be32 mask;
+ __u32 flags;
+};
+
+#endif
diff --git a/include/netlink-private/cache-api.h b/include/netlink-private/cache-api.h
index c684e79..38662b7 100644
--- a/include/netlink-private/cache-api.h
+++ b/include/netlink-private/cache-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/cache-api.h Caching API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/genl.h b/include/netlink-private/genl.h
index 5b93db3..ac592bd 100644
--- a/include/netlink-private/genl.h
+++ b/include/netlink-private/genl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/genl.h Local Generic Netlink Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
index 5f6e3f7..d86a55d 100644
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/netlink.h Local Netlink Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -65,6 +59,7 @@
#include <netlink-private/object-api.h>
#include <netlink-private/cache-api.h>
#include <netlink-private/types.h>
+#include <netlink-private/utils.h>
#define NSEC_PER_SEC 1000000000L
diff --git a/include/netlink-private/nl-auto.h b/include/netlink-private/nl-auto.h
new file mode 100644
index 0000000..4092782
--- /dev/null
+++ b/include/netlink-private/nl-auto.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef NETLINK_NL_AUTO_H_
+#define NETLINK_NL_AUTO_H_
+
+#include <stdlib.h>
+
+#define _nl_auto(fcn) __attribute__ ((__cleanup__(fcn)))
+
+#define _NL_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \
+static inline void name(void *v) \
+{ \
+ if (*((CastType *) v)) \
+ func(*((CastType *) v)); \
+} \
+struct _nl_dummy_for_tailing_semicolon
+
+#define _NL_AUTO_DEFINE_FCN_STRUCT(CastType, name, func) \
+static inline void name(CastType *v) \
+{ \
+ if (v) \
+ func(v); \
+} \
+struct _nl_dummy_for_tailing_semicolon
+
+#define _NL_AUTO_DEFINE_FCN_TYPED0(CastType, name, func) \
+static inline void name(CastType *v) \
+{ \
+ if (*v) \
+ func(*v); \
+} \
+struct _nl_dummy_for_tailing_semicolon
+
+#define _nl_auto_free _nl_auto(_nl_auto_free_fcn)
+_NL_AUTO_DEFINE_FCN_VOID0(void *, _nl_auto_free_fcn, free);
+
+struct nl_addr;
+void nl_addr_put(struct nl_addr *);
+#define _nl_auto_nl_addr _nl_auto(_nl_auto_nl_addr_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_addr *, _nl_auto_nl_addr_fcn, nl_addr_put);
+
+struct nl_data;
+void nl_data_free(struct nl_data *data);
+#define _nl_auto_nl_data _nl_auto(_nl_auto_nl_data_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_data *, _nl_auto_nl_data_fcn, nl_data_free);
+
+struct nl_msg;
+void nlmsg_free(struct nl_msg *);
+#define _nl_auto_nl_msg _nl_auto(_nl_auto_nl_msg_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_msg *, _nl_auto_nl_msg_fcn, nlmsg_free);
+
+struct rtnl_link;
+void rtnl_link_put(struct rtnl_link *);
+#define _nl_auto_rtnl_link _nl_auto(_nl_auto_rtnl_link_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_link *, _nl_auto_rtnl_link_fcn, rtnl_link_put);
+
+struct rtnl_route;
+void rtnl_route_put(struct rtnl_route *);
+#define _nl_auto_rtnl_route _nl_auto(_nl_auto_rtnl_route_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_route *, _nl_auto_rtnl_route_fcn, rtnl_route_put);
+
+struct rtnl_mdb;
+void rtnl_mdb_put(struct rtnl_mdb *);
+#define _nl_auto_rtnl_mdb _nl_auto(_nl_auto_rtnl_mdb_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_mdb *, _nl_auto_rtnl_mdb_fcn, rtnl_mdb_put);
+
+struct rtnl_nexthop;
+void rtnl_route_nh_free(struct rtnl_nexthop *);
+#define _nl_auto_rtnl_nexthop _nl_auto(_nl_auto_rtnl_nexthop_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_nexthop *, _nl_auto_rtnl_nexthop_fcn, rtnl_route_nh_free);
+
+struct nl_cache;
+void nl_cache_put(struct nl_cache *);
+#define _nl_auto_nl_cache _nl_auto(_nl_auto_nl_cache_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_cache *, _nl_auto_nl_cache_fcn, nl_cache_put);
+
+struct rtnl_link_af_ops;
+void rtnl_link_af_ops_put(struct rtnl_link_af_ops *);
+#define _nl_auto_rtnl_link_af_ops _nl_auto(_nl_auto_rtnl_link_af_ops_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_link_af_ops *, _nl_auto_rtnl_link_af_ops_fcn, rtnl_link_af_ops_put);
+
+struct rtnl_act;
+void rtnl_act_put(struct rtnl_act *);
+#define _nl_auto_rtnl_act _nl_auto(_nl_auto_rtnl_act_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_act *, _nl_auto_rtnl_act_fcn, rtnl_act_put);
+
+struct rtnl_ematch_tree;
+void rtnl_ematch_tree_free(struct rtnl_ematch_tree *);
+#define _nl_auto_rtnl_ematch_tree _nl_auto(_nl_auto_rtnl_ematch_tree_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_ematch_tree *, _nl_auto_rtnl_ematch_tree_fcn, rtnl_ematch_tree_free);
+
+struct rtnl_cls;
+void rtnl_cls_put(struct rtnl_cls *);
+#define _nl_auto_rtnl_cls _nl_auto(_nl_auto_rtnl_cls_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_cls *, _nl_auto_rtnl_cls_fcn, rtnl_cls_put);
+
+struct nl_sock;
+void nl_socket_free(struct nl_sock *);
+#define _nl_auto_nl_socket _nl_auto(_nl_auto_nl_socket_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_sock *, _nl_auto_nl_socket_fcn, nl_socket_free);
+
+#endif /* NETLINK_NL_AUTO_H_ */
diff --git a/include/netlink-private/object-api.h b/include/netlink-private/object-api.h
index 517e672..a2838fd 100644
--- a/include/netlink-private/object-api.h
+++ b/include/netlink-private/object-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/object-api.c Object API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/route/link/api.h b/include/netlink-private/route/link/api.h
index 6d30bf7..189f361 100644
--- a/include/netlink-private/route/link/api.h
+++ b/include/netlink-private/route/link/api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/route/link/api.h Link Modules API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -68,6 +62,7 @@
};
extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *);
+extern void rtnl_link_info_ops_get(struct rtnl_link_info_ops *);
extern void rtnl_link_info_ops_put(struct rtnl_link_info_ops *);
extern int rtnl_link_register_info(struct rtnl_link_info_ops *);
extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *);
diff --git a/include/netlink-private/route/link/sriov.h b/include/netlink-private/route/link/sriov.h
index ac653ed..f7c027a 100644
--- a/include/netlink-private/route/link/sriov.h
+++ b/include/netlink-private/route/link/sriov.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * include/netlink-private/route/link/sriov.h SRIOV VF Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Intel Corp. All rights reserved.
* Copyright (c) 2016 Jef Oliver <jef.oliver@intel.com>
*/
diff --git a/include/netlink-private/route/tc-api.h b/include/netlink-private/route/tc-api.h
index 7158ce5..1eb27dc 100644
--- a/include/netlink-private/route/tc-api.h
+++ b/include/netlink-private/route/tc-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/route/tc-api.h Traffic Control API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/route/utils.h b/include/netlink-private/route/utils.h
new file mode 100644
index 0000000..65ff531
--- /dev/null
+++ b/include/netlink-private/route/utils.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef NETLINK_ROUTE_UTILS_PRIV_H_
+#define NETLINK_ROUTE_UTILS_PRIV_H_
+
+extern const uint8_t *const _nltst_map_stat_id_from_IPSTATS_MIB_v2;
+
+#endif
diff --git a/include/netlink-private/socket.h b/include/netlink-private/socket.h
index 9ceecfd..5fe77fa 100644
--- a/include/netlink-private/socket.h
+++ b/include/netlink-private/socket.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/socket.h Private declarations for socket
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/tc.h b/include/netlink-private/tc.h
index b0f9c50..5f5d1ff 100644
--- a/include/netlink-private/tc.h
+++ b/include/netlink-private/tc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/tc.h Local Traffic Control Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 97af3e5..b8f785a 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/types.h Netlink Types (Private)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
@@ -33,6 +27,9 @@
#include <linux/tc_act/tc_vlan.h>
#include <linux/sock_diag.h>
#include <linux/fib_rules.h>
+#include <linux/if_ether.h>
+
+#include <netinet/in.h>
#define NL_SOCK_PASSCRED (1<<1)
#define NL_OWN_PORT (1<<2)
@@ -616,6 +613,27 @@
int m_mask;
};
+struct rtnl_flower
+{
+ struct rtnl_act *cf_act;
+ int cf_mask;
+ uint32_t cf_flags;
+ uint16_t cf_proto;
+ uint16_t cf_vlan_id;
+ uint16_t cf_vlan_ethtype;
+ uint8_t cf_vlan_prio;
+ uint8_t cf_src_mac[ETH_ALEN];
+ uint8_t cf_src_mac_mask[ETH_ALEN];
+ uint8_t cf_dst_mac[ETH_ALEN];
+ uint8_t cf_dst_mac_mask[ETH_ALEN];
+ in_addr_t cf_ipv4_src;
+ in_addr_t cf_ipv4_src_mask;
+ in_addr_t cf_ipv4_dst;
+ in_addr_t cf_ipv4_dst_mask;
+ uint8_t cf_ip_dscp;
+ uint8_t cf_ip_dscp_mask;
+};
+
struct rtnl_cgroup
{
struct rtnl_ematch_tree *cg_ematch;
@@ -1015,6 +1033,14 @@
uint32_t log_msg_gid;
uint32_t log_msg_seq;
uint32_t log_msg_seq_global;
+ uint16_t log_msg_hwtype;
+ uint16_t log_msg_hwlen;
+ void * log_msg_hwheader;
+ int log_msg_hwheader_len;
+ uint16_t log_msg_vlan_tag;
+ uint16_t log_msg_vlan_proto;
+ uint32_t log_msg_ct_info;
+ struct nfnl_ct * log_msg_ct;
};
struct nfnl_queue {
@@ -1237,6 +1263,11 @@
struct nl_addr* encap_oa;
};
+struct xfrmnl_user_offload {
+ int ifindex;
+ uint8_t flags;
+};
+
struct xfrmnl_sa {
NLHDR_COMMON
@@ -1266,6 +1297,7 @@
struct xfrmnl_replay_state replay_state;
struct xfrmnl_replay_state_esn* replay_state_esn;
uint8_t hard;
+ struct xfrmnl_user_offload* user_offload;
};
struct xfrmnl_usersa_flush {
@@ -1338,4 +1370,19 @@
uint32_t v_flags;
};
+struct rtnl_mdb {
+ NLHDR_COMMON
+ uint32_t ifindex;
+
+ struct nl_list_head mdb_entry_list;
+};
+
+struct rtnl_mdb_entry {
+ struct nl_list_head mdb_list;
+ struct nl_addr *addr;
+ uint32_t ifindex;
+ uint16_t vid;
+ uint16_t proto;
+ uint8_t state;
+};
#endif
diff --git a/include/netlink-private/utils.h b/include/netlink-private/utils.h
index f33a2f8..93a04c9 100644
--- a/include/netlink-private/utils.h
+++ b/include/netlink-private/utils.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink-private/utils.h Local Utility Functions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -13,6 +7,13 @@
#define NETLINK_UTILS_PRIV_H_
#include <byteswap.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdbool.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#define ntohll(x) (x)
@@ -71,6 +72,23 @@
/*****************************************************************************/
+#ifdef thread_local
+#define _nl_thread_local thread_local
+/*
+ * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
+ * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
+ */
+#elif __STDC_VERSION__ >= 201112L && \
+ !(defined(__STDC_NO_THREADS__) || \
+ (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && \
+ __GLIBC_MINOR__ < 16))
+#define _nl_thread_local _Thread_local
+#else
+#define _nl_thread_local __thread
+#endif
+
+/*****************************************************************************/
+
#define _NL_STATIC_ASSERT(cond) ((void) sizeof (char[(cond) ? 1 : -1]))
/*****************************************************************************/
@@ -81,17 +99,45 @@
#define _nl_assert(cond) do { if (0) { assert(cond); } } while (0)
#endif
+#define _nl_assert_not_reached() assert(0)
+
/*****************************************************************************/
-#define _NL_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \
-static inline void name (void *v) \
-{ \
- if (*((CastType *) v)) \
- func (*((CastType *) v)); \
-}
+#define _nl_assert_addr_family_or_unspec(addr_family) \
+ do { \
+ typeof(addr_family) _addr_family = (addr_family); \
+ \
+ _nl_assert(_addr_family == AF_UNSPEC || \
+ _addr_family == AF_INET || \
+ _addr_family == AF_INET6); \
+ } while (0)
-#define _nl_auto_free _nl_auto(_nl_auto_free_fcn)
-_NL_AUTO_DEFINE_FCN_VOID0 (void *, _nl_auto_free_fcn, free)
+#define _nl_assert_addr_family(addr_family) \
+ do { \
+ typeof(addr_family) _addr_family = (addr_family); \
+ \
+ _nl_assert(_addr_family == AF_INET || \
+ _addr_family == AF_INET6); \
+ } while (0)
+
+/*****************************************************************************/
+
+#define _NL_SWAP(pa, pb) \
+ do { \
+ typeof(*(pa)) *_pa = (pa); \
+ typeof(*(pb)) *_pb = (pb); \
+ typeof(*_pa) _tmp; \
+ \
+ _nl_assert(_pa); \
+ _nl_assert(_pb); \
+ _tmp = *_pa; \
+ *_pa = *_pb; \
+ *_pb = _tmp; \
+ } while (0)
+
+/*****************************************************************************/
+
+#define _NL_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
/*****************************************************************************/
@@ -163,11 +209,21 @@
/*****************************************************************************/
+static inline bool _nl_streq(const char *a, const char *b)
+{
+ return !strcmp(a, b);
+}
+
+static inline bool _nl_streq0(const char *a, const char *b)
+{
+ return a == b || (a && b && _nl_streq(a, b));
+}
+
static inline char *
_nl_strncpy_trunc(char *dst, const char *src, size_t len)
{
/* we don't use/reimplement strlcpy(), because we want the fill-all-with-NUL
- * behavior of strncpy(). This is just strncpy() with gracefully handling trunction
+ * behavior of strncpy(). This is just strncpy() with gracefully handling truncation
* (and disabling the "-Wstringop-truncation" warning).
*
* Note that truncation is silently accepted.
@@ -192,32 +248,146 @@
}
static inline char *
-_nl_strncpy(char *dst, const char *src, size_t len)
+_nl_strncpy_assert(char *dst, const char *src, size_t len)
{
/* we don't use/reimplement strlcpy(), because we want the fill-all-with-NUL
- * behavior of strncpy(). This is just strncpy() with gracefully handling trunction
+ * behavior of strncpy(). This is just strncpy() with assertion against truncation
* (and disabling the "-Wstringop-truncation" warning).
*
* Note that truncation is still a bug and there is an _nl_assert()
* against that.
*/
+ _NL_PRAGMA_WARNING_DISABLE ("-Wstringop-truncation");
+ _NL_PRAGMA_WARNING_DISABLE ("-Wstringop-overflow");
+
if (len > 0) {
_nl_assert(dst);
_nl_assert(src);
strncpy(dst, src, len);
- /* Truncation is a bug and we assert against it. But note that this
- * assertion is disabled by default because we cannot be sure that
- * there are not wrong uses of _nl_strncpy() where truncation might
- * happen (wrongly!!). */
- _nl_assert (memchr(dst, '\0', len));
+ _nl_assert (dst[len - 1] == '\0');
dst[len - 1] = '\0';
}
+ _NL_PRAGMA_WARNING_REENABLE;
+ _NL_PRAGMA_WARNING_REENABLE;
+
return dst;
}
+#include "nl-auto.h"
+
+#define _NL_RETURN_ON_ERR(cmd) \
+ do { \
+ int _err; \
+ \
+ _err = (cmd); \
+ if (_err < 0) \
+ return _err; \
+ } while (0)
+
+#define _NL_RETURN_E_ON_ERR(e, cmd) \
+ do { \
+ int _err; \
+ \
+ _err = (cmd); \
+ if (_err < 0) { \
+ _NL_STATIC_ASSERT((e) > 0); \
+ return -(e); \
+ } \
+ } while (0)
+
+/* _NL_RETURN_ON_PUT_ERR() shall only be used with a put command (nla_put or nlmsg_append).
+ * These commands can either fail with a regular error code (which gets propagated)
+ * or with -NLE_NOMEM. However, they don't really try to allocate memory, so we don't
+ * want to propagate -NLE_NOMEM. Instead, we coerce such failure to -NLE_MSGSIZE. */
+#define _NL_RETURN_ON_PUT_ERR(put_cmd) \
+ do { \
+ int _err; \
+ \
+ _err = (put_cmd); \
+ if (_err < 0) { \
+ if (_err == -NLE_NOMEM) { \
+ /* nla_put() returns -NLE_NOMEM in case of out of buffer size. We don't
+ * want to propagate that error and map it to -NLE_MSGSIZE. */ \
+ return -NLE_MSGSIZE; \
+ } \
+ /* any other error can only be due to invalid parameters. Propagate the
+ * error, however also assert that it cannot be reached. */ \
+ _nl_assert_not_reached (); \
+ return _err; \
+ } else \
+ _nl_assert (_err == 0); \
+ } while (0)
+
+static inline int
+_nl_close(int fd)
+{
+ int r;
+
+ r = close(fd);
+ _nl_assert(r == 0 || fd < 0 || errno != EBADF);
+ return r;
+}
+
+static inline void *
+_nl_memdup(const void *ptr, size_t len)
+{
+ void *p;
+
+ if (len == 0) {
+ /* malloc() leaves it implementation defined whether to return NULL.
+ * Callers rely on returning NULL if len is zero. */
+ return NULL;
+ }
+
+ p = malloc(len);
+ if (!p)
+ return NULL;
+ memcpy(p, ptr, len);
+ return p;
+}
+
+#define _nl_memdup_ptr(ptr) ((__typeof__(ptr)) _nl_memdup((ptr), sizeof(*(ptr))))
+
+/*****************************************************************************/
+
+typedef union {
+ in_addr_t addr4;
+ struct in_addr a4;
+ struct in6_addr a6;
+} _NLIPAddr;
+
+static inline char *_nl_inet_ntop(int addr_family, const void *addr,
+ char buf[static INET_ADDRSTRLEN])
+{
+ char *r;
+
+ _nl_assert_addr_family(addr_family);
+ _nl_assert(addr);
+
+ /* inet_ntop() is documented to fail, but if we pass a known address family
+ * and a suitably large buffer, it cannot. Assert for that. */
+
+ r = (char *)inet_ntop(addr_family, addr, buf,
+ (addr_family == AF_INET) ? INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN);
+ _nl_assert(r == buf);
+ _nl_assert(strlen(r) < ((addr_family == AF_INET) ? INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN));
+
+ return r;
+}
+
+static inline char *_nl_inet_ntop_dup(int addr_family, const void *addr)
+{
+ return (char *)_nl_inet_ntop(addr_family, addr,
+ malloc((addr_family == AF_INET) ?
+ INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN));
+}
+
#endif
diff --git a/include/netlink/.gitignore b/include/netlink/.gitignore
deleted file mode 100644
index 6702033..0000000
--- a/include/netlink/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-version.h
diff --git a/include/netlink/addr.h b/include/netlink/addr.h
index 00ca784..851e940 100644
--- a/include/netlink/addr.h
+++ b/include/netlink/addr.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/addr.h Abstract Address
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/attr.h b/include/netlink/attr.h
index e47aa5d..2cd32ee 100644
--- a/include/netlink/attr.h
+++ b/include/netlink/attr.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/attr.h Netlink Attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/cache-api.h b/include/netlink/cache-api.h
index e43c7ca..851eca0 100644
--- a/include/netlink/cache-api.h
+++ b/include/netlink/cache-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cache-api.h Caching API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index c0797d0..abeeccb 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cache.h Caching Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/cli/addr.h b/include/netlink/cli/addr.h
index d0fd055..5fcf734 100644
--- a/include/netlink/cli/addr.h
+++ b/include/netlink/cli/addr.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/addr.h CLI Address Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,6 +8,10 @@
#include <netlink/route/addr.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define nl_cli_addr_alloc_cache(sk) \
nl_cli_alloc_cache((sk), "address", rtnl_addr_alloc_cache)
@@ -29,4 +27,8 @@
extern void nl_cli_addr_parse_preferred(struct rtnl_addr *, char *);
extern void nl_cli_addr_parse_valid(struct rtnl_addr *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/class.h b/include/netlink/cli/class.h
index 5001e42..9552374 100644
--- a/include/netlink/cli/class.h
+++ b/include/netlink/cli/class.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/class.h CLI Class Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -15,7 +9,15 @@
#include <netlink/route/class.h>
#include <netlink/cli/tc.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct rtnl_class *nl_cli_class_alloc(void);
extern struct nl_cache *nl_cli_class_alloc_cache(struct nl_sock *, int);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/cls.h b/include/netlink/cli/cls.h
index a2707b8..602b198 100644
--- a/include/netlink/cli/cls.h
+++ b/include/netlink/cli/cls.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/cls.h CLI Classifier Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -15,10 +9,18 @@
#include <netlink/route/classifier.h>
#include <netlink/cli/tc.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct rtnl_cls * nl_cli_cls_alloc(void);
extern struct nl_cache * nl_cli_cls_alloc_cache(struct nl_sock *,
int, uint32_t);
extern void nl_cli_cls_parse_proto(struct rtnl_cls *, char *);
extern struct rtnl_ematch_tree *nl_cli_cls_parse_ematch(struct rtnl_cls *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/ct.h b/include/netlink/cli/ct.h
index ebe7c9d..a50b430 100644
--- a/include/netlink/cli/ct.h
+++ b/include/netlink/cli/ct.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/ct.h CLI Conntrack Helper
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -15,6 +9,10 @@
#include <netlink/netfilter/ct.h>
#include <linux/netfilter/nf_conntrack_common.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct nfnl_ct *nl_cli_ct_alloc(void);
extern struct nl_cache *nl_cli_ct_alloc_cache(struct nl_sock *);
@@ -32,4 +30,8 @@
extern void nl_cli_ct_parse_status(struct nfnl_ct *, char *);
extern void nl_cli_ct_parse_zone(struct nfnl_ct *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/exp.h b/include/netlink/cli/exp.h
index b2418f8..64d3b08 100644
--- a/include/netlink/cli/exp.h
+++ b/include/netlink/cli/exp.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/exp.h CLI Expectation Helper
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Rich Fought <Rich.Fought@watchguard.com>
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -16,6 +10,10 @@
#include <netlink/netfilter/exp.h>
#include <linux/netfilter/nf_conntrack_common.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct nfnl_exp *nl_cli_exp_alloc(void);
extern struct nl_cache *nl_cli_exp_alloc_cache(struct nl_sock *);
@@ -38,5 +36,8 @@
extern void nl_cli_exp_parse_icmp_type(struct nfnl_exp *, int, char *);
extern void nl_cli_exp_parse_icmp_code(struct nfnl_exp *, int, char *);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/include/netlink/cli/link.h b/include/netlink/cli/link.h
index f2c720b..fb6c0a4 100644
--- a/include/netlink/cli/link.h
+++ b/include/netlink/cli/link.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/link.h CLI Link Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -15,6 +9,10 @@
#include <netlink/route/link.h>
#include <netlink/cli/utils.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct rtnl_link *nl_cli_link_alloc(void);
extern struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *, int);
extern struct nl_cache *nl_cli_link_alloc_cache_family_flags(struct nl_sock *, int,
@@ -31,4 +29,8 @@
extern void nl_cli_link_parse_weight(struct rtnl_link *, char *);
extern void nl_cli_link_parse_ifalias(struct rtnl_link *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/mdb.h b/include/netlink/cli/mdb.h
new file mode 100644
index 0000000..cd37604
--- /dev/null
+++ b/include/netlink/cli/mdb.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef __NETLINK_CLI_MDB_H_
+#define __NETLINK_CLI_MDB_H_
+
+#include <netlink/route/mdb.h>
+
+#define nl_cli_mdb_alloc_cache(sk) \
+ nl_cli_alloc_cache_flags((sk), "mdb", NL_CACHE_AF_ITER, rtnl_mdb_alloc_cache)
+
+#endif
diff --git a/include/netlink/cli/neigh.h b/include/netlink/cli/neigh.h
index 1c1be91..89a336c 100644
--- a/include/netlink/cli/neigh.h
+++ b/include/netlink/cli/neigh.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/neighbour.h CLI Neighbour Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,6 +8,10 @@
#include <netlink/route/neighbour.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define nl_cli_neigh_alloc_cache(sk) \
nl_cli_alloc_cache_flags((sk), "neighbour", NL_CACHE_AF_ITER, \
rtnl_neigh_alloc_cache_flags)
@@ -25,4 +23,8 @@
extern void nl_cli_neigh_parse_family(struct rtnl_neigh *, char *);
extern void nl_cli_neigh_parse_state(struct rtnl_neigh *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/qdisc.h b/include/netlink/cli/qdisc.h
index b102da4..d70e559 100644
--- a/include/netlink/cli/qdisc.h
+++ b/include/netlink/cli/qdisc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/qdisc.h CLI QDisc Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,10 +8,18 @@
#include <netlink/route/qdisc.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define nl_cli_qdisc_alloc_cache(sk) \
nl_cli_alloc_cache((sk), "queueing disciplines", \
rtnl_qdisc_alloc_cache)
extern struct rtnl_qdisc *nl_cli_qdisc_alloc(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/route.h b/include/netlink/cli/route.h
index 089c658..3650d8b 100644
--- a/include/netlink/cli/route.h
+++ b/include/netlink/cli/route.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli//route.h CLI Route Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,6 +8,10 @@
#include <netlink/route/route.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct rtnl_route *nl_cli_route_alloc(void);
extern struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *, int);
@@ -31,4 +29,8 @@
extern void nl_cli_route_parse_type(struct rtnl_route *, char *);
extern void nl_cli_route_parse_iif(struct rtnl_route *, char *, struct nl_cache *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/rule.h b/include/netlink/cli/rule.h
index 61cd63e..82bf067 100644
--- a/include/netlink/cli/rule.h
+++ b/include/netlink/cli/rule.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/rule.h CLI Routing Rule Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,8 +8,16 @@
#include <netlink/route/rule.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct rtnl_rule *nl_cli_rule_alloc(void);
extern struct nl_cache *nl_cli_rule_alloc_cache(struct nl_sock *);
extern void nl_cli_rule_parse_family(struct rtnl_rule *, char *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/tc.h b/include/netlink/cli/tc.h
index 77042c7..7d4ed7a 100644
--- a/include/netlink/cli/tc.h
+++ b/include/netlink/cli/tc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/cli/tc.h CLI Traffic Control Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,6 +8,10 @@
#include <netlink/route/tc.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct rtnl_tc_ops;
extern void nl_cli_tc_parse_dev(struct rtnl_tc *, struct nl_cache *, char *);
@@ -38,4 +36,8 @@
extern void nl_cli_tc_register(struct nl_cli_tc_module *);
extern void nl_cli_tc_unregister(struct nl_cli_tc_module *);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/netlink/cli/utils.h b/include/netlink/cli/utils.h
index 7d69543..7047d2e 100644
--- a/include/netlink/cli/utils.h
+++ b/include/netlink/cli/utils.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/utils.h Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/data.h b/include/netlink/data.h
index 45010fe..c9c76a1 100644
--- a/include/netlink/data.h
+++ b/include/netlink/data.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/data.h Abstract Data
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/errno.h b/include/netlink/errno.h
index 35710cf..6a5b4de 100644
--- a/include/netlink/errno.h
+++ b/include/netlink/errno.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/errno.h Error Numbers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/fib_lookup/lookup.h b/include/netlink/fib_lookup/lookup.h
index b3c7b5f..81fa435 100644
--- a/include/netlink/fib_lookup/lookup.h
+++ b/include/netlink/fib_lookup/lookup.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/fib_lookup/fib_lookup.h FIB Lookup
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/fib_lookup/request.h b/include/netlink/fib_lookup/request.h
index 60e8820..ed7cdd8 100644
--- a/include/netlink/fib_lookup/request.h
+++ b/include/netlink/fib_lookup/request.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/fib_lookup/request.h FIB Lookup Request
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/genl/ctrl.h b/include/netlink/genl/ctrl.h
index 017b8fd..92d60b3 100644
--- a/include/netlink/genl/ctrl.h
+++ b/include/netlink/genl/ctrl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/genl/ctrl.h Generic Netlink Controller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/genl/family.h b/include/netlink/genl/family.h
index 5432b59..2e9f9fd 100644
--- a/include/netlink/genl/family.h
+++ b/include/netlink/genl/family.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/genl/family.h Generic Netlink Family
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/genl/genl.h b/include/netlink/genl/genl.h
index c4ac137..f1e3a65 100644
--- a/include/netlink/genl/genl.h
+++ b/include/netlink/genl/genl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/genl/genl.h Generic Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/genl/mngt.h b/include/netlink/genl/mngt.h
index 8a51ccd..af9edb3 100644
--- a/include/netlink/genl/mngt.h
+++ b/include/netlink/genl/mngt.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/genl/mngt.h Generic Netlink Management
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/handlers.h b/include/netlink/handlers.h
index 4fac148..2043844 100644
--- a/include/netlink/handlers.h
+++ b/include/netlink/handlers.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/handlers.c default netlink message handlers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
@@ -39,7 +33,7 @@
* nl_recvmsgs() callback for message processing customization
* @ingroup cb
* @arg msg netlink message being processed
- * @arg arg argument passwd on through caller
+ * @arg arg argument passed on through caller
*/
typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg);
@@ -60,7 +54,7 @@
* @ingroup cb
*/
enum nl_cb_action {
- /** Proceed with wathever would come next */
+ /** Proceed with whatever would come next */
NL_OK,
/** Skip this message */
NL_SKIP,
@@ -99,7 +93,7 @@
NL_CB_OVERRUN,
/** Message wants to be skipped */
NL_CB_SKIPPED,
- /** Message is an acknowledge */
+ /** Message is an acknowledgement */
NL_CB_ACK,
/** Called for every message received */
NL_CB_MSG_IN,
diff --git a/include/netlink/hashtable.h b/include/netlink/hashtable.h
index 3b40d86..32578dc 100644
--- a/include/netlink/hashtable.h
+++ b/include/netlink/hashtable.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/hashtable.h Netlink hashtable Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Cumulus Networks, Inc
*/
diff --git a/include/netlink/idiag/idiagnl.h b/include/netlink/idiag/idiagnl.h
index b69cbf1..7385d5f 100644
--- a/include/netlink/idiag/idiagnl.h
+++ b/include/netlink/idiag/idiagnl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/idiag/idiagnl.h Inetdiag Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/include/netlink/idiag/meminfo.h b/include/netlink/idiag/meminfo.h
index 1922395..8a27647 100644
--- a/include/netlink/idiag/meminfo.h
+++ b/include/netlink/idiag/meminfo.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/idiag/meminfo.h Inetdiag Netlink Memory Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/include/netlink/idiag/msg.h b/include/netlink/idiag/msg.h
index 01e30db..f2a79ce 100644
--- a/include/netlink/idiag/msg.h
+++ b/include/netlink/idiag/msg.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/idiag/msg.h Inetdiag Netlink Message
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/include/netlink/idiag/req.h b/include/netlink/idiag/req.h
index b63a4ce..fb75b96 100644
--- a/include/netlink/idiag/req.h
+++ b/include/netlink/idiag/req.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/idiag/req.h Inetdiag Netlink Request
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/include/netlink/idiag/vegasinfo.h b/include/netlink/idiag/vegasinfo.h
index 792b5c1..890c175 100644
--- a/include/netlink/idiag/vegasinfo.h
+++ b/include/netlink/idiag/vegasinfo.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/idiag/vegasinfo.h Inetdiag Netlink TCP Vegas Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/include/netlink/list.h b/include/netlink/list.h
index 2f20634..7ab1438 100644
--- a/include/netlink/list.h
+++ b/include/netlink/list.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/list.h Netlink List Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/msg.h b/include/netlink/msg.h
index 51d9aeb..84aaa60 100644
--- a/include/netlink/msg.h
+++ b/include/netlink/msg.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/msg.c Netlink Messages Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/netfilter/ct.h b/include/netlink/netfilter/ct.h
index ef5d035..ddf1373 100644
--- a/include/netlink/netfilter/ct.h
+++ b/include/netlink/netfilter/ct.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/ct.h Conntrack
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -18,6 +12,7 @@
#include <netlink/addr.h>
#include <netlink/cache.h>
#include <netlink/msg.h>
+#include <netlink/attr.h>
#ifdef __cplusplus
extern "C" {
@@ -37,6 +32,7 @@
extern int nfnlmsg_ct_group(struct nlmsghdr *);
extern int nfnlmsg_ct_parse(struct nlmsghdr *, struct nfnl_ct **);
+extern int nfnlmsg_ct_parse_nested(struct nlattr *, struct nfnl_ct **);
extern void nfnl_ct_get(struct nfnl_ct *);
extern void nfnl_ct_put(struct nfnl_ct *);
diff --git a/include/netlink/netfilter/exp.h b/include/netlink/netfilter/exp.h
index 736af24..bd80514 100644
--- a/include/netlink/netfilter/exp.h
+++ b/include/netlink/netfilter/exp.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/exp.h Conntrack Expectation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/include/netlink/netfilter/log.h b/include/netlink/netfilter/log.h
index e48eddf..a8ca81d 100644
--- a/include/netlink/netfilter/log.h
+++ b/include/netlink/netfilter/log.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/log.h Netfilter Log
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -36,6 +30,7 @@
enum nfnl_log_flags {
NFNL_LOG_FLAG_SEQ = 0x1,
NFNL_LOG_FLAG_SEQ_GLOBAL = 0x2,
+ NFNL_LOG_FLAG_CONNTRACK = 0x4,
};
/* General */
diff --git a/include/netlink/netfilter/log_msg.h b/include/netlink/netfilter/log_msg.h
index 63b0f64..b3672da 100644
--- a/include/netlink/netfilter/log_msg.h
+++ b/include/netlink/netfilter/log_msg.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/log_msg.h Netfilter Log Message
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -23,6 +17,7 @@
struct nlmsghdr;
struct nfnl_log_msg;
+struct nfnl_ct;
extern struct nl_object_ops log_msg_obj_ops;
@@ -90,6 +85,36 @@
extern int nfnl_log_msg_test_seq_global(const struct nfnl_log_msg *);
extern uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *);
+extern void nfnl_log_msg_set_hwtype(struct nfnl_log_msg *, uint16_t);
+extern int nfnl_log_msg_test_hwtype(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_hwtype(const struct nfnl_log_msg *);
+
+extern void nfnl_log_msg_set_hwlen(struct nfnl_log_msg *, uint16_t);
+extern int nfnl_log_msg_test_hwlen(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_hwlen(const struct nfnl_log_msg *);
+
+extern int nfnl_log_msg_set_hwheader(struct nfnl_log_msg *, void *, int);
+extern int nfnl_log_msg_test_hwheader(const struct nfnl_log_msg *);
+extern const void * nfnl_log_msg_get_hwheader(const struct nfnl_log_msg *, int *);
+
+extern void nfnl_log_msg_set_vlan_proto(struct nfnl_log_msg *, uint16_t);
+extern int nfnl_log_msg_test_vlan_proto(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_vlan_proto(const struct nfnl_log_msg *);
+extern void nfnl_log_msg_set_vlan_tag(struct nfnl_log_msg *, uint16_t);
+extern int nfnl_log_msg_test_vlan_tag(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_vlan_tag(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_vlan_id(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_vlan_cfi(const struct nfnl_log_msg *);
+extern uint16_t nfnl_log_msg_get_vlan_prio(const struct nfnl_log_msg *);
+
+extern void nfnl_log_msg_set_ct_info(struct nfnl_log_msg *, uint32_t);
+extern int nfnl_log_msg_test_ct_info(const struct nfnl_log_msg *);
+extern uint32_t nfnl_log_msg_get_ct_info(const struct nfnl_log_msg *);
+
+extern void nfnl_log_msg_set_ct(struct nfnl_log_msg *, struct nfnl_ct *);
+extern int nfnl_log_msg_test_ct(const struct nfnl_log_msg *);
+extern struct nfnl_ct * nfnl_log_msg_get_ct(const struct nfnl_log_msg *);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/netfilter/netfilter.h b/include/netlink/netfilter/netfilter.h
index dd3589c..f365a21 100644
--- a/include/netlink/netfilter/netfilter.h
+++ b/include/netlink/netfilter/netfilter.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/netfilter.h Netfilter generic functions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/include/netlink/netfilter/nfnl.h b/include/netlink/netfilter/nfnl.h
index 8da4ba1..6e349ad 100644
--- a/include/netlink/netfilter/nfnl.h
+++ b/include/netlink/netfilter/nfnl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/nfnl/nfnl.h Netfilter Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/include/netlink/netfilter/queue.h b/include/netlink/netfilter/queue.h
index 224d469..f393f4e 100644
--- a/include/netlink/netfilter/queue.h
+++ b/include/netlink/netfilter/queue.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/queue.h Netfilter Queue
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/include/netlink/netfilter/queue_msg.h b/include/netlink/netfilter/queue_msg.h
index 86f4b86..dc333e0 100644
--- a/include/netlink/netfilter/queue_msg.h
+++ b/include/netlink/netfilter/queue_msg.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netfilter/queue_msg.h Netfilter Queue Messages
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/include/netlink/netlink-compat.h b/include/netlink/netlink-compat.h
index 2839ed0..ed71ed4 100644
--- a/include/netlink/netlink-compat.h
+++ b/include/netlink/netlink-compat.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netlink-compat.h Netlink Compatability
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/netlink.h b/include/netlink/netlink.h
index 41d48c6..c5ec350 100644
--- a/include/netlink/netlink.h
+++ b/include/netlink/netlink.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/netlink.h Netlink Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/object-api.h b/include/netlink/object-api.h
index 75f29cb..d08bafa 100644
--- a/include/netlink/object-api.h
+++ b/include/netlink/object-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/object-api.h Object API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/object.h b/include/netlink/object.h
index b0c32c9..7448df6 100644
--- a/include/netlink/object.h
+++ b/include/netlink/object.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/object.c Generic Cacheable Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/act/gact.h b/include/netlink/route/act/gact.h
index 9538711..b3a57f7 100644
--- a/include/netlink/route/act/gact.h
+++ b/include/netlink/route/act/gact.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/act/gact.h gact action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Sushma Sitaram <sushma.sitaram@intel.com>
*/
diff --git a/include/netlink/route/act/mirred.h b/include/netlink/route/act/mirred.h
index d65ed37..14fe988 100644
--- a/include/netlink/route/act/mirred.h
+++ b/include/netlink/route/act/mirred.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/mirred.h mirred action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/act/nat.h b/include/netlink/route/act/nat.h
new file mode 100644
index 0000000..41295ce
--- /dev/null
+++ b/include/netlink/route/act/nat.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2016 Magnus Öberg <magnus.oberg@westermo.se>
+ */
+
+#ifndef NETLINK_NAT_H_
+#define NETLINK_NAT_H_
+
+#include <netlink/netlink.h>
+#include <netlink/cache.h>
+#include <netlink/route/action.h>
+#include <linux/tc_act/tc_nat.h>
+
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int rtnl_nat_set_old_addr(struct rtnl_act *act, in_addr_t addr);
+extern int rtnl_nat_get_old_addr(struct rtnl_act *act, in_addr_t *addr);
+extern int rtnl_nat_set_new_addr(struct rtnl_act *act, in_addr_t addr);
+extern int rtnl_nat_get_new_addr(struct rtnl_act *act, in_addr_t *addr);
+extern int rtnl_nat_set_mask(struct rtnl_act *act, in_addr_t bitmask);
+extern int rtnl_nat_get_mask(struct rtnl_act *act, in_addr_t *bitmask);
+extern int rtnl_nat_set_flags(struct rtnl_act *act, uint32_t flags);
+extern int rtnl_nat_get_flags(struct rtnl_act *act, uint32_t *flags);
+extern int rtnl_nat_set_action(struct rtnl_act *act, int action);
+extern int rtnl_nat_get_action(struct rtnl_act *act, int *action);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETLINK_NAT_H */
diff --git a/include/netlink/route/act/skbedit.h b/include/netlink/route/act/skbedit.h
index 69829e8..3e662ad 100644
--- a/include/netlink/route/act/skbedit.h
+++ b/include/netlink/route/act/skbedit.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/act/skbedit.h skbedit action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/act/vlan.h b/include/netlink/route/act/vlan.h
index 3dcce7c..f5001ba 100644
--- a/include/netlink/route/act/vlan.h
+++ b/include/netlink/route/act/vlan.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/act/vlan.h vlan action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
*/
diff --git a/include/netlink/route/action.h b/include/netlink/route/action.h
index 7d4c185..fed491f 100644
--- a/include/netlink/route/action.h
+++ b/include/netlink/route/action.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/action.h Actions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/addr.h b/include/netlink/route/addr.h
index 56c12e7..240ae48 100644
--- a/include/netlink/route/addr.h
+++ b/include/netlink/route/addr.h
@@ -1,14 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/addr.c rtnetlink addr layer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
- * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
- * Mediatrix Telecom, inc. <ericb@mediatrix.com>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>
+ * Copyright (c) 2003-2006 Mediatrix Telecom, inc. <ericb@mediatrix.com>
*/
#ifndef NETADDR_ADDR_H_
diff --git a/include/netlink/route/class.h b/include/netlink/route/class.h
index 3833339..91252f1 100644
--- a/include/netlink/route/class.h
+++ b/include/netlink/route/class.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/class.h Traffic Classes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/classifier.h b/include/netlink/route/classifier.h
index 18832ad..d92652b 100644
--- a/include/netlink/route/classifier.h
+++ b/include/netlink/route/classifier.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/classifier.h Classifiers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -26,6 +20,10 @@
extern int rtnl_cls_alloc_cache(struct nl_sock *, int, uint32_t,
struct nl_cache **);
+extern struct rtnl_cls *rtnl_cls_find_by_handle(struct nl_cache *cache, int ifindex,
+ uint32_t parent, uint32_t handle);
+extern struct rtnl_cls *rtnl_cls_find_by_prio(struct nl_cache *cache, int ifindex,
+ uint32_t parent, uint16_t prio);
extern void rtnl_cls_cache_set_tc_params(struct nl_cache *, int, uint32_t);
diff --git a/include/netlink/route/cls/basic.h b/include/netlink/route/cls/basic.h
index 51232ae..98bbe67 100644
--- a/include/netlink/route/cls/basic.h
+++ b/include/netlink/route/cls/basic.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/basic.h Basic Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/cgroup.h b/include/netlink/route/cls/cgroup.h
index 9cd4845..8452f6c 100644
--- a/include/netlink/route/cls/cgroup.h
+++ b/include/netlink/route/cls/cgroup.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/cgroup.h Control Groups Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2009-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/ematch.h b/include/netlink/route/cls/ematch.h
index f4dac1d..4362423 100644
--- a/include/netlink/route/cls/ematch.h
+++ b/include/netlink/route/cls/ematch.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/ematch.h Extended Matches
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/ematch/cmp.h b/include/netlink/route/cls/ematch/cmp.h
index 7afb792..8aacb51 100644
--- a/include/netlink/route/cls/ematch/cmp.h
+++ b/include/netlink/route/cls/ematch/cmp.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/ematch/cmp.h Simple Comparison
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/ematch/meta.h b/include/netlink/route/cls/ematch/meta.h
index 2fe5899..b197246 100644
--- a/include/netlink/route/cls/ematch/meta.h
+++ b/include/netlink/route/cls/ematch/meta.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/ematch/meta.h Metadata Match
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/ematch/nbyte.h b/include/netlink/route/cls/ematch/nbyte.h
index 014c719..6bcf7f2 100644
--- a/include/netlink/route/cls/ematch/nbyte.h
+++ b/include/netlink/route/cls/ematch/nbyte.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/ematch/nbyte.h N-Byte Comparison
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/ematch/text.h b/include/netlink/route/cls/ematch/text.h
index e599abf..1493b09 100644
--- a/include/netlink/route/cls/ematch/text.h
+++ b/include/netlink/route/cls/ematch/text.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/ematch/text.h Text Search
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/flower.h b/include/netlink/route/cls/flower.h
new file mode 100644
index 0000000..1a772a8
--- /dev/null
+++ b/include/netlink/route/cls/flower.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
+ */
+
+#ifndef NETLINK_FLOWER_H_
+#define NETLINK_FLOWER_H_
+
+#include <netlink/netlink.h>
+#include <netlink/cache.h>
+#include <netlink/route/classifier.h>
+#include <netlink/route/action.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int rtnl_flower_set_proto(struct rtnl_cls *cls, uint16_t);
+extern int rtnl_flower_get_proto(struct rtnl_cls *cls, uint16_t *);
+
+extern int rtnl_flower_set_vlan_id(struct rtnl_cls *, uint16_t);
+extern int rtnl_flower_get_vlan_id(struct rtnl_cls *, uint16_t *);
+
+extern int rtnl_flower_set_vlan_prio(struct rtnl_cls *, uint8_t);
+extern int rtnl_flower_get_vlan_prio(struct rtnl_cls *, uint8_t *);
+
+extern int rtnl_flower_set_vlan_ethtype(struct rtnl_cls *, uint16_t);
+
+extern int rtnl_flower_set_dst_mac(struct rtnl_cls *, unsigned char *,
+ unsigned char *);
+extern int rtnl_flower_get_dst_mac(struct rtnl_cls *, unsigned char *,
+ unsigned char *);
+
+extern int rtnl_flower_set_src_mac(struct rtnl_cls *, unsigned char *,
+ unsigned char *);
+extern int rtnl_flower_get_src_mac(struct rtnl_cls *, unsigned char *,
+ unsigned char *);
+
+extern int rtnl_flower_set_ip_dscp(struct rtnl_cls *, uint8_t, uint8_t);
+extern int rtnl_flower_get_ip_dscp(struct rtnl_cls *, uint8_t *, uint8_t *);
+
+extern int rtnl_flower_set_ipv4_src(struct rtnl_cls *, in_addr_t, in_addr_t);
+extern int rtnl_flower_get_ipv4_src(struct rtnl_cls *, in_addr_t *,
+ in_addr_t *);
+extern int rtnl_flower_set_ipv4_dst(struct rtnl_cls *, in_addr_t, in_addr_t);
+extern int rtnl_flower_get_ipv4_dst(struct rtnl_cls *, in_addr_t *,
+ in_addr_t *);
+
+extern int rtnl_flower_set_flags(struct rtnl_cls *, int);
+
+extern int rtnl_flower_append_action(struct rtnl_cls *, struct rtnl_act *);
+extern int rtnl_flower_del_action(struct rtnl_cls *, struct rtnl_act *);
+extern struct rtnl_act* rtnl_flower_get_action(struct rtnl_cls *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netlink/route/cls/fw.h b/include/netlink/route/cls/fw.h
index 2e1bade..57d7c3f 100644
--- a/include/netlink/route/cls/fw.h
+++ b/include/netlink/route/cls/fw.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/fw.h fw classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2006 Siemens AG Oesterreich
diff --git a/include/netlink/route/cls/matchall.h b/include/netlink/route/cls/matchall.h
index 1955694..bfe1e7c 100644
--- a/include/netlink/route/cls/matchall.h
+++ b/include/netlink/route/cls/matchall.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/matchall.h matchall classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2017 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
*/
diff --git a/include/netlink/route/cls/police.h b/include/netlink/route/cls/police.h
index cd1efb0..9c18b87 100644
--- a/include/netlink/route/cls/police.h
+++ b/include/netlink/route/cls/police.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/police.h Policer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/cls/u32.h b/include/netlink/route/cls/u32.h
index 2443f51..b8f0223 100644
--- a/include/netlink/route/cls/u32.h
+++ b/include/netlink/route/cls/u32.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/cls/u32.h u32 classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index 8fd0994..add464b 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link.h Links (Interfaces)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -35,70 +29,71 @@
* @ingroup link
*/
typedef enum {
- RTNL_LINK_RX_PACKETS, /*!< Packets received */
- RTNL_LINK_TX_PACKETS, /*!< Packets sent */
- RTNL_LINK_RX_BYTES, /*!< Bytes received */
- RTNL_LINK_TX_BYTES, /*!< Bytes sent */
- RTNL_LINK_RX_ERRORS, /*!< Receive errors */
- RTNL_LINK_TX_ERRORS, /*!< Send errors */
- RTNL_LINK_RX_DROPPED, /*!< Received packets dropped */
- RTNL_LINK_TX_DROPPED, /*!< Packets dropped during transmit */
- RTNL_LINK_RX_COMPRESSED, /*!< Compressed packets received */
- RTNL_LINK_TX_COMPRESSED, /*!< Compressed packets sent */
- RTNL_LINK_RX_FIFO_ERR, /*!< Receive FIFO errors */
- RTNL_LINK_TX_FIFO_ERR, /*!< Send FIFO errors */
- RTNL_LINK_RX_LEN_ERR, /*!< Length errors */
- RTNL_LINK_RX_OVER_ERR, /*!< Over errors */
- RTNL_LINK_RX_CRC_ERR, /*!< CRC errors */
- RTNL_LINK_RX_FRAME_ERR, /*!< Frame errors */
- RTNL_LINK_RX_MISSED_ERR, /*!< Missed errors */
- RTNL_LINK_TX_ABORT_ERR, /*!< Aborted errors */
- RTNL_LINK_TX_CARRIER_ERR, /*!< Carrier errors */
- RTNL_LINK_TX_HBEAT_ERR, /*!< Heartbeat errors */
- RTNL_LINK_TX_WIN_ERR, /*!< Window errors */
- RTNL_LINK_COLLISIONS, /*!< Send collisions */
- RTNL_LINK_MULTICAST, /*!< Multicast */
- RTNL_LINK_IP6_INPKTS, /*!< IPv6 SNMP InReceives */
- RTNL_LINK_IP6_INHDRERRORS, /*!< IPv6 SNMP InHdrErrors */
- RTNL_LINK_IP6_INTOOBIGERRORS, /*!< IPv6 SNMP InTooBigErrors */
- RTNL_LINK_IP6_INNOROUTES, /*!< IPv6 SNMP InNoRoutes */
- RTNL_LINK_IP6_INADDRERRORS, /*!< IPv6 SNMP InAddrErrors */
- RTNL_LINK_IP6_INUNKNOWNPROTOS, /*!< IPv6 SNMP InUnknownProtos */
- RTNL_LINK_IP6_INTRUNCATEDPKTS, /*!< IPv6 SNMP InTruncatedPkts */
- RTNL_LINK_IP6_INDISCARDS, /*!< IPv6 SNMP InDiscards */
- RTNL_LINK_IP6_INDELIVERS, /*!< IPv6 SNMP InDelivers */
- RTNL_LINK_IP6_OUTFORWDATAGRAMS, /*!< IPv6 SNMP OutForwDatagrams */
- RTNL_LINK_IP6_OUTPKTS, /*!< IPv6 SNMP OutRequests */
- RTNL_LINK_IP6_OUTDISCARDS, /*!< IPv6 SNMP OutDiscards */
- RTNL_LINK_IP6_OUTNOROUTES, /*!< IPv6 SNMP OutNoRoutes */
- RTNL_LINK_IP6_REASMTIMEOUT, /*!< IPv6 SNMP ReasmTimeout */
- RTNL_LINK_IP6_REASMREQDS, /*!< IPv6 SNMP ReasmReqds */
- RTNL_LINK_IP6_REASMOKS, /*!< IPv6 SNMP ReasmOKs */
- RTNL_LINK_IP6_REASMFAILS, /*!< IPv6 SNMP ReasmFails */
- RTNL_LINK_IP6_FRAGOKS, /*!< IPv6 SNMP FragOKs */
- RTNL_LINK_IP6_FRAGFAILS, /*!< IPv6 SNMP FragFails */
- RTNL_LINK_IP6_FRAGCREATES, /*!< IPv6 SNMP FragCreates */
- RTNL_LINK_IP6_INMCASTPKTS, /*!< IPv6 SNMP InMcastPkts */
- RTNL_LINK_IP6_OUTMCASTPKTS, /*!< IPv6 SNMP OutMcastPkts */
- RTNL_LINK_IP6_INBCASTPKTS, /*!< IPv6 SNMP InBcastPkts */
- RTNL_LINK_IP6_OUTBCASTPKTS, /*!< IPv6 SNMP OutBcastPkts */
- RTNL_LINK_IP6_INOCTETS, /*!< IPv6 SNMP InOctets */
- RTNL_LINK_IP6_OUTOCTETS, /*!< IPv6 SNMP OutOctets */
- RTNL_LINK_IP6_INMCASTOCTETS, /*!< IPv6 SNMP InMcastOctets */
- RTNL_LINK_IP6_OUTMCASTOCTETS, /*!< IPv6 SNMP OutMcastOctets */
- RTNL_LINK_IP6_INBCASTOCTETS, /*!< IPv6 SNMP InBcastOctets */
- RTNL_LINK_IP6_OUTBCASTOCTETS, /*!< IPv6 SNMP OutBcastOctets */
- RTNL_LINK_ICMP6_INMSGS, /*!< ICMPv6 SNMP InMsgs */
- RTNL_LINK_ICMP6_INERRORS, /*!< ICMPv6 SNMP InErrors */
- RTNL_LINK_ICMP6_OUTMSGS, /*!< ICMPv6 SNMP OutMsgs */
- RTNL_LINK_ICMP6_OUTERRORS, /*!< ICMPv6 SNMP OutErrors */
- RTNL_LINK_ICMP6_CSUMERRORS, /*!< ICMPv6 SNMP InCsumErrors */
- RTNL_LINK_IP6_CSUMERRORS, /*!< IPv6 SNMP InCsumErrors */
- RTNL_LINK_IP6_NOECTPKTS, /*!< IPv6 SNMP InNoECTPkts */
- RTNL_LINK_IP6_ECT1PKTS, /*!< IPv6 SNMP InECT1Pkts */
- RTNL_LINK_IP6_ECT0PKTS, /*!< IPv6 SNMP InECT0Pkts */
- RTNL_LINK_IP6_CEPKTS, /*!< IPv6 SNMP InCEPkts */
- RTNL_LINK_RX_NOHANDLER, /*!< Received packets dropped on inactive device */
+ RTNL_LINK_RX_PACKETS, /*!< Packets received */
+ RTNL_LINK_TX_PACKETS, /*!< Packets sent */
+ RTNL_LINK_RX_BYTES, /*!< Bytes received */
+ RTNL_LINK_TX_BYTES, /*!< Bytes sent */
+ RTNL_LINK_RX_ERRORS, /*!< Receive errors */
+ RTNL_LINK_TX_ERRORS, /*!< Send errors */
+ RTNL_LINK_RX_DROPPED, /*!< Received packets dropped */
+ RTNL_LINK_TX_DROPPED, /*!< Packets dropped during transmit */
+ RTNL_LINK_RX_COMPRESSED, /*!< Compressed packets received */
+ RTNL_LINK_TX_COMPRESSED, /*!< Compressed packets sent */
+ RTNL_LINK_RX_FIFO_ERR, /*!< Receive FIFO errors */
+ RTNL_LINK_TX_FIFO_ERR, /*!< Send FIFO errors */
+ RTNL_LINK_RX_LEN_ERR, /*!< Length errors */
+ RTNL_LINK_RX_OVER_ERR, /*!< Over errors */
+ RTNL_LINK_RX_CRC_ERR, /*!< CRC errors */
+ RTNL_LINK_RX_FRAME_ERR, /*!< Frame errors */
+ RTNL_LINK_RX_MISSED_ERR, /*!< Missed errors */
+ RTNL_LINK_TX_ABORT_ERR, /*!< Aborted errors */
+ RTNL_LINK_TX_CARRIER_ERR, /*!< Carrier errors */
+ RTNL_LINK_TX_HBEAT_ERR, /*!< Heartbeat errors */
+ RTNL_LINK_TX_WIN_ERR, /*!< Window errors */
+ RTNL_LINK_COLLISIONS, /*!< Send collisions */
+ RTNL_LINK_MULTICAST, /*!< Multicast */
+ RTNL_LINK_IP6_INPKTS, /*!< IPv6 SNMP InReceives */
+ RTNL_LINK_IP6_INHDRERRORS, /*!< IPv6 SNMP InHdrErrors */
+ RTNL_LINK_IP6_INTOOBIGERRORS, /*!< IPv6 SNMP InTooBigErrors */
+ RTNL_LINK_IP6_INNOROUTES, /*!< IPv6 SNMP InNoRoutes */
+ RTNL_LINK_IP6_INADDRERRORS, /*!< IPv6 SNMP InAddrErrors */
+ RTNL_LINK_IP6_INUNKNOWNPROTOS, /*!< IPv6 SNMP InUnknownProtos */
+ RTNL_LINK_IP6_INTRUNCATEDPKTS, /*!< IPv6 SNMP InTruncatedPkts */
+ RTNL_LINK_IP6_INDISCARDS, /*!< IPv6 SNMP InDiscards */
+ RTNL_LINK_IP6_INDELIVERS, /*!< IPv6 SNMP InDelivers */
+ RTNL_LINK_IP6_OUTFORWDATAGRAMS, /*!< IPv6 SNMP OutForwDatagrams */
+ RTNL_LINK_IP6_OUTPKTS, /*!< IPv6 SNMP OutRequests */
+ RTNL_LINK_IP6_OUTDISCARDS, /*!< IPv6 SNMP OutDiscards */
+ RTNL_LINK_IP6_OUTNOROUTES, /*!< IPv6 SNMP OutNoRoutes */
+ RTNL_LINK_IP6_REASMTIMEOUT, /*!< IPv6 SNMP ReasmTimeout */
+ RTNL_LINK_IP6_REASMREQDS, /*!< IPv6 SNMP ReasmReqds */
+ RTNL_LINK_IP6_REASMOKS, /*!< IPv6 SNMP ReasmOKs */
+ RTNL_LINK_IP6_REASMFAILS, /*!< IPv6 SNMP ReasmFails */
+ RTNL_LINK_IP6_FRAGOKS, /*!< IPv6 SNMP FragOKs */
+ RTNL_LINK_IP6_FRAGFAILS, /*!< IPv6 SNMP FragFails */
+ RTNL_LINK_IP6_FRAGCREATES, /*!< IPv6 SNMP FragCreates */
+ RTNL_LINK_IP6_INMCASTPKTS, /*!< IPv6 SNMP InMcastPkts */
+ RTNL_LINK_IP6_OUTMCASTPKTS, /*!< IPv6 SNMP OutMcastPkts */
+ RTNL_LINK_IP6_INBCASTPKTS, /*!< IPv6 SNMP InBcastPkts */
+ RTNL_LINK_IP6_OUTBCASTPKTS, /*!< IPv6 SNMP OutBcastPkts */
+ RTNL_LINK_IP6_INOCTETS, /*!< IPv6 SNMP InOctets */
+ RTNL_LINK_IP6_OUTOCTETS, /*!< IPv6 SNMP OutOctets */
+ RTNL_LINK_IP6_INMCASTOCTETS, /*!< IPv6 SNMP InMcastOctets */
+ RTNL_LINK_IP6_OUTMCASTOCTETS, /*!< IPv6 SNMP OutMcastOctets */
+ RTNL_LINK_IP6_INBCASTOCTETS, /*!< IPv6 SNMP InBcastOctets */
+ RTNL_LINK_IP6_OUTBCASTOCTETS, /*!< IPv6 SNMP OutBcastOctets */
+ RTNL_LINK_ICMP6_INMSGS, /*!< ICMPv6 SNMP InMsgs */
+ RTNL_LINK_ICMP6_INERRORS, /*!< ICMPv6 SNMP InErrors */
+ RTNL_LINK_ICMP6_OUTMSGS, /*!< ICMPv6 SNMP OutMsgs */
+ RTNL_LINK_ICMP6_OUTERRORS, /*!< ICMPv6 SNMP OutErrors */
+ RTNL_LINK_ICMP6_CSUMERRORS, /*!< ICMPv6 SNMP InCsumErrors */
+ RTNL_LINK_IP6_CSUMERRORS, /*!< IPv6 SNMP InCsumErrors */
+ RTNL_LINK_IP6_NOECTPKTS, /*!< IPv6 SNMP InNoECTPkts */
+ RTNL_LINK_IP6_ECT1PKTS, /*!< IPv6 SNMP InECT1Pkts */
+ RTNL_LINK_IP6_ECT0PKTS, /*!< IPv6 SNMP InECT0Pkts */
+ RTNL_LINK_IP6_CEPKTS, /*!< IPv6 SNMP InCEPkts */
+ RTNL_LINK_RX_NOHANDLER, /*!< Received packets dropped on inactive device */
+ RTNL_LINK_REASM_OVERLAPS, /*!< SNMP ReasmOverlaps */
__RTNL_LINK_STATS_MAX,
} rtnl_link_stat_id_t;
@@ -107,156 +102,156 @@
extern struct nla_policy rtln_link_policy[];
extern struct rtnl_link *rtnl_link_alloc(void);
-extern void rtnl_link_put(struct rtnl_link *);
+extern void rtnl_link_put(struct rtnl_link *);
-extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **);
-extern int rtnl_link_alloc_cache_flags(struct nl_sock *, int,
- struct nl_cache **,
- unsigned int flags);
+extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **);
+extern int rtnl_link_alloc_cache_flags(struct nl_sock *, int,
+ struct nl_cache **,
+ unsigned int flags);
extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int);
extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *);
-extern int rtnl_link_build_add_request(struct rtnl_link *, int,
- struct nl_msg **);
-extern int rtnl_link_add(struct nl_sock *, struct rtnl_link *, int);
-extern int rtnl_link_build_change_request(struct rtnl_link *,
- struct rtnl_link *, int,
- struct nl_msg **);
-extern int rtnl_link_change(struct nl_sock *, struct rtnl_link *,
- struct rtnl_link *, int);
+extern int rtnl_link_build_add_request(struct rtnl_link *, int,
+ struct nl_msg **);
+extern int rtnl_link_add(struct nl_sock *, struct rtnl_link *, int);
+extern int rtnl_link_build_change_request(struct rtnl_link *,
+ struct rtnl_link *, int,
+ struct nl_msg **);
+extern int rtnl_link_change(struct nl_sock *, struct rtnl_link *,
+ struct rtnl_link *, int);
-extern int rtnl_link_build_delete_request(const struct rtnl_link *,
- struct nl_msg **);
-extern int rtnl_link_delete(struct nl_sock *, const struct rtnl_link *);
-extern int rtnl_link_build_get_request(int, const char *,
- struct nl_msg **);
-extern int rtnl_link_get_kernel(struct nl_sock *, int, const char *,
- struct rtnl_link **);
+extern int rtnl_link_build_delete_request(const struct rtnl_link *,
+ struct nl_msg **);
+extern int rtnl_link_delete(struct nl_sock *, const struct rtnl_link *);
+extern int rtnl_link_build_get_request(int, const char *,
+ struct nl_msg **);
+extern int rtnl_link_get_kernel(struct nl_sock *, int, const char *,
+ struct rtnl_link **);
/* Name <-> Index Translations */
-extern char * rtnl_link_i2name(struct nl_cache *, int, char *, size_t);
-extern int rtnl_link_name2i(struct nl_cache *, const char *);
+extern char * rtnl_link_i2name(struct nl_cache *, int, char *, size_t);
+extern int rtnl_link_name2i(struct nl_cache *, const char *);
/* Name <-> Statistic Translations */
-extern char * rtnl_link_stat2str(int, char *, size_t);
-extern int rtnl_link_str2stat(const char *);
+extern char * rtnl_link_stat2str(int, char *, size_t);
+extern int rtnl_link_str2stat(const char *);
/* Link Flags Translations */
-extern char * rtnl_link_flags2str(int, char *, size_t);
-extern int rtnl_link_str2flags(const char *);
+extern char * rtnl_link_flags2str(int, char *, size_t);
+extern int rtnl_link_str2flags(const char *);
-extern char * rtnl_link_operstate2str(uint8_t, char *, size_t);
-extern int rtnl_link_str2operstate(const char *);
+extern char * rtnl_link_operstate2str(uint8_t, char *, size_t);
+extern int rtnl_link_str2operstate(const char *);
-extern char * rtnl_link_mode2str(uint8_t, char *, size_t);
-extern int rtnl_link_str2mode(const char *);
+extern char * rtnl_link_mode2str(uint8_t, char *, size_t);
+extern int rtnl_link_str2mode(const char *);
/* Carrier State Translations */
-extern char * rtnl_link_carrier2str(uint8_t, char *, size_t);
-extern int rtnl_link_str2carrier(const char *);
+extern char * rtnl_link_carrier2str(uint8_t, char *, size_t);
+extern int rtnl_link_str2carrier(const char *);
/* Access Functions */
-extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *);
-extern char * rtnl_link_get_qdisc(struct rtnl_link *);
+extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_qdisc(struct rtnl_link *);
-extern void rtnl_link_set_name(struct rtnl_link *, const char *);
-extern char * rtnl_link_get_name(struct rtnl_link *);
+extern void rtnl_link_set_name(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_name(struct rtnl_link *);
-extern void rtnl_link_set_group(struct rtnl_link *, uint32_t);
-extern uint32_t rtnl_link_get_group(struct rtnl_link *);
+extern void rtnl_link_set_group(struct rtnl_link *, uint32_t);
+extern uint32_t rtnl_link_get_group(struct rtnl_link *);
-extern void rtnl_link_set_flags(struct rtnl_link *, unsigned int);
-extern void rtnl_link_unset_flags(struct rtnl_link *, unsigned int);
+extern void rtnl_link_set_flags(struct rtnl_link *, unsigned int);
+extern void rtnl_link_unset_flags(struct rtnl_link *, unsigned int);
extern unsigned int rtnl_link_get_flags(struct rtnl_link *);
-extern void rtnl_link_set_mtu(struct rtnl_link *, unsigned int);
+extern void rtnl_link_set_mtu(struct rtnl_link *, unsigned int);
extern unsigned int rtnl_link_get_mtu(struct rtnl_link *);
-extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int);
+extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int);
extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *);
-extern void rtnl_link_set_ifindex(struct rtnl_link *, int);
-extern int rtnl_link_get_ifindex(struct rtnl_link *);
+extern void rtnl_link_set_ifindex(struct rtnl_link *, int);
+extern int rtnl_link_get_ifindex(struct rtnl_link *);
-extern void rtnl_link_set_family(struct rtnl_link *, int);
-extern int rtnl_link_get_family(struct rtnl_link *);
+extern void rtnl_link_set_family(struct rtnl_link *, int);
+extern int rtnl_link_get_family(struct rtnl_link *);
-extern void rtnl_link_set_arptype(struct rtnl_link *, unsigned int);
+extern void rtnl_link_set_arptype(struct rtnl_link *, unsigned int);
extern unsigned int rtnl_link_get_arptype(struct rtnl_link *);
-extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *);
+extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *);
extern struct nl_addr *rtnl_link_get_addr(struct rtnl_link *);
-extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *);
+extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *);
extern struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *);
-extern void rtnl_link_set_link(struct rtnl_link *, int);
-extern int rtnl_link_get_link(struct rtnl_link *);
+extern void rtnl_link_set_link(struct rtnl_link *, int);
+extern int rtnl_link_get_link(struct rtnl_link *);
-extern void rtnl_link_set_master(struct rtnl_link *, int);
-extern int rtnl_link_get_master(struct rtnl_link *);
+extern void rtnl_link_set_master(struct rtnl_link *, int);
+extern int rtnl_link_get_master(struct rtnl_link *);
-extern void rtnl_link_set_carrier(struct rtnl_link *, uint8_t);
-extern uint8_t rtnl_link_get_carrier(struct rtnl_link *);
+extern void rtnl_link_set_carrier(struct rtnl_link *, uint8_t);
+extern uint8_t rtnl_link_get_carrier(struct rtnl_link *);
-extern int rtnl_link_get_carrier_changes(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_get_carrier_changes(struct rtnl_link *, uint32_t *);
-extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t);
-extern uint8_t rtnl_link_get_operstate(struct rtnl_link *);
+extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t);
+extern uint8_t rtnl_link_get_operstate(struct rtnl_link *);
-extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t);
-extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *);
+extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t);
+extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *);
int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid);
int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid);
-extern const char * rtnl_link_get_ifalias(struct rtnl_link *);
-extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *);
+extern const char * rtnl_link_get_ifalias(struct rtnl_link *);
+extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *);
-extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *);
extern uint64_t rtnl_link_get_stat(struct rtnl_link *, rtnl_link_stat_id_t);
-extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t,
- const uint64_t);
+extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t,
+ const uint64_t);
-extern int rtnl_link_set_type(struct rtnl_link *, const char *);
-extern char * rtnl_link_get_type(struct rtnl_link *);
+extern int rtnl_link_set_type(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_type(struct rtnl_link *);
-extern int rtnl_link_set_slave_type(struct rtnl_link *, const char *);
-extern const char * rtnl_link_get_slave_type(const struct rtnl_link *);
+extern int rtnl_link_set_slave_type(struct rtnl_link *, const char *);
+extern const char * rtnl_link_get_slave_type(const struct rtnl_link *);
-extern void rtnl_link_set_promiscuity(struct rtnl_link *, uint32_t);
-extern uint32_t rtnl_link_get_promiscuity(struct rtnl_link *);
+extern void rtnl_link_set_promiscuity(struct rtnl_link *, uint32_t);
+extern uint32_t rtnl_link_get_promiscuity(struct rtnl_link *);
-extern void rtnl_link_set_num_tx_queues(struct rtnl_link *, uint32_t);
-extern uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *);
+extern void rtnl_link_set_num_tx_queues(struct rtnl_link *, uint32_t);
+extern uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *);
-extern void rtnl_link_set_num_rx_queues(struct rtnl_link *, uint32_t);
-extern uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *);
+extern void rtnl_link_set_num_rx_queues(struct rtnl_link *, uint32_t);
+extern uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *);
-extern int rtnl_link_get_gso_max_segs(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_get_gso_max_segs(struct rtnl_link *, uint32_t *);
-extern int rtnl_link_get_gso_max_size(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_get_gso_max_size(struct rtnl_link *, uint32_t *);
-extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *);
+extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *);
-extern char* rtnl_link_get_phys_port_name(struct rtnl_link *);
+extern char* rtnl_link_get_phys_port_name(struct rtnl_link *);
-extern struct nl_data * rtnl_link_get_phys_switch_id(struct rtnl_link *);
+extern struct nl_data * rtnl_link_get_phys_switch_id(struct rtnl_link *);
-extern void rtnl_link_set_ns_fd(struct rtnl_link *, int);
-extern int rtnl_link_get_ns_fd(struct rtnl_link *);
-extern void rtnl_link_set_ns_pid(struct rtnl_link *, pid_t);
-extern pid_t rtnl_link_get_ns_pid(struct rtnl_link *);
+extern void rtnl_link_set_ns_fd(struct rtnl_link *, int);
+extern int rtnl_link_get_ns_fd(struct rtnl_link *);
+extern void rtnl_link_set_ns_pid(struct rtnl_link *, pid_t);
+extern pid_t rtnl_link_get_ns_pid(struct rtnl_link *);
-extern int rtnl_link_enslave_ifindex(struct nl_sock *, int, int);
-extern int rtnl_link_enslave(struct nl_sock *, struct rtnl_link *,
- struct rtnl_link *);
-extern int rtnl_link_release_ifindex(struct nl_sock *, int);
-extern int rtnl_link_release(struct nl_sock *, struct rtnl_link *);
-extern int rtnl_link_fill_info(struct nl_msg *, struct rtnl_link *);
-extern int rtnl_link_info_parse(struct rtnl_link *, struct nlattr **);
+extern int rtnl_link_enslave_ifindex(struct nl_sock *, int, int);
+extern int rtnl_link_enslave(struct nl_sock *, struct rtnl_link *,
+ struct rtnl_link *);
+extern int rtnl_link_release_ifindex(struct nl_sock *, int);
+extern int rtnl_link_release(struct nl_sock *, struct rtnl_link *);
+extern int rtnl_link_fill_info(struct nl_msg *, struct rtnl_link *);
+extern int rtnl_link_info_parse(struct rtnl_link *, struct nlattr **);
extern int rtnl_link_has_vf_list(struct rtnl_link *);
extern void rtnl_link_set_vf_list(struct rtnl_link *);
@@ -264,9 +259,9 @@
/* deprecated */
-extern int rtnl_link_set_info_type(struct rtnl_link *, const char *) __attribute__((deprecated));
-extern char * rtnl_link_get_info_type(struct rtnl_link *) __attribute__((deprecated));
-extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int) __attribute__((deprecated));
+extern int rtnl_link_set_info_type(struct rtnl_link *, const char *) __attribute__((deprecated));
+extern char * rtnl_link_get_info_type(struct rtnl_link *) __attribute__((deprecated));
+extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int) __attribute__((deprecated));
extern unsigned int rtnl_link_get_weight(struct rtnl_link *) __attribute__((deprecated));
diff --git a/include/netlink/route/link/api.h b/include/netlink/route/link/api.h
index 03b1e5e..abdd8b2 100644
--- a/include/netlink/route/link/api.h
+++ b/include/netlink/route/link/api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/api.h Link Modules API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/bonding.h b/include/netlink/route/link/bonding.h
index 5c34662..09d495e 100644
--- a/include/netlink/route/link/bonding.h
+++ b/include/netlink/route/link/bonding.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/bonding.h Bonding Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/bridge.h b/include/netlink/route/link/bridge.h
index f2e16e3..e606bd4 100644
--- a/include/netlink/route/link/bridge.h
+++ b/include/netlink/route/link/bridge.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/bridge.h Bridge
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/can.h b/include/netlink/route/link/can.h
index 1979a71..7df50e3 100644
--- a/include/netlink/route/link/can.h
+++ b/include/netlink/route/link/can.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/can.h CAN interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Benedikt Spranger <b.spranger@linutronix.de>
*/
@@ -38,11 +32,11 @@
extern int rtnl_link_can_berr(struct rtnl_link *, struct can_berr_counter *);
extern int rtnl_link_can_get_bt_const(struct rtnl_link *,
- struct can_bittiming_const *);
+ struct can_bittiming_const *);
extern int rtnl_link_can_get_bittiming(struct rtnl_link *,
- struct can_bittiming *);
+ struct can_bittiming *);
extern int rtnl_link_can_set_bittiming(struct rtnl_link *,
- struct can_bittiming *);
+ const struct can_bittiming *);
extern int rtnl_link_can_get_bitrate(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_set_bitrate(struct rtnl_link *, uint32_t);
@@ -57,6 +51,15 @@
extern int rtnl_link_can_set_ctrlmode(struct rtnl_link *, uint32_t);
extern int rtnl_link_can_unset_ctrlmode(struct rtnl_link *, uint32_t);
+extern int rtnl_link_can_get_data_bittiming_const(struct rtnl_link *,
+ struct can_bittiming_const *);
+extern int rtnl_link_can_set_data_bittiming_const(struct rtnl_link *,
+ const struct can_bittiming_const *);
+extern int rtnl_link_can_get_data_bittiming(struct rtnl_link *,
+ struct can_bittiming *);
+extern int rtnl_link_can_set_data_bittiming(struct rtnl_link *,
+ const struct can_bittiming *);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/geneve.h b/include/netlink/route/link/geneve.h
index aaba1f9..cf37c4e 100644
--- a/include/netlink/route/link/geneve.h
+++ b/include/netlink/route/link/geneve.h
@@ -1,10 +1,4 @@
-/*
- * netlink/route/link/geneve.h GENEVE interface
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- */
+/* SPDX-License-Identifier: LGPL-2.1-only */
#ifndef NETLINK_LINK_GENEVE_H_
#define NETLINK_LINK_GENEVE_H_
diff --git a/include/netlink/route/link/inet.h b/include/netlink/route/link/inet.h
index 506542f..2e93cc5 100644
--- a/include/netlink/route/link/inet.h
+++ b/include/netlink/route/link/inet.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/inet.h INET Link Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/inet6.h b/include/netlink/route/link/inet6.h
index 666a9b8..cf257ca 100644
--- a/include/netlink/route/link/inet6.h
+++ b/include/netlink/route/link/inet6.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/inet6.h INET6 Link Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Dan Williams <dcbw@redhat.com>
*/
diff --git a/include/netlink/route/link/info-api.h b/include/netlink/route/link/info-api.h
index 1087ad4..11cffcf 100644
--- a/include/netlink/route/link/info-api.h
+++ b/include/netlink/route/link/info-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/info-api.h Link Modules API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/ip6gre.h b/include/netlink/route/link/ip6gre.h
new file mode 100644
index 0000000..2838592
--- /dev/null
+++ b/include/netlink/route/link/ip6gre.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef NETLINK_LINK_IP6GRE_H_
+#define NETLINK_LINK_IP6GRE_H_
+
+#include <netlink/netlink.h>
+#include <netlink/route/link.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern int rtnl_link_is_ip6gre(struct rtnl_link *link);
+
+ extern struct rtnl_link *rtnl_link_ip6gre_alloc(void);
+ extern int rtnl_link_ip6gre_add(struct nl_sock *sk, const char *name);
+
+ extern int rtnl_link_ip6gre_set_link(struct rtnl_link *link, uint32_t index);
+ extern int rtnl_link_ip6gre_get_link(struct rtnl_link *link, uint32_t *index);
+
+ extern int rtnl_link_ip6gre_set_iflags(struct rtnl_link *link, uint16_t iflags);
+ extern int rtnl_link_ip6gre_get_iflags(struct rtnl_link *link, uint16_t *iflags);
+
+ extern int rtnl_link_ip6gre_set_oflags(struct rtnl_link *link, uint16_t oflags);
+ extern int rtnl_link_ip6gre_get_oflags(struct rtnl_link *link, uint16_t *oflags);
+
+ extern int rtnl_link_ip6gre_set_ikey(struct rtnl_link *link, uint32_t ikey);
+ extern int rtnl_link_ip6gre_get_ikey(struct rtnl_link *link, uint32_t *ikey);
+
+ extern int rtnl_link_ip6gre_set_okey(struct rtnl_link *link, uint32_t okey);
+ extern int rtnl_link_ip6gre_get_okey(struct rtnl_link *link, uint32_t *okey);
+
+ extern int rtnl_link_ip6gre_set_local(struct rtnl_link *link, struct in6_addr *local);
+ extern int rtnl_link_ip6gre_get_local(struct rtnl_link *link, struct in6_addr *local);
+
+ extern int rtnl_link_ip6gre_set_remote(struct rtnl_link *link, struct in6_addr *remote);
+ extern int rtnl_link_ip6gre_get_remote(struct rtnl_link *link, struct in6_addr *remote);
+
+ extern int rtnl_link_ip6gre_set_ttl(struct rtnl_link *link, uint8_t ttl);
+ extern int rtnl_link_ip6gre_get_ttl(struct rtnl_link *link, uint8_t *ttl);
+
+ extern int rtnl_link_ip6gre_set_encaplimit(struct rtnl_link *link, uint8_t encaplimit);
+ extern int rtnl_link_ip6gre_get_encaplimit(struct rtnl_link *link, uint8_t *encaplimit);
+
+ extern int rtnl_link_ip6gre_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo);
+ extern int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowinfo);
+
+ extern int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags);
+ extern int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags);
+
+ extern int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netlink/route/link/ip6tnl.h b/include/netlink/route/link/ip6tnl.h
index 87ab164..865d973 100644
--- a/include/netlink/route/link/ip6tnl.h
+++ b/include/netlink/route/link/ip6tnl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ip6tnl.h IP6TNL interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -51,6 +45,9 @@
extern int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto);
extern uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link);
+ extern int rtnl_link_ip6_tnl_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ip6_tnl_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/ip6vti.h b/include/netlink/route/link/ip6vti.h
new file mode 100644
index 0000000..bfe33d3
--- /dev/null
+++ b/include/netlink/route/link/ip6vti.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef NETLINK_LINK_IP6VTI_H_
+#define NETLINK_LINK_IP6VTI_H_
+
+#include <netlink/netlink.h>
+#include <netlink/route/link.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ int rtnl_link_is_ip6vti(struct rtnl_link *link);
+
+ extern struct rtnl_link *rtnl_link_ip6vti_alloc(void);
+ extern int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name);
+
+ extern int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index);
+ extern int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index);
+
+ extern int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey);
+ extern int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey);
+
+ extern int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey);
+ extern int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey);
+
+ extern int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local);
+ extern int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *remote);
+
+ extern int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote);
+ extern int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote);
+
+ extern int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netlink/route/link/ipgre.h b/include/netlink/route/link/ipgre.h
index 4c5f86b..09a4957 100644
--- a/include/netlink/route/link/ipgre.h
+++ b/include/netlink/route/link/ipgre.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ip_gre.h IPGRE interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -57,6 +51,9 @@
extern int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
extern uint8_t rtnl_link_ipgre_get_pmtudisc(struct rtnl_link *link);
+ extern int rtnl_link_ipgre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ipgre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/ipip.h b/include/netlink/route/link/ipip.h
index a7f5158..65d9f18 100644
--- a/include/netlink/route/link/ipip.h
+++ b/include/netlink/route/link/ipip.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ipip.h IPIP interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -41,6 +35,9 @@
extern int rtnl_link_ipip_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
extern uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link);
+ extern int rtnl_link_ipip_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ipip_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/ipvlan.h b/include/netlink/route/link/ipvlan.h
index d13bcbb..09b1d2d 100644
--- a/include/netlink/route/link/ipvlan.h
+++ b/include/netlink/route/link/ipvlan.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ipvlan.h IPVLAN interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cong Wang <cwang@twopensource.com>
*/
diff --git a/include/netlink/route/link/ipvti.h b/include/netlink/route/link/ipvti.h
index c97e57f..8e31dab 100644
--- a/include/netlink/route/link/ipvti.h
+++ b/include/netlink/route/link/ipvti.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ipvti.h IPVTI interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -38,6 +32,9 @@
extern int rtnl_link_ipvti_set_remote(struct rtnl_link *link, uint32_t addr);
extern uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link);
+ extern int rtnl_link_ipvti_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ipvti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/macsec.h b/include/netlink/route/link/macsec.h
index ace4de2..3139b47 100644
--- a/include/netlink/route/link/macsec.h
+++ b/include/netlink/route/link/macsec.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/macsec.h MACsec Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Sabrina Dubroca <sd@queasysnail.net>
*/
@@ -43,6 +37,9 @@
int rtnl_link_macsec_set_encrypt(struct rtnl_link *, uint8_t);
int rtnl_link_macsec_get_encrypt(struct rtnl_link *, uint8_t *);
+int rtnl_link_macsec_set_offload(struct rtnl_link *, uint8_t);
+int rtnl_link_macsec_get_offload(struct rtnl_link *, uint8_t *);
+
int rtnl_link_macsec_set_encoding_sa(struct rtnl_link *, uint8_t);
int rtnl_link_macsec_get_encoding_sa(struct rtnl_link *, uint8_t *);
diff --git a/include/netlink/route/link/macvlan.h b/include/netlink/route/link/macvlan.h
index 15a6cc1..7c133cb 100644
--- a/include/netlink/route/link/macvlan.h
+++ b/include/netlink/route/link/macvlan.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/macvlan.h MACVLAN interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Michael Braun <michael-dev@fami-braun.de>
*/
diff --git a/include/netlink/route/link/macvtap.h b/include/netlink/route/link/macvtap.h
index affcddc..6fff30d 100644
--- a/include/netlink/route/link/macvtap.h
+++ b/include/netlink/route/link/macvtap.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/macvtap.h MACVTAP interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Beniamino Galvani <bgalvani@redhat.com>
*/
diff --git a/include/netlink/route/link/ppp.h b/include/netlink/route/link/ppp.h
index 4ff811d..d65582a 100644
--- a/include/netlink/route/link/ppp.h
+++ b/include/netlink/route/link/ppp.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/ppp.h PPP Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Jonas Johansson <jonasj76@gmail.com>
*/
diff --git a/include/netlink/route/link/sit.h b/include/netlink/route/link/sit.h
index d6f5851..f41e101 100644
--- a/include/netlink/route/link/sit.h
+++ b/include/netlink/route/link/sit.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/sit.h SIT interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -60,6 +54,9 @@
int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefix);
int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefix);
+ extern int rtnl_link_sit_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_sit_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/link/sriov.h b/include/netlink/route/link/sriov.h
index 3f7cacf..36d66bf 100644
--- a/include/netlink/route/link/sriov.h
+++ b/include/netlink/route/link/sriov.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * include/netlink/route/link/sriov.h SRIOV VF Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Intel Corp. All rights reserved.
* Copyright (c) 2016 Jef Oliver <jef.oliver@intel.com>
*/
diff --git a/include/netlink/route/link/team.h b/include/netlink/route/link/team.h
new file mode 100644
index 0000000..a55cdf9
--- /dev/null
+++ b/include/netlink/route/link/team.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2015 Jonas Johansson <jonasj76@gmail.com>
+ */
+
+#ifndef NETLINK_LINK_TEAM_H_
+#define NETLINK_LINK_TEAM_H_
+
+#include <netlink/netlink.h>
+#include <netlink/route/link.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct rtnl_link *rtnl_link_team_alloc(void);
+
+extern int rtnl_link_team_add(struct nl_sock *, const char *,
+ struct rtnl_link *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/netlink/route/link/veth.h b/include/netlink/route/link/veth.h
index 35c2345c..66a0d93 100644
--- a/include/netlink/route/link/veth.h
+++ b/include/netlink/route/link/veth.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/veth.h VETH interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/link/vlan.h b/include/netlink/route/link/vlan.h
index 4ec751e..2729d6e 100644
--- a/include/netlink/route/link/vlan.h
+++ b/include/netlink/route/link/vlan.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/vlan.h VLAN interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/link/vrf.h b/include/netlink/route/link/vrf.h
index 0a56d91..5d49437 100644
--- a/include/netlink/route/link/vrf.h
+++ b/include/netlink/route/link/vrf.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/vrf.h VRF interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cumulus Networks. All rights reserved.
* Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
*/
diff --git a/include/netlink/route/link/vxlan.h b/include/netlink/route/link/vxlan.h
index a929a9f..6321b09 100644
--- a/include/netlink/route/link/vxlan.h
+++ b/include/netlink/route/link/vxlan.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/vxlan.h VXLAN interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Yasunobu Chiba <yasu@dsl.gr.jp>
*/
diff --git a/include/netlink/route/link/xfrmi.h b/include/netlink/route/link/xfrmi.h
index 6e4cda7..094ea11 100644
--- a/include/netlink/route/link/xfrmi.h
+++ b/include/netlink/route/link/xfrmi.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/link/xfrmi.h XFRMI interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2019 Eyal Birger <eyal.birger@gmail.com>
*
* Based on netlink/route/link/ipvti.h
diff --git a/include/netlink/route/mdb.h b/include/netlink/route/mdb.h
new file mode 100644
index 0000000..a65ea84
--- /dev/null
+++ b/include/netlink/route/mdb.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef NETLINK_MDB_H_
+#define NETLINK_MDB_H_
+
+#include <netlink/netlink.h>
+#include <netlink/cache.h>
+#include <netlink/route/link.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rtnl_mdb;
+struct rtnl_mdb_entry;
+
+struct rtnl_mdb *rtnl_mdb_alloc(void);
+void rtnl_mdb_put(struct rtnl_mdb *mdb);
+
+int rtnl_mdb_alloc_cache(struct nl_sock *sk, struct nl_cache **result);
+int rtnl_mdb_alloc_cache_flags(struct nl_sock *sock,
+ struct nl_cache **result,
+ unsigned int flags);
+
+uint32_t rtnl_mdb_get_ifindex(struct rtnl_mdb *mdb);
+void rtnl_mdb_add_entry(struct rtnl_mdb *mdb,
+ struct rtnl_mdb_entry *_entry);
+
+void rtnl_mdb_foreach_entry(struct rtnl_mdb *mdb,
+ void (*cb)(struct rtnl_mdb_entry *, void *),
+ void *arg);
+
+int rtnl_mdb_entry_get_ifindex(struct rtnl_mdb_entry *mdb_entry);
+int rtnl_mdb_entry_get_vid(struct rtnl_mdb_entry *mdb_entry);
+int rtnl_mdb_entry_get_state(struct rtnl_mdb_entry *mdb_entry);
+struct nl_addr *rtnl_mdb_entry_get_addr(struct rtnl_mdb_entry
+ *mdb_entry);
+uint16_t rtnl_mdb_entry_get_proto(struct rtnl_mdb_entry *mdb_entry);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/netlink/route/neighbour.h b/include/netlink/route/neighbour.h
index 0f17b66..3760414 100644
--- a/include/netlink/route/neighbour.h
+++ b/include/netlink/route/neighbour.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/neighbour.h Neighbours
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/neightbl.h b/include/netlink/route/neightbl.h
index 6c6c9a5..8bcdab2 100644
--- a/include/netlink/route/neightbl.h
+++ b/include/netlink/route/neightbl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/neightbl.h Neighbour Tables
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/netconf.h b/include/netlink/route/netconf.h
index 1993438..7006c6e 100644
--- a/include/netlink/route/netconf.h
+++ b/include/netlink/route/netconf.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/netconf.h rtnetlink netconf layer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2017 David Ahern <dsa@cumulusnetworks.com>
*/
diff --git a/include/netlink/route/nexthop.h b/include/netlink/route/nexthop.h
index 5b422dd..c4a2604 100644
--- a/include/netlink/route/nexthop.h
+++ b/include/netlink/route/nexthop.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/nexthop.h Routing Nexthop
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -70,6 +64,8 @@
extern int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
struct nl_addr *addr,
uint8_t ttl);
+extern struct nl_addr * rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *);
+extern uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *);
#ifdef __cplusplus
}
#endif
diff --git a/include/netlink/route/pktloc.h b/include/netlink/route/pktloc.h
index c3768ce..ab83821 100644
--- a/include/netlink/route/pktloc.h
+++ b/include/netlink/route/pktloc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/pktloc.h Packet Location Aliasing
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc.h b/include/netlink/route/qdisc.h
index 10b85c5..7d963a5 100644
--- a/include/netlink/route/qdisc.h
+++ b/include/netlink/route/qdisc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/qdisc.h Queueing Disciplines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -33,6 +27,8 @@
extern struct rtnl_qdisc *
rtnl_qdisc_get_by_parent(struct nl_cache *, int, uint32_t);
+extern struct rtnl_qdisc *rtnl_qdisc_get_by_kind(struct nl_cache *cache,
+ int ifindex, char *kind);
extern int rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int,
struct nl_msg **);
diff --git a/include/netlink/route/qdisc/cbq.h b/include/netlink/route/qdisc/cbq.h
index 3dbdd2d..3af6d88 100644
--- a/include/netlink/route/qdisc/cbq.h
+++ b/include/netlink/route/qdisc/cbq.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/cbq.h Class Based Queueing
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/dsmark.h b/include/netlink/route/qdisc/dsmark.h
index 06bd9d3..b8c358f 100644
--- a/include/netlink/route/qdisc/dsmark.h
+++ b/include/netlink/route/qdisc/dsmark.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/dsmark.h DSMARK
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/fifo.h b/include/netlink/route/qdisc/fifo.h
index c033427..291aac5 100644
--- a/include/netlink/route/qdisc/fifo.h
+++ b/include/netlink/route/qdisc/fifo.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/fifo.c FIFO Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/fq_codel.h b/include/netlink/route/qdisc/fq_codel.h
index d2c3d25..1a69cd8 100644
--- a/include/netlink/route/qdisc/fq_codel.h
+++ b/include/netlink/route/qdisc/fq_codel.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/fq_codel.h fq_codel
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/qdisc/hfsc.h b/include/netlink/route/qdisc/hfsc.h
index 4c33809..d6a6417 100644
--- a/include/netlink/route/qdisc/hfsc.h
+++ b/include/netlink/route/qdisc/hfsc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/hfsc.h HFSC Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/include/netlink/route/qdisc/htb.h b/include/netlink/route/qdisc/htb.h
index 5d7ca45..b751855 100644
--- a/include/netlink/route/qdisc/htb.h
+++ b/include/netlink/route/qdisc/htb.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/htb.h HTB Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2005 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2005 Siemens AG Oesterreich
diff --git a/include/netlink/route/qdisc/mqprio.h b/include/netlink/route/qdisc/mqprio.h
index 1a38aeb..0b26fdb 100644
--- a/include/netlink/route/qdisc/mqprio.h
+++ b/include/netlink/route/qdisc/mqprio.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/mqprio.c MQPRIO Qdisc/Class
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
*/
diff --git a/include/netlink/route/qdisc/netem.h b/include/netlink/route/qdisc/netem.h
index 47c9dd8..5012ef5 100644
--- a/include/netlink/route/qdisc/netem.h
+++ b/include/netlink/route/qdisc/netem.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/netem.h Network Emulator Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/plug.h b/include/netlink/route/qdisc/plug.h
index 40f7e53..f14c043 100644
--- a/include/netlink/route/qdisc/plug.h
+++ b/include/netlink/route/qdisc/plug.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/qdisc/plug.c PLUG Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Shriram Rajagopalan <rshriram@cs.ubc.ca>
*/
diff --git a/include/netlink/route/qdisc/prio.h b/include/netlink/route/qdisc/prio.h
index 636a8f9..28bcc1b 100644
--- a/include/netlink/route/qdisc/prio.h
+++ b/include/netlink/route/qdisc/prio.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/prio.c PRIO Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/red.h b/include/netlink/route/qdisc/red.h
index accb8d9..51d38ed 100644
--- a/include/netlink/route/qdisc/red.h
+++ b/include/netlink/route/qdisc/red.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/red.h RED Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/sfq.h b/include/netlink/route/qdisc/sfq.h
index 77d2e29..38ee0ce 100644
--- a/include/netlink/route/qdisc/sfq.h
+++ b/include/netlink/route/qdisc/sfq.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/sfq.c SFQ Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/qdisc/tbf.h b/include/netlink/route/qdisc/tbf.h
index ce31c54..b6c4f3d 100644
--- a/include/netlink/route/qdisc/tbf.h
+++ b/include/netlink/route/qdisc/tbf.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/sch/tbf.h TBF Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/route.h b/include/netlink/route/route.h
index 824dae3..3824762 100644
--- a/include/netlink/route/route.h
+++ b/include/netlink/route/route.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/route.h Routes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -58,6 +52,9 @@
extern int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **);
extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *);
+extern int rtnl_route_lookup(struct nl_sock *sk, struct nl_addr *dst,
+ struct rtnl_route **result);
+
extern int rtnl_route_build_add_request(struct rtnl_route *, int,
struct nl_msg **);
extern int rtnl_route_add(struct nl_sock *, struct rtnl_route *, int);
diff --git a/include/netlink/route/rtnl.h b/include/netlink/route/rtnl.h
index f551a5d..6cae88f 100644
--- a/include/netlink/route/rtnl.h
+++ b/include/netlink/route/rtnl.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/rtnl.h Routing Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/rule.h b/include/netlink/route/rule.h
index d0c335f..26f5b52 100644
--- a/include/netlink/route/rule.h
+++ b/include/netlink/route/rule.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/rule.h Rules
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/tc-api.h b/include/netlink/route/tc-api.h
index b7771b5..3f400ba 100644
--- a/include/netlink/route/tc-api.h
+++ b/include/netlink/route/tc-api.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/tc-api.h Traffic Control API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/route/tc.h b/include/netlink/route/tc.h
index 51d670a..ee55555 100644
--- a/include/netlink/route/tc.h
+++ b/include/netlink/route/tc.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/route/tc.h Traffic Control
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/socket.h b/include/netlink/socket.h
index 9a68cad..2bd98c3 100644
--- a/include/netlink/socket.h
+++ b/include/netlink/socket.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/socket.h Netlink Socket
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/types.h b/include/netlink/types.h
index 09cc5bd..1e3a9a9 100644
--- a/include/netlink/types.h
+++ b/include/netlink/types.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/types.h Definition of public types
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
index b05ce66..c62df82 100644
--- a/include/netlink/utils.h
+++ b/include/netlink/utils.h
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/utils.h Utility Functions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -19,6 +13,12 @@
extern "C" {
#endif
+#if defined(__GNUC__) && __GNUC__ > 5
+#define _nl_attribute_printf(a, b) __attribute__((__format__(printf, a, b)))
+#else
+#define _nl_attribute_printf(a, b)
+#endif
+
/**
* @name Probability Constants
* @{
@@ -76,8 +76,8 @@
/* Dumping helpers */
extern void nl_new_line(struct nl_dump_params *);
-extern void nl_dump(struct nl_dump_params *, const char *, ...);
-extern void nl_dump_line(struct nl_dump_params *, const char *, ...);
+extern void nl_dump(struct nl_dump_params *, const char *, ...) _nl_attribute_printf(2, 3);
+extern void nl_dump_line(struct nl_dump_params *, const char *, ...) _nl_attribute_printf(2, 3);
enum {
NL_CAPABILITY_NONE,
@@ -300,6 +300,25 @@
NL_CAPABILITY_VERSION_3_5_0 = 30,
#define NL_CAPABILITY_VERSION_3_5_0 NL_CAPABILITY_VERSION_3_5_0
+ /**
+ * nl_object_identical() can consider objects identical, if they both lack the same
+ * set of ID attributes.
+ */
+ NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL = 31,
+#define NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL
+
+ /**
+ * The library version is libnl3 3.6.0 or newer. This capability should never be backported.
+ */
+ NL_CAPABILITY_VERSION_3_6_0 = 32,
+#define NL_CAPABILITY_VERSION_3_6_0 NL_CAPABILITY_VERSION_3_6_0
+
+ /**
+ * The library version is libnl3 3.7.0 or newer. This capability should never be backported.
+ */
+ NL_CAPABILITY_VERSION_3_7_0 = 33,
+#define NL_CAPABILITY_VERSION_3_7_0 NL_CAPABILITY_VERSION_3_7_0
+
__NL_CAPABILITY_MAX,
NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1),
#define NL_CAPABILITY_MAX NL_CAPABILITY_MAX
diff --git a/include/netlink/version.h.in b/include/netlink/version.h.in
index 35bf2aa..7fccc95 100644
--- a/include/netlink/version.h.in
+++ b/include/netlink/version.h.in
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/version.h Versioning Information
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/include/netlink/xfrm/sa.h b/include/netlink/xfrm/sa.h
index 7362c36..cd5e552 100644
--- a/include/netlink/xfrm/sa.h
+++ b/include/netlink/xfrm/sa.h
@@ -164,6 +164,9 @@
unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int*);
+extern int xfrmnl_sa_get_user_offload (struct xfrmnl_sa*, int*, uint8_t *);
+extern int xfrmnl_sa_set_user_offload (struct xfrmnl_sa*, int, uint8_t);
+
extern int xfrmnl_sa_is_expiry_reached (struct xfrmnl_sa*);
extern int xfrmnl_sa_is_hardexpiry_reached (struct xfrmnl_sa*);
diff --git a/lib/.gitignore b/lib/.gitignore
deleted file mode 100644
index e1abf18..0000000
--- a/lib/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-libnl.so*
-libnl-*.so*
-lex.yy.c
diff --git a/lib/addr.c b/lib/addr.c
index 06f3138..fae1293 100644
--- a/lib/addr.c
+++ b/lib/addr.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/addr.c Network Address
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/attr.c b/lib/attr.c
index a4f5852..6838dba 100644
--- a/lib/attr.c
+++ b/lib/attr.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/attr.c Netlink Attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -257,7 +250,7 @@
if (policy) {
err = validate_nla(nla, maxtype, policy);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[type])
@@ -267,13 +260,12 @@
tb[type] = nla;
}
- if (rem > 0)
+ if (rem > 0) {
NL_DBG(1, "netlink: %d bytes leftover after parsing "
"attributes.\n", rem);
+ }
- err = 0;
-errout:
- return err;
+ return 0;
}
/**
diff --git a/lib/cache.c b/lib/cache.c
index 4bb10d1..eadce57 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cache.c Caching Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -51,6 +44,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink-private/utils.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/object.h>
@@ -757,7 +751,10 @@
* @arg cache Cache to put items into.
*
* Waits for netlink messages to arrive, parses them and puts them into
- * the specified cache.
+ * the specified cache. If an old object with same key attributes is
+ * present in the cache, it is replaced with the new object.
+ * If the old object type supports an update operation, an update is
+ * attempted before a replace.
*
* @return 0 on success or a negative error code.
*/
@@ -772,10 +769,7 @@
* @arg cache Cache to put items into.
*
* Waits for netlink messages to arrive, parses them and puts them into
- * the specified cache. If an old object with same key attributes is
- * present in the cache, it is replaced with the new object.
- * If the old object type supports an update operation, an update is
- * attempted before a replace.
+ * the specified cache.
*
* @return 0 on success or a negative error code.
*/
@@ -1208,7 +1202,7 @@
/**
* Dump all elements of a cache (filtered).
* @arg cache cache to dump
- * @arg params dumping parameters (optional)
+ * @arg params dumping parameters
* @arg filter filter object
*
* Dumps all elements of the \a cache to the file descriptor \a fd
@@ -1218,13 +1212,30 @@
struct nl_dump_params *params,
struct nl_object *filter)
{
- int type = params ? params->dp_type : NL_DUMP_DETAILS;
+ struct nl_dump_params params_copy;
struct nl_object_ops *ops;
struct nl_object *obj;
+ int type;
NL_DBG(2, "Dumping cache %p <%s> with filter %p\n",
cache, nl_cache_name(cache), filter);
+ if (!params) {
+ /* It doesn't really make sense that @params is an optional parameter. In the
+ * past, nl_cache_dump() was documented that the @params would be optional, so
+ * try to save it.
+ *
+ * Note that this still isn't useful, because we don't set any dump option.
+ * It only exists not to crash applications that wrongly pass %NULL here. */
+ _nl_assert_not_reached ();
+ params_copy = (struct nl_dump_params) {
+ .dp_type = NL_DUMP_DETAILS,
+ };
+ params = ¶ms_copy;
+ }
+
+ type = params->dp_type;
+
if (type > NL_DUMP_MAX || type < 0)
BUG();
@@ -1235,7 +1246,7 @@
if (!ops->oo_dump[type])
return;
- if (params && params->dp_buf)
+ if (params->dp_buf)
memset(params->dp_buf, 0, params->dp_buflen);
nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
diff --git a/lib/cache_mngr.c b/lib/cache_mngr.c
index 380834f..dd119f2 100644
--- a/lib/cache_mngr.c
+++ b/lib/cache_mngr.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cache_mngr.c Cache Manager
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c
index 4178e43..f506976 100644
--- a/lib/cache_mngt.c
+++ b/lib/cache_mngt.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cache_mngt.c Cache Management
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/cls/basic.c b/lib/cli/cls/basic.c
index 1a6b188..90ef554 100644
--- a/lib/cli/cls/basic.c
+++ b/lib/cli/cls/basic.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cli/cls/basic.c basic classifier module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/cls/cgroup.c b/lib/cli/cls/cgroup.c
index 9e1443c..43536b5 100644
--- a/lib/cli/cls/cgroup.c
+++ b/lib/cli/cls/cgroup.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cli/cls/cgroup.c cgroup classifier module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/qdisc/bfifo.c b/lib/cli/qdisc/bfifo.c
index 6b0206f..7e53541 100644
--- a/lib/cli/qdisc/bfifo.c
+++ b/lib/cli/qdisc/bfifo.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/bfifo.c bfifo module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/qdisc/blackhole.c b/lib/cli/qdisc/blackhole.c
index 372855f..2425ab7 100644
--- a/lib/cli/qdisc/blackhole.c
+++ b/lib/cli/qdisc/blackhole.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/blackhole.c Blackhole module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/qdisc/fq_codel.c b/lib/cli/qdisc/fq_codel.c
index a592f90..90e609e 100644
--- a/lib/cli/qdisc/fq_codel.c
+++ b/lib/cli/qdisc/fq_codel.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cli/qdisc/fq_codel.c fq_codel module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/cli/qdisc/hfsc.c b/lib/cli/qdisc/hfsc.c
index 619befc..cbbc100 100644
--- a/lib/cli/qdisc/hfsc.c
+++ b/lib/cli/qdisc/hfsc.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/cli/qdisc/hfsc.c HFSC module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/cli/qdisc/htb.c b/lib/cli/qdisc/htb.c
index 628e6cc..235701c 100644
--- a/lib/cli/qdisc/htb.c
+++ b/lib/cli/qdisc/htb.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/htb.c HTB module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/qdisc/ingress.c b/lib/cli/qdisc/ingress.c
index 8892a64..3c2a6c0 100644
--- a/lib/cli/qdisc/ingress.c
+++ b/lib/cli/qdisc/ingress.c
@@ -1,12 +1,5 @@
-
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/ingress.c ingress module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/cli/qdisc/pfifo.c b/lib/cli/qdisc/pfifo.c
index 7aac7df..fbda6eb 100644
--- a/lib/cli/qdisc/pfifo.c
+++ b/lib/cli/qdisc/pfifo.c
@@ -1,12 +1,5 @@
-
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/pfifo.c pfifo module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/cli/qdisc/plug.c b/lib/cli/qdisc/plug.c
index 227082d..549db0b 100644
--- a/lib/cli/qdisc/plug.c
+++ b/lib/cli/qdisc/plug.c
@@ -1,12 +1,5 @@
-
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/cli/qdisc/plug.c plug module for CLI lib
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Shriram Rajagopalan <rshriram@cs.ubc.ca>
*/
diff --git a/lib/data.c b/lib/data.c
index fea3060..87df30f 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/data.c Abstract Data
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/error.c b/lib/error.c
index 1106cb0..bd0b92d 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/error.c Error Handling
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/fib_lookup/lookup.c b/lib/fib_lookup/lookup.c
index fbd6291..e258546 100644
--- a/lib/fib_lookup/lookup.c
+++ b/lib/fib_lookup/lookup.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/fib_lookup/lookup.c FIB Lookup
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -62,11 +55,13 @@
struct flnl_result *dst = nl_object_priv(_dst);
struct flnl_result *src = nl_object_priv(_src);
- if (src->fr_req)
- if (!(dst->fr_req = (struct flnl_request *)
- nl_object_clone(OBJ_CAST(src->fr_req))))
+ dst->fr_req = NULL;
+
+ if (src->fr_req) {
+ if (!(dst->fr_req = (struct flnl_request *) nl_object_clone(OBJ_CAST(src->fr_req))))
return -NLE_NOMEM;
-
+ }
+
return 0;
}
diff --git a/lib/fib_lookup/request.c b/lib/fib_lookup/request.c
index 7749a07..0773c3b 100644
--- a/lib/fib_lookup/request.c
+++ b/lib/fib_lookup/request.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/fib_lookup/request.c FIB Lookup Request
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -47,9 +40,12 @@
struct flnl_request *dst = nl_object_priv(_dst);
struct flnl_request *src = nl_object_priv(_src);
- if (src->lr_addr)
+ dst->lr_addr = NULL;
+
+ if (src->lr_addr) {
if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
return -NLE_NOMEM;
+ }
return 0;
}
diff --git a/lib/genl/ctrl.c b/lib/genl/ctrl.c
index 2d5d6f2..65b5f05 100644
--- a/lib/genl/ctrl.c
+++ b/lib/genl/ctrl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/genl/ctrl.c Generic Netlink Controller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/genl/family.c b/lib/genl/family.c
index ed8b08b..e8e0c9e 100644
--- a/lib/genl/family.c
+++ b/lib/genl/family.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/genl/family.c Generic Netlink Family
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -74,6 +67,9 @@
struct genl_family_grp *grp;
int err;
+ nl_init_list_head(&dst->gf_ops);
+ nl_init_list_head(&dst->gf_mc_grps);
+
nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
if (err < 0)
@@ -260,7 +256,7 @@
*/
void genl_family_set_name(struct genl_family *family, const char *name)
{
- strncpy(family->gf_name, name, GENL_NAMSIZ-1);
+ _nl_strncpy_trunc(family->gf_name, name, GENL_NAMSIZ);
family->ce_mask |= FAMILY_ATTR_NAME;
}
@@ -380,7 +376,7 @@
return -NLE_NOMEM;
grp->id = id;
- _nl_strncpy(grp->name, name, GENL_NAMSIZ);
+ _nl_strncpy_assert(grp->name, name, GENL_NAMSIZ);
nl_list_add_tail(&grp->list, &family->gf_mc_grps);
diff --git a/lib/genl/genl.c b/lib/genl/genl.c
index b4f37b5..4fd7962 100644
--- a/lib/genl/genl.c
+++ b/lib/genl/genl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/genl/genl.c Generic Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/genl/mngt.c b/lib/genl/mngt.c
index 28326cd..1dcddbc 100644
--- a/lib/genl/mngt.c
+++ b/lib/genl/mngt.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/genl/mngt.c Generic Netlink Management
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -133,13 +126,13 @@
cmd = &ops->o_cmds[i];
if (cmd->c_id == op) {
- strncpy(buf, cmd->c_name, len - 1);
+ _nl_strncpy_trunc(buf, cmd->c_name, len);
return buf;
}
}
}
- strncpy(buf, "unknown", len - 1);
+ _nl_strncpy_trunc(buf, "unknown", len);
return NULL;
}
diff --git a/lib/handlers.c b/lib/handlers.c
index 85cb3c6..e6fca0e 100644
--- a/lib/handlers.c
+++ b/lib/handlers.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/handlers.c default netlink message handlers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/hashtable.c b/lib/hashtable.c
index db4ed8b..1b332ba 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -1,14 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * netlink/hashtable.c Netlink hashtable Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Cumulus Networks, Inc
*/
+
#include <string.h>
#include <netlink-private/netlink.h>
#include <netlink/object.h>
@@ -59,15 +53,15 @@
int i;
for(i = 0; i < ht->size; i++) {
- nl_hash_node_t *node = ht->nodes[i];
- nl_hash_node_t *saved_node;
+ nl_hash_node_t *node = ht->nodes[i];
+ nl_hash_node_t *saved_node;
- while (node) {
- saved_node = node;
- node = node->next;
- nl_object_put(saved_node->obj);
- free(saved_node);
- }
+ while (node) {
+ saved_node = node;
+ node = node->next;
+ nl_object_put(saved_node->obj);
+ free(saved_node);
+ }
}
free(ht->nodes);
@@ -94,9 +88,9 @@
node = ht->nodes[key_hash];
while (node) {
- if (nl_object_identical(node->obj, obj))
- return node->obj;
- node = node->next;
+ if (nl_object_identical(node->obj, obj))
+ return node->obj;
+ node = node->next;
}
return NULL;
@@ -124,11 +118,11 @@
node = ht->nodes[key_hash];
while (node) {
- if (nl_object_identical(node->obj, obj)) {
- NL_DBG(2, "Warning: Add to hashtable found duplicate...\n");
- return -NLE_EXIST;
- }
- node = node->next;
+ if (nl_object_identical(node->obj, obj)) {
+ NL_DBG(2, "Warning: Add to hashtable found duplicate...\n");
+ return -NLE_EXIST;
+ }
+ node = node->next;
}
NL_DBG (5, "adding cache entry of obj %p in table %p, with hash 0x%x\n",
@@ -168,20 +162,20 @@
prev = node = ht->nodes[key_hash];
while (node) {
- if (nl_object_identical(node->obj, obj)) {
- nl_object_put(obj);
+ if (nl_object_identical(node->obj, obj)) {
+ nl_object_put(obj);
- NL_DBG (5, "deleting cache entry of obj %p in table %p, with"
- " hash 0x%x\n", obj, ht, key_hash);
+ NL_DBG (5, "deleting cache entry of obj %p in table %p, with"
+ " hash 0x%x\n", obj, ht, key_hash);
- if (node == ht->nodes[key_hash])
- ht->nodes[key_hash] = node->next;
- else
- prev->next = node->next;
+ if (node == ht->nodes[key_hash])
+ ht->nodes[key_hash] = node->next;
+ else
+ prev->next = node->next;
- free(node);
+ free(node);
- return 0;
+ return 0;
}
prev = node;
node = node->next;
diff --git a/lib/idiag/idiag.c b/lib/idiag/idiag.c
index 23a8413..38c3a6b 100644
--- a/lib/idiag/idiag.c
+++ b/lib/idiag/idiag.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/idiag/idiag.c Inet Diag Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/lib/idiag/idiag_meminfo_obj.c b/lib/idiag/idiag_meminfo_obj.c
index 0ada71e..55ff8cc 100644
--- a/lib/idiag/idiag_meminfo_obj.c
+++ b/lib/idiag/idiag_meminfo_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/idiag/idiagnl_meminfo_obj.c Inet Diag Meminfo Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index a1beb2c..f42bd59 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/idiag/idiagnl_msg_obj.c Inet Diag Message Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
@@ -629,9 +622,9 @@
struct idiagnl_msg *dst = (struct idiagnl_msg *) _dst;
struct idiagnl_msg *src = (struct idiagnl_msg *) _src;
- dst->idiag_cong = NULL;
dst->idiag_src = NULL;
dst->idiag_dst = NULL;
+ dst->idiag_cong = NULL;
dst->idiag_meminfo = NULL;
dst->idiag_vegasinfo = NULL;
dst->ce_mask &= ~(IDIAGNL_ATTR_CONG |
diff --git a/lib/idiag/idiag_req_obj.c b/lib/idiag/idiag_req_obj.c
index c825e40..e88fbc2 100644
--- a/lib/idiag/idiag_req_obj.c
+++ b/lib/idiag/idiag_req_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/idiag/idiagnl_req_obj.c Inet Diag Request Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
@@ -176,6 +169,9 @@
struct idiagnl_req *dst = (struct idiagnl_req *) _dst;
struct idiagnl_req *src = (struct idiagnl_req *) _src;
+ src->idiag_src = NULL;
+ src->idiag_dst = NULL;
+
if (src->idiag_src)
if (!(dst->idiag_src = nl_addr_clone(src->idiag_src)))
return -NLE_NOMEM;
diff --git a/lib/idiag/idiag_vegasinfo_obj.c b/lib/idiag/idiag_vegasinfo_obj.c
index 9a8f993..ff9213d 100644
--- a/lib/idiag/idiag_vegasinfo_obj.c
+++ b/lib/idiag/idiag_vegasinfo_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/idiag/idiagnl_vegasinfo_obj.c Inet Diag TCP Vegas Info Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/lib/msg.c b/lib/msg.c
index c08b3a4..17ca812 100644
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/msg.c Netlink Messages Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/netfilter/ct.c b/lib/netfilter/ct.c
index 98aaafc..d5725f4 100644
--- a/lib/netfilter/ct.c
+++ b/lib/netfilter/ct.c
@@ -1,16 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/ct.c Conntrack
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
- * Copyright (c= 2008 Patrick McHardy <kaber@trash.net>
+ * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*/
/**
@@ -315,6 +308,61 @@
return 0;
}
+static int _nfnlmsg_ct_parse(struct nlattr **tb, struct nfnl_ct *ct)
+{
+ int err;
+
+ if (tb[CTA_TUPLE_ORIG]) {
+ err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
+ if (err < 0)
+ return err;
+ }
+ if (tb[CTA_TUPLE_REPLY]) {
+ err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
+ if (err < 0)
+ return err;
+ }
+
+ if (tb[CTA_PROTOINFO]) {
+ err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
+ if (err < 0)
+ return err;
+ }
+
+ if (tb[CTA_STATUS])
+ nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS])));
+ if (tb[CTA_TIMEOUT])
+ nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT])));
+ if (tb[CTA_MARK])
+ nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK])));
+ if (tb[CTA_USE])
+ nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE])));
+ if (tb[CTA_ID])
+ nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID])));
+ if (tb[CTA_ZONE])
+ nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE])));
+
+ if (tb[CTA_COUNTERS_ORIG]) {
+ err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
+ if (err < 0)
+ return err;
+ }
+
+ if (tb[CTA_COUNTERS_REPLY]) {
+ err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
+ if (err < 0)
+ return err;
+ }
+
+ if (tb[CTA_TIMESTAMP]) {
+ err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
{
struct nfnl_ct *ct;
@@ -334,57 +382,43 @@
nfnl_ct_set_family(ct, nfnlmsg_family(nlh));
- if (tb[CTA_TUPLE_ORIG]) {
- err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
- if (err < 0)
- goto errout;
- }
- if (tb[CTA_TUPLE_REPLY]) {
- err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
- if (err < 0)
- goto errout;
- }
-
- if (tb[CTA_PROTOINFO]) {
- err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
- if (err < 0)
- goto errout;
- }
-
- if (tb[CTA_STATUS])
- nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS])));
- if (tb[CTA_TIMEOUT])
- nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT])));
- if (tb[CTA_MARK])
- nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK])));
- if (tb[CTA_USE])
- nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE])));
- if (tb[CTA_ID])
- nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID])));
- if (tb[CTA_ZONE])
- nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE])));
-
- if (tb[CTA_COUNTERS_ORIG]) {
- err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
- if (err < 0)
- goto errout;
- }
-
- if (tb[CTA_COUNTERS_REPLY]) {
- err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
- if (err < 0)
- goto errout;
- }
-
- if (tb[CTA_TIMESTAMP]) {
- err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]);
- if (err < 0)
- goto errout;
- }
+ err = _nfnlmsg_ct_parse(tb, ct);
+ if (err < 0)
+ goto errout;
*result = ct;
return 0;
+errout:
+ nfnl_ct_put(ct);
+ return err;
+}
+int nfnlmsg_ct_parse_nested(struct nlattr *attr, struct nfnl_ct **result)
+{
+ struct nfnl_ct *ct;
+ struct nlattr *tb[CTA_MAX+1];
+ int err;
+
+ ct = nfnl_ct_alloc();
+ if (!ct)
+ return -NLE_NOMEM;
+
+ // msgtype not given for nested
+ //ct->ce_msgtype = nlh->nlmsg_type;
+
+ err = nla_parse_nested(tb, CTA_MAX, attr, ct_policy);
+ if (err < 0)
+ goto errout;
+
+ // family not known
+ //nfnl_ct_set_family(ct, nfnlmsg_family(nlh));
+
+ err = _nfnlmsg_ct_parse(tb, ct);
+ if (err < 0)
+ goto errout;
+
+ *result = ct;
+ return 0;
errout:
nfnl_ct_put(ct);
return err;
@@ -508,20 +542,24 @@
{
struct nl_msg *msg;
int err;
+ int reply = 0;
msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
nfnl_ct_get_family(ct), 0);
if (msg == NULL)
return -NLE_NOMEM;
- if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
- goto err_out;
-
- /* REPLY tuple is optional, dont add unless at least src/dst specified */
-
- if ( nfnl_ct_get_src(ct, 1) && nfnl_ct_get_dst(ct, 1) )
+ /* We use REPLY || ORIG, depending on requests. */
+ if (nfnl_ct_get_src(ct, 1) || nfnl_ct_get_dst(ct, 1)) {
+ reply = 1;
if ((err = nfnl_ct_build_tuple(msg, ct, 1)) < 0)
goto err_out;
+ }
+
+ if (!reply || nfnl_ct_get_src(ct, 0) || nfnl_ct_get_dst(ct, 0)) {
+ if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
+ goto err_out;
+ }
if (nfnl_ct_test_status(ct))
NLA_PUT_U32(msg, CTA_STATUS, htonl(nfnl_ct_get_status(ct)));
diff --git a/lib/netfilter/ct_obj.c b/lib/netfilter/ct_obj.c
index 08aa945..86cbc17 100644
--- a/lib/netfilter/ct_obj.c
+++ b/lib/netfilter/ct_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/ct_obj.c Conntrack Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -75,6 +68,11 @@
struct nfnl_ct *src = (struct nfnl_ct *) _src;
struct nl_addr *addr;
+ dst->ct_orig.src = NULL;
+ dst->ct_orig.dst = NULL;
+ dst->ct_repl.src = NULL;
+ dst->ct_repl.dst = NULL;
+
if (src->ct_orig.src) {
addr = nl_addr_clone(src->ct_orig.src);
if (!addr)
@@ -206,7 +204,7 @@
delta_time /= NSEC_PER_SEC;
else
delta_time = 0;
- nl_dump(p, "delta-time %llu ", delta_time);
+ nl_dump(p, "delta-time %llu ", (long long unsigned)delta_time);
}
nl_dump(p, "\n");
@@ -221,8 +219,9 @@
ct_dump_line(a, p);
nl_dump(p, " id 0x%x ", ct->ct_id);
- nl_dump_line(p, "family %s ",
- nl_af2str(ct->ct_family, buf, sizeof(buf)));
+ if (ct->ce_mask & CT_ATTR_FAMILY)
+ nl_dump_line(p, "family %s ",
+ nl_af2str(ct->ct_family, buf, sizeof(buf)));
if (nfnl_ct_test_use(ct))
nl_dump(p, "refcnt %u ", nfnl_ct_get_use(ct));
diff --git a/lib/netfilter/exp.c b/lib/netfilter/exp.c
index d475861..05a6cdc 100644
--- a/lib/netfilter/exp.c
+++ b/lib/netfilter/exp.c
@@ -1,16 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/exp.c Conntrack Expectation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
- * Copyright (c= 2008 Patrick McHardy <kaber@trash.net>
+ * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
* Copyright (c) 2012 Rich Fought <rich.fought@watchguard.com>
*/
@@ -423,7 +416,6 @@
static int nfnl_exp_build_nat(struct nl_msg *msg, const struct nfnl_exp *exp)
{
struct nlattr *nat;
- int err;
nat = nla_nest_start(msg, CTA_EXPECT_NAT);
@@ -432,7 +424,7 @@
nfnl_exp_get_nat_dir(exp));
}
- if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT)) < 0)
+ if (nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT) < 0)
goto nla_put_failure;
nla_nest_end(msg, nat);
diff --git a/lib/netfilter/exp_obj.c b/lib/netfilter/exp_obj.c
index 8cd59ee..21311c9 100644
--- a/lib/netfilter/exp_obj.c
+++ b/lib/netfilter/exp_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/exp_obj.c Conntrack Expectation Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -88,7 +81,17 @@
struct nfnl_exp *src = (struct nfnl_exp *) _src;
struct nl_addr *addr;
- // Expectation
+ dst->exp_helper_name = NULL;
+ dst->exp_fn = NULL;
+ dst->exp_expect.src = NULL;
+ dst->exp_expect.dst = NULL;
+ dst->exp_master.src = NULL;
+ dst->exp_master.dst = NULL;
+ dst->exp_mask.src = NULL;
+ dst->exp_mask.dst = NULL;
+ dst->exp_nat.src = NULL;
+ dst->exp_nat.dst = NULL;
+
if (src->exp_expect.src) {
addr = nl_addr_clone(src->exp_expect.src);
if (!addr)
@@ -103,7 +106,6 @@
dst->exp_expect.dst = addr;
}
- // Master CT
if (src->exp_master.src) {
addr = nl_addr_clone(src->exp_master.src);
if (!addr)
@@ -118,7 +120,6 @@
dst->exp_master.dst = addr;
}
- // Mask
if (src->exp_mask.src) {
addr = nl_addr_clone(src->exp_mask.src);
if (!addr)
@@ -133,7 +134,6 @@
dst->exp_mask.dst = addr;
}
- // NAT
if (src->exp_nat.src) {
addr = nl_addr_clone(src->exp_nat.src);
if (!addr)
@@ -218,7 +218,7 @@
}
if (nfnl_exp_test_nat_dir(exp))
- nl_dump(p, "nat dir %s ", exp->exp_nat_dir);
+ nl_dump(p, "nat dir %u ", exp->exp_nat_dir);
}
diff --git a/lib/netfilter/log.c b/lib/netfilter/log.c
index 1761808..c14a4ea 100644
--- a/lib/netfilter/log.c
+++ b/lib/netfilter/log.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/log.c Netfilter Log
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -151,6 +144,11 @@
htonl(nfnl_log_get_queue_threshold(log))) < 0)
goto nla_put_failure;
+ if (nfnl_log_get_flags(log) &&
+ nla_put_u16(msg, NFULA_CFG_FLAGS,
+ htons(nfnl_log_get_flags(log))) < 0)
+ goto nla_put_failure;
+
*result = msg;
return 0;
diff --git a/lib/netfilter/log_msg.c b/lib/netfilter/log_msg.c
index e1f92eb..2b1b125 100644
--- a/lib/netfilter/log_msg.c
+++ b/lib/netfilter/log_msg.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/log_msg.c Netfilter Log Message
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -50,8 +43,41 @@
[NFULA_GID] = { .type = NLA_U32 },
[NFULA_SEQ] = { .type = NLA_U32 },
[NFULA_SEQ_GLOBAL] = { .type = NLA_U32 },
+ [NFULA_HWTYPE] = { .type = NLA_U16 },
+ [NFULA_HWLEN] = { .type = NLA_U16 },
+ [NFULA_VLAN] = { .type = NLA_NESTED },
+ [NFULA_CT] = { .type = NLA_NESTED },
+ [NFULA_CT_INFO] = { .type = NLA_U32 },
};
+static struct nla_policy log_msg_vlan_policy[NFULA_VLAN_MAX+1] = {
+ [NFULA_VLAN_PROTO] = { .type = NLA_U16 },
+ [NFULA_VLAN_TCI] = { .type = NLA_U16 },
+};
+
+static int
+nfnlmsg_log_msg_parse_vlan(struct nlattr *attr_full, struct nfnl_log_msg *msg)
+{
+ struct nlattr *tb[NFULA_VLAN_MAX+1];
+ struct nlattr *attr;
+ int err;
+
+ err = nla_parse_nested(tb, NFULA_VLAN_MAX, attr_full,
+ log_msg_vlan_policy);
+ if (err < 0)
+ return err;
+
+ attr = tb[NFULA_VLAN_PROTO];
+ if (attr)
+ nfnl_log_msg_set_vlan_proto(msg, nla_get_u16(attr));
+
+ attr = tb[NFULA_VLAN_TCI];
+ if (attr)
+ nfnl_log_msg_set_vlan_tag(msg, ntohs(nla_get_u16(attr)));
+
+ return 0;
+}
+
int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
{
struct nfnl_log_msg *msg;
@@ -148,6 +174,39 @@
if (attr)
nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
+ attr = tb[NFULA_HWTYPE];
+ if (attr)
+ nfnl_log_msg_set_hwtype(msg, ntohs(nla_get_u16(attr)));
+
+ attr = tb[NFULA_HWLEN];
+ if (attr)
+ nfnl_log_msg_set_hwlen(msg, ntohs(nla_get_u16(attr)));
+
+ attr = tb[NFULA_HWHEADER];
+ if (attr)
+ nfnl_log_msg_set_hwheader(msg, nla_data(attr), nla_len(attr));
+
+ attr = tb[NFULA_VLAN];
+ if (attr) {
+ err = nfnlmsg_log_msg_parse_vlan(attr, msg);
+ if (err < 0)
+ goto errout;
+ }
+
+ attr = tb[NFULA_CT];
+ if (attr) {
+ struct nfnl_ct *ct = NULL;
+ err = nfnlmsg_ct_parse_nested(attr, &ct);
+ if (err < 0)
+ goto errout;
+ nfnl_log_msg_set_ct(msg, ct);
+ nfnl_ct_put(ct);
+ }
+
+ attr = tb[NFULA_CT_INFO];
+ if (attr)
+ nfnl_log_msg_set_ct_info(msg, ntohl(nla_get_u32(attr)));
+
*result = msg;
return 0;
diff --git a/lib/netfilter/log_msg_obj.c b/lib/netfilter/log_msg_obj.c
index 90b7bc9..6b26bc5 100644
--- a/lib/netfilter/log_msg_obj.c
+++ b/lib/netfilter/log_msg_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/log_msg_obj.c Netfilter Log Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -34,6 +27,13 @@
#define LOG_MSG_ATTR_GID (1UL << 13)
#define LOG_MSG_ATTR_SEQ (1UL << 14)
#define LOG_MSG_ATTR_SEQ_GLOBAL (1UL << 15)
+#define LOG_MSG_ATTR_HWTYPE (1UL << 16)
+#define LOG_MSG_ATTR_HWLEN (1UL << 17)
+#define LOG_MSG_ATTR_HWHEADER (1UL << 18)
+#define LOG_MSG_ATTR_VLAN_PROTO (1UL << 19)
+#define LOG_MSG_ATTR_VLAN_TAG (1UL << 20)
+#define LOG_MSG_ATTR_CT_INFO (1UL << 21)
+#define LOG_MSG_ATTR_CT (1UL << 22)
/** @endcond */
static void log_msg_free_data(struct nl_object *c)
@@ -45,6 +45,9 @@
free(msg->log_msg_payload);
free(msg->log_msg_prefix);
+ free(msg->log_msg_hwheader);
+ if (msg->log_msg_ct)
+ nfnl_ct_put(msg->log_msg_ct);
}
static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src)
@@ -53,22 +56,41 @@
struct nfnl_log_msg *src = (struct nfnl_log_msg *) _src;
int err;
+ dst->log_msg_payload = NULL;
+ dst->log_msg_payload_len = 0;
+ dst->log_msg_prefix = NULL;
+ dst->log_msg_hwheader = NULL;
+ dst->log_msg_hwheader_len = 0;
+ dst->log_msg_ct = NULL;
+
if (src->log_msg_payload) {
err = nfnl_log_msg_set_payload(dst, src->log_msg_payload,
- src->log_msg_payload_len);
+ src->log_msg_payload_len);
if (err < 0)
- goto errout;
+ return err;
}
if (src->log_msg_prefix) {
err = nfnl_log_msg_set_prefix(dst, src->log_msg_prefix);
if (err < 0)
- goto errout;
+ return err;
+ }
+
+ if (src->log_msg_hwheader) {
+ err = nfnl_log_msg_set_hwheader(dst, src->log_msg_hwheader,
+ src->log_msg_hwheader_len);
+ if (err < 0)
+ return err;
+ }
+
+ if (src->log_msg_ct) {
+ dst->log_msg_ct = (struct nfnl_ct *) nl_object_clone((struct nl_object *) src->log_msg_ct);
+ if (!dst->log_msg_ct) {
+ return -NLE_NOMEM;
+ }
}
return 0;
-errout:
- return err;
}
static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p)
@@ -101,7 +123,7 @@
msg->log_msg_physindev,
buf, sizeof(buf)));
else
- nl_dump(p, "IN=%d ", msg->log_msg_physindev);
+ nl_dump(p, "PHYSIN=%d ", msg->log_msg_physindev);
}
if (msg->ce_mask & LOG_MSG_ATTR_OUTDEV) {
@@ -167,8 +189,35 @@
if (msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL)
nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global);
+ if (msg->ce_mask & LOG_MSG_ATTR_HWTYPE)
+ nl_dump(p, "HWTYPE=%u ", msg->log_msg_hwtype);
+
+ if (msg->ce_mask & LOG_MSG_ATTR_HWLEN)
+ nl_dump(p, "HWLEN=%u ", msg->log_msg_hwlen);
+
+ if (msg->ce_mask & LOG_MSG_ATTR_HWHEADER) {
+ int i;
+
+ nl_dump(p, "HWHEADER");
+ for (i = 0; i < msg->log_msg_hwheader_len; i++)
+ nl_dump(p, "%c%02x", i?':':'=', ((uint8_t*) msg->log_msg_hwheader) [i]);
+ nl_dump(p, " ");
+ }
+
+ if (msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG)
+ nl_dump(p, "VLAN=%d CFI=%d PRIO=%d",
+ (int) nfnl_log_msg_get_vlan_id(msg),
+ (int) nfnl_log_msg_get_vlan_cfi(msg),
+ (int) nfnl_log_msg_get_vlan_prio(msg));
+
+ if (msg->ce_mask & LOG_MSG_ATTR_CT_INFO)
+ nl_dump(p, "CTINFO=%u ", msg->log_msg_ct_info);
+
nl_dump(p, "\n");
+ if (msg->ce_mask & LOG_MSG_ATTR_CT)
+ ct_obj_ops.oo_dump[NL_DUMP_LINE]((struct nl_object *)msg->log_msg_ct, p);
+
if (link_cache)
nl_cache_put(link_cache);
}
@@ -342,14 +391,22 @@
int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len)
{
- free(msg->log_msg_payload);
- msg->log_msg_payload = malloc(len);
- if (!msg->log_msg_payload)
+ uint8_t *p = NULL;
+
+ if (len < 0)
+ return -NLE_INVAL;
+
+ p = _nl_memdup(payload, len);
+ if (!p && len > 0)
return -NLE_NOMEM;
- memcpy(msg->log_msg_payload, payload, len);
+ free(msg->log_msg_payload);
+ msg->log_msg_payload = p;
msg->log_msg_payload_len = len;
- msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD;
+ if (len > 0)
+ msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD;
+ else
+ msg->ce_mask &= ~LOG_MSG_ATTR_PAYLOAD;
return 0;
}
@@ -366,12 +423,21 @@
int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix)
{
- free(msg->log_msg_prefix);
- msg->log_msg_prefix = strdup(prefix);
- if (!msg->log_msg_prefix)
- return -NLE_NOMEM;
+ char *p = NULL;
- msg->ce_mask |= LOG_MSG_ATTR_PREFIX;
+ if (prefix) {
+ p = strdup(prefix);
+ if (!p)
+ return -NLE_NOMEM;
+ }
+
+ free(msg->log_msg_prefix);
+ msg->log_msg_prefix = p;
+
+ if (p)
+ msg->ce_mask |= LOG_MSG_ATTR_PREFIX;
+ else
+ msg->ce_mask &= ~LOG_MSG_ATTR_PREFIX;
return 0;
}
@@ -445,6 +511,154 @@
return msg->log_msg_seq_global;
}
+void nfnl_log_msg_set_hwtype(struct nfnl_log_msg *msg, uint16_t hwtype)
+{
+ msg->log_msg_hwtype = hwtype;
+ msg->ce_mask |= LOG_MSG_ATTR_HWTYPE;
+}
+
+int nfnl_log_msg_test_hwtype(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_HWTYPE);
+}
+
+uint16_t nfnl_log_msg_get_hwtype(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_hwtype;
+}
+
+void nfnl_log_msg_set_hwlen(struct nfnl_log_msg *msg, uint16_t hwlen)
+{
+ msg->log_msg_hwlen = hwlen;
+ msg->ce_mask |= LOG_MSG_ATTR_HWLEN;
+}
+
+int nfnl_log_msg_test_hwlen(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_HWLEN);
+}
+
+uint16_t nfnl_log_msg_get_hwlen(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_hwlen;
+}
+
+int nfnl_log_msg_set_hwheader(struct nfnl_log_msg *msg, void *data, int len)
+{
+ void *p = NULL;
+
+ if (len < 0)
+ return -NLE_INVAL;
+
+ p = _nl_memdup(data, len);
+ if (!p && len > 0)
+ return -NLE_NOMEM;
+
+ free(msg->log_msg_hwheader);
+ msg->log_msg_hwheader = p;
+ msg->log_msg_hwheader_len = len;
+ if (len > 0)
+ msg->ce_mask |= LOG_MSG_ATTR_HWHEADER;
+ else
+ msg->ce_mask &= ~LOG_MSG_ATTR_HWHEADER;
+ return 0;
+}
+
+int nfnl_log_msg_test_hwheader(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER);
+}
+
+const void *nfnl_log_msg_get_hwheader(const struct nfnl_log_msg *msg, int *len)
+{
+ if (!(msg->ce_mask & LOG_MSG_ATTR_HWHEADER)) {
+ *len = 0;
+ return NULL;
+ }
+
+ *len = msg->log_msg_hwheader_len;
+ return msg->log_msg_hwheader;
+}
+
+void nfnl_log_msg_set_vlan_proto(struct nfnl_log_msg *msg, uint16_t vlan_proto)
+{
+ msg->log_msg_vlan_proto = vlan_proto;
+ msg->ce_mask |= LOG_MSG_ATTR_VLAN_PROTO;
+}
+
+int nfnl_log_msg_test_vlan_proto(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_PROTO);
+}
+
+uint16_t nfnl_log_msg_get_vlan_proto(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_vlan_proto;
+}
+
+void nfnl_log_msg_set_vlan_tag(struct nfnl_log_msg *msg, uint16_t vlan_tag)
+{
+ msg->log_msg_vlan_tag = vlan_tag;
+ msg->ce_mask |= LOG_MSG_ATTR_VLAN_TAG;
+}
+
+int nfnl_log_msg_test_vlan_tag(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_VLAN_TAG);
+}
+
+uint16_t nfnl_log_msg_get_vlan_tag(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_vlan_tag;
+}
+
+uint16_t nfnl_log_msg_get_vlan_id(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_vlan_tag & 0x0fff;
+}
+
+uint16_t nfnl_log_msg_get_vlan_cfi(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->log_msg_vlan_tag & 0x1000);
+}
+
+uint16_t nfnl_log_msg_get_vlan_prio(const struct nfnl_log_msg *msg)
+{
+ return (msg->log_msg_vlan_tag & 0xe000 ) >> 13;
+}
+
+void nfnl_log_msg_set_ct_info(struct nfnl_log_msg *msg, uint32_t ct_info)
+{
+ msg->log_msg_ct_info = ct_info;
+ msg->ce_mask |= LOG_MSG_ATTR_CT_INFO;
+}
+
+int nfnl_log_msg_test_ct_info(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_CT_INFO);
+}
+
+uint32_t nfnl_log_msg_get_ct_info(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_ct_info;
+}
+
+void nfnl_log_msg_set_ct(struct nfnl_log_msg *msg, struct nfnl_ct *ct)
+{
+ msg->log_msg_ct = (struct nfnl_ct *) nl_object_clone((struct nl_object *)ct);
+ msg->ce_mask |= LOG_MSG_ATTR_CT;
+}
+
+int nfnl_log_msg_test_ct(const struct nfnl_log_msg *msg)
+{
+ return !!(msg->ce_mask & LOG_MSG_ATTR_CT);
+}
+
+struct nfnl_ct *nfnl_log_msg_get_ct(const struct nfnl_log_msg *msg)
+{
+ return msg->log_msg_ct;
+}
+
/** @} */
struct nl_object_ops log_msg_obj_ops = {
diff --git a/lib/netfilter/log_obj.c b/lib/netfilter/log_obj.c
index a33ef9f..e26e5bd 100644
--- a/lib/netfilter/log_obj.c
+++ b/lib/netfilter/log_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/log_obj.c Netfilter Log Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
@@ -215,9 +208,15 @@
log->log_flag_mask |= flags;
}
+unsigned int nfnl_log_get_flags(const struct nfnl_log *log)
+{
+ return log->log_flags;
+}
+
static const struct trans_tbl log_flags[] = {
__ADD(NFNL_LOG_FLAG_SEQ, seq),
__ADD(NFNL_LOG_FLAG_SEQ_GLOBAL, seq_global),
+ __ADD(NFNL_LOG_FLAG_CONNTRACK, conntrack),
};
char *nfnl_log_flags2str(unsigned int flags, char *buf, size_t len)
diff --git a/lib/netfilter/netfilter.c b/lib/netfilter/netfilter.c
index dba435d..616c10c 100644
--- a/lib/netfilter/netfilter.c
+++ b/lib/netfilter/netfilter.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/netfilter.c Netfilter Generic Functions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/lib/netfilter/nfnl.c b/lib/netfilter/nfnl.c
index ac502fb..f18e498 100644
--- a/lib/netfilter/nfnl.c
+++ b/lib/netfilter/nfnl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/nfnl.c Netfilter Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/lib/netfilter/queue.c b/lib/netfilter/queue.c
index d20dee5..4ce3ad1 100644
--- a/lib/netfilter/queue.c
+++ b/lib/netfilter/queue.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/queue.c Netfilter Queue
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/lib/netfilter/queue_msg.c b/lib/netfilter/queue_msg.c
index 68ed71e..840b5e8 100644
--- a/lib/netfilter/queue_msg.c
+++ b/lib/netfilter/queue_msg.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/queue_msg.c Netfilter Queue Messages
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
* Copyright (c) 2010 Karl Hiramoto <karl@hiramoto.org>
*/
diff --git a/lib/netfilter/queue_msg_obj.c b/lib/netfilter/queue_msg_obj.c
index 1e89cc4..251cd90 100644
--- a/lib/netfilter/queue_msg_obj.c
+++ b/lib/netfilter/queue_msg_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/queue_msg_obj.c Netfilter Queue Message Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
@@ -49,16 +42,17 @@
struct nfnl_queue_msg *src = (struct nfnl_queue_msg *) _src;
int err;
+ dst->queue_msg_payload = NULL;
+ dst->queue_msg_payload_len = 0;
+
if (src->queue_msg_payload) {
err = nfnl_queue_msg_set_payload(dst, src->queue_msg_payload,
- src->queue_msg_payload_len);
+ src->queue_msg_payload_len);
if (err < 0)
- goto errout;
+ return err;
}
return 0;
-errout:
- return err;
}
static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p)
@@ -392,7 +386,7 @@
}
const uint8_t *nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *msg,
- int *len)
+ int *len)
{
if (!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR)) {
*len = 0;
@@ -404,19 +398,24 @@
}
int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload,
- int len)
+ int len)
{
- void *new_payload = malloc(len);
+ void *p = NULL;
- if (new_payload == NULL)
+ if (len < 0)
+ return -NLE_INVAL;
+
+ p = _nl_memdup(payload, len);
+ if (!p && len > 0)
return -NLE_NOMEM;
- memcpy(new_payload, payload, len);
free(msg->queue_msg_payload);
-
- msg->queue_msg_payload = new_payload;
+ msg->queue_msg_payload = p;
msg->queue_msg_payload_len = len;
- msg->ce_mask |= QUEUE_MSG_ATTR_PAYLOAD;
+ if (len > 0)
+ msg->ce_mask |= QUEUE_MSG_ATTR_PAYLOAD;
+ else
+ msg->ce_mask &= ~QUEUE_MSG_ATTR_PAYLOAD;
return 0;
}
diff --git a/lib/netfilter/queue_obj.c b/lib/netfilter/queue_obj.c
index 690b26e..1ea461d 100644
--- a/lib/netfilter/queue_obj.c
+++ b/lib/netfilter/queue_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/netfilter/queue_obj.c Netfilter Queue
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
diff --git a/lib/nl.c b/lib/nl.c
index bd8e331..2a2f1eb 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/nl.c Core Netlink Interface
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/object.c b/lib/object.c
index 4e14554..bef0b6f 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/object.c Generic Cacheable Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -134,6 +127,11 @@
if (size)
memcpy((char *)new + doff, (char *)obj + doff, size);
+ /* Note that the base implementation already initializes @new via memcpy().
+ * That means, simple fields don't need to be handled via oo_clone().
+ * However, this is only a shallow-copy, so oo_clone() MUST fix all
+ * pointer values accordingly. */
+
if (ops->oo_clone) {
if (ops->oo_clone(new, obj) < 0) {
nl_object_free(new);
@@ -313,38 +311,42 @@
*/
int nl_object_identical(struct nl_object *a, struct nl_object *b)
{
- struct nl_object_ops *ops = obj_ops(a);
- uint32_t req_attrs;
+ struct nl_object_ops *ops;
+ uint64_t req_attrs_a;
+ uint64_t req_attrs_b;
+
+ if (a == b)
+ return 1;
/* Both objects must be of same type */
+ ops = obj_ops(a);
if (ops != obj_ops(b))
return 0;
- if (ops->oo_id_attrs_get) {
- int req_attrs_a = ops->oo_id_attrs_get(a);
- int req_attrs_b = ops->oo_id_attrs_get(b);
- if (req_attrs_a != req_attrs_b)
- return 0;
- req_attrs = req_attrs_a;
- } else if (ops->oo_id_attrs) {
- req_attrs = ops->oo_id_attrs;
- } else {
- req_attrs = 0xFFFFFFFF;
- }
- if (req_attrs == 0xFFFFFFFF)
- req_attrs = a->ce_mask & b->ce_mask;
-
- /* Both objects must provide all required attributes to uniquely
- * identify an object */
- if ((a->ce_mask & req_attrs) != req_attrs ||
- (b->ce_mask & req_attrs) != req_attrs)
- return 0;
-
/* Can't judge unless we can compare */
if (ops->oo_compare == NULL)
return 0;
- return !(ops->oo_compare(a, b, req_attrs, ID_COMPARISON));
+ if (ops->oo_id_attrs_get) {
+ req_attrs_a = ops->oo_id_attrs_get(a);
+ req_attrs_b = ops->oo_id_attrs_get(b);
+ } else if (ops->oo_id_attrs) {
+ req_attrs_a = ops->oo_id_attrs;
+ req_attrs_b = req_attrs_a;
+ } else {
+ req_attrs_a = UINT64_MAX;
+ req_attrs_b = req_attrs_a;
+ }
+
+ req_attrs_a &= a->ce_mask;
+ req_attrs_b &= b->ce_mask;
+
+ /* Both objects must provide all required attributes to uniquely
+ * identify an object */
+ if (req_attrs_a != req_attrs_b)
+ return 0;
+
+ return !(ops->oo_compare(a, b, req_attrs_a, ID_COMPARISON));
}
/**
@@ -366,7 +368,7 @@
if (ops != obj_ops(b) || ops->oo_compare == NULL)
return UINT64_MAX;
- return ops->oo_compare(a, b, ~0, 0);
+ return ops->oo_compare(a, b, UINT64_MAX, 0);
}
/**
diff --git a/lib/route/.gitignore b/lib/route/.gitignore
deleted file mode 100644
index debf3b7..0000000
--- a/lib/route/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-pktloc_grammar.h
-pktloc_grammar.c
-pktloc_syntax.h
-pktloc_syntax.c
diff --git a/lib/route/act.c b/lib/route/act.c
index a0aff7f..f7c0a78 100644
--- a/lib/route/act.c
+++ b/lib/route/act.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/act.c Action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
@@ -17,6 +10,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink-private/utils.h>
#include <netlink-private/tc.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
@@ -125,7 +119,7 @@
while (p_act) {
err = rtnl_act_fill_one(msg, p_act, ++order);
- if (err)
+ if (err < 0)
return err;
p_act = p_act->a_next;
}
@@ -519,8 +513,13 @@
p_act = act;
while(p_act) {
err = pp->pp_cb(OBJ_CAST(act), pp);
- if (err)
+ if (err) {
+ if (err > 0) {
+ _nl_assert_not_reached();
+ err = -NLE_FAILURE;
+ }
break;
+ }
p_act = p_act->a_next;
}
errout:
diff --git a/lib/route/act/gact.c b/lib/route/act/gact.c
index e37ef9f..1a4bacb 100644
--- a/lib/route/act/gact.c
+++ b/lib/route/act/gact.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/act/gact.c gact action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Sushma Sitaram <sushma.sitaram@intel.com>
*/
@@ -50,14 +44,6 @@
{
}
-static int gact_clone(void *_dst, void *_src)
-{
- struct rtnl_gact *dst = _dst, *src = _src;
-
- memcpy(&dst->g_parm, &src->g_parm, sizeof(src->g_parm));
- return 0;
-}
-
static void gact_dump_line(struct rtnl_tc *tc, void *data,
struct nl_dump_params *p)
{
@@ -126,19 +112,7 @@
if (!(u = (struct rtnl_gact *) rtnl_tc_data(TC_CAST(act))))
return -NLE_NOMEM;
- if (action > TC_ACT_SHOT || action < TC_ACT_UNSPEC)
- return -NLE_INVAL;
-
- switch (action) {
- case TC_ACT_UNSPEC:
- case TC_ACT_SHOT:
- u->g_parm.action = action;
- break;
- case TC_ACT_OK:
- case TC_ACT_RECLASSIFY:
- default:
- return NLE_OPNOTSUPP;
- }
+ u->g_parm.action = action;
return 0;
}
@@ -161,7 +135,7 @@
.to_size = sizeof(struct rtnl_gact),
.to_msg_parser = gact_msg_parser,
.to_free_data = gact_free_data,
- .to_clone = gact_clone,
+ .to_clone = NULL,
.to_msg_fill = gact_msg_fill,
.to_dump = {
[NL_DUMP_LINE] = gact_dump_line,
diff --git a/lib/route/act/mirred.c b/lib/route/act/mirred.c
index b674fb8..01da134 100644
--- a/lib/route/act/mirred.c
+++ b/lib/route/act/mirred.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/act/mirred.c mirred action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
@@ -49,14 +43,6 @@
{
}
-static int mirred_clone(void *_dst, void *_src)
-{
- struct rtnl_mirred *dst = _dst, *src = _src;
-
- memcpy(&dst->m_parm, &src->m_parm, sizeof(src->m_parm));
- return 0;
-}
-
static void mirred_dump_line(struct rtnl_tc *tc, void *data,
struct nl_dump_params *p)
{
@@ -187,19 +173,8 @@
if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
return -NLE_NOMEM;
- if (policy > TC_ACT_REPEAT || policy < TC_ACT_OK)
- return -NLE_INVAL;
+ u->m_parm.action = policy;
- switch (u->m_parm.eaction) {
- case TCA_EGRESS_MIRROR:
- case TCA_EGRESS_REDIR:
- u->m_parm.action = policy;
- break;
- case TCA_INGRESS_REDIR:
- case TCA_INGRESS_MIRROR:
- default:
- return NLE_OPNOTSUPP;
- }
return 0;
}
@@ -220,7 +195,7 @@
.to_size = sizeof(struct rtnl_mirred),
.to_msg_parser = mirred_msg_parser,
.to_free_data = mirred_free_data,
- .to_clone = mirred_clone,
+ .to_clone = NULL,
.to_msg_fill = mirred_msg_fill,
.to_dump = {
[NL_DUMP_LINE] = mirred_dump_line,
diff --git a/lib/route/act/nat.c b/lib/route/act/nat.c
new file mode 100644
index 0000000..21c4247
--- /dev/null
+++ b/lib/route/act/nat.c
@@ -0,0 +1,288 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2016 Magnus Öberg <magnus.oberg@westermo.se>
+ */
+
+/**
+ * @ingroup act
+ * @defgroup act_nat NAT
+ *
+ * @{
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink-private/tc.h>
+#include <netlink/netlink.h>
+#include <netlink/attr.h>
+#include <netlink/utils.h>
+#include <netlink-private/route/tc-api.h>
+#include <netlink/route/act/nat.h>
+#include <netlink/route/tc.h>
+
+static struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
+ [TCA_NAT_PARMS] = { .minlen = sizeof(struct tc_nat) },
+};
+
+/**
+ * nat operations
+ */
+
+static int nat_msg_parser(struct rtnl_tc *tc, void *data)
+{
+ struct tc_nat *nat = data;
+ struct nlattr *tb[TCA_NAT_MAX + 1];
+ int err;
+
+ err = tca_parse(tb, TCA_NAT_MAX, tc, nat_policy);
+ if (err < 0)
+ return err;
+
+ if (!tb[TCA_NAT_PARMS])
+ return -NLE_MISSING_ATTR;
+
+ nla_memcpy(nat, tb[TCA_NAT_PARMS], sizeof(*nat));
+
+ return NLE_SUCCESS;
+}
+
+static void nat_free_data(struct rtnl_tc *tc, void *data)
+{
+}
+
+static int nat_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
+{
+ struct tc_nat *nat = data;
+
+ if (!nat)
+ return -NLE_OBJ_NOTFOUND;
+
+ NLA_PUT(msg, TCA_NAT_PARMS, sizeof(*nat), nat);
+
+ return NLE_SUCCESS;
+
+nla_put_failure:
+ return -NLE_NOMEM;
+}
+
+static void nat_dump_line(struct rtnl_tc *tc, void *data,
+ struct nl_dump_params *p)
+{
+ struct tc_nat *nat = data;
+ char buf[32];
+ uint32_t mask;
+ int pfx = 0;
+
+ if (!nat)
+ return;
+
+ if (nat->flags & TCA_NAT_FLAG_EGRESS)
+ nl_dump(p, " egress");
+ else
+ nl_dump(p, " ingress");
+
+ mask = nat->mask;
+ while (mask > 0) {
+ mask = mask >> 1;
+ pfx++;
+ }
+
+ inet_ntop(AF_INET, &nat->old_addr, buf, sizeof(buf));
+ nl_dump(p, " %s", buf);
+ if (pfx < 32)
+ nl_dump(p, "/%d", pfx);
+
+ inet_ntop(AF_INET, &nat->new_addr, buf, sizeof(buf));
+ nl_dump(p, " %s", buf);
+ if (pfx < 32)
+ nl_dump(p, "/%d", pfx);
+}
+
+/**
+ * @name Attribute Modifications
+ * @{
+ */
+
+/**
+ * Set old IPv4 address on a netlink NAT action object
+ * @arg act Action object
+ * @arg addr Binary IPv4 address in host byte order
+ *
+ * @return 0 on success or negative error code in case of an error.
+ */
+int rtnl_nat_set_old_addr(struct rtnl_act *act, in_addr_t addr)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
+ return -NLE_NOMEM;
+
+ nat->old_addr = addr;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_get_old_addr(struct rtnl_act *act, in_addr_t *addr)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
+ return -NLE_NOATTR;
+
+ *addr = nat->old_addr;
+
+ return NLE_SUCCESS;
+}
+
+/**
+ * Set new IPv4 address on a netlink NAT action object
+ * @arg act Action object
+ * @arg addr Binary IPv4 address in host byte order
+ *
+ * @return 0 on success or negative error code in case of an error.
+ */
+int rtnl_nat_set_new_addr(struct rtnl_act *act, in_addr_t addr)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
+ return -NLE_NOMEM;
+
+ nat->new_addr = addr;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_get_new_addr(struct rtnl_act *act, in_addr_t *addr)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
+ return -NLE_NOATTR;
+
+ *addr = nat->new_addr;
+
+ return NLE_SUCCESS;
+}
+
+/**
+ * Set IPv4 address mask on a netlink NAT action object
+ * @arg act Action object
+ * @arg mask IPv4 address mask
+ *
+ * @return 0 on success or negative error code in case of an error.
+ */
+int rtnl_nat_set_mask(struct rtnl_act *act, in_addr_t bitmask)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
+ return -NLE_NOMEM;
+
+ nat->mask = bitmask;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_get_mask(struct rtnl_act *act, in_addr_t *bitmask)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
+ return -NLE_NOATTR;
+
+ *bitmask = nat->mask;
+
+ return NLE_SUCCESS;
+}
+
+/**
+ * Set flags for a netlink NAT action object
+ * @arg act Action object
+ * @arg flags TCA_NAT_FLAG_* flags.
+ *
+ * Currently only TCA_NAT_FLAG_EGRESS is defined. Selects NAT on
+ * egress/IP src if set, ingress/IP dst otherwise.
+ *
+ * @return 0 on success or negative error code in case of an error.
+ */
+int rtnl_nat_set_flags(struct rtnl_act *act, uint32_t flags)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
+ return -NLE_NOMEM;
+
+ nat->flags = flags;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_get_flags(struct rtnl_act *act, uint32_t *flags)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
+ return -NLE_NOATTR;
+
+ *flags = nat->flags;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_set_action(struct rtnl_act *act, int action)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
+ return -NLE_NOMEM;
+
+ if (action < TC_ACT_UNSPEC)
+ return -NLE_INVAL;
+
+ nat->action = action;
+
+ return NLE_SUCCESS;
+}
+
+int rtnl_nat_get_action(struct rtnl_act *act, int *action)
+{
+ struct tc_nat *nat;
+
+ if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
+ return -NLE_NOATTR;
+
+ *action = nat->action;
+
+ return NLE_SUCCESS;
+}
+
+/**
+ * @}
+ */
+
+static struct rtnl_tc_ops nat_ops = {
+ .to_kind = "nat",
+ .to_type = RTNL_TC_TYPE_ACT,
+ .to_size = sizeof(struct tc_nat),
+ .to_msg_parser = nat_msg_parser,
+ .to_free_data = nat_free_data,
+ .to_clone = NULL,
+ .to_msg_fill = nat_msg_fill,
+ .to_dump = {
+ [NL_DUMP_LINE] = nat_dump_line,
+ },
+};
+
+static void __init nat_init(void)
+{
+ rtnl_tc_register(&nat_ops);
+}
+
+static void __exit nat_exit(void)
+{
+ rtnl_tc_unregister(&nat_ops);
+}
+
+/**
+ * @}
+ */
diff --git a/lib/route/act/skbedit.c b/lib/route/act/skbedit.c
index d85265e..24f57e5 100644
--- a/lib/route/act/skbedit.c
+++ b/lib/route/act/skbedit.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/act/skbedit.c skbedit action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cong Wang <xiyou.wangcong@gmail.com>
*/
@@ -67,14 +61,6 @@
{
}
-static int skbedit_clone(void *_dst, void *_src)
-{
- struct rtnl_skbedit *dst = _dst, *src = _src;
-
- memcpy(dst, src, sizeof(*src));
- return 0;
-}
-
static void skbedit_dump_line(struct rtnl_tc *tc, void *data,
struct nl_dump_params *p)
{
@@ -166,10 +152,8 @@
if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
return -NLE_NOMEM;
- if (action > TC_ACT_REPEAT || action < TC_ACT_UNSPEC)
- return -NLE_INVAL;
-
u->s_parm.action = action;
+
return 0;
}
@@ -268,7 +252,7 @@
.to_size = sizeof(struct rtnl_skbedit),
.to_msg_parser = skbedit_msg_parser,
.to_free_data = skbedit_free_data,
- .to_clone = skbedit_clone,
+ .to_clone = NULL,
.to_msg_fill = skbedit_msg_fill,
.to_dump = {
[NL_DUMP_LINE] = skbedit_dump_line,
diff --git a/lib/route/act/vlan.c b/lib/route/act/vlan.c
index 69b6f24..3d9fc33 100644
--- a/lib/route/act/vlan.c
+++ b/lib/route/act/vlan.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/act/vlan.c vlan action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
*/
@@ -109,14 +103,6 @@
{
}
-static int vlan_clone(void *_dst, void *_src)
-{
- struct rtnl_vlan *dst = _dst, *src = _src;
-
- memcpy(&dst->v_parm, &src->v_parm, sizeof(src->v_parm));
- return 0;
-}
-
static void vlan_dump_line(struct rtnl_tc *tc, void *data,
struct nl_dump_params *p)
{
@@ -405,7 +391,7 @@
.to_size = sizeof(struct rtnl_vlan),
.to_msg_parser = vlan_msg_parser,
.to_free_data = vlan_free_data,
- .to_clone = vlan_clone,
+ .to_clone = NULL,
.to_msg_fill = vlan_msg_fill,
.to_dump = {
[NL_DUMP_LINE] = vlan_dump_line,
diff --git a/lib/route/addr.c b/lib/route/addr.c
index f65e7e9..2873449 100644
--- a/lib/route/addr.c
+++ b/lib/route/addr.c
@@ -1,15 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/addr.c Addresses
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
- * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
- * Mediatrix Telecom, inc. <ericb@mediatrix.com>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>
+ * Copyright (c) 2003-2006 Mediatrix Telecom, inc. <ericb@mediatrix.com>
*/
/**
@@ -160,6 +153,13 @@
struct rtnl_addr *dst = nl_object_priv(_dst);
struct rtnl_addr *src = nl_object_priv(_src);
+ dst->a_peer = NULL;
+ dst->a_local = NULL;
+ dst->a_bcast = NULL;
+ dst->a_anycast = NULL;
+ dst->a_multicast = NULL;
+ dst->a_link = NULL;
+
if (src->a_link) {
nl_object_get(OBJ_CAST(src->a_link));
dst->a_link = src->a_link;
@@ -168,7 +168,7 @@
if (src->a_peer)
if (!(dst->a_peer = nl_addr_clone(src->a_peer)))
return -NLE_NOMEM;
-
+
if (src->a_local)
if (!(dst->a_local = nl_addr_clone(src->a_local)))
return -NLE_NOMEM;
@@ -1136,6 +1136,7 @@
__ADD(IFA_F_SECONDARY, secondary),
__ADD(IFA_F_NODAD, nodad),
__ADD(IFA_F_OPTIMISTIC, optimistic),
+ __ADD(IFA_F_DADFAILED, dadfailed),
__ADD(IFA_F_HOMEADDRESS, homeaddress),
__ADD(IFA_F_DEPRECATED, deprecated),
__ADD(IFA_F_TENTATIVE, tentative),
diff --git a/lib/route/class.c b/lib/route/class.c
index d164112..76cfac9 100644
--- a/lib/route/class.c
+++ b/lib/route/class.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/class.c Traffic Classes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/classid.c b/lib/route/classid.c
index 9dcf993..350962a 100644
--- a/lib/route/classid.c
+++ b/lib/route/classid.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/classid.c ClassID Management
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -415,7 +408,7 @@
fclose(fd);
- if ((err = classid_map_add(classid, name)) < 0) {
+ if (classid_map_add(classid, name) < 0) {
/*
* Error adding classid map, re-read classid file is best
* option here. It is likely to fail as well but better
diff --git a/lib/route/cls.c b/lib/route/cls.c
index fa87cd4..8583103 100644
--- a/lib/route/cls.c
+++ b/lib/route/cls.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/classifier.c Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -364,6 +357,78 @@
cache->c_iarg2 = parent;
}
+/**
+ * Search classifier by interface index, parent and handle
+ * @arg cache Classifier cache
+ * @arg ifindex Interface index
+ * @arg parent Parent
+ * @arg handle Handle
+ *
+ * Searches a classifier cache previously allocated with rtnl_cls_alloc_cache()
+ * and searches for a classifier matching the interface index, parent
+ * and handle.
+ *
+ * The reference counter is incremented before returning the classifier,
+ * therefore the reference must be given back with rtnl_cls_put() after usage.
+ *
+ * @return Classifier or NULL if no match was found.
+ */
+struct rtnl_cls *rtnl_cls_find_by_handle(struct nl_cache *cache, int ifindex, uint32_t parent,
+ uint32_t handle)
+{
+ struct rtnl_cls *cls;
+
+ if (cache->c_ops != &rtnl_cls_ops)
+ return NULL;
+
+ nl_list_for_each_entry(cls, &cache->c_items, ce_list) {
+ if ((cls->c_parent == parent) &&
+ (cls->c_ifindex == ifindex)&&
+ (cls->c_handle == handle)) {
+ nl_object_get((struct nl_object *) cls);
+ return cls;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Search classifier by interface index, parent and priority
+ * @arg cache Classifier cache
+ * @arg ifindex Interface index
+ * @arg parent Parent
+ * @arg prio Priority
+ *
+ * Searches a classifier cache previously allocated with rtnl_cls_alloc_cache()
+ * and searches for a classifier matching the interface index, parent
+ * and prio.
+ *
+ * The reference counter is incremented before returning the classifier,
+ * therefore the reference must be given back with rtnl_cls_put() after usage.
+ *
+ * @return Classifier or NULL if no match was found.
+ */
+struct rtnl_cls *rtnl_cls_find_by_prio(struct nl_cache *cache, int ifindex,
+ uint32_t parent, uint16_t prio)
+{
+ struct rtnl_cls *cls;
+
+ if (cache->c_ops != &rtnl_cls_ops)
+ return NULL;
+
+ nl_list_for_each_entry(cls, &cache->c_items, ce_list) {
+ if ((cls->c_parent == parent) &&
+ (cls->c_ifindex == ifindex) &&
+ (cls->c_prio == prio)) {
+ nl_object_get((struct nl_object *) cls);
+ return cls;
+ }
+ }
+
+ return NULL;
+}
+
/** @} */
static void cls_dump_line(struct rtnl_tc *tc, struct nl_dump_params *p)
diff --git a/lib/route/cls/.gitignore b/lib/route/cls/.gitignore
deleted file mode 100644
index 30f4521..0000000
--- a/lib/route/cls/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-ematch_syntax.[ch]
-ematch_grammar.[ch]
diff --git a/lib/route/cls/basic.c b/lib/route/cls/basic.c
index 3581c60..93bf75d 100644
--- a/lib/route/cls/basic.c
+++ b/lib/route/cls/basic.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/basic.c Basic Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -93,7 +87,7 @@
if (tb[TCA_BASIC_ACT]) {
b->b_mask |= BASIC_ATTR_ACTION;
err = rtnl_act_parse(&b->b_act, tb[TCA_BASIC_ACT]);
- if (err)
+ if (err < 0)
return err;
}
diff --git a/lib/route/cls/cgroup.c b/lib/route/cls/cgroup.c
index b145261..ff993d1 100644
--- a/lib/route/cls/cgroup.c
+++ b/lib/route/cls/cgroup.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/cgroup.c Control Groups Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2009-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -36,17 +30,14 @@
static int cgroup_clone(void *_dst, void *_src)
{
- struct rtnl_cgroup *dst = NULL, *src = _src;
+ struct rtnl_cgroup *dst = _dst, *src = _src;
- dst = calloc(1, sizeof(*dst));
- if (!dst)
- return -NLE_NOMEM;
+ dst->cg_ematch = NULL;
- dst->cg_mask = src->cg_mask;
- dst->cg_ematch = rtnl_ematch_tree_clone(src->cg_ematch);
- if (!dst) {
- free(dst);
- return -NLE_NOMEM;
+ if (src->cg_ematch) {
+ dst->cg_ematch = rtnl_ematch_tree_clone(src->cg_ematch);
+ if (!dst->cg_ematch)
+ return -NLE_NOMEM;
}
return 0;
diff --git a/lib/route/cls/ematch.c b/lib/route/cls/ematch.c
index 18f5be9..9052030 100644
--- a/lib/route/cls/ematch.c
+++ b/lib/route/cls/ematch.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch.c Extended Matches
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -699,14 +693,14 @@
if (!(tree = rtnl_ematch_tree_alloc(RTNL_EMATCH_PROGID)))
return -NLE_FAILURE;
- if ((err = ematch_lex_init(&scanner)) < 0) {
+ if (ematch_lex_init(&scanner) < 0) {
err = -NLE_FAILURE;
goto errout;
}
buf = ematch__scan_string(expr, scanner);
- if ((err = ematch_parse(scanner, errp, &tree->et_list)) != 0) {
+ if (ematch_parse(scanner, errp, &tree->et_list) != 0) {
ematch__delete_buffer(buf, scanner);
err = -NLE_PARSE_ERR;
goto errout;
diff --git a/lib/route/cls/ematch/cmp.c b/lib/route/cls/ematch/cmp.c
index 2e380c3..f575866 100644
--- a/lib/route/cls/ematch/cmp.c
+++ b/lib/route/cls/ematch/cmp.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch/cmp.c Simple packet data comparison ematch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/cls/ematch/container.c b/lib/route/cls/ematch/container.c
index 813391a..b23169b 100644
--- a/lib/route/cls/ematch/container.c
+++ b/lib/route/cls/ematch/container.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch/container.c Container Ematch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/cls/ematch/meta.c b/lib/route/cls/ematch/meta.c
index a26ed4c..3f63cde 100644
--- a/lib/route/cls/ematch/meta.c
+++ b/lib/route/cls/ematch/meta.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch/meta.c Metadata Match
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -246,9 +240,9 @@
nl_dump(p, " >> %u", v->mv_shift);
if (v->mv_len == 4)
- nl_dump(p, " & %#x", *(uint32_t *) (v + 1));
+ nl_dump(p, " & %#lx", (long unsigned) *(uint32_t *) (v + 1));
else if (v->mv_len == 8)
- nl_dump(p, " & %#x", *(uint64_t *) (v + 1));
+ nl_dump(p, " & %#llx", (long long unsigned) (*(uint64_t *) (v + 1)));
}
break;
diff --git a/lib/route/cls/ematch/nbyte.c b/lib/route/cls/ematch/nbyte.c
index 2942c0d..735dfc8 100644
--- a/lib/route/cls/ematch/nbyte.c
+++ b/lib/route/cls/ematch/nbyte.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch/nbyte.c Nbyte comparison
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/cls/ematch/text.c b/lib/route/cls/ematch/text.c
index 4dcd4f0..b524833 100644
--- a/lib/route/cls/ematch/text.c
+++ b/lib/route/cls/ematch/text.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch/text.c Text Search
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -17,6 +11,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink-private/utils.h>
#include <netlink-private/tc.h>
#include <netlink/netlink.h>
#include <netlink/route/cls/ematch.h>
@@ -91,8 +86,7 @@
{
struct text_data *t = rtnl_ematch_data(e);
- strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo));
- t->cfg.algo[sizeof(t->cfg.algo) - 1] = '\0';
+ _nl_strncpy_trunc(t->cfg.algo, algo, sizeof(t->cfg.algo));
}
char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
diff --git a/lib/route/cls/ematch_grammar.l b/lib/route/cls/ematch_grammar.l
index e97f9fe..4f57951 100644
--- a/lib/route/cls/ematch_grammar.l
+++ b/lib/route/cls/ematch_grammar.l
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch_grammar.l ematch expression grammar
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/cls/ematch_syntax.y b/lib/route/cls/ematch_syntax.y
index 82d753d..0c89603 100644
--- a/lib/route/cls/ematch_syntax.y
+++ b/lib/route/cls/ematch_syntax.y
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/ematch_syntax.y ematch expression syntax
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -52,6 +46,7 @@
%{
extern int ematch_lex(YYSTYPE *, void *);
+#define ematch_error yyerror
static void yyerror(void *scanner, char **errp, struct nl_list_head *root, const char *msg)
{
if (msg)
diff --git a/lib/route/cls/flower.c b/lib/route/cls/flower.c
new file mode 100644
index 0000000..11bd709
--- /dev/null
+++ b/lib/route/cls/flower.c
@@ -0,0 +1,896 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink-private/tc.h>
+#include <netlink/netlink.h>
+#include <netlink/attr.h>
+#include <netlink/utils.h>
+#include <netlink-private/route/tc-api.h>
+#include <netlink/route/classifier.h>
+#include <netlink/route/action.h>
+#include <netlink/route/cls/flower.h>
+
+
+/** @cond SKIP */
+#define FLOWER_ATTR_FLAGS (1 << 0)
+#define FLOWER_ATTR_ACTION (1 << 1)
+#define FLOWER_ATTR_VLAN_ID (1 << 2)
+#define FLOWER_ATTR_VLAN_PRIO (1 << 3)
+#define FLOWER_ATTR_VLAN_ETH_TYPE (1 << 4)
+#define FLOWER_ATTR_DST_MAC (1 << 5)
+#define FLOWER_ATTR_DST_MAC_MASK (1 << 6)
+#define FLOWER_ATTR_SRC_MAC (1 << 7)
+#define FLOWER_ATTR_SRC_MAC_MASK (1 << 8)
+#define FLOWER_ATTR_IP_DSCP (1 << 9)
+#define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
+#define FLOWER_ATTR_PROTO (1 << 11)
+#define FLOWER_ATTR_IPV4_SRC (1 << 12)
+#define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
+#define FLOWER_ATTR_IPV4_DST (1 << 14)
+#define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
+/** @endcond */
+
+#define FLOWER_DSCP_MAX 0xe0
+#define FLOWER_DSCP_MASK_MAX 0xe0
+#define FLOWER_VID_MAX 4095
+#define FLOWER_VLAN_PRIO_MAX 7
+
+static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
+ [TCA_FLOWER_FLAGS] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_ETH_TYPE] = { .type = NLA_U16 },
+ [TCA_FLOWER_KEY_ETH_DST] = { .maxlen = ETH_ALEN },
+ [TCA_FLOWER_KEY_ETH_DST_MASK] = { .maxlen = ETH_ALEN },
+ [TCA_FLOWER_KEY_ETH_SRC] = { .maxlen = ETH_ALEN },
+ [TCA_FLOWER_KEY_ETH_SRC_MASK] = { .maxlen = ETH_ALEN },
+ [TCA_FLOWER_KEY_VLAN_ID] = { .type = NLA_U16 },
+ [TCA_FLOWER_KEY_VLAN_PRIO] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type = NLA_U16 },
+ [TCA_FLOWER_KEY_IPV4_SRC] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_DST] = { .type = NLA_U32 },
+ [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type = NLA_U32 },
+};
+
+static int flower_msg_parser(struct rtnl_tc *tc, void *data)
+{
+ struct rtnl_flower *f = data;
+ struct nlattr *tb[TCA_FLOWER_MAX + 1];
+ int err;
+
+ err = tca_parse(tb, TCA_FLOWER_MAX, tc, flower_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_FLOWER_FLAGS]) {
+ f->cf_flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
+ f->cf_mask |= FLOWER_ATTR_FLAGS;
+ }
+
+ if (tb[TCA_FLOWER_ACT]) {
+ err = rtnl_act_parse(&f->cf_act, tb[TCA_FLOWER_ACT]);
+ if (err)
+ return err;
+
+ f->cf_mask |= FLOWER_ATTR_ACTION;
+ }
+
+ if (tb[TCA_FLOWER_KEY_ETH_TYPE]) {
+ f->cf_proto = nla_get_u16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
+ f->cf_mask |= FLOWER_ATTR_PROTO;
+ }
+
+ if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
+ f->cf_vlan_id = nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]);
+ f->cf_mask |= FLOWER_ATTR_VLAN_ID;
+ }
+
+ if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
+ f->cf_vlan_prio = nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]);
+ f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
+ }
+
+ if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
+ f->cf_vlan_ethtype = nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
+ f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
+ }
+
+ if (tb[TCA_FLOWER_KEY_ETH_DST]) {
+ nla_memcpy(f->cf_dst_mac, tb[TCA_FLOWER_KEY_ETH_DST], ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_DST_MAC;
+ }
+
+ if (tb[TCA_FLOWER_KEY_ETH_DST_MASK]) {
+ nla_memcpy(f->cf_dst_mac_mask, tb[TCA_FLOWER_KEY_ETH_DST_MASK], ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
+ }
+
+ if (tb[TCA_FLOWER_KEY_ETH_SRC]) {
+ nla_memcpy(f->cf_src_mac, tb[TCA_FLOWER_KEY_ETH_SRC], ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_SRC_MAC;
+ }
+
+ if (tb[TCA_FLOWER_KEY_ETH_SRC_MASK]) {
+ nla_memcpy(f->cf_src_mac_mask, tb[TCA_FLOWER_KEY_ETH_SRC_MASK], ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IP_TOS]) {
+ f->cf_ip_dscp = nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS]);
+ f->cf_mask |= FLOWER_ATTR_IP_DSCP;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IP_TOS_MASK]) {
+ f->cf_ip_dscp_mask = nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
+ f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
+ f->cf_ipv4_src = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
+ f->cf_ipv4_src_mask =
+ nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
+ f->cf_ipv4_dst = nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST;
+ }
+
+ if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
+ f->cf_ipv4_dst_mask =
+ nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST_MASK]);
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
+ }
+
+ return 0;
+}
+
+static int flower_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
+{
+ struct rtnl_flower *f = data;
+ int err;
+
+ if (!f)
+ return 0;
+
+ if (f->cf_mask & FLOWER_ATTR_FLAGS)
+ NLA_PUT_U32(msg, TCA_FLOWER_FLAGS, f->cf_flags);
+
+ if (f->cf_mask & FLOWER_ATTR_ACTION) {
+ err = rtnl_act_fill(msg, TCA_FLOWER_ACT, f->cf_act);
+ if (err)
+ return err;
+ }
+
+ if (f->cf_mask & FLOWER_ATTR_PROTO)
+ NLA_PUT_U16(msg, TCA_FLOWER_KEY_ETH_TYPE, f->cf_proto);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
+ NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ID, f->cf_vlan_id);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
+ NLA_PUT_U8(msg, TCA_FLOWER_KEY_VLAN_PRIO, f->cf_vlan_prio);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
+ NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE, f->cf_vlan_ethtype);
+
+ if (f->cf_mask & FLOWER_ATTR_DST_MAC)
+ NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST, ETH_ALEN, f->cf_dst_mac);
+
+ if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
+ NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST_MASK, ETH_ALEN, f->cf_dst_mac_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
+ NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC, ETH_ALEN, f->cf_src_mac);
+
+ if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
+ NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, ETH_ALEN, f->cf_src_mac_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
+ NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS, f->cf_ip_dscp);
+
+ if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
+ NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC_MASK,
+ f->cf_ipv4_src_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
+ NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST_MASK,
+ f->cf_ipv4_dst_mask);
+
+ return 0;
+
+nla_put_failure:
+ return -NLE_NOMEM;
+}
+
+static void flower_free_data(struct rtnl_tc *tc, void *data)
+{
+ struct rtnl_flower *f = data;
+
+ if (f->cf_act)
+ rtnl_act_put_all(&f->cf_act);
+}
+
+static int flower_clone(void *_dst, void *_src)
+{
+ struct rtnl_flower *dst = _dst, *src = _src;
+
+ if (src->cf_act) {
+ if (!(dst->cf_act = rtnl_act_alloc()))
+ return -NLE_NOMEM;
+
+ memcpy(dst->cf_act, src->cf_act, sizeof(struct rtnl_act));
+
+ /* action nl list next and prev pointers must be updated */
+ nl_init_list_head(&dst->cf_act->ce_list);
+
+ if ( src->cf_act->c_opts
+ && !(dst->cf_act->c_opts = nl_data_clone(src->cf_act->c_opts)))
+ return -NLE_NOMEM;
+
+ if ( src->cf_act->c_xstats
+ && !(dst->cf_act->c_xstats = nl_data_clone(src->cf_act->c_xstats)))
+ return -NLE_NOMEM;
+
+ if ( src->cf_act->c_subdata
+ && !(dst->cf_act->c_subdata = nl_data_clone(src->cf_act->c_subdata)))
+ return -NLE_NOMEM;
+
+ if (dst->cf_act->c_link) {
+ nl_object_get(OBJ_CAST(dst->cf_act->c_link));
+ }
+
+ dst->cf_act->a_next = NULL; /* Only clone first in chain */
+ }
+
+ return 0;
+}
+
+static void flower_dump_details(struct rtnl_tc *tc, void *data,
+ struct nl_dump_params *p)
+{
+ struct rtnl_flower *f = data;
+ char addr_str[INET_ADDRSTRLEN];
+ char mask_str[INET_ADDRSTRLEN];
+
+ if (!f)
+ return;
+
+ if (f->cf_mask & FLOWER_ATTR_FLAGS)
+ nl_dump(p, " flags %u", f->cf_flags);
+
+ if (f->cf_mask & FLOWER_ATTR_PROTO)
+ nl_dump(p, " protocol %u", f->cf_proto);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
+ nl_dump(p, " vlan_id %u", f->cf_vlan_id);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
+ nl_dump(p, " vlan_prio %u", f->cf_vlan_prio);
+
+ if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
+ nl_dump(p, " vlan_ethtype %u", f->cf_vlan_ethtype);
+
+ if (f->cf_mask & FLOWER_ATTR_DST_MAC)
+ nl_dump(p, " dst_mac %02x:%02x:%02x:%02x:%02x:%02x",
+ f->cf_dst_mac[0], f->cf_dst_mac[1],
+ f->cf_dst_mac[2], f->cf_dst_mac[3],
+ f->cf_dst_mac[4], f->cf_dst_mac[5]);
+
+ if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
+ nl_dump(p, " dst_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
+ f->cf_dst_mac_mask[0], f->cf_dst_mac_mask[1],
+ f->cf_dst_mac_mask[2], f->cf_dst_mac_mask[3],
+ f->cf_dst_mac_mask[4], f->cf_dst_mac_mask[5]);
+
+ if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
+ nl_dump(p, " src_mac %02x:%02x:%02x:%02x:%02x:%02x",
+ f->cf_src_mac[0], f->cf_src_mac[1],
+ f->cf_src_mac[2], f->cf_src_mac[3],
+ f->cf_src_mac[4], f->cf_src_mac[5]);
+
+ if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
+ nl_dump(p, " src_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
+ f->cf_src_mac_mask[0], f->cf_src_mac_mask[1],
+ f->cf_src_mac_mask[2], f->cf_src_mac_mask[3],
+ f->cf_src_mac_mask[4], f->cf_src_mac_mask[5]);
+
+ if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
+ nl_dump(p, " dscp %u", f->cf_ip_dscp);
+
+ if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
+ nl_dump(p, " dscp_mask %u", f->cf_ip_dscp_mask);
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
+ inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str, sizeof(addr_str));
+ inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str, sizeof(mask_str));
+ nl_dump(p, "IPv4 src %s mask %s\n", addr_str, mask_str);
+ }
+
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
+ inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str, sizeof(addr_str));
+ inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str, sizeof(mask_str));
+ nl_dump(p, "IPv4 dst %s mask %s\n", addr_str, mask_str);
+ }
+}
+
+/**
+ * @name Attribute Modification
+ * @{
+ */
+
+/**
+ * Set protocol for flower classifier
+ * @arg cls Flower classifier.
+ * @arg proto protocol (ETH_P_*)
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_proto(struct rtnl_cls *cls, uint16_t proto)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ f->cf_proto = htons(proto);
+ f->cf_mask |= FLOWER_ATTR_PROTO;
+
+ return 0;
+}
+
+/**
+ * Get protocol for flower classifier
+ * @arg cls Flower classifier.
+ * @arg proto protocol
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_proto(struct rtnl_cls *cls, uint16_t *proto)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_PROTO))
+ return -NLE_MISSING_ATTR;
+
+ *proto = ntohs(f->cf_proto);
+
+ return 0;
+}
+
+/**
+ * Set vlan id for flower classifier
+ * @arg cls Flower classifier.
+ * @arg vid vlan id
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_vlan_id(struct rtnl_cls *cls, uint16_t vid)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (vid > FLOWER_VID_MAX)
+ return -NLE_RANGE;
+
+ f->cf_vlan_id = vid;
+ f->cf_mask |= FLOWER_ATTR_VLAN_ID;
+
+ return 0;
+}
+
+/**
+ * Get vlan id for flower classifier
+ * @arg cls Flower classifier.
+ * @arg vid vlan id
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_vlan_id(struct rtnl_cls *cls, uint16_t *vid)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_VLAN_ID))
+ return -NLE_MISSING_ATTR;
+
+ *vid = f->cf_vlan_id;
+
+ return 0;
+}
+
+/**
+ * Set vlan priority for flower classifier
+ * @arg cls Flower classifier.
+ * @arg prio vlan priority
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_vlan_prio(struct rtnl_cls *cls, uint8_t prio)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (prio > FLOWER_VLAN_PRIO_MAX)
+ return -NLE_RANGE;
+
+ f->cf_vlan_prio = prio;
+ f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
+
+ return 0;
+}
+
+/**
+ * Get vlan prio for flower classifier
+ * @arg cls Flower classifier.
+ * @arg prio vlan priority
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_vlan_prio(struct rtnl_cls *cls, uint8_t *prio)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_VLAN_PRIO))
+ return -NLE_MISSING_ATTR;
+
+ *prio = f->cf_vlan_prio;
+
+ return 0;
+}
+
+/**
+ * Set vlan ethertype for flower classifier
+ * @arg cls Flower classifier.
+ * @arg ethtype vlan ethertype
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_vlan_ethtype(struct rtnl_cls *cls, uint16_t ethtype)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (!(f->cf_mask & FLOWER_ATTR_PROTO))
+ return -NLE_MISSING_ATTR;
+
+ if (f->cf_proto != htons(ETH_P_8021Q))
+ return -NLE_INVAL;
+
+ f->cf_vlan_ethtype = htons(ethtype);
+ f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
+
+ return 0;
+}
+
+/**
+ * Set destination mac address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg mac destination mac address
+ * @arg mask mask for mac address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_dst_mac(struct rtnl_cls *cls, unsigned char *mac,
+ unsigned char *mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (mac) {
+ memcpy(f->cf_dst_mac, mac, ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_DST_MAC;
+
+ if (mask) {
+ memcpy(f->cf_dst_mac_mask, mask, ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get destination mac address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg mac destination mac address
+ * @arg mask mask for mac address
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_dst_mac(struct rtnl_cls *cls, unsigned char *mac,
+ unsigned char *mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_DST_MAC))
+ return -NLE_MISSING_ATTR;
+
+ if (mac)
+ memcpy(mac, f->cf_dst_mac, ETH_ALEN);
+
+ if (mask)
+ memcpy(mask, f->cf_dst_mac_mask, ETH_ALEN);
+
+ return 0;
+}
+
+/**
+ * Set source mac address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg mac source mac address
+ * @arg mask mask for mac address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_src_mac(struct rtnl_cls *cls, unsigned char *mac,
+ unsigned char *mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (mac) {
+ memcpy(f->cf_src_mac, mac, ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_SRC_MAC;
+
+ if (mask) {
+ memcpy(f->cf_src_mac_mask, mask, ETH_ALEN);
+ f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get source mac address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg mac source mac address
+ * @arg mask mask for mac address
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_src_mac(struct rtnl_cls *cls, unsigned char *mac,
+ unsigned char *mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_SRC_MAC))
+ return -NLE_MISSING_ATTR;
+
+ if (mac)
+ memcpy(mac, f->cf_src_mac, ETH_ALEN);
+
+ if (mask)
+ memcpy(mask, f->cf_src_mac_mask, ETH_ALEN);
+
+ return 0;
+}
+
+/**
+ * Set dscp value for flower classifier
+ * @arg cls Flower classifier.
+ * @arg dscp dscp value
+ * @arg mask mask for dscp value
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_ip_dscp(struct rtnl_cls *cls, uint8_t dscp, uint8_t mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (dscp > FLOWER_DSCP_MAX)
+ return -NLE_RANGE;
+
+ if (mask > FLOWER_DSCP_MASK_MAX)
+ return -NLE_RANGE;
+
+ f->cf_ip_dscp = dscp;
+ f->cf_mask |= FLOWER_ATTR_IP_DSCP;
+
+ if (mask) {
+ f->cf_ip_dscp_mask = mask;
+ f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
+ }
+
+ return 0;
+}
+
+/**
+ * Get dscp value for flower classifier
+ * @arg cls Flower classifier.
+ * @arg dscp dscp value
+ * @arg mask mask for dscp value
+ * @return 0 on success or a negative error code.
+*/
+int rtnl_flower_get_ip_dscp(struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_IP_DSCP))
+ return -NLE_MISSING_ATTR;
+
+ *dscp = f->cf_ip_dscp;
+ *mask = f->cf_ip_dscp_mask;
+
+ return 0;
+}
+
+/**
+ * Set IPv4 source address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 source address
+ * @arg mask mask for IPv4 source address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_ipv4_src(struct rtnl_cls *cls, in_addr_t addr,
+ in_addr_t mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (addr) {
+ f->cf_ipv4_src = addr;
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
+
+ if (mask) {
+ f->cf_ipv4_src_mask = mask;
+ f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get IPv4 source address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 source address
+ * @arg mask mask for IPv4 source address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_get_ipv4_src(struct rtnl_cls *cls, in_addr_t *out_addr,
+ in_addr_t *out_mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
+ return -NLE_MISSING_ATTR;
+
+ if (out_addr)
+ *out_addr = f->cf_ipv4_src;
+
+ if (out_mask) {
+ if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
+ *out_mask = f->cf_ipv4_src_mask;
+ else
+ *out_mask = 0xffffffff;
+ }
+
+ return 0;
+}
+
+/**
+ * Set IPv4 destination address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 destination address
+ * @arg mask mask for IPv4 destination address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_ipv4_dst(struct rtnl_cls *cls, in_addr_t addr,
+ in_addr_t mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (addr) {
+ f->cf_ipv4_dst = addr;
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST;
+
+ if (mask) {
+ f->cf_ipv4_dst_mask = mask;
+ f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
+ }
+
+ return 0;
+ }
+
+ return -NLE_FAILURE;
+}
+
+/**
+ * Get IPv4 destination address for flower classifier
+ * @arg cls Flower classifier.
+ * @arg addr IPv4 destination address
+ * @arg mask mask for IPv4 destination address
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_get_ipv4_dst(struct rtnl_cls *cls, in_addr_t *out_addr,
+ in_addr_t *out_mask)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return -NLE_INVAL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
+ return -NLE_MISSING_ATTR;
+
+ if (out_addr)
+ *out_addr = f->cf_ipv4_dst;
+
+ if (out_mask) {
+ if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
+ *out_mask = f->cf_ipv4_dst_mask;
+ else
+ *out_mask = 0xffffffff;
+ }
+
+ return 0;
+}
+
+/**
+ * Append action for flower classifier
+ * @arg cls Flower classifier.
+ * @arg act action to append
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_append_action(struct rtnl_cls *cls, struct rtnl_act *act)
+{
+ struct rtnl_flower *f;
+
+ if (!act)
+ return 0;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ f->cf_mask |= FLOWER_ATTR_ACTION;
+
+ rtnl_act_get(act);
+ return rtnl_act_append(&f->cf_act, act);
+}
+
+/**
+ * Delete action from flower classifier
+ * @arg cls Flower classifier.
+ * @arg act action to delete
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
+{
+ struct rtnl_flower *f;
+ int ret;
+
+ if (!act)
+ return 0;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ if (!(f->cf_mask & FLOWER_ATTR_ACTION))
+ return -NLE_INVAL;
+
+ ret = rtnl_act_remove(&f->cf_act, act);
+ if (ret)
+ return ret;
+
+ if (!f->cf_act)
+ f->cf_mask &= ~FLOWER_ATTR_ACTION;
+ rtnl_act_put(act);
+
+ return 0;
+}
+
+/**
+ * Get action from flower classifier
+ * @arg cls Flower classifier.
+ * @return action on success or NULL on error.
+ */
+struct rtnl_act* rtnl_flower_get_action(struct rtnl_cls *cls)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data_peek(TC_CAST(cls))))
+ return NULL;
+
+ if (!(f->cf_mask & FLOWER_ATTR_ACTION))
+ return NULL;
+
+ rtnl_act_get(f->cf_act);
+
+ return f->cf_act;
+}
+
+/**
+ * Set flags for flower classifier
+ * @arg cls Flower classifier.
+ * @arg flags (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW)
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_flower_set_flags(struct rtnl_cls *cls, int flags)
+{
+ struct rtnl_flower *f;
+
+ if (!(f = rtnl_tc_data(TC_CAST(cls))))
+ return -NLE_NOMEM;
+
+ f->cf_flags = flags;
+ f->cf_mask |= FLOWER_ATTR_FLAGS;
+
+ return 0;
+}
+
+/** @} */
+
+static struct rtnl_tc_ops flower_ops = {
+ .to_kind = "flower",
+ .to_type = RTNL_TC_TYPE_CLS,
+ .to_size = sizeof(struct rtnl_flower),
+ .to_msg_parser = flower_msg_parser,
+ .to_free_data = flower_free_data,
+ .to_clone = flower_clone,
+ .to_msg_fill = flower_msg_fill,
+ .to_dump = {
+ [NL_DUMP_DETAILS] = flower_dump_details,
+ },
+};
+
+static void __init flower_init(void)
+{
+ rtnl_tc_register(&flower_ops);
+}
+
+static void __exit flower_exit(void)
+{
+ rtnl_tc_unregister(&flower_ops);
+}
diff --git a/lib/route/cls/fw.c b/lib/route/cls/fw.c
index b569d4f..2952efc 100644
--- a/lib/route/cls/fw.c
+++ b/lib/route/cls/fw.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/fw.c fw classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2006 Siemens AG Oesterreich
@@ -94,9 +88,12 @@
{
struct rtnl_fw *dst = _dst, *src = _src;
+ dst->cf_act = NULL;
+ dst->cf_police = NULL;
+
if (src->cf_act && !(dst->cf_act = nl_data_clone(src->cf_act)))
return -NLE_NOMEM;
-
+
if (src->cf_police && !(dst->cf_police = nl_data_clone(src->cf_police)))
return -NLE_NOMEM;
diff --git a/lib/route/cls/mall.c b/lib/route/cls/mall.c
index e13ee92..ded08c6 100644
--- a/lib/route/cls/mall.c
+++ b/lib/route/cls/mall.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/mall.c match-all classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2017 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
*/
@@ -108,7 +102,7 @@
mall->m_mask |= MALL_ATTR_ACTION;
err = rtnl_act_append(&mall->m_act, act);
- if (err)
+ if (err < 0)
return err;
rtnl_act_get(act);
@@ -188,7 +182,7 @@
if (tb[TCA_MATCHALL_ACT]) {
mall->m_mask |= MALL_ATTR_ACTION;
err = rtnl_act_parse(&mall->m_act, tb[TCA_MATCHALL_ACT]);
- if (err)
+ if (err < 0)
return err;
}
@@ -212,13 +206,13 @@
int err;
err = rtnl_act_fill(msg, TCA_MATCHALL_ACT, mall->m_act);
- if (err)
+ if (err < 0)
return err;
}
return 0;
- nla_put_failure:
+nla_put_failure:
return -NLE_NOMEM;
}
@@ -228,6 +222,8 @@
struct rtnl_act *next, *new;
int err;
+ dst->m_act = NULL;
+
if (src->m_act) {
if (!(dst->m_act = rtnl_act_alloc()))
return -NLE_NOMEM;
diff --git a/lib/route/cls/police.c b/lib/route/cls/police.c
index 14b5608..f7771ae 100644
--- a/lib/route/cls/police.c
+++ b/lib/route/cls/police.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/police.c Policer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c
index f06bc24..56952fb 100644
--- a/lib/route/cls/u32.c
+++ b/lib/route/cls/u32.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/cls/u32.c u32 classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2005-2006 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2005-2006 Siemens AG Oesterreich
@@ -28,6 +22,8 @@
#include <netlink/route/cls/u32.h>
#include <netlink/route/action.h>
+#include "netlink-private/utils.h"
+
/** @cond SKIP */
#define U32_ATTR_DIVISOR 0x001
#define U32_ATTR_HASH 0x002
@@ -121,7 +117,7 @@
if (tb[TCA_U32_ACT]) {
u->cu_mask |= U32_ATTR_ACTION;
err = rtnl_act_parse(&u->cu_act, tb[TCA_U32_ACT]);
- if (err)
+ if (err < 0)
return err;
}
@@ -183,27 +179,96 @@
static int u32_clone(void *_dst, void *_src)
{
struct rtnl_u32 *dst = _dst, *src = _src;
+ _nl_auto_nl_data struct nl_data *selector = NULL;
+ _nl_auto_nl_data struct nl_data *mark = NULL;
+ _nl_auto_nl_data struct nl_data *police = NULL;
+ _nl_auto_nl_data struct nl_data *pcnt = NULL;
+ _nl_auto_nl_data struct nl_data *opts = NULL;
+ _nl_auto_nl_data struct nl_data *xstats = NULL;
+ _nl_auto_nl_data struct nl_data *subdata = NULL;
+ _nl_auto_rtnl_act struct rtnl_act *act = NULL;
- if (src->cu_selector &&
- !(dst->cu_selector = nl_data_clone(src->cu_selector)))
- return -NLE_NOMEM;
+ dst->cu_pcnt = NULL;
+ dst->cu_selector = NULL;
+ dst->cu_mark = NULL;
+ dst->cu_act = NULL;
+ dst->cu_police = NULL;
- if (src->cu_mark &&
- !(dst->cu_mark = nl_data_clone(src->cu_mark)))
- return -NLE_NOMEM;
-
- if (src->cu_act) {
- if (!(dst->cu_act = rtnl_act_alloc()))
+ if (src->cu_selector) {
+ if (!(selector = nl_data_clone(src->cu_selector)))
return -NLE_NOMEM;
-
- memcpy(dst->cu_act, src->cu_act, sizeof(struct rtnl_act));
}
- if (src->cu_police && !(dst->cu_police = nl_data_clone(src->cu_police)))
- return -NLE_NOMEM;
+ if (src->cu_mark) {
+ if (!(mark = nl_data_clone(src->cu_mark)))
+ return -NLE_NOMEM;
+ }
- if (src->cu_pcnt && !(dst->cu_pcnt = nl_data_clone(src->cu_pcnt)))
- return -NLE_NOMEM;
+ if (src->cu_act) {
+ if (!(act = rtnl_act_alloc()))
+ return -NLE_NOMEM;
+
+ if (src->cu_act->c_opts) {
+ if (!(opts = nl_data_clone(src->cu_act->c_opts)))
+ return -NLE_NOMEM;
+ }
+
+ if (src->cu_act->c_xstats) {
+ if (!(xstats = nl_data_clone(src->cu_act->c_xstats)))
+ return -NLE_NOMEM;
+ }
+
+ if (src->cu_act->c_subdata) {
+ if (!(subdata = nl_data_clone(src->cu_act->c_subdata)))
+ return -NLE_NOMEM;
+ }
+ }
+
+ if (src->cu_police) {
+ if (!(police = nl_data_clone(src->cu_police)))
+ return -NLE_NOMEM;
+ }
+
+ if (src->cu_pcnt) {
+ if (!(pcnt = nl_data_clone(src->cu_pcnt)))
+ return -NLE_NOMEM;
+ }
+
+ /* we've passed the critical point and its safe to proceed */
+
+ if (selector)
+ dst->cu_selector = _nl_steal_pointer(&selector);
+
+ if (mark)
+ dst->cu_mark = _nl_steal_pointer(&mark);
+
+ if (police)
+ dst->cu_police = _nl_steal_pointer(&police);
+
+ if (pcnt)
+ dst->cu_pcnt = _nl_steal_pointer(&pcnt);
+
+ if (act) {
+ dst->cu_act = _nl_steal_pointer(&act);
+
+ /* action nl list next and prev pointers must be updated */
+ nl_init_list_head(&dst->cu_act->ce_list);
+
+ if (opts)
+ dst->cu_act->c_opts = _nl_steal_pointer(&opts);
+
+ if (xstats)
+ dst->cu_act->c_xstats = _nl_steal_pointer(&xstats);
+
+ if (subdata)
+ dst->cu_act->c_subdata = _nl_steal_pointer(&subdata);
+
+ if (dst->cu_act->c_link) {
+ nl_object_get(OBJ_CAST(dst->cu_act->c_link));
+ }
+
+ dst->cu_act->a_next = NULL; /* Only clone first in chain */
+ }
return 0;
}
@@ -278,7 +343,9 @@
if (p->dp_type == NL_DUMP_STATS &&
(u->cu_mask & U32_ATTR_PCNT)) {
struct tc_u32_pcnt *pcnt = u->cu_pcnt->d_data;
- nl_dump(p, " successful %" PRIu64, pcnt->kcnts[i]);
+
+ nl_dump(p, " successful %llu",
+ (long long unsigned)pcnt->kcnts[i]);
}
}
}
@@ -293,11 +360,6 @@
if (!u)
return;
- if (!(u->cu_mask & (U32_ATTR_SELECTOR & U32_ATTR_MARK))) {
- nl_dump(p, "no-selector no-mark\n");
- return;
- }
-
if (!(u->cu_mask & U32_ATTR_SELECTOR)) {
nl_dump(p, "no-selector");
} else {
@@ -338,9 +400,11 @@
if (u->cu_mask & U32_ATTR_PCNT) {
struct tc_u32_pcnt *pc = u->cu_pcnt->d_data;
+
nl_dump(p, "\n");
- nl_dump_line(p, " hit %8" PRIu64 " count %8" PRIu64 "\n",
- pc->rhit, pc->rcnt);
+ nl_dump_line(p, " hit %8llu count %8llu\n",
+ (long long unsigned)pc->rhit,
+ (long long unsigned)pc->rcnt);
}
}
@@ -373,7 +437,7 @@
int err;
err = rtnl_act_fill(msg, TCA_U32_ACT, u->cu_act);
- if (err)
+ if (err < 0)
return err;
}
diff --git a/lib/route/link.c b/lib/route/link.c
index df01a71..df8ea5b 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link.c Links (Interfaces)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -93,13 +86,12 @@
int family)
{
struct rtnl_link_af_ops *af_ops;
- void *data;
af_ops = rtnl_link_af_ops_lookup(family);
if (!af_ops)
return NULL;
- if (!(data = rtnl_link_af_alloc(link, af_ops))) {
+ if (!rtnl_link_af_alloc(link, af_ops)) {
rtnl_link_af_ops_put(af_ops);
return NULL;
}
@@ -223,22 +215,19 @@
static int do_foreach_af(struct rtnl_link *link,
int (*cb)(struct rtnl_link *,
- struct rtnl_link_af_ops *, void *, void *),
+ struct rtnl_link_af_ops *, void *, void *),
void *arg)
{
int i, err;
for (i = 0; i < AF_MAX; i++) {
if (link->l_af_data[i]) {
- struct rtnl_link_af_ops *ops;
+ _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *ops = NULL;
if (!(ops = rtnl_link_af_ops_lookup(i)))
BUG();
err = cb(link, ops, link->l_af_data[i], arg);
-
- rtnl_link_af_ops_put(ops);
-
if (err < 0)
return err;
}
@@ -296,6 +285,19 @@
struct rtnl_link *src = nl_object_priv(_src);
int err;
+ dst->l_addr = NULL;
+ dst->l_bcast = NULL;
+ dst->l_info_kind = NULL;
+ dst->l_info_slave_kind = NULL;
+ dst->l_info_ops = NULL;
+ memset(dst->l_af_data, 0, sizeof (dst->l_af_data));
+ dst->l_info = NULL;
+ dst->l_ifalias = NULL;
+ dst->l_af_ops = NULL;
+ dst->l_phys_port_id = NULL;
+ dst->l_phys_switch_id = NULL;
+ dst->l_vf_list = NULL;
+
if (src->l_addr)
if (!(dst->l_addr = nl_addr_clone(src->l_addr)))
return -NLE_NOMEM;
@@ -316,15 +318,24 @@
if (!(dst->l_info_slave_kind = strdup(src->l_info_slave_kind)))
return -NLE_NOMEM;
- if (src->l_info_ops && src->l_info_ops->io_clone) {
- err = src->l_info_ops->io_clone(dst, src);
- if (err < 0)
- return err;
+ if (src->l_info_ops) {
+
+ rtnl_link_info_ops_get(src->l_info_ops);
+ dst->l_info_ops = src->l_info_ops;
+
+ if (src->l_info_ops->io_clone) {
+ err = src->l_info_ops->io_clone(dst, src);
+ if (err < 0)
+ return err;
+ }
}
if ((err = do_foreach_af(src, af_clone, dst)) < 0)
return err;
+ if (src->l_af_ops)
+ dst->l_af_ops = af_lookup_and_alloc(dst, src->l_af_ops->ao_family);
+
if (src->l_phys_port_id)
if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id)))
return -NLE_NOMEM;
@@ -387,7 +398,7 @@
return -NLE_MISSING_ATTR;
nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ);
-
+ link->ce_mask |= LINK_ATTR_IFNAME;
if (tb[IFLA_STATS]) {
struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]);
@@ -580,28 +591,22 @@
static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ struct nla_policy real_link_policy[ARRAY_SIZE(rtln_link_policy)];
+ struct nla_policy *link_policy = rtln_link_policy;
+ struct rtnl_link_af_ops *af_ops_family;
struct ifinfomsg *ifi;
struct nlattr *tb[IFLA_MAX+1];
- struct rtnl_link_af_ops *af_ops = NULL;
- struct rtnl_link_af_ops *af_ops_family;
int err, family;
- struct nla_policy real_link_policy[IFLA_MAX+1];
-
- memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy));
link = rtnl_link_alloc();
- if (link == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link == NULL)
+ return -NLE_NOMEM;
link->ce_msgtype = n->nlmsg_type;
- if (!nlmsg_valid_hdr(n, sizeof(*ifi))) {
- err = -NLE_MSG_TOOSHORT;
- goto errout;
- }
+ if (!nlmsg_valid_hdr(n, sizeof(*ifi)))
+ return -NLE_MSG_TOOSHORT;
ifi = nlmsg_data(n);
link->l_family = family = ifi->ifi_family;
@@ -609,35 +614,37 @@
link->l_index = ifi->ifi_index;
link->l_flags = ifi->ifi_flags;
link->l_change = ifi->ifi_change;
- link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY |
+ link->ce_mask = (LINK_ATTR_FAMILY |
LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
- if ((af_ops_family = af_ops = af_lookup_and_alloc(link, family))) {
- if (af_ops->ao_protinfo_policy) {
+ if ((link->l_af_ops = af_lookup_and_alloc(link, family))) {
+ if (link->l_af_ops->ao_protinfo_policy) {
+ _NL_STATIC_ASSERT (sizeof(rtln_link_policy) == sizeof(real_link_policy));
+ memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy));
memcpy(&real_link_policy[IFLA_PROTINFO],
- af_ops->ao_protinfo_policy,
+ link->l_af_ops->ao_protinfo_policy,
sizeof(struct nla_policy));
+ link_policy = real_link_policy;
}
-
- link->l_af_ops = af_ops;
}
- err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, real_link_policy);
+ af_ops_family = link->l_af_ops;
+
+ err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy);
if (err < 0)
- goto errout;
+ return err;
err = rtnl_link_info_parse(link, tb);
if (err < 0)
- goto errout;
+ return err;
if (tb[IFLA_NUM_VF]) {
link->l_num_vf = nla_get_u32(tb[IFLA_NUM_VF]);
link->ce_mask |= LINK_ATTR_NUM_VF;
if (link->l_num_vf && tb[IFLA_VFINFO_LIST]) {
- if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0) {
- goto errout;
- }
+ if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0)
+ return err;
link->ce_mask |= LINK_ATTR_VF_LIST;
}
}
@@ -648,7 +655,7 @@
err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO],
link_info_policy);
if (err < 0)
- goto errout;
+ return err;
if (li[IFLA_INFO_KIND]) {
struct rtnl_link_info_ops *ops;
@@ -657,18 +664,19 @@
err = rtnl_link_set_type(link, kind);
if (err < 0)
- goto errout;
+ return err;
- if ((af = nl_str2af(kind)) >= 0 &&
- !af_ops && (af_ops = af_lookup_and_alloc(link, af))) {
-
- if (af_ops->ao_protinfo_policy) {
- tb[IFLA_PROTINFO] = (struct nlattr *)af_ops->ao_protinfo_policy;
- }
+ if ( (af = nl_str2af(kind)) >= 0
+ && !link->l_af_ops
+ && (link->l_af_ops = af_lookup_and_alloc(link, af))) {
link->l_family = af;
- link->l_af_ops = af_ops;
+ if (link->l_af_ops->ao_protinfo_policy)
+ tb[IFLA_PROTINFO] = (struct nlattr *)link->l_af_ops->ao_protinfo_policy;
}
+ if (link->l_info_ops)
+ release_link_info(link);
+
ops = rtnl_link_info_ops_lookup(kind);
link->l_info_ops = ops;
@@ -678,7 +686,7 @@
err = ops->io_parse(link, li[IFLA_INFO_DATA],
li[IFLA_INFO_XSTATS]);
if (err < 0)
- goto errout;
+ return err;
} else {
/* XXX: Warn about unparsed info? */
}
@@ -692,17 +700,19 @@
err = rtnl_link_set_slave_type(link, kind);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
}
}
- if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
- err = af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
- link->l_af_data[link->l_family]);
+ if ( tb[IFLA_PROTINFO]
+ && link->l_af_ops
+ && link->l_af_ops->ao_parse_protinfo) {
+ err = link->l_af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
+ link->l_af_data[link->l_family]);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_PROTINFO;
}
@@ -710,25 +720,28 @@
/* parsing of IFLA_AF_SPEC is dependent on the family used
* in the request message.
*/
- if (af_ops_family && af_ops_family->ao_parse_af_full) {
+ if ( af_ops_family
+ && af_ops_family->ao_parse_af_full) {
err = af_ops_family->ao_parse_af_full(link,
tb[IFLA_AF_SPEC],
link->l_af_data[af_ops_family->ao_family]);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_AF_SPEC;
} else if (family == AF_UNSPEC) {
struct nlattr *af_attr;
int remaining;
nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC], remaining) {
+ _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *af_ops = NULL;
+
af_ops = af_lookup_and_alloc(link, nla_type(af_attr));
if (af_ops && af_ops->ao_parse_af) {
char *af_data = link->l_af_data[nla_type(af_attr)];
err = af_ops->ao_parse_af(link, af_attr, af_data);
if (err < 0)
- goto errout;
+ return err;
}
}
link->ce_mask |= LINK_ATTR_AF_SPEC;
@@ -770,10 +783,8 @@
if (tb[IFLA_PHYS_PORT_ID]) {
link->l_phys_port_id = nl_data_alloc_attr(tb[IFLA_PHYS_PORT_ID]);
- if (link->l_phys_port_id == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link->l_phys_port_id == NULL)
+ return -NLE_NOMEM;
link->ce_mask |= LINK_ATTR_PHYS_PORT_ID;
}
@@ -784,26 +795,20 @@
if (tb[IFLA_PHYS_SWITCH_ID]) {
link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]);
- if (link->l_phys_switch_id == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link->l_phys_switch_id == NULL)
+ return -NLE_NOMEM;
link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID;
}
- err = pp->pp_cb((struct nl_object *) link, pp);
-errout:
- rtnl_link_af_ops_put(af_ops);
- rtnl_link_put(link);
- return err;
+ return pp->pp_cb((struct nl_object *) link, pp);
}
static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
{
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int family = cache->c_iarg1;
struct ifinfomsg hdr = { .ifi_family = family };
struct rtnl_link_af_ops *ops;
- struct nl_msg *msg;
int err;
__u32 ext_filter_mask = RTEXT_FILTER_VF;
@@ -811,30 +816,27 @@
if (!msg)
return -NLE_NOMEM;
- err = -NLE_MSGSIZE;
if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
- goto nla_put_failure;
+ return -NLE_MSGSIZE;
ops = rtnl_link_af_ops_lookup(family);
if (ops && ops->ao_get_af) {
err = ops->ao_get_af(msg, &ext_filter_mask);
- if (err)
- goto nla_put_failure;
+ if (err < 0)
+ return err;
}
if (ext_filter_mask) {
err = nla_put(msg, IFLA_EXT_MASK, sizeof(ext_filter_mask), &ext_filter_mask);
- if (err)
- goto nla_put_failure;
+ if (err < 0)
+ return err;
}
err = nl_send_auto(sk, msg);
- if (err > 0)
- err = 0;
+ if (err < 0)
+ return 0;
-nla_put_failure:
- nlmsg_free(msg);
- return err;
+ return 0;
}
static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
@@ -860,10 +862,9 @@
if (link->ce_mask & LINK_ATTR_MASTER) {
if (cache) {
- struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
+ _nl_auto_rtnl_link struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
+
nl_dump(p, "master %s ", master ? master->l_name : "inv");
- if (master)
- rtnl_link_put(master);
} else
nl_dump(p, "master %d ", link->l_master);
}
@@ -875,10 +876,9 @@
if (link->ce_mask & LINK_ATTR_LINK) {
if ( cache
&& !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) {
- struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
+ _nl_auto_rtnl_link struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
+
nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE");
- if (ll)
- rtnl_link_put(ll);
} else
nl_dump(p, "slave-of %d ", link->l_link);
}
@@ -1369,10 +1369,9 @@
int rtnl_link_build_get_request(int ifindex, const char *name,
struct nl_msg **result)
{
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct ifinfomsg ifi;
- struct nl_msg *msg;
__u32 vf_mask = RTEXT_FILTER_VF;
- int err = -NLE_MSGSIZE;
if (ifindex <= 0 && !name) {
APPBUG("ifindex or name must be specified");
@@ -1387,24 +1386,15 @@
if (ifindex > 0)
ifi.ifi_index = ifindex;
- if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) {
- err = -NLE_MSGSIZE;
- goto nla_put_failure;
- }
+ _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
if (name)
- NLA_PUT_STRING(msg, IFLA_IFNAME, name);
+ _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, name));
- err = nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask);
- if (err)
- goto nla_put_failure;
+ _NL_RETURN_ON_PUT_ERR(nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask));
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
-
-nla_put_failure:
- nlmsg_free(msg);
- return err;
}
/**
@@ -1431,8 +1421,8 @@
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
struct rtnl_link **result)
{
- struct nl_msg *msg = NULL;
- struct nl_object *obj;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int err;
int syserr;
@@ -1440,14 +1430,15 @@
return err;
err = nl_send_auto(sk, msg);
- nlmsg_free(msg);
if (err < 0)
return err;
- if ((err = nl_pickup_keep_syserr(sk, link_msg_parser, &obj, &syserr)) < 0) {
- if (syserr == -EINVAL &&
- ifindex <= 0 &&
- name && *name) {
+ err = nl_pickup_keep_syserr(sk, link_msg_parser, (struct nl_object **) &link, &syserr);
+ if (err < 0) {
+ if ( syserr == -EINVAL
+ && ifindex <= 0
+ && name
+ && *name) {
/* Older kernels do not support lookup by ifname. This was added
* by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f .
* Detect this error case and return NLE_OPNOTSUPP instead of
@@ -1457,13 +1448,11 @@
return err;
}
- /* We have used link_msg_parser(), object is definitely a link */
- *result = (struct rtnl_link *) obj;
-
/* If an object has been returned, we also need to wait for the ACK */
- if (err == 0 && obj)
+ if (err == 0 && link)
wait_for_ack(sk);
+ *result = _nl_steal_pointer(&link);
return 0;
}
@@ -1484,11 +1473,11 @@
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
size_t len)
{
- struct rtnl_link *link = rtnl_link_get(cache, ifindex);
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ link = rtnl_link_get(cache, ifindex);
if (link) {
- strncpy(dst, link->l_name, len - 1);
- rtnl_link_put(link);
+ _nl_strncpy_trunc(dst, link->l_name, len);
return dst;
}
@@ -1506,16 +1495,13 @@
*/
int rtnl_link_name2i(struct nl_cache *cache, const char *name)
{
- int ifindex = 0;
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
link = rtnl_link_get_by_name(cache, name);
- if (link) {
- ifindex = link->l_index;
- rtnl_link_put(link);
- }
+ if (link)
+ return link->l_index;
- return ifindex;
+ return 0;
}
/** @} */
@@ -1582,7 +1568,7 @@
static int build_link_msg(int cmd, struct ifinfomsg *hdr,
struct rtnl_link *link, int flags, struct nl_msg **result)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct nlattr *af_spec;
msg = nlmsg_alloc_simple(cmd, flags);
@@ -1637,11 +1623,10 @@
nla_nest_end(msg, af_spec);
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
nla_put_failure:
- nlmsg_free(msg);
return -NLE_MSGSIZE;
}
@@ -1759,12 +1744,9 @@
rt = af_request_type(orig->l_family, changes);
if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
- goto errout;
+ return err;
return 0;
-
-errout:
- return err;
}
/**
@@ -1805,7 +1787,7 @@
int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
struct rtnl_link *changes, int flags)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int err;
err = rtnl_link_build_change_request(orig, changes, flags, &msg);
@@ -1816,18 +1798,20 @@
retry:
err = nl_send_auto_complete(sk, msg);
if (err < 0)
- goto errout;
+ return err;
err = wait_for_ack(sk);
- if (err == -NLE_OPNOTSUPP && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
+ if ( err == -NLE_OPNOTSUPP
+ && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
msg->nm_nlh->nlmsg_type = RTM_SETLINK;
msg->nm_nlh->nlmsg_seq = NL_AUTO_SEQ;
goto retry;
}
-errout:
- nlmsg_free(msg);
- return err;
+ if (err < 0)
+ return err;
+
+ return 0;
}
/** @} */
@@ -1853,7 +1837,7 @@
int rtnl_link_build_delete_request(const struct rtnl_link *link,
struct nl_msg **result)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct ifinfomsg ifi = {
.ifi_index = link->l_index,
};
@@ -1866,18 +1850,13 @@
if (!(msg = nlmsg_alloc_simple(RTM_DELLINK, 0)))
return -NLE_NOMEM;
- if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
- goto nla_put_failure;
+ _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
if (link->ce_mask & LINK_ATTR_IFNAME)
- NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name);
+ _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, link->l_name));
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
-
-nla_put_failure:
- nlmsg_free(msg);
- return -NLE_MSGSIZE;
}
/**
@@ -1958,7 +1937,7 @@
*/
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
{
- strncpy(link->l_name, name, sizeof(link->l_name) - 1);
+ _nl_strncpy_trunc(link->l_name, name, sizeof(link->l_name));
link->ce_mask |= LINK_ATTR_IFNAME;
}
@@ -2125,9 +2104,10 @@
link->ce_mask |= LINK_ATTR_FAMILY;
if (link->l_af_ops) {
- af_free(link, link->l_af_ops,
- link->l_af_data[link->l_af_ops->ao_family], NULL);
- link->l_af_data[link->l_af_ops->ao_family] = NULL;
+ int ao_family = link->l_af_ops->ao_family;
+
+ af_free(link, link->l_af_ops, link->l_af_data[ao_family], NULL);
+ link->l_af_data[ao_family] = NULL;
}
link->l_af_ops = af_lookup_and_alloc(link, family);
@@ -2482,7 +2462,7 @@
*/
void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name)
{
- strncpy(link->l_qdisc, name, sizeof(link->l_qdisc) - 1);
+ _nl_strncpy_trunc(link->l_qdisc, name, sizeof(link->l_qdisc));
link->ce_mask |= LINK_ATTR_QDISC;
}
@@ -2568,8 +2548,8 @@
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
{
struct rtnl_link_info_ops *io;
+ _nl_auto_free char *kind = NULL;
int err;
- char *kind;
free(link->l_info_kind);
link->ce_mask &= ~LINK_ATTR_LINKINFO;
@@ -2584,20 +2564,18 @@
io = rtnl_link_info_ops_lookup(type);
if (io) {
- if (io->io_alloc && (err = io->io_alloc(link)) < 0)
- goto errout;
+ if (io->io_alloc && (err = io->io_alloc(link)) < 0) {
+ _nl_clear_free(&kind);
+ return err;
+ }
link->l_info_ops = io;
}
- link->l_info_kind = kind;
+ link->l_info_kind = _nl_steal_pointer(&kind);
link->ce_mask |= LINK_ATTR_LINKINFO;
return 0;
-
-errout:
- free(kind);
- return err;
}
/**
@@ -2857,7 +2835,7 @@
*/
int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
{
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
int err;
if (!(link = rtnl_link_alloc()))
@@ -2867,12 +2845,12 @@
rtnl_link_set_master(link, master);
if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
- goto errout;
+ return err;
- rtnl_link_put(link);
+ _nl_clear_pointer(&link, rtnl_link_put);
/*
- * Due to the kernel not signaling whether this opertion is
+ * Due to the kernel not signaling whether this operation is
* supported or not, we will retrieve the attribute to see if the
* request was successful. If the master assigned remains unchanged
* we will return NLE_OPNOTSUPP to allow performing backwards
@@ -2882,12 +2860,9 @@
return err;
if (rtnl_link_get_master(link) != master)
- err = -NLE_OPNOTSUPP;
+ return -NLE_OPNOTSUPP;
-errout:
- rtnl_link_put(link);
-
- return err;
+ return 0;
}
/**
@@ -3063,6 +3038,7 @@
__ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts),
__ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts),
__ADD(RTNL_LINK_RX_NOHANDLER, rx_nohandler),
+ __ADD(RTNL_LINK_REASM_OVERLAPS, ReasmOverlaps),
};
char *rtnl_link_stat2str(int st, char *buf, size_t len)
@@ -3135,22 +3111,16 @@
return 0;
}
-void rtnl_link_set_vf_list(struct rtnl_link *link) {
- int err;
-
- if (!(err = rtnl_link_has_vf_list(link)))
+void rtnl_link_set_vf_list(struct rtnl_link *link)
+{
+ if (!rtnl_link_has_vf_list(link))
link->ce_mask |= LINK_ATTR_VF_LIST;
-
- return;
}
-void rtnl_link_unset_vf_list(struct rtnl_link *link) {
- int err;
-
- if ((err = rtnl_link_has_vf_list(link)))
+void rtnl_link_unset_vf_list(struct rtnl_link *link)
+{
+ if (rtnl_link_has_vf_list(link))
link->ce_mask &= ~LINK_ATTR_VF_LIST;
-
- return;
}
/** @} */
@@ -3213,6 +3183,7 @@
static struct nl_af_group link_groups[] = {
{ AF_UNSPEC, RTNLGRP_LINK },
{ AF_BRIDGE, RTNLGRP_LINK },
+ { AF_INET6, RTNLGRP_IPV6_IFINFO },
{ END_OF_GROUP_LIST },
};
diff --git a/lib/route/link/api.c b/lib/route/link/api.c
index d406783..cd2c42b 100644
--- a/lib/route/link/api.c
+++ b/lib/route/link/api.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/api.c Link Info API
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -87,13 +81,32 @@
}
/**
+ * Take reference to a set of operations.
+ * @arg ops Link info operations.
+ */
+void rtnl_link_info_ops_get(struct rtnl_link_info_ops *ops)
+{
+ if (!ops)
+ return;
+
+ nl_write_lock(&info_lock);
+ ops->io_refcnt++;
+ nl_write_unlock(&info_lock);
+}
+
+/**
* Give back reference to a set of operations.
* @arg ops Link info operations.
*/
void rtnl_link_info_ops_put(struct rtnl_link_info_ops *ops)
{
- if (ops)
- ops->io_refcnt--;
+ if (!ops)
+ return;
+
+ nl_write_lock(&info_lock);
+ _nl_assert(ops->io_refcnt > 0);
+ ops->io_refcnt--;
+ nl_write_unlock(&info_lock);
}
/**
@@ -152,6 +165,7 @@
nl_list_for_each_entry(t, &info_ops, io_list) {
if (t == ops) {
+ _nl_assert(t->io_refcnt >= 0);
if (t->io_refcnt > 0) {
err = -NLE_BUSY;
goto errout;
@@ -208,8 +222,11 @@
*/
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops)
{
- if (ops)
+ if (ops) {
+ nl_write_lock(&info_lock);
ops->ao_refcnt--;
+ nl_write_unlock(&info_lock);
+ }
}
/**
diff --git a/lib/route/link/bonding.c b/lib/route/link/bonding.c
index 11b6d3d..90e6470 100644
--- a/lib/route/link/bonding.c
+++ b/lib/route/link/bonding.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/bonding.c Bonding Link Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -33,12 +27,11 @@
struct rtnl_link *rtnl_link_bond_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "bond")) < 0) {
+ if (rtnl_link_set_type(link, "bond") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/bridge.c b/lib/route/link/bridge.c
index 2d95faf..bd04253 100644
--- a/lib/route/link/bridge.c
+++ b/lib/route/link/bridge.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/bridge.c AF_BRIDGE link support
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -464,12 +458,11 @@
struct rtnl_link *rtnl_link_bridge_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "bridge")) < 0) {
+ if (rtnl_link_set_type(link, "bridge") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/can.c b/lib/route/link/can.c
index 884121f..da8f092 100644
--- a/lib/route/link/can.c
+++ b/lib/route/link/can.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/can.c CAN Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Benedikt Spranger <b.spranger@linutronix.de>
*/
@@ -42,6 +36,8 @@
#define CAN_HAS_RESTART_MS (1<<5)
#define CAN_HAS_RESTART (1<<6)
#define CAN_HAS_BERR_COUNTER (1<<7)
+#define CAN_HAS_DATA_BITTIMING (1<<8)
+#define CAN_HAS_DATA_BITTIMING_CONST (1<<9)
struct can_info {
uint32_t ci_state;
@@ -53,6 +49,8 @@
struct can_clock ci_clock;
struct can_berr_counter ci_berr_counter;
uint32_t ci_mask;
+ struct can_bittiming ci_data_bittiming;
+ struct can_bittiming_const ci_data_bittiming_const;
};
/** @endcond */
@@ -67,6 +65,10 @@
= { .minlen = sizeof(struct can_bittiming_const) },
[IFLA_CAN_CLOCK] = { .minlen = sizeof(struct can_clock) },
[IFLA_CAN_BERR_COUNTER] = { .minlen = sizeof(struct can_berr_counter) },
+ [IFLA_CAN_DATA_BITTIMING]
+ = { .minlen = sizeof(struct can_bittiming) },
+ [IFLA_CAN_DATA_BITTIMING_CONST]
+ = { .minlen = sizeof(struct can_bittiming_const) },
};
static int can_alloc(struct rtnl_link *link)
@@ -149,6 +151,18 @@
ci->ci_mask |= CAN_HAS_BERR_COUNTER;
}
+ if (tb[IFLA_CAN_DATA_BITTIMING]) {
+ nla_memcpy(&ci->ci_data_bittiming, tb[IFLA_CAN_DATA_BITTIMING],
+ sizeof(ci->ci_data_bittiming));
+ ci->ci_mask |= CAN_HAS_DATA_BITTIMING;
+ }
+
+ if (tb[IFLA_CAN_DATA_BITTIMING_CONST]) {
+ nla_memcpy(&ci->ci_data_bittiming_const, tb[IFLA_CAN_DATA_BITTIMING_CONST],
+ sizeof(ci->ci_data_bittiming_const));
+ ci->ci_mask |= CAN_HAS_DATA_BITTIMING_CONST;
+ }
+
err = 0;
errout:
return err;
@@ -259,7 +273,7 @@
}
if (ci->ci_mask & CAN_HAS_CLOCK) {
- nl_dump_line(p," base freq %d Hz\n", ci->ci_clock);
+ nl_dump_line(p," base freq %u Hz\n", ci->ci_clock.freq);
}
@@ -303,28 +317,36 @@
return -NLE_MSGSIZE;
if (ci->ci_mask & CAN_HAS_RESTART)
- NLA_PUT_U32(msg, CAN_HAS_RESTART, ci->ci_restart);
+ NLA_PUT_U32(msg, IFLA_CAN_RESTART, ci->ci_restart);
if (ci->ci_mask & CAN_HAS_RESTART_MS)
- NLA_PUT_U32(msg, CAN_HAS_RESTART_MS, ci->ci_restart_ms);
+ NLA_PUT_U32(msg, IFLA_CAN_RESTART_MS, ci->ci_restart_ms);
if (ci->ci_mask & CAN_HAS_CTRLMODE)
- NLA_PUT(msg, CAN_HAS_CTRLMODE, sizeof(ci->ci_ctrlmode),
+ NLA_PUT(msg, IFLA_CAN_CTRLMODE, sizeof(ci->ci_ctrlmode),
&ci->ci_ctrlmode);
if (ci->ci_mask & CAN_HAS_BITTIMING)
- NLA_PUT(msg, CAN_HAS_BITTIMING, sizeof(ci->ci_bittiming),
+ NLA_PUT(msg, IFLA_CAN_BITTIMING, sizeof(ci->ci_bittiming),
&ci->ci_bittiming);
if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
- NLA_PUT(msg, CAN_HAS_BITTIMING_CONST,
+ NLA_PUT(msg, IFLA_CAN_BITTIMING_CONST,
sizeof(ci->ci_bittiming_const),
&ci->ci_bittiming_const);
if (ci->ci_mask & CAN_HAS_CLOCK)
- NLA_PUT(msg, CAN_HAS_CLOCK, sizeof(ci->ci_clock),
+ NLA_PUT(msg, IFLA_CAN_CLOCK, sizeof(ci->ci_clock),
&ci->ci_clock);
+ if (ci->ci_mask & CAN_HAS_DATA_BITTIMING)
+ NLA_PUT(msg, IFLA_CAN_DATA_BITTIMING, sizeof(ci->ci_data_bittiming),
+ &ci->ci_data_bittiming);
+
+ if (ci->ci_mask & CAN_HAS_DATA_BITTIMING_CONST)
+ NLA_PUT(msg, IFLA_CAN_DATA_BITTIMING_CONST, sizeof(ci->ci_data_bittiming_const),
+ &ci->ci_data_bittiming_const);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -489,7 +511,7 @@
}
/**
- * Get CAN harware-dependent bit-timing constant
+ * Get CAN hardware-dependent bit-timing constant
* @arg link Link object
* @arg bt_const Bit-timing constant
*
@@ -544,7 +566,7 @@
* @return 0 on success or a negative error code
*/
int rtnl_link_can_set_bittiming(struct rtnl_link *link,
- struct can_bittiming *bit_timing)
+ const struct can_bittiming *bit_timing)
{
struct can_info *ci = link->l_info;
@@ -747,6 +769,98 @@
return 0;
}
+/**
+ * Get CAN FD hardware-dependent data bit-timing constant
+ * @arg link Link object
+ * @arg data_bt_const CAN FD data bit-timing constant
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_data_bittiming_const(struct rtnl_link *link,
+ struct can_bittiming_const *data_bt_const)
+{
+ struct can_info *ci = link->l_info;
+
+ IS_CAN_LINK_ASSERT(link);
+ if (!data_bt_const)
+ return -NLE_INVAL;
+
+ if (ci->ci_mask & CAN_HAS_DATA_BITTIMING_CONST)
+ *data_bt_const = ci->ci_data_bittiming_const;
+ else
+ return -NLE_AGAIN;
+
+ return 0;
+}
+
+/**
+ * Set CAN FD device data bit-timing-const
+ * @arg link Link object
+ * @arg data_bit_timing CAN FD data bit-timing
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_data_bittiming_const(struct rtnl_link *link,
+ const struct can_bittiming_const *data_bt_const)
+{
+ struct can_info *ci = link->l_info;
+
+ IS_CAN_LINK_ASSERT(link);
+ if (!data_bt_const)
+ return -NLE_INVAL;
+
+ ci->ci_data_bittiming_const = *data_bt_const;
+ ci->ci_mask |= CAN_HAS_DATA_BITTIMING_CONST;
+
+ return 0;
+}
+
+/**
+ * Get CAN FD device data bit-timing
+ * @arg link Link object
+ * @arg data_bit_timing CAN FD data bit-timing
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_data_bittiming(struct rtnl_link *link,
+ struct can_bittiming *data_bit_timing)
+{
+ struct can_info *ci = link->l_info;
+
+ IS_CAN_LINK_ASSERT(link);
+ if (!data_bit_timing)
+ return -NLE_INVAL;
+
+ if (ci->ci_mask & CAN_HAS_DATA_BITTIMING)
+ *data_bit_timing = ci->ci_data_bittiming;
+ else
+ return -NLE_AGAIN;
+
+ return 0;
+}
+
+/**
+ * Set CAN FD device data bit-timing
+ * @arg link Link object
+ * @arg data_bit_timing CAN FD data bit-timing
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_data_bittiming(struct rtnl_link *link,
+ const struct can_bittiming *data_bit_timing)
+{
+ struct can_info *ci = link->l_info;
+
+ IS_CAN_LINK_ASSERT(link);
+ if (!data_bit_timing)
+ return -NLE_INVAL;
+
+ ci->ci_data_bittiming = *data_bit_timing;
+ ci->ci_mask |= CAN_HAS_DATA_BITTIMING;
+
+ return 0;
+}
+
/** @} */
/**
@@ -760,6 +874,9 @@
__ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling),
__ADD(CAN_CTRLMODE_ONE_SHOT, one-shot),
__ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting),
+ __ADD(CAN_CTRLMODE_FD, fd),
+ __ADD(CAN_CTRLMODE_PRESUME_ACK, presume-ack),
+ __ADD(CAN_CTRLMODE_FD_NON_ISO, fd-non-iso),
};
char *rtnl_link_can_ctrlmode2str(int ctrlmode, char *buf, size_t len)
diff --git a/lib/route/link/dummy.c b/lib/route/link/dummy.c
index 1fd9f5a..a6478d0 100644
--- a/lib/route/link/dummy.c
+++ b/lib/route/link/dummy.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/dummy.c Dummy Interfaces
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/link/geneve.c b/lib/route/link/geneve.c
index 7232b07..cab57cc 100644
--- a/lib/route/link/geneve.c
+++ b/lib/route/link/geneve.c
@@ -1,12 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/geneve.c Geneve Link Info
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Wang Jian <jianjian.wang1@gmail.com>
*/
+
/**
* @ingroup link
* @defgroup geneve Geneve
@@ -190,16 +186,12 @@
if (geneve->mask & GENEVE_ATTR_REMOTE) {
nl_dump(p, " remote ");
- if (inet_ntop(AF_INET, &geneve->remote, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", ntohs(geneve->remote));
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET, &geneve->remote, addr));
} else if (geneve->mask & GENEVE_ATTR_REMOTE6) {
nl_dump(p, " remote ");
- if (inet_ntop(AF_INET6, &geneve->remote6, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", geneve->remote6);
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &geneve->remote6, addr));
}
if (geneve->mask & GENEVE_ATTR_TTL) {
@@ -240,7 +232,7 @@
if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX) {
nl_dump(p, " udp-zero-csum6-rx ");
- if (geneve->udp_zero_csum6_tx)
+ if (geneve->udp_zero_csum6_rx)
nl_dump_line(p, "enabled (%#x)\n", geneve->udp_zero_csum6_rx);
else
nl_dump_line(p, "disabled\n");
@@ -356,12 +348,11 @@
struct rtnl_link *rtnl_link_geneve_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "geneve")) < 0) {
+ if (rtnl_link_set_type(link, "geneve") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/ifb.c b/lib/route/link/ifb.c
index 524f5c6..528647e 100644
--- a/lib/route/link/ifb.c
+++ b/lib/route/link/ifb.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ifb.c IFB Interfaces
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index 6651bc3..2f95fb6 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/inet.c AF_INET link operations
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index f02792c..afcbbce 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/inet6.c AF_INET6 link operations
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -16,6 +10,7 @@
#include <netlink/route/link/inet6.h>
#include <netlink-private/route/link/api.h>
+#include "netlink-private/route/utils.h"
#include "netlink-private/utils.h"
#define I6_ADDR_GEN_MODE_UNKNOWN UINT8_MAX
@@ -141,8 +136,11 @@
[33] = RTNL_LINK_IP6_ECT1PKTS, /* IPSTATS_MIB_ECT1PKTS */
[34] = RTNL_LINK_IP6_ECT0PKTS, /* IPSTATS_MIB_ECT0PKTS */
[35] = RTNL_LINK_IP6_CEPKTS, /* IPSTATS_MIB_CEPKTS */
+ [36] = RTNL_LINK_REASM_OVERLAPS, /* IPSTATS_MIB_REASM_OVERLAPS */
};
+const uint8_t *const _nltst_map_stat_id_from_IPSTATS_MIB_v2 = map_stat_id_from_IPSTATS_MIB_v2;
+
static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
void *data)
{
@@ -212,6 +210,9 @@
int i;
int len = min_t(int, __ICMP6_MIB_MAX, nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8);
+ _NL_STATIC_ASSERT (__ICMP6_MIB_MAX == 6);
+ _NL_STATIC_ASSERT (RTNL_LINK_ICMP6_CSUMERRORS - RTNL_LINK_ICMP6_INMSGS + 1 == 5);
+
for (i = 1; i < len; i++) {
memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1,
@@ -412,7 +413,7 @@
if (octets)
nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B ", 0);
+ nl_dump(p, "%16u B ", 0);
nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n",
link->l_stats[RTNL_LINK_IP6_INDISCARDS],
@@ -428,7 +429,7 @@
if (octets)
nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B ", 0);
+ nl_dump(p, "%16u B ", 0);
nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n",
link->l_stats[RTNL_LINK_IP6_OUTDISCARDS],
@@ -444,7 +445,7 @@
if (octets)
nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B ", 0);
+ nl_dump(p, "%16u B ", 0);
nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INBCASTPKTS]);
octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INBCASTOCTETS],
@@ -452,7 +453,7 @@
if (octets)
nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B\n", 0);
+ nl_dump(p, "%16u B\n", 0);
nl_dump(p, " OutMcastPkts OutMcastOctets "
" OutBcastPkts OutBcastOctests\n");
@@ -464,7 +465,7 @@
if (octets)
nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B ", 0);
+ nl_dump(p, "%16u B ", 0);
nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTBCASTPKTS]);
octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTBCASTOCTETS],
@@ -472,7 +473,7 @@
if (octets)
nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
else
- nl_dump(p, "%16" PRIu64 " B\n", 0);
+ nl_dump(p, "%16u B\n", 0);
nl_dump(p, " ReasmOKs ReasmFails "
" ReasmReqds ReasmTimeout\n");
diff --git a/lib/route/link/ip6gre.c b/lib/route/link/ip6gre.c
new file mode 100644
index 0000000..5d5c3a0
--- /dev/null
+++ b/lib/route/link/ip6gre.c
@@ -0,0 +1,886 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/**
+ * @ingroup link
+ * @defgroup ip6gre IP6GRE
+ * ip6gre link module
+ *
+ * @details
+ * \b Link Type Name: "ip6gre"
+ *
+ * @route_doc{link_ip6gre, IP6GRE Documentation}
+ *
+ * @{
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink/netlink.h>
+#include <netlink/attr.h>
+#include <netlink/utils.h>
+#include <netlink/object.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/link/ip6gre.h>
+#include <netlink-private/route/link/api.h>
+#include <linux/if_tunnel.h>
+
+#define IP6GRE_ATTR_LINK (1 << 0)
+#define IP6GRE_ATTR_IFLAGS (1 << 1)
+#define IP6GRE_ATTR_OFLAGS (1 << 2)
+#define IP6GRE_ATTR_IKEY (1 << 3)
+#define IP6GRE_ATTR_OKEY (1 << 4)
+#define IP6GRE_ATTR_LOCAL (1 << 5)
+#define IP6GRE_ATTR_REMOTE (1 << 6)
+#define IP6GRE_ATTR_TTL (1 << 7)
+#define IP6GRE_ATTR_ENCAPLIMIT (1 << 8)
+#define IP6GRE_ATTR_FLOWINFO (1 << 9)
+#define IP6GRE_ATTR_FLAGS (1 << 10)
+#define IP6GRE_ATTR_FWMARK (1 << 11)
+
+struct ip6gre_info
+{
+ uint8_t ttl;
+ uint8_t encaplimit;
+ uint16_t iflags;
+ uint16_t oflags;
+ uint32_t ikey;
+ uint32_t okey;
+ uint32_t link;
+ uint32_t flowinfo;
+ uint32_t flags;
+ struct in6_addr local;
+ struct in6_addr remote;
+ uint32_t fwmark;
+ uint32_t ip6gre_mask;
+};
+
+static struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = {
+ [IFLA_GRE_LINK] = { .type = NLA_U32 },
+ [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
+ [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
+ [IFLA_GRE_IKEY] = { .type = NLA_U32 },
+ [IFLA_GRE_OKEY] = { .type = NLA_U32 },
+ [IFLA_GRE_LOCAL] = { .minlen = sizeof(struct in6_addr) },
+ [IFLA_GRE_REMOTE] = { .minlen = sizeof(struct in6_addr) },
+ [IFLA_GRE_TTL] = { .type = NLA_U8 },
+ [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
+ [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },
+ [IFLA_GRE_FLAGS] = { .type = NLA_U32 },
+ [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
+};
+
+static int ip6gre_alloc(struct rtnl_link *link)
+{
+ struct ip6gre_info *ip6gre;
+
+ if (link->l_info)
+ memset(link->l_info, 0, sizeof(*ip6gre));
+ else {
+ ip6gre = calloc(1, sizeof(*ip6gre));
+ if (!ip6gre)
+ return -NLE_NOMEM;
+
+ link->l_info = ip6gre;
+ }
+
+ return 0;
+}
+
+static int ip6gre_parse(struct rtnl_link *link, struct nlattr *data,
+ struct nlattr *xstats)
+{
+ struct nlattr *tb[IFLA_GRE_MAX + 1];
+ struct ip6gre_info *ip6gre;
+ int err;
+
+ NL_DBG(3, "Parsing IP6GRE link info\n");
+
+ err = nla_parse_nested(tb, IFLA_GRE_MAX, data, ip6gre_policy);
+ if (err < 0)
+ goto errout;
+
+ err = ip6gre_alloc(link);
+ if (err < 0)
+ goto errout;
+
+ ip6gre = link->l_info;
+
+ if (tb[IFLA_GRE_LINK]) {
+ ip6gre->link = nla_get_u32(tb[IFLA_GRE_LINK]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_LINK;
+ }
+
+ if (tb[IFLA_GRE_IFLAGS]) {
+ ip6gre->iflags = nla_get_u16(tb[IFLA_GRE_IFLAGS]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_IFLAGS;
+ }
+
+ if (tb[IFLA_GRE_OFLAGS]) {
+ ip6gre->oflags = nla_get_u16(tb[IFLA_GRE_OFLAGS]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_OFLAGS;
+ }
+
+ if (tb[IFLA_GRE_IKEY]) {
+ ip6gre->ikey = nla_get_u32(tb[IFLA_GRE_IKEY]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_IKEY;
+ }
+
+ if (tb[IFLA_GRE_OKEY]) {
+ ip6gre->okey = nla_get_u32(tb[IFLA_GRE_OKEY]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_OKEY;
+ }
+
+ if (tb[IFLA_GRE_LOCAL]) {
+ nla_memcpy(&ip6gre->local, tb[IFLA_GRE_LOCAL], sizeof(struct in6_addr));
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_LOCAL;
+ }
+
+ if (tb[IFLA_GRE_REMOTE]) {
+ nla_memcpy(&ip6gre->remote, tb[IFLA_GRE_REMOTE], sizeof(struct in6_addr));
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_REMOTE;
+ }
+
+ if (tb[IFLA_GRE_TTL]) {
+ ip6gre->ttl = nla_get_u8(tb[IFLA_GRE_TTL]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_TTL;
+ }
+
+ if (tb[IFLA_GRE_ENCAP_LIMIT]) {
+ ip6gre->encaplimit = nla_get_u8(tb[IFLA_GRE_ENCAP_LIMIT]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_ENCAPLIMIT;
+ }
+
+ if (tb[IFLA_GRE_FLOWINFO]) {
+ ip6gre->flowinfo = nla_get_u32(tb[IFLA_GRE_FLOWINFO]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLOWINFO;
+ }
+
+ if (tb[IFLA_GRE_FLAGS]) {
+ ip6gre->flags = nla_get_u32(tb[IFLA_GRE_FLAGS]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLAGS;
+ }
+
+ if (tb[IFLA_GRE_FWMARK]) {
+ ip6gre->fwmark = nla_get_u32(tb[IFLA_GRE_FWMARK]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
+ }
+
+ err = 0;
+
+ errout:
+ return err;
+}
+
+static int ip6gre_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+ struct nlattr *data;
+
+ data = nla_nest_start(msg, IFLA_INFO_DATA);
+ if (!data)
+ return -NLE_MSGSIZE;
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LINK)
+ NLA_PUT_U32(msg, IFLA_GRE_LINK, ip6gre->link);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IFLAGS)
+ NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, ip6gre->iflags);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OFLAGS)
+ NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, ip6gre->oflags);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IKEY)
+ NLA_PUT_U32(msg, IFLA_GRE_IKEY, ip6gre->ikey);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OKEY)
+ NLA_PUT_U32(msg, IFLA_GRE_OKEY, ip6gre->okey);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LOCAL)
+ NLA_PUT(msg, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &ip6gre->local);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_REMOTE)
+ NLA_PUT(msg, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &ip6gre->remote);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_TTL)
+ NLA_PUT_U8(msg, IFLA_GRE_TTL, ip6gre->ttl);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_ENCAPLIMIT)
+ NLA_PUT_U8(msg, IFLA_GRE_ENCAP_LIMIT, ip6gre->encaplimit);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLOWINFO)
+ NLA_PUT_U32(msg, IFLA_GRE_FLOWINFO, ip6gre->flowinfo);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLAGS)
+ NLA_PUT_U32(msg, IFLA_GRE_FLAGS, ip6gre->flags);
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_GRE_FWMARK, ip6gre->fwmark);
+
+ nla_nest_end(msg, data);
+
+ nla_put_failure:
+
+ return 0;
+}
+
+static void ip6gre_free(struct rtnl_link *link)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ free(ip6gre);
+ link->l_info = NULL;
+}
+
+static void ip6gre_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
+{
+ nl_dump(p, "ip6gre : %s", link->l_name);
+}
+
+static void ip6gre_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+ char *name;
+ char addr[INET6_ADDRSTRLEN];
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LINK) {
+ nl_dump(p, " link ");
+ name = rtnl_link_get_name(link);
+ if (name)
+ nl_dump_line(p, "%s\n", name);
+ else
+ nl_dump_line(p, "%u\n", ip6gre->link);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IFLAGS) {
+ nl_dump(p, " iflags ");
+ nl_dump_line(p, "%x\n", ip6gre->iflags);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OFLAGS) {
+ nl_dump(p, " oflags ");
+ nl_dump_line(p, "%x\n", ip6gre->oflags);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_IKEY) {
+ nl_dump(p, " ikey ");
+ nl_dump_line(p, "%x\n",ip6gre->ikey);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_OKEY) {
+ nl_dump(p, " okey ");
+ nl_dump_line(p, "%x\n", ip6gre->okey);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_LOCAL) {
+ nl_dump(p, " local ");
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6gre->local, addr));
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_REMOTE) {
+ nl_dump(p, " remote ");
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6gre->remote, addr));
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_TTL) {
+ nl_dump(p, " ttl ");
+ nl_dump_line(p, "%u\n", ip6gre->ttl);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_ENCAPLIMIT) {
+ nl_dump(p, " encaplimit ");
+ nl_dump_line(p, "%u\n", ip6gre->encaplimit);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLOWINFO) {
+ nl_dump(p, " flowinfo ");
+ nl_dump_line(p, "%x\n", ip6gre->flowinfo);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLAGS) {
+ nl_dump(p, " flags ");
+ nl_dump_line(p, "%x\n", ip6gre->flags);
+ }
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ip6gre->fwmark);
+ }
+}
+
+static int ip6gre_clone(struct rtnl_link *dst, struct rtnl_link *src)
+{
+ struct ip6gre_info *ip6gre_dst, *ip6gre_src = src->l_info;
+ int err;
+
+ dst->l_info = NULL;
+
+ err = rtnl_link_set_type(dst, "ip6gre");
+ if (err < 0)
+ return err;
+
+ ip6gre_dst = dst->l_info;
+
+ if (!ip6gre_dst || !ip6gre_src)
+ BUG();
+
+ memcpy(ip6gre_dst, ip6gre_src, sizeof(struct ip6gre_info));
+
+ return 0;
+}
+
+static struct rtnl_link_info_ops ip6gre_info_ops = {
+ .io_name = "ip6gre",
+ .io_alloc = ip6gre_alloc,
+ .io_parse = ip6gre_parse,
+ .io_dump = {
+ [NL_DUMP_LINE] = ip6gre_dump_line,
+ [NL_DUMP_DETAILS] = ip6gre_dump_details,
+ },
+ .io_clone = ip6gre_clone,
+ .io_put_attrs = ip6gre_put_attrs,
+ .io_free = ip6gre_free,
+};
+
+#define IS_IP6GRE_LINK_ASSERT(link) \
+ if ((link)->l_info_ops != &ip6gre_info_ops) { \
+ APPBUG("Link is not a ip6gre link. set type \"ip6gre\" first.");\
+ return -NLE_OPNOTSUPP; \
+ }
+
+#define HAS_IP6GRE_ATTR_ASSERT(link,attr) \
+ if (!((link)->ip6gre_mask & (attr))) \
+ return -NLE_NOATTR;
+
+struct rtnl_link *rtnl_link_ip6gre_alloc(void)
+{
+ struct rtnl_link *link;
+ int err;
+
+ link = rtnl_link_alloc();
+ if (!link)
+ return NULL;
+
+ err = rtnl_link_set_type(link, "ip6gre");
+ if (err < 0) {
+ rtnl_link_put(link);
+ return NULL;
+ }
+
+ return link;
+}
+
+/**
+ * Check if link is a IP6GRE link
+ * @arg link Link object
+ *
+ * @return True if link is a IP6GRE link, otherwise 0 is returned.
+ */
+int rtnl_link_is_ip6gre(struct rtnl_link *link)
+{
+ return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ip6gre");
+}
+
+/**
+ * Create a new IP6GRE tunnel device
+ * @arg sock netlink socket
+ * @arg name name of the tunnel deviceL
+ *
+ * Creates a new ip6gre tunnel device in the kernel
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_add(struct nl_sock *sk, const char *name)
+{
+ struct rtnl_link *link;
+ int err;
+
+ link = rtnl_link_ip6gre_alloc();
+ if (!link)
+ return -NLE_NOMEM;
+
+ if(name)
+ rtnl_link_set_name(link, name);
+
+ err = rtnl_link_add(sk, link, NLM_F_CREATE);
+ rtnl_link_put(link);
+
+ return err;
+}
+
+/**
+ * Set IP6GRE tunnel interface index
+ * @arg link Link object
+ * @arg index interface index
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_link(struct rtnl_link *link, uint32_t index)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->link = index;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_LINK;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel interface index
+ * @arg link Link object
+ * @arg index addr to fill in with the interface index
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_link(struct rtnl_link *link, uint32_t *index)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_LINK);
+
+ *index = ip6gre->link;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel set iflags
+ * @arg link Link object
+ * @arg iflags ip6gre iflags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_iflags(struct rtnl_link *link, uint16_t iflags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->iflags = iflags;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_IFLAGS;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel iflags
+ * @arg link Link object
+ * @arg iflags addr to fill in with the iflags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_iflags(struct rtnl_link *link, uint16_t *iflags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_IFLAGS);
+
+ *iflags = ip6gre->iflags;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel set oflags
+ * @arg link Link object
+ * @arg oflags ip6gre oflags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_oflags(struct rtnl_link *link, uint16_t oflags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->oflags = oflags;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_OFLAGS;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel oflags
+ * @arg link Link object
+ * @arg oflags addr to fill in with the oflags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_oflags(struct rtnl_link *link, uint16_t *oflags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_OFLAGS);
+
+ *oflags = ip6gre->oflags;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel set ikey
+ * @arg link Link object
+ * @arg ikey ip6gre ikey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_ikey(struct rtnl_link *link, uint32_t ikey)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->ikey = ikey;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_IKEY;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel ikey
+ * @arg link Link object
+ * @arg ikey addr to fill in with the ikey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_ikey(struct rtnl_link *link, uint32_t *ikey)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_IKEY);
+
+ *ikey = ip6gre->ikey;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel set okey
+ * @arg link Link object
+ * @arg okey ip6gre okey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_okey(struct rtnl_link *link, uint32_t okey)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->okey = okey;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_OKEY;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel okey
+ * @arg link Link object
+ * @arg okey addr to fill in with the okey
+ *
+ * @return okey value
+ */
+int rtnl_link_ip6gre_get_okey(struct rtnl_link *link, uint32_t *okey)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_OKEY);
+
+ *okey = ip6gre->okey;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel local address
+ * @arg link Link object
+ * @arg local local address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_local(struct rtnl_link *link, struct in6_addr *local)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ memcpy(&ip6gre->local, local, sizeof(struct in6_addr));
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_LOCAL;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel local address
+ * @arg link Link object
+ * @arg local addr to fill in with local address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_local(struct rtnl_link *link, struct in6_addr *local)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_LOCAL);
+
+ memcpy(local, &ip6gre->local, sizeof(struct in6_addr));
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel remote address
+ * @arg link Link object
+ * @arg remote remote address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_remote(struct rtnl_link *link, struct in6_addr *remote)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ memcpy(&ip6gre->remote, remote, sizeof(struct in6_addr));
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_REMOTE;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel remote address
+ * @arg link Link object
+ * @arg remote addr to fill in with remote address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_remote(struct rtnl_link *link, struct in6_addr *remote)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_REMOTE);
+
+ memcpy(remote, &ip6gre->remote, sizeof(struct in6_addr));
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel ttl
+ * @arg link Link object
+ * @arg ttl tunnel ttl
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_ttl(struct rtnl_link *link, uint8_t ttl)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->ttl = ttl;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_TTL;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel ttl
+ * @arg link Link object
+ * @arg ttl addr to fill in with the ttl
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_ttl(struct rtnl_link *link, uint8_t *ttl)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_TTL);
+
+ *ttl = ip6gre->ttl;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel encap limit
+ * @arg link Link object
+ * @arg encaplimit tunnel encap limit value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_encaplimit(struct rtnl_link *link, uint8_t encaplimit)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->encaplimit = encaplimit;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_ENCAPLIMIT;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel encap limit
+ * @arg link Link object
+ * @arg encaplimit addr to fill in with the encaplimit
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_encaplimit(struct rtnl_link *link, uint8_t *encaplimit)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_ENCAPLIMIT);
+
+ *encaplimit = ip6gre->encaplimit;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel flowinfo
+ * @arg link Link object
+ * @arg flowinfo flowinfo value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->flowinfo = flowinfo;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLOWINFO;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE flowinfo
+ * @arg link Link object
+ * @arg flowinfo addr to fill in with the flowinfo
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowinfo)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FLOWINFO);
+
+ *flowinfo = ip6gre->flowinfo;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel flags
+ * @arg link Link object
+ * @arg flags tunnel flags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->flags = flags;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLAGS;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE flags
+ * @arg link Link object
+ * @arg flags addr to fill in with the tunnel flags
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FLAGS);
+
+ *flags = ip6gre->flags;
+
+ return 0;
+}
+
+/**
+ * Set IP6GRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->fwmark = fwmark;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FWMARK);
+
+ *fwmark = ip6gre->fwmark;
+
+ return 0;
+}
+
+static void __init ip6gre_init(void)
+{
+ rtnl_link_register_info(&ip6gre_info_ops);
+}
+
+static void __exit ip6gre_exit(void)
+{
+ rtnl_link_unregister_info(&ip6gre_info_ops);
+}
diff --git a/lib/route/link/ip6tnl.c b/lib/route/link/ip6tnl.c
index 085bf66..cdc9024 100644
--- a/lib/route/link/ip6tnl.c
+++ b/lib/route/link/ip6tnl.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ip6tnl.c IP6TNL Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -42,6 +36,7 @@
#define IP6_TNL_ATTR_FLAGS (1 << 6)
#define IP6_TNL_ATTR_PROTO (1 << 7)
#define IP6_TNL_ATTR_FLOWINFO (1 << 8)
+#define IP6_TNL_ATTR_FWMARK (1 << 9)
struct ip6_tnl_info
{
@@ -54,6 +49,7 @@
uint32_t flowinfo;
struct in6_addr local;
struct in6_addr remote;
+ uint32_t fwmark;
uint32_t ip6_tnl_mask;
};
@@ -67,6 +63,7 @@
[IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
[IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
};
static int ip6_tnl_alloc(struct rtnl_link *link)
@@ -150,6 +147,11 @@
ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_PROTO;
}
+ if (tb[IFLA_IPTUN_FWMARK]) {
+ ip6_tnl->fwmark = nla_get_u32(tb[IFLA_IPTUN_FWMARK]);
+ ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -195,6 +197,9 @@
else
NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, 0);
+ if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_IPTUN_FWMARK, ip6_tnl->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -236,20 +241,14 @@
if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LOCAL) {
nl_dump(p, " local ");
-
- if(inet_ntop(AF_INET6, &ip6_tnl->local, addr, INET6_ADDRSTRLEN))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", ip6_tnl->local);
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6_tnl->local, addr));
}
if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_REMOTE) {
nl_dump(p, " remote ");
-
- if(inet_ntop(AF_INET6, &ip6_tnl->remote, addr, INET6_ADDRSTRLEN))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", ip6_tnl->remote);
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6_tnl->remote, addr));
}
if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_TTL) {
@@ -281,6 +280,11 @@
nl_dump(p, " proto ");
nl_dump_line(p, " (%x)\n", ip6_tnl->proto);
}
+
+ if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ip6_tnl->fwmark);
+ }
}
static int ip6_tnl_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -688,6 +692,46 @@
return ip6_tnl->proto;
}
+/**
+ * Set IP6_TNL tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6_tnl_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ip6_tnl_info *ip6_tnl = link->l_info;
+
+ IS_IP6_TNL_LINK_ASSERT(link);
+
+ ip6_tnl->fwmark = fwmark;
+ ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IP6_TNL tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6_tnl_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ip6_tnl_info *ip6_tnl = link->l_info;
+
+ IS_IP6_TNL_LINK_ASSERT(link);
+
+ if (!(ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = ip6_tnl->fwmark;
+
+ return 0;
+}
+
static void __init ip6_tnl_init(void)
{
rtnl_link_register_info(&ip6_tnl_info_ops);
diff --git a/lib/route/link/ip6vti.c b/lib/route/link/ip6vti.c
new file mode 100644
index 0000000..8c603ab
--- /dev/null
+++ b/lib/route/link/ip6vti.c
@@ -0,0 +1,554 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/**
+ * @ingroup link
+ * @defgroup ip6vti IP6VTI
+ * ip6vti link module
+ *
+ * @details
+ * \b Link Type Name: "vti6"
+ *
+ * @route_doc{link_ip6vti, IP6VTI Documentation}
+ *
+ * @{
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink/netlink.h>
+#include <netlink/attr.h>
+#include <netlink/utils.h>
+#include <netlink/object.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/link/ip6vti.h>
+#include <netlink-private/route/link/api.h>
+#include <linux/if_tunnel.h>
+
+#define IP6VTI_ATTR_LINK (1 << 0)
+#define IP6VTI_ATTR_IKEY (1 << 1)
+#define IP6VTI_ATTR_OKEY (1 << 2)
+#define IP6VTI_ATTR_LOCAL (1 << 3)
+#define IP6VTI_ATTR_REMOTE (1 << 4)
+#define IP6VTI_ATTR_FWMARK (1 << 5)
+
+struct ip6vti_info
+{
+ uint32_t link;
+ uint32_t ikey;
+ uint32_t okey;
+ struct in6_addr local;
+ struct in6_addr remote;
+ uint32_t fwmark;
+ uint32_t ip6vti_mask;
+};
+
+static struct nla_policy ip6vti_policy[IFLA_VTI_MAX + 1] = {
+ [IFLA_VTI_LINK] = { .type = NLA_U32 },
+ [IFLA_VTI_IKEY] = { .type = NLA_U32 },
+ [IFLA_VTI_OKEY] = { .type = NLA_U32 },
+ [IFLA_VTI_LOCAL] = { .minlen = sizeof(struct in6_addr) },
+ [IFLA_VTI_REMOTE] = { .minlen = sizeof(struct in6_addr) },
+ [IFLA_VTI_FWMARK] = { .type = NLA_U32 },
+};
+
+static int ip6vti_alloc(struct rtnl_link *link)
+{
+ struct ip6vti_info *ip6vti;
+
+ if (link->l_info)
+ memset(link->l_info, 0, sizeof(*ip6vti));
+ else {
+ ip6vti = calloc(1, sizeof(*ip6vti));
+ if (!ip6vti)
+ return -NLE_NOMEM;
+
+ link->l_info = ip6vti;
+ }
+
+ return 0;
+}
+
+static int ip6vti_parse(struct rtnl_link *link, struct nlattr *data,
+ struct nlattr *xstats)
+{
+ struct nlattr *tb[IFLA_VTI_MAX + 1];
+ struct ip6vti_info *ip6vti;
+ int err;
+
+ NL_DBG(3, "Parsing IP6VTI link info\n");
+
+ err = nla_parse_nested(tb, IFLA_VTI_MAX, data, ip6vti_policy);
+ if (err < 0)
+ goto errout;
+
+ err = ip6vti_alloc(link);
+ if (err < 0)
+ goto errout;
+
+ ip6vti = link->l_info;
+
+ if (tb[IFLA_VTI_LINK]) {
+ ip6vti->link = nla_get_u32(tb[IFLA_VTI_LINK]);
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
+ }
+
+ if (tb[IFLA_VTI_IKEY]) {
+ ip6vti->ikey = nla_get_u32(tb[IFLA_VTI_IKEY]);
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
+ }
+
+ if (tb[IFLA_VTI_OKEY]) {
+ ip6vti->okey = nla_get_u32(tb[IFLA_VTI_OKEY]);
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
+ }
+
+ if (tb[IFLA_VTI_LOCAL]) {
+ nla_memcpy(&ip6vti->local, tb[IFLA_VTI_LOCAL], sizeof(struct in6_addr));
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
+ }
+
+ if (tb[IFLA_VTI_REMOTE]) {
+ nla_memcpy(&ip6vti->remote, tb[IFLA_VTI_REMOTE], sizeof(struct in6_addr));
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
+ }
+
+ if (tb[IFLA_VTI_FWMARK]) {
+ ip6vti->fwmark = nla_get_u32(tb[IFLA_VTI_FWMARK]);
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
+ }
+
+ err = 0;
+
+ errout:
+ return err;
+}
+
+static int ip6vti_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+ struct nlattr *data;
+
+ data = nla_nest_start(msg, IFLA_INFO_DATA);
+ if (!data)
+ return -NLE_MSGSIZE;
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK)
+ NLA_PUT_U32(msg, IFLA_VTI_LINK, ip6vti->link);
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY)
+ NLA_PUT_U32(msg, IFLA_VTI_IKEY, ip6vti->ikey);
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY)
+ NLA_PUT_U32(msg, IFLA_VTI_OKEY, ip6vti->okey);
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL)
+ NLA_PUT(msg, IFLA_VTI_LOCAL, sizeof(struct in6_addr), &ip6vti->local);
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE)
+ NLA_PUT(msg, IFLA_VTI_REMOTE, sizeof(struct in6_addr), &ip6vti->remote);
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_VTI_FWMARK, ip6vti->fwmark);
+
+ nla_nest_end(msg, data);
+
+nla_put_failure:
+
+ return 0;
+}
+
+static void ip6vti_free(struct rtnl_link *link)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ free(ip6vti);
+ link->l_info = NULL;
+}
+
+static void ip6vti_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
+{
+ nl_dump(p, "ip6vti : %s", link->l_name);
+}
+
+static void ip6vti_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+ char *name;
+ char addr[INET6_ADDRSTRLEN];
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK) {
+ nl_dump(p, " link ");
+ name = rtnl_link_get_name(link);
+ if (name)
+ nl_dump_line(p, "%s\n", name);
+ else
+ nl_dump_line(p, "%u\n", ip6vti->link);
+ }
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY) {
+ nl_dump(p, " ikey ");
+ nl_dump_line(p, "%x\n",ip6vti->ikey);
+ }
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY) {
+ nl_dump(p, " okey ");
+ nl_dump_line(p, "%x\n", ip6vti->okey);
+ }
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL) {
+ nl_dump(p, " local ");
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6vti->local, addr));
+ }
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE) {
+ nl_dump(p, " remote ");
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &ip6vti->remote, addr));
+ }
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ip6vti->fwmark);
+ }
+}
+
+static int ip6vti_clone(struct rtnl_link *dst, struct rtnl_link *src)
+{
+ struct ip6vti_info *ip6vti_dst, *ip6vti_src = src->l_info;
+ int err;
+
+ dst->l_info = NULL;
+
+ err = rtnl_link_set_type(dst, "vti6");
+ if (err < 0)
+ return err;
+
+ ip6vti_dst = dst->l_info;
+
+ if (!ip6vti_dst || !ip6vti_src)
+ BUG();
+
+ memcpy(ip6vti_dst, ip6vti_src, sizeof(struct ip6vti_info));
+
+ return 0;
+}
+
+static struct rtnl_link_info_ops ip6vti_info_ops = {
+ .io_name = "vti6",
+ .io_alloc = ip6vti_alloc,
+ .io_parse = ip6vti_parse,
+ .io_dump = {
+ [NL_DUMP_LINE] = ip6vti_dump_line,
+ [NL_DUMP_DETAILS] = ip6vti_dump_details,
+ },
+ .io_clone = ip6vti_clone,
+ .io_put_attrs = ip6vti_put_attrs,
+ .io_free = ip6vti_free,
+};
+
+#define IS_IP6VTI_LINK_ASSERT(link) \
+ if ((link)->l_info_ops != &ip6vti_info_ops) { \
+ APPBUG("Link is not a ip6vti link. set type \"vti6\" first."); \
+ return -NLE_OPNOTSUPP; \
+ }
+
+#define HAS_IP6VTI_ATTR_ASSERT(ip6vti,attr) \
+ if (!((ip6vti)->ip6vti_mask & (attr))) \
+ return -NLE_NOATTR;
+
+struct rtnl_link *rtnl_link_ip6vti_alloc(void)
+{
+ struct rtnl_link *link;
+ int err;
+
+ link = rtnl_link_alloc();
+ if (!link)
+ return NULL;
+
+ err = rtnl_link_set_type(link, "vti6");
+ if (err < 0) {
+ rtnl_link_put(link);
+ return NULL;
+ }
+
+ return link;
+}
+
+/**
+ * Check if link is a IP6VTI link
+ * @arg link Link object
+ *
+ * @return True if link is a IP6VTI link, otherwise 0 is returned.
+ */
+int rtnl_link_is_ip6vti(struct rtnl_link *link)
+{
+ return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vti6");
+}
+/**
+ * Create a new vti6 tunnel device
+ * @arg sock netlink socket
+ * @arg name name of the tunnel deviceL
+ *
+ * Creates a new vti6 tunnel device in the kernel
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name)
+{
+ struct rtnl_link *link;
+ int err;
+
+ link = rtnl_link_ip6vti_alloc();
+ if (!link)
+ return -NLE_NOMEM;
+
+ if(name)
+ rtnl_link_set_name(link, name);
+
+ err = rtnl_link_add(sk, link, NLM_F_CREATE);
+ rtnl_link_put(link);
+
+ return err;
+}
+/**
+ * Set IP6VTI tunnel interface index
+ * @arg link Link object
+ * @arg index interface index
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ ip6vti->link = index;
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel interface index
+ * @arg link Link object
+ * @arg index addr to fill in with the interface index
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LINK);
+
+ *index = ip6vti->link;
+
+ return 0;
+}
+
+/**
+ * Set IP6VTI tunnel set ikey
+ * @arg link Link object
+ * @arg ikey gre ikey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ ip6vti->ikey = ikey;
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel ikey
+ * @arg link Link object
+ * @arg ikey addr to fill in with the ikey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_IKEY);
+
+ *ikey = ip6vti->ikey;
+
+ return 0;
+}
+
+/**
+ * Set IP6VTI tunnel set okey
+ * @arg link Link object
+ * @arg okey gre okey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ ip6vti->okey = okey;
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel okey
+ * @arg link Link object
+ * @arg okey addr to fill in with the okey
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_OKEY);
+
+ *okey = ip6vti->okey;
+
+ return 0;
+}
+
+/**
+ * Set IP6VTI tunnel local address
+ * @arg link Link object
+ * @arg local local address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ memcpy(&ip6vti->local, local, sizeof(struct in6_addr));
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel local address
+ * @arg link Link object
+ * @arg local addr to fill in with remote address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *local)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LOCAL);
+
+ memcpy(local, &ip6vti->local, sizeof(struct in6_addr));
+
+ return 0;
+}
+
+/**
+ * Set IP6VTI tunnel remote address
+ * @arg link Link object
+ * @arg remote remote address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ memcpy(&ip6vti->remote, remote, sizeof(struct in6_addr));
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel remote address
+ * @arg link Link object
+ * @arg remote addr to fill in with remote address
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_REMOTE);
+
+ memcpy(remote, &ip6vti->remote, sizeof(struct in6_addr));
+
+ return 0;
+}
+
+/**
+ * Set IP6VTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ ip6vti->fwmark = fwmark;
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_FWMARK);
+
+ *fwmark = ip6vti->fwmark;
+
+ return 0;
+}
+
+static void __init ip6vti_init(void)
+{
+ rtnl_link_register_info(&ip6vti_info_ops);
+}
+
+static void __exit ip6vti_exit(void)
+{
+ rtnl_link_unregister_info(&ip6vti_info_ops);
+}
diff --git a/lib/route/link/ipgre.c b/lib/route/link/ipgre.c
index a7665fe..f5a4998 100644
--- a/lib/route/link/ipgre.c
+++ b/lib/route/link/ipgre.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ipgre.c IPGRE Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -42,6 +36,7 @@
#define IPGRE_ATTR_TTL (1 << 7)
#define IPGRE_ATTR_TOS (1 << 8)
#define IPGRE_ATTR_PMTUDISC (1 << 9)
+#define IPGRE_ATTR_FWMARK (1 << 10)
struct ipgre_info
{
@@ -55,6 +50,7 @@
uint32_t link;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipgre_mask;
};
@@ -69,6 +65,7 @@
[IFLA_GRE_TTL] = { .type = NLA_U8 },
[IFLA_GRE_TOS] = { .type = NLA_U8 },
[IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
+ [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
};
static int ipgre_alloc(struct rtnl_link *link)
@@ -157,6 +154,11 @@
ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
}
+ if (tb[IFLA_GRE_FWMARK]) {
+ ipgre->fwmark = nla_get_u32(tb[IFLA_GRE_FWMARK]);
+ ipgre->ipgre_mask |= IPGRE_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -202,6 +204,9 @@
if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC)
NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, ipgre->pmtudisc);
+ if (ipgre->ipgre_mask & IPGRE_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_GRE_FWMARK, ipgre->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -292,6 +297,11 @@
nl_dump(p, " pmtudisc ");
nl_dump_line(p, "enabled (%#x)\n", ipgre->pmtudisc);
}
+
+ if (ipgre->ipgre_mask & IPGRE_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ipgre->fwmark);
+ }
}
static int ipgre_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -829,6 +839,46 @@
return rtnl_link_ipgre_get_pmtudisc (link);
}
+/**
+ * Set IPGRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipgre_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ipgre_info *ipgre = link->l_info;
+
+ IS_IPGRE_LINK_ASSERT(link);
+
+ ipgre->fwmark = fwmark;
+ ipgre->ipgre_mask |= IPGRE_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IPGRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipgre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ipgre_info *ipgre = link->l_info;
+
+ IS_IPGRE_LINK_ASSERT(link);
+
+ if (!(ipgre->ipgre_mask & IPGRE_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = ipgre->fwmark;
+
+ return 0;
+}
+
static void __init ipgre_init(void)
{
rtnl_link_register_info(&ipgre_info_ops);
diff --git a/lib/route/link/ipip.c b/lib/route/link/ipip.c
index 3243b56..e905ef9 100644
--- a/lib/route/link/ipip.c
+++ b/lib/route/link/ipip.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ipip.c IPIP Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -38,6 +32,7 @@
#define IPIP_ATTR_TTL (1 << 3)
#define IPIP_ATTR_TOS (1 << 4)
#define IPIP_ATTR_PMTUDISC (1 << 5)
+#define IPIP_ATTR_FWMARK (1 << 6)
struct ipip_info
{
@@ -47,6 +42,7 @@
uint32_t link;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipip_mask;
};
@@ -57,6 +53,7 @@
[IFLA_IPTUN_TTL] = { .type = NLA_U8 },
[IFLA_IPTUN_TOS] = { .type = NLA_U8 },
[IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
};
static int ipip_alloc(struct rtnl_link *link)
@@ -125,6 +122,11 @@
ipip->ipip_mask |= IPIP_ATTR_PMTUDISC;
}
+ if (tb[IFLA_IPTUN_FWMARK]) {
+ ipip->fwmark = nla_get_u32(tb[IFLA_IPTUN_FWMARK]);
+ ipip->ipip_mask |= IPIP_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -158,6 +160,9 @@
if (ipip->ipip_mask & IPIP_ATTR_PMTUDISC)
NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, ipip->pmtudisc);
+ if (ipip->ipip_mask & IPIP_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_IPTUN_FWMARK, ipip->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -227,6 +232,11 @@
nl_dump(p, " pmtudisc ");
nl_dump_line(p, "enabled (%#x)\n", ipip->pmtudisc);
}
+
+ if (ipip->ipip_mask & IPIP_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ipip->fwmark);
+ }
}
static int ipip_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -528,6 +538,46 @@
return ipip->pmtudisc;
}
+/**
+ * Set IPIP tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipip_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ipip_info *ipip = link->l_info;
+
+ IS_IPIP_LINK_ASSERT(link);
+
+ ipip->fwmark = fwmark;
+ ipip->ipip_mask |= IPIP_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IPIP tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipip_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ipip_info *ipip = link->l_info;
+
+ IS_IPIP_LINK_ASSERT(link);
+
+ if (!(ipip->ipip_mask & IPIP_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = ipip->fwmark;
+
+ return 0;
+}
+
static void __init ipip_init(void)
{
rtnl_link_register_info(&ipip_info_ops);
diff --git a/lib/route/link/ipvlan.c b/lib/route/link/ipvlan.c
index 84ace43..020f2cb 100644
--- a/lib/route/link/ipvlan.c
+++ b/lib/route/link/ipvlan.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ipvlan.c IPVLAN Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cong Wang <cwang@twopensource.com>
*/
@@ -178,12 +172,11 @@
struct rtnl_link *rtnl_link_ipvlan_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "ipvlan")) < 0) {
+ if (rtnl_link_set_type(link, "ipvlan") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/ipvti.c b/lib/route/link/ipvti.c
index 851d566..9f9d3d6 100644
--- a/lib/route/link/ipvti.c
+++ b/lib/route/link/ipvti.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ipvti.c IPVTI Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -37,6 +31,7 @@
#define IPVTI_ATTR_OKEY (1 << 2)
#define IPVTI_ATTR_LOCAL (1 << 3)
#define IPVTI_ATTR_REMOTE (1 << 4)
+#define IPVTI_ATTR_FWMARK (1 << 5)
struct ipvti_info
{
@@ -45,6 +40,7 @@
uint32_t okey;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipvti_mask;
};
@@ -54,6 +50,7 @@
[IFLA_VTI_OKEY] = { .type = NLA_U32 },
[IFLA_VTI_LOCAL] = { .type = NLA_U32 },
[IFLA_VTI_REMOTE] = { .type = NLA_U32 },
+ [IFLA_VTI_FWMARK] = { .type = NLA_U32 },
};
static int ipvti_alloc(struct rtnl_link *link)
@@ -117,6 +114,11 @@
ipvti->ipvti_mask |= IPVTI_ATTR_REMOTE;
}
+ if (tb[IFLA_VTI_FWMARK]) {
+ ipvti->fwmark = nla_get_u32(tb[IFLA_VTI_FWMARK]);
+ ipvti->ipvti_mask |= IPVTI_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -147,6 +149,9 @@
if (ipvti->ipvti_mask & IPVTI_ATTR_REMOTE)
NLA_PUT_U32(msg, IFLA_VTI_REMOTE, ipvti->remote);
+ if (ipvti->ipvti_mask & IPVTI_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_VTI_FWMARK, ipvti->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -212,6 +217,11 @@
else
nl_dump_line(p, "%#x\n", ntohs(ipvti->remote));
}
+
+ if (ipvti->ipvti_mask & IPVTI_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ipvti->fwmark);
+ }
}
static int ipvti_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -477,6 +487,46 @@
return ipvti->remote;
}
+/**
+ * Set IPVTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipvti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ipvti_info *ipvti = link->l_info;
+
+ IS_IPVTI_LINK_ASSERT(link);
+
+ ipvti->fwmark = fwmark;
+ ipvti->ipvti_mask |= IPVTI_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IPVTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipvti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ipvti_info *ipvti = link->l_info;
+
+ IS_IPVTI_LINK_ASSERT(link);
+
+ if (!(ipvti->ipvti_mask & IPVTI_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = ipvti->fwmark;
+
+ return 0;
+}
+
static void __init ipvti_init(void)
{
rtnl_link_register_info(&ipvti_info_ops);
diff --git a/lib/route/link/macsec.c b/lib/route/link/macsec.c
index fa115e2..16b65b0 100644
--- a/lib/route/link/macsec.c
+++ b/lib/route/link/macsec.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/macsec.c MACsec Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Sabrina Dubroca <sd@queasysnail.net>
*/
@@ -47,6 +41,7 @@
#define MACSEC_ATTR_REPLAY_PROTECT (1 << 10)
#define MACSEC_ATTR_VALIDATION (1 << 11)
#define MACSEC_ATTR_PORT (1 << 12)
+#define MACSEC_ATTR_OFFLOAD (1 << 13)
struct macsec_info {
int ifindex;
@@ -58,7 +53,7 @@
enum macsec_validation_type validate;
uint8_t encoding_sa;
- uint8_t send_sci, end_station, scb, replay_protect, protect, encrypt;
+ uint8_t send_sci, end_station, scb, replay_protect, protect, encrypt, offload;
uint32_t ce_mask;
};
@@ -80,6 +75,7 @@
[IFLA_MACSEC_SCB] = { .type = NLA_U8 },
[IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
[IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
+ [IFLA_MACSEC_OFFLOAD] = { .type = NLA_U8 },
};
/**
@@ -164,6 +160,11 @@
info->ce_mask |= MACSEC_ATTR_ENCRYPT;
}
+ if (tb[IFLA_MACSEC_OFFLOAD]) {
+ info->offload = nla_get_u8(tb[IFLA_MACSEC_OFFLOAD]);
+ info->ce_mask |= MACSEC_ATTR_OFFLOAD;
+ }
+
if (tb[IFLA_MACSEC_INC_SCI]) {
info->send_sci = nla_get_u8(tb[IFLA_MACSEC_INC_SCI]);
info->ce_mask |= MACSEC_ATTR_INC_SCI;
@@ -262,7 +263,8 @@
struct macsec_info *info = link->l_info;
char tmp[128];
- nl_dump(p, "sci %016llx <%s>", ntohll(info->sci), flags_str(tmp, sizeof(tmp), info));
+ nl_dump(p, "sci %016llx <%s>", (long long unsigned)ntohll(info->sci),
+ flags_str(tmp, sizeof(tmp), info));
}
static void macsec_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
@@ -270,12 +272,15 @@
struct macsec_info *info = link->l_info;
char tmp[128];
- nl_dump(p, " sci %016llx protect %s encoding_sa %d encrypt %s send_sci %s validate %s %s\n",
- ntohll(info->sci), values_on_off[info->protect], info->encoding_sa, values_on_off[info->encrypt], values_on_off[info->send_sci],
+ nl_dump(p,
+ " sci %016llx protect %s encoding_sa %d encrypt %s send_sci %s validate %s %s\n",
+ (long long unsigned)ntohll(info->sci),
+ values_on_off[info->protect], info->encoding_sa,
+ values_on_off[info->encrypt], values_on_off[info->send_sci],
VALIDATE_STR[info->validate],
replay_protect_str(tmp, info->replay_protect, info->window));
nl_dump(p, " cipher suite: %016llx, icv_len %d\n",
- info->cipher_suite, info->icv_len);
+ (long long unsigned)info->cipher_suite, info->icv_len);
}
static int macsec_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -312,6 +317,9 @@
if ((info->ce_mask & MACSEC_ATTR_ENCRYPT))
NLA_PUT_U8(msg, IFLA_MACSEC_ENCRYPT, info->encrypt);
+ if ((info->ce_mask & MACSEC_ATTR_OFFLOAD))
+ NLA_PUT_U8(msg, IFLA_MACSEC_OFFLOAD, info->offload);
+
if (info->cipher_suite != MACSEC_DEFAULT_CIPHER_ID || info->icv_len != DEFAULT_ICV_LEN) {
NLA_PUT_U64(msg, IFLA_MACSEC_CIPHER_SUITE, info->cipher_suite);
NLA_PUT_U8(msg, IFLA_MACSEC_ICV_LEN, info->icv_len);
@@ -638,6 +646,36 @@
return 0;
}
+int rtnl_link_macsec_set_offload(struct rtnl_link *link, uint8_t offload)
+{
+ struct macsec_info *info = link->l_info;
+
+ IS_MACSEC_LINK_ASSERT(link);
+
+ if (offload > 1)
+ return -NLE_INVAL;
+
+ info->offload = offload;
+ info->ce_mask |= MACSEC_ATTR_OFFLOAD;
+
+ return 0;
+}
+
+int rtnl_link_macsec_get_offload(struct rtnl_link *link, uint8_t *offload)
+{
+ struct macsec_info *info = link->l_info;
+
+ IS_MACSEC_LINK_ASSERT(link);
+
+ if (!(info->ce_mask & MACSEC_ATTR_OFFLOAD))
+ return -NLE_NOATTR;
+
+ if (offload)
+ *offload = info->offload;
+
+ return 0;
+}
+
int rtnl_link_macsec_set_encoding_sa(struct rtnl_link *link, uint8_t encoding_sa)
{
struct macsec_info *info = link->l_info;
@@ -674,7 +712,7 @@
IS_MACSEC_LINK_ASSERT(link);
- if (validate > 1)
+ if (validate > MACSEC_VALIDATE_MAX)
return -NLE_INVAL;
info->validate = validate;
diff --git a/lib/route/link/macvlan.c b/lib/route/link/macvlan.c
index a23fe6d..df61bb2 100644
--- a/lib/route/link/macvlan.c
+++ b/lib/route/link/macvlan.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/macvlan.c MACVLAN Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Michael Braun <michael-dev@fami-braun.de>
*/
@@ -123,6 +117,10 @@
mvi->mvi_macaddr = calloc(mvi->mvi_maccount,
sizeof(*(mvi->mvi_macaddr)));
+ if (mvi->mvi_macaddr == NULL) {
+ err = -NLE_NOMEM;
+ goto errout;
+ }
i = 0;
for (; nla_ok(nla, len); nla = nla_next(nla, &len)) {
@@ -149,6 +147,8 @@
uint32_t i;
mvi = link->l_info;
+ if (!mvi)
+ return;
for (i = 0; i < mvi->mvi_maccount; i++)
nl_addr_put(mvi->mvi_macaddr[i]);
@@ -307,12 +307,11 @@
struct rtnl_link *rtnl_link_macvlan_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "macvlan")) < 0) {
+ if (rtnl_link_set_type(link, "macvlan") < 0) {
rtnl_link_put(link);
return NULL;
}
@@ -653,12 +652,11 @@
struct rtnl_link *rtnl_link_macvtap_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "macvtap")) < 0) {
+ if (rtnl_link_set_type(link, "macvtap") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/ppp.c b/lib/route/link/ppp.c
index b05e7f3..a5fb400 100644
--- a/lib/route/link/ppp.c
+++ b/lib/route/link/ppp.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/ppp.c PPP Link Module
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Jonas Johansson <jonasj76@gmail.com>
*/
@@ -156,12 +150,11 @@
struct rtnl_link *rtnl_link_ppp_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "ppp")) < 0) {
+ if (rtnl_link_set_type(link, "ppp") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/sit.c b/lib/route/link/sit.c
index 8856513..fabb811 100644
--- a/lib/route/link/sit.c
+++ b/lib/route/link/sit.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/sit.c SIT Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Susant Sahani <susant@redhat.com>
*/
@@ -44,6 +38,7 @@
#define SIT_ATTR_6RD_RELAY_PREFIX (1 << 9)
#define SIT_ATTR_6RD_PREFIXLEN (1 << 10)
#define SIT_ATTR_6RD_RELAY_PREFIXLEN (1 << 11)
+#define SIT_ATTR_FWMARK (1 << 12)
struct sit_info
{
@@ -59,6 +54,7 @@
uint32_t ip6rd_relay_prefix;
uint16_t ip6rd_prefixlen;
uint16_t ip6rd_relay_prefixlen;
+ uint32_t fwmark;
uint32_t sit_mask;
};
@@ -75,6 +71,7 @@
[IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
[IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
[IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
+ [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
};
static int sit_alloc(struct rtnl_link *link)
@@ -174,6 +171,11 @@
sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN;
}
+ if (tb[IFLA_IPTUN_FWMARK]) {
+ sit->fwmark = nla_get_u32(tb[IFLA_IPTUN_FWMARK]);
+ sit->sit_mask |= SIT_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -225,6 +227,9 @@
if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN)
NLA_PUT_U16(msg, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, sit->ip6rd_relay_prefixlen);
+ if (sit->sit_mask & SIT_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_IPTUN_FWMARK, sit->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -326,6 +331,11 @@
nl_dump(p, " 6rd_relay_prefixlen ");
nl_dump_line(p, "%d\n", sit->ip6rd_relay_prefixlen);
}
+
+ if (sit->sit_mask & SIT_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", sit->fwmark);
+ }
}
static int sit_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -812,6 +822,42 @@
return 0;
}
+/**
+ * Set SIT tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_sit_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ IS_SIT_LINK_ASSERT(link, sit);
+
+ sit->fwmark = fwmark;
+ sit->sit_mask |= SIT_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get SIT tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_sit_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ IS_SIT_LINK_ASSERT(link, sit);
+
+ if (!(sit->sit_mask & SIT_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = sit->fwmark;
+
+ return 0;
+}
+
static void __init sit_init(void)
{
rtnl_link_register_info(&sit_info_ops);
diff --git a/lib/route/link/sriov.c b/lib/route/link/sriov.c
index 2a87cfe..3a72814 100644
--- a/lib/route/link/sriov.c
+++ b/lib/route/link/sriov.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/sriov.c SRIOV VF Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2016 Intel Corp. All rights reserved.
* Copyright (c) 2016 Jef Oliver <jef.oliver@intel.com>
*/
@@ -92,7 +86,7 @@
nl_vf_vlans_t *src_vlans = NULL, *dst_vlans = NULL;
nl_vf_vlan_info_t *src_vlan_info = NULL, *dst_vlan_info = NULL;
- if (!(err = rtnl_link_has_vf_list(src)))
+ if (!rtnl_link_has_vf_list(src))
return 0;
dst->l_vf_list = rtnl_link_vf_alloc();
@@ -129,7 +123,7 @@
dst_vlan_info = dst_vlans->vlans;
memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t));
memcpy(dst_vlan_info, src_vlan_info,
- dst_vlans->size * sizeof(dst_vlan_info));
+ dst_vlans->size * sizeof(*dst_vlan_info));
d_vf->vf_vlans = dst_vlans;
}
@@ -213,10 +207,9 @@
/* Loop through SRIOV VF list dump details */
void rtnl_link_sriov_dump_details(struct rtnl_link *link,
struct nl_dump_params *p) {
- int err;
struct rtnl_link_vf *vf_data, *list, *next;
- if (!(err = rtnl_link_has_vf_list(link)))
+ if (!rtnl_link_has_vf_list(link))
BUG();
nl_dump(p, " SRIOV VF List\n");
@@ -235,7 +228,7 @@
char *unit;
float res;
- nl_dump(p, " VF %" PRIu64 " Stats:\n", vf_data->vf_index);
+ nl_dump(p, " VF %u Stats:\n", vf_data->vf_index);
nl_dump_line(p, "\tRX: %-14s %-10s %-10s %-10s\n",
"bytes", "packets", "multicast", "broadcast");
@@ -277,10 +270,9 @@
/* Free stored SRIOV VF data */
void rtnl_link_sriov_free_data(struct rtnl_link *link) {
- int err = 0;
struct rtnl_link_vf *list, *vf, *next;
- if (!(err = rtnl_link_has_vf_list(link)))
+ if (!rtnl_link_has_vf_list(link))
return;
list = link->l_vf_list;
@@ -656,7 +648,7 @@
}
if (t[IFLA_VF_STATS]) {
- err = nla_parse_nested(stb, IFLA_VF_STATS_MAX,
+ err = nla_parse_nested(stb, RTNL_LINK_VF_STATS_MAX,
t[IFLA_VF_STATS],
sriov_stats_policy);
if (err < 0) {
@@ -683,7 +675,7 @@
RTNL_LINK_VF_STATS_MULTICAST,
IFLA_VF_STATS_MULTICAST);
- vf_data->ce_mask |= IFLA_VF_STATS;
+ vf_data->ce_mask |= SRIOV_ATTR_STATS;
}
if (t[IFLA_VF_TRUST]) {
diff --git a/lib/route/link/team.c b/lib/route/link/team.c
new file mode 100644
index 0000000..1bcc86e
--- /dev/null
+++ b/lib/route/link/team.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2015 Jonas Johansson <jonasj76@gmail.com>
+ */
+
+/**
+ * @ingroup link
+ * @defgroup team Team
+ *
+ * @details
+ * \b Link Type Name: "team"
+ *
+ * @route_doc{link_team, Team Documentation}
+ * @{
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink/netlink.h>
+#include <netlink-private/route/link/api.h>
+#include <netlink/route/link/team.h>
+
+/**
+ * Allocate link object of type team
+ *
+ * @return Allocated link object or NULL.
+ */
+struct rtnl_link *rtnl_link_team_alloc(void)
+{
+ struct rtnl_link *link;
+
+ if (!(link = rtnl_link_alloc()))
+ return NULL;
+
+ if (rtnl_link_set_type(link, "team") < 0) {
+ rtnl_link_put(link);
+ return NULL;
+ }
+
+ return link;
+}
+
+/**
+ * Create a new kernel team device
+ * @arg sock netlink socket
+ * @arg name name of team device or NULL
+ * @arg opts team options (currently unused)
+ *
+ * Creates a new team device in the kernel. If no name is
+ * provided, the kernel will automatically pick a name of the
+ * form "type%d" (e.g. team0, vlan1, etc.)
+ *
+ * The \a opts argument is currently unused. In the future, it
+ * may be used to carry additional team options to be set
+ * when creating the team device.
+ *
+ * @note When letting the kernel assign a name, it will become
+ * difficult to retrieve the interface afterwards because
+ * you have to guess the name the kernel has chosen. It is
+ * therefore not recommended to not provide a device name.
+ *
+ * @see rtnl_link_team_enslave()
+ * @see rtnl_link_team_release()
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_team_add(struct nl_sock *sock, const char *name,
+ struct rtnl_link *opts)
+{
+ struct rtnl_link *link;
+ int err;
+
+ if (!(link = rtnl_link_team_alloc()))
+ return -NLE_NOMEM;
+
+ if (!name && opts)
+ name = rtnl_link_get_name(opts);
+
+ if (name)
+ rtnl_link_set_name(link, name);
+
+ err = rtnl_link_add(sock, link, NLM_F_CREATE);
+
+ rtnl_link_put(link);
+
+ return err;
+}
+
+static struct rtnl_link_info_ops team_info_ops = {
+ .io_name = "team",
+};
+
+static void __init team_init(void)
+{
+ rtnl_link_register_info(&team_info_ops);
+}
+
+static void __exit team_exit(void)
+{
+ rtnl_link_unregister_info(&team_info_ops);
+}
+
+/** @} */
diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 15859de..37f43f6 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/veth.c Virtual Ethernet
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
@@ -213,11 +207,10 @@
struct rtnl_link *rtnl_link_veth_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "veth")) < 0) {
+ if (rtnl_link_set_type(link, "veth") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c
index 7c5aa06..36f8822 100644
--- a/lib/route/link/vlan.c
+++ b/lib/route/link/vlan.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/vlan.c VLAN Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -392,12 +386,11 @@
struct rtnl_link *rtnl_link_vlan_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "vlan")) < 0) {
+ if (rtnl_link_set_type(link, "vlan") < 0) {
rtnl_link_put(link);
return NULL;
}
@@ -647,6 +640,7 @@
__ADD(VLAN_FLAG_GVRP, gvrp),
__ADD(VLAN_FLAG_LOOSE_BINDING, loose_binding),
__ADD(VLAN_FLAG_MVRP, mvrp),
+ __ADD(VLAN_FLAG_BRIDGE_BINDING, bridge_binding),
};
/**
diff --git a/lib/route/link/vrf.c b/lib/route/link/vrf.c
index 8b6b451..c4edd3e 100644
--- a/lib/route/link/vrf.c
+++ b/lib/route/link/vrf.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/vrf.c VRF Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2015 Cumulus Networks. All rights reserved.
* Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
*/
@@ -181,12 +175,11 @@
struct rtnl_link *rtnl_link_vrf_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "vrf")) < 0) {
+ if (rtnl_link_set_type(link, "vrf") < 0) {
rtnl_link_put(link);
return NULL;
}
@@ -240,8 +233,8 @@
struct vrf_info *vi = link->l_info;
IS_VRF_LINK_ASSERT(link);
- if(id > VRF_TABLE_ID_MAX)
- return -NLE_INVAL;
+
+ _NL_STATIC_ASSERT(VRF_TABLE_ID_MAX == UINT32_MAX);
vi->table_id = id;
vi->vi_mask |= VRF_HAS_TABLE_ID;
diff --git a/lib/route/link/vxlan.c b/lib/route/link/vxlan.c
index 686ac31..7b8429c 100644
--- a/lib/route/link/vxlan.c
+++ b/lib/route/link/vxlan.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/vxlan.c VXLAN Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Yasunobu Chiba <yasu@dsl.gr.jp>
*/
@@ -322,16 +316,12 @@
if (vxi->ce_mask & VXLAN_ATTR_GROUP) {
nl_dump(p, " group ");
- if (inet_ntop(AF_INET, &vxi->vxi_group, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_group));
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET, &vxi->vxi_group, addr));
} else if (vxi->ce_mask & VXLAN_ATTR_GROUP6) {
nl_dump(p, " group ");
- if (inet_ntop(AF_INET6, &vxi->vxi_group6, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", vxi->vxi_group6);
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &vxi->vxi_group6, addr));
}
if (vxi->ce_mask & VXLAN_ATTR_LINK) {
@@ -350,19 +340,14 @@
if (vxi->ce_mask & VXLAN_ATTR_LOCAL) {
nl_dump(p, " local ");
- if (inet_ntop(AF_INET, &vxi->vxi_local, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_local));
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET, &vxi->vxi_local, addr));
} else if (vxi->ce_mask & VXLAN_ATTR_LOCAL6) {
nl_dump(p, " local ");
- if (inet_ntop(AF_INET6, &vxi->vxi_local6, addr, sizeof(addr)))
- nl_dump_line(p, "%s\n", addr);
- else
- nl_dump_line(p, "%#x\n", vxi->vxi_local6);
+ nl_dump_line(p, "%s\n",
+ _nl_inet_ntop(AF_INET6, &vxi->vxi_local6, addr));
}
-
if (vxi->ce_mask & VXLAN_ATTR_TTL) {
nl_dump(p, " ttl ");
if(vxi->vxi_ttl)
@@ -374,7 +359,7 @@
if (vxi->ce_mask & VXLAN_ATTR_TOS) {
nl_dump(p, " tos ");
if (vxi->vxi_tos == 1)
- nl_dump_line(p, "inherit\n", vxi->vxi_tos);
+ nl_dump_line(p, "inherit\n");
else
nl_dump_line(p, "%#x\n", vxi->vxi_tos);
}
@@ -701,12 +686,11 @@
struct rtnl_link *rtnl_link_vxlan_alloc(void)
{
struct rtnl_link *link;
- int err;
if (!(link = rtnl_link_alloc()))
return NULL;
- if ((err = rtnl_link_set_type(link, "vxlan")) < 0) {
+ if (rtnl_link_set_type(link, "vxlan") < 0) {
rtnl_link_put(link);
return NULL;
}
diff --git a/lib/route/link/xfrmi.c b/lib/route/link/xfrmi.c
index 5a4a563..92531f2 100644
--- a/lib/route/link/xfrmi.c
+++ b/lib/route/link/xfrmi.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/link/xfrmi.c XFRMI Link Info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2019 Eyal Birger <eyal.birger@gmail.com>
*
* Based on lib/route/link/ipvti.c
diff --git a/lib/route/mdb.c b/lib/route/mdb.c
new file mode 100644
index 0000000..459959e
--- /dev/null
+++ b/lib/route/mdb.c
@@ -0,0 +1,466 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * lib/route/mdb.c Multicast Database
+ */
+
+#include <netlink-private/netlink.h>
+#include <netlink/netlink.h>
+#include <netlink/route/mdb.h>
+#include <netlink/utils.h>
+#include <linux/if_bridge.h>
+
+/** @cond SKIP */
+#define MDB_ATTR_IFINDEX 0x000001
+#define MDB_ATTR_ENTRIES 0x000002
+
+static struct rtnl_mdb_entry *rtnl_mdb_entry_alloc(void);
+static void rtnl_mdb_entry_free(struct rtnl_mdb_entry *mdb_entry);
+
+static struct nl_cache_ops rtnl_mdb_ops;
+static struct nl_object_ops mdb_obj_ops;
+/** @endcond */
+
+static void mdb_constructor(struct nl_object *obj)
+{
+ struct rtnl_mdb *_mdb = (struct rtnl_mdb *) obj;
+
+ nl_init_list_head(&_mdb->mdb_entry_list);
+}
+
+static void mdb_free_data(struct nl_object *obj)
+{
+ struct rtnl_mdb *mdb = (struct rtnl_mdb *)obj;
+ struct rtnl_mdb_entry *mdb_entry;
+ struct rtnl_mdb_entry *mdb_entry_safe;
+
+ nl_list_for_each_entry_safe(mdb_entry, mdb_entry_safe,
+ &mdb->mdb_entry_list, mdb_list)
+ rtnl_mdb_entry_free(mdb_entry);
+}
+
+static int mdb_entry_equal(struct rtnl_mdb_entry *a, struct rtnl_mdb_entry *b)
+{
+ return a->ifindex == b->ifindex
+ && a->vid == b->vid
+ && a->proto == b->proto
+ && a->state == b->state
+ && nl_addr_cmp(a->addr, b->addr) == 0;
+}
+
+static uint64_t mdb_compare(struct nl_object *_a, struct nl_object *_b,
+ uint64_t attrs, int flags)
+{
+ struct rtnl_mdb *a = (struct rtnl_mdb *) _a;
+ struct rtnl_mdb *b = (struct rtnl_mdb *) _b;
+ struct rtnl_mdb_entry *a_entry, *b_entry;
+ uint64_t diff = 0;
+
+#define MDB_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MDB_ATTR_##ATTR, a, b, EXPR)
+ diff |= MDB_DIFF(IFINDEX, a->ifindex != b->ifindex);
+#undef MDB_DIFF
+
+ a_entry = nl_list_entry(a->mdb_entry_list.next, struct rtnl_mdb_entry, mdb_list);
+ b_entry = nl_list_entry(b->mdb_entry_list.next, struct rtnl_mdb_entry, mdb_list);
+ while (1) {
+ if ( &a_entry->mdb_list == &a->mdb_entry_list
+ || &b_entry->mdb_list == &b->mdb_entry_list) {
+ if ( &a_entry->mdb_list != &a->mdb_entry_list
+ || &b_entry->mdb_list != &b->mdb_entry_list)
+ diff |= MDB_ATTR_ENTRIES;
+ break;
+ }
+ if (!mdb_entry_equal(a_entry, b_entry)) {
+ diff |= MDB_ATTR_ENTRIES;
+ break;
+ }
+ a_entry = nl_list_entry(a_entry->mdb_list.next, struct rtnl_mdb_entry, mdb_list);
+ b_entry = nl_list_entry(b_entry->mdb_list.next, struct rtnl_mdb_entry, mdb_list);
+ }
+
+ return diff;
+}
+
+static struct rtnl_mdb_entry *mdb_entry_clone(struct rtnl_mdb_entry *src)
+{
+ struct rtnl_mdb_entry *dst = rtnl_mdb_entry_alloc();
+ if (!dst)
+ return NULL;
+
+ dst->ifindex = src->ifindex;
+ dst->state = src->state;
+ dst->vid = src->vid;
+ dst->proto = src->proto;
+
+ dst->addr = nl_addr_clone(src->addr);
+ if (dst->addr == NULL) {
+ free(dst);
+ return NULL;
+ }
+
+ return dst;
+}
+
+static int mdb_clone(struct nl_object *_dst, struct nl_object *_src)
+{
+ struct rtnl_mdb *dst = nl_object_priv(_dst);
+ struct rtnl_mdb *src = nl_object_priv(_src);
+ struct rtnl_mdb_entry *entry;
+
+ nl_init_list_head(&dst->mdb_entry_list);
+
+ nl_list_for_each_entry(entry, &src->mdb_entry_list, mdb_list) {
+ struct rtnl_mdb_entry *copy = mdb_entry_clone(entry);
+
+ if (!copy)
+ return -NLE_NOMEM;
+
+ rtnl_mdb_add_entry(dst, copy);
+ }
+
+ return 0;
+}
+
+static int mdb_update(struct nl_object *old_obj, struct nl_object *new_obj)
+{
+ struct rtnl_mdb *old = (struct rtnl_mdb *) old_obj;
+ struct rtnl_mdb *new = (struct rtnl_mdb *) new_obj;
+ struct rtnl_mdb_entry *entry, *old_entry;
+ int action = new_obj->ce_msgtype;
+
+ if (new->ifindex != old->ifindex)
+ return -NLE_OPNOTSUPP;
+
+ switch (action) {
+ case RTM_NEWMDB:
+ nl_list_for_each_entry(entry, &new->mdb_entry_list, mdb_list) {
+ struct rtnl_mdb_entry *copy = mdb_entry_clone(entry);
+
+ if (!copy)
+ return -NLE_NOMEM;
+
+ rtnl_mdb_add_entry(old, copy);
+ }
+ break;
+ case RTM_DELMDB:
+ entry = nl_list_first_entry(&new->mdb_entry_list,
+ struct rtnl_mdb_entry,
+ mdb_list);
+ nl_list_for_each_entry(old_entry, &old->mdb_entry_list, mdb_list) {
+ if ( old_entry->ifindex == entry->ifindex
+ && !nl_addr_cmp(old_entry->addr, entry->addr)) {
+ nl_list_del(&old_entry->mdb_list);
+ break;
+ }
+ }
+ break;
+ }
+
+ return NLE_SUCCESS;
+}
+
+static struct nla_policy mdb_policy[MDBA_MAX + 1] = {
+ [MDBA_MDB] = {.type = NLA_NESTED},
+};
+
+static struct nla_policy mdb_db_policy[MDBA_MDB_MAX + 1] = {
+ [MDBA_MDB_ENTRY] = {.type = NLA_NESTED},
+};
+
+static int mdb_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
+ struct nlmsghdr *nlh, struct nl_parser_param *pp)
+{
+ int err = 0;
+ int rem = 0;
+ struct nlattr *tb[MDBA_MAX + 1];
+ struct br_port_msg *port;
+ struct nlattr *nla;
+ struct br_mdb_entry *e;
+ _nl_auto_rtnl_mdb struct rtnl_mdb *mdb = rtnl_mdb_alloc();
+
+ if (!mdb)
+ return -NLE_NOMEM;
+
+ err = nlmsg_parse(nlh, sizeof(struct br_port_msg), tb, MDBA_MAX,
+ mdb_policy);
+ if (err < 0)
+ return err;
+
+ mdb->ce_msgtype = nlh->nlmsg_type;
+
+ port = nlmsg_data(nlh);
+ mdb->ifindex = port->ifindex;
+ mdb->ce_mask |= MDB_ATTR_IFINDEX;
+
+ if (tb[MDBA_MDB]) {
+ struct nlattr *db_attr[MDBA_MDB_MAX+1];
+
+ err = nla_parse_nested(db_attr, MDBA_MDB_MAX, tb[MDBA_MDB],
+ mdb_db_policy);
+ if (err < 0)
+ return err;
+ rem = nla_len(tb[MDBA_MDB]);
+
+ for (nla = nla_data(tb[MDBA_MDB]); nla_ok(nla, rem);
+ nla = nla_next(nla, &rem)) {
+ int rm = nla_len(nla);
+ struct nlattr *nla2;
+
+ for (nla2 = nla_data(nla); nla_ok(nla2, rm);
+ nla2 = nla_next(nla2, &rm)) {
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
+ struct rtnl_mdb_entry *entry;
+ uint16_t proto;
+
+ e = nla_data(nla2);
+
+ proto = ntohs(e->addr.proto);
+
+ if (proto == ETH_P_IP) {
+ addr = nl_addr_build(
+ AF_INET, &e->addr.u.ip4,
+ sizeof(e->addr.u.ip4));
+ } else if (proto == ETH_P_IPV6) {
+ addr = nl_addr_build(
+ AF_INET6, &e->addr.u.ip6,
+ sizeof(e->addr.u.ip6));
+ } else {
+ addr = nl_addr_build(
+ AF_LLC, e->addr.u.mac_addr,
+ sizeof(e->addr.u.mac_addr));
+ }
+ if (!addr)
+ return -NLE_NOMEM;
+
+ entry = rtnl_mdb_entry_alloc();
+ if (!entry)
+ return -NLE_NOMEM;
+
+ mdb->ce_mask |= MDB_ATTR_ENTRIES;
+
+ entry->ifindex = e->ifindex;
+ entry->vid = e->vid;
+ entry->state = e->state;
+ entry->proto = ntohs(e->addr.proto);
+ entry->addr = _nl_steal_pointer(&addr);
+ rtnl_mdb_add_entry(mdb, entry);
+ }
+ }
+ }
+
+ return pp->pp_cb((struct nl_object *) mdb, pp);
+}
+
+static int mdb_request_update(struct nl_cache *cache, struct nl_sock *sk)
+{
+ return nl_rtgen_request(sk, RTM_GETMDB, AF_BRIDGE, NLM_F_DUMP);
+}
+
+static void mdb_entry_dump_line(struct rtnl_mdb_entry *entry,
+ struct nl_dump_params *p)
+{
+ char buf[INET6_ADDRSTRLEN];
+
+ nl_dump(p, "port %d ", entry->ifindex);
+ nl_dump(p, "vid %d ", entry->vid);
+ nl_dump(p, "proto 0x%04x ", entry->proto);
+ nl_dump(p, "address %s\n", nl_addr2str(entry->addr, buf, sizeof(buf)));
+}
+
+static void mdb_dump_line(struct nl_object *obj, struct nl_dump_params *p)
+{
+ struct rtnl_mdb *mdb = (struct rtnl_mdb *) obj;
+ struct rtnl_mdb_entry *_mdb;
+
+ nl_dump(p, "dev %d \n", mdb->ifindex);
+
+ nl_list_for_each_entry(_mdb, &mdb->mdb_entry_list, mdb_list) {
+ p->dp_ivar = NH_DUMP_FROM_ONELINE;
+ mdb_entry_dump_line(_mdb, p);
+ }
+}
+
+static void mdb_dump_details(struct nl_object *obj, struct nl_dump_params *p)
+{
+ mdb_dump_line(obj, p);
+}
+
+static void mdb_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
+{
+ mdb_dump_details(obj, p);
+}
+
+void rtnl_mdb_put(struct rtnl_mdb *mdb)
+{
+ nl_object_put((struct nl_object *) mdb);
+}
+
+/** @} */
+
+/**
+ * @name Cache Management
+ * @{
+ */
+int rtnl_mdb_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
+{
+ return nl_cache_alloc_and_fill(&rtnl_mdb_ops, sk, result);
+}
+
+/**
+ * Build a neighbour cache including all MDB entries currently configured in the kernel.
+ * @arg sock Netlink socket.
+ * @arg result Pointer to store resulting cache.
+ * @arg flags Flags to apply to cache before filling
+ *
+ * Allocates a new MDB cache, initializes it properly and updates it
+ * to include all Multicast Database entries currently configured in the kernel.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_mdb_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result,
+ unsigned int flags)
+{
+ struct nl_cache *cache;
+ int err;
+
+ cache = nl_cache_alloc(&rtnl_mdb_ops);
+ if (!cache)
+ return -NLE_NOMEM;
+
+ nl_cache_set_flags(cache, flags);
+
+ if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
+ nl_cache_free(cache);
+ return err;
+ }
+
+ *result = cache;
+ return 0;
+}
+
+/** @} */
+
+/**
+ * @name Attributes
+ * @{
+ */
+uint32_t rtnl_mdb_get_ifindex(struct rtnl_mdb *mdb)
+{
+ return mdb->ifindex;
+}
+
+void rtnl_mdb_add_entry(struct rtnl_mdb *mdb, struct rtnl_mdb_entry *entry)
+{
+ nl_list_add_tail(&entry->mdb_list, &mdb->mdb_entry_list);
+}
+
+void rtnl_mdb_foreach_entry(struct rtnl_mdb *mdb,
+ void (*cb)(struct rtnl_mdb_entry *, void *),
+ void *arg)
+{
+ struct rtnl_mdb_entry *entry;
+
+ nl_list_for_each_entry(entry, &mdb->mdb_entry_list, mdb_list) {
+ cb(entry, arg);
+ }
+}
+
+int rtnl_mdb_entry_get_ifindex(struct rtnl_mdb_entry *mdb_entry)
+{
+ return mdb_entry->ifindex;
+}
+
+int rtnl_mdb_entry_get_vid(struct rtnl_mdb_entry *mdb_entry)
+{
+ return mdb_entry->vid;
+}
+
+int rtnl_mdb_entry_get_state(struct rtnl_mdb_entry *mdb_entry)
+{
+ return mdb_entry->state;
+}
+
+struct nl_addr *rtnl_mdb_entry_get_addr(struct rtnl_mdb_entry *mdb_entry)
+{
+ return mdb_entry->addr;
+}
+
+uint16_t rtnl_mdb_entry_get_proto(struct rtnl_mdb_entry *mdb_entry)
+{
+ return mdb_entry->proto;
+}
+
+/** @} */
+
+static struct nl_object_ops mdb_obj_ops = {
+ .oo_name = "route/mdb",
+ .oo_size = sizeof(struct rtnl_mdb),
+ .oo_constructor = mdb_constructor,
+ .oo_dump = {
+ [NL_DUMP_LINE] = mdb_dump_line,
+ [NL_DUMP_DETAILS] = mdb_dump_details,
+ [NL_DUMP_STATS] = mdb_dump_stats,
+ },
+ .oo_clone = mdb_clone,
+ .oo_compare = mdb_compare,
+ .oo_update = mdb_update,
+ .oo_free_data = mdb_free_data,
+};
+
+struct rtnl_mdb *rtnl_mdb_alloc(void)
+{
+ return (struct rtnl_mdb *) nl_object_alloc(&mdb_obj_ops);
+}
+
+static struct rtnl_mdb_entry *rtnl_mdb_entry_alloc(void)
+{
+ struct rtnl_mdb_entry *mdb;
+
+ mdb = calloc(1, sizeof(struct rtnl_mdb_entry));
+ if (!mdb)
+ return NULL;
+
+ nl_init_list_head(&mdb->mdb_list);
+
+ return mdb;
+
+}
+
+static void rtnl_mdb_entry_free(struct rtnl_mdb_entry *mdb_entry)
+{
+ nl_list_del(&mdb_entry->mdb_list);
+ nl_addr_put(mdb_entry->addr);
+ free(mdb_entry);
+}
+
+static struct nl_af_group mdb_groups[] = {
+ {AF_BRIDGE, RTNLGRP_MDB},
+ {END_OF_GROUP_LIST},
+};
+
+static struct nl_cache_ops rtnl_mdb_ops = {
+ .co_name = "route/mdb",
+ .co_hdrsize = sizeof(struct br_port_msg),
+ .co_msgtypes = {
+ { RTM_NEWMDB, NL_ACT_NEW, "new"},
+ { RTM_DELMDB, NL_ACT_DEL, "del"},
+ { RTM_GETMDB, NL_ACT_GET, "get"},
+ END_OF_MSGTYPES_LIST,
+ },
+ .co_protocol = NETLINK_ROUTE,
+ .co_groups = mdb_groups,
+ .co_request_update = mdb_request_update,
+ .co_msg_parser = mdb_msg_parser,
+ .co_obj_ops = &mdb_obj_ops,
+};
+
+static void __init mdb_init(void)
+{
+ nl_cache_mngt_register(&rtnl_mdb_ops);
+}
+
+static void __exit mdb_exit(void)
+{
+ nl_cache_mngt_unregister(&rtnl_mdb_ops);
+}
+
+/** @} */
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index ca4f2b6..e1ef6a1 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/neigh.c Neighbours
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -192,6 +185,9 @@
struct rtnl_neigh *dst = nl_object_priv(_dst);
struct rtnl_neigh *src = nl_object_priv(_src);
+ dst->n_lladdr = NULL;
+ dst->n_dst = NULL;
+
if (src->n_lladdr)
if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
return -NLE_NOMEM;
@@ -716,7 +712,7 @@
if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
- if (tmpl->n_family != AF_BRIDGE)
+ if (tmpl->ce_mask & NEIGH_ATTR_DST)
NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
diff --git a/lib/route/neightbl.c b/lib/route/neightbl.c
index 96ca44a..c4244fc 100644
--- a/lib/route/neightbl.c
+++ b/lib/route/neightbl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/neightbl.c neighbour tables
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -18,6 +11,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink-private/utils.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/rtnl.h>
@@ -25,31 +19,31 @@
#include <netlink/route/link.h>
/** @cond SKIP */
-#define NEIGHTBL_ATTR_FAMILY 0x001
-#define NEIGHTBL_ATTR_STATS 0x002
-#define NEIGHTBL_ATTR_NAME 0x004
-#define NEIGHTBL_ATTR_THRESH1 0x008
-#define NEIGHTBL_ATTR_THRESH2 0x010
-#define NEIGHTBL_ATTR_THRESH3 0x020
-#define NEIGHTBL_ATTR_CONFIG 0x040
-#define NEIGHTBL_ATTR_PARMS 0x080
-#define NEIGHTBL_ATTR_GC_INTERVAL 0x100
+#define NEIGHTBL_ATTR_FAMILY 0x001
+#define NEIGHTBL_ATTR_STATS 0x002
+#define NEIGHTBL_ATTR_NAME 0x004
+#define NEIGHTBL_ATTR_THRESH1 0x008
+#define NEIGHTBL_ATTR_THRESH2 0x010
+#define NEIGHTBL_ATTR_THRESH3 0x020
+#define NEIGHTBL_ATTR_CONFIG 0x040
+#define NEIGHTBL_ATTR_PARMS 0x080
+#define NEIGHTBL_ATTR_GC_INTERVAL 0x100
-#define NEIGHTBLPARM_ATTR_IFINDEX 0x0001
-#define NEIGHTBLPARM_ATTR_REFCNT 0x0002
-#define NEIGHTBLPARM_ATTR_QUEUE_LEN 0x0004
-#define NEIGHTBLPARM_ATTR_APP_PROBES 0x0008
-#define NEIGHTBLPARM_ATTR_UCAST_PROBES 0x0010
-#define NEIGHTBLPARM_ATTR_MCAST_PROBES 0x0020
-#define NEIGHTBLPARM_ATTR_PROXY_QLEN 0x0040
-#define NEIGHTBLPARM_ATTR_REACHABLE_TIME 0x0080
+#define NEIGHTBLPARM_ATTR_IFINDEX 0x0001
+#define NEIGHTBLPARM_ATTR_REFCNT 0x0002
+#define NEIGHTBLPARM_ATTR_QUEUE_LEN 0x0004
+#define NEIGHTBLPARM_ATTR_APP_PROBES 0x0008
+#define NEIGHTBLPARM_ATTR_UCAST_PROBES 0x0010
+#define NEIGHTBLPARM_ATTR_MCAST_PROBES 0x0020
+#define NEIGHTBLPARM_ATTR_PROXY_QLEN 0x0040
+#define NEIGHTBLPARM_ATTR_REACHABLE_TIME 0x0080
#define NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME 0x0100
-#define NEIGHTBLPARM_ATTR_RETRANS_TIME 0x0200
-#define NEIGHTBLPARM_ATTR_GC_STALETIME 0x0400
+#define NEIGHTBLPARM_ATTR_RETRANS_TIME 0x0200
+#define NEIGHTBLPARM_ATTR_GC_STALETIME 0x0400
#define NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME 0x0800
-#define NEIGHTBLPARM_ATTR_ANYCAST_DELAY 0x1000
-#define NEIGHTBLPARM_ATTR_PROXY_DELAY 0x2000
-#define NEIGHTBLPARM_ATTR_LOCKTIME 0x4000
+#define NEIGHTBLPARM_ATTR_ANYCAST_DELAY 0x1000
+#define NEIGHTBLPARM_ATTR_PROXY_DELAY 0x2000
+#define NEIGHTBLPARM_ATTR_LOCKTIME 0x4000
static struct nl_cache_ops rtnl_neightbl_ops;
static struct nl_object_ops neightbl_obj_ops;
@@ -58,18 +52,18 @@
static uint64_t neightbl_compare(struct nl_object *_a, struct nl_object *_b,
uint64_t attrs, int flags)
{
- struct rtnl_neightbl *a = (struct rtnl_neightbl *) _a;
- struct rtnl_neightbl *b = (struct rtnl_neightbl *) _b;
+ struct rtnl_neightbl *a = (struct rtnl_neightbl *)_a;
+ struct rtnl_neightbl *b = (struct rtnl_neightbl *)_b;
uint64_t diff = 0;
#define NT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGHTBL_ATTR_##ATTR, a, b, EXPR)
- diff |= NT_DIFF(FAMILY, a->nt_family != b->nt_family);
- diff |= NT_DIFF(NAME, strcmp(a->nt_name, b->nt_name));
- diff |= NT_DIFF(THRESH1, a->nt_gc_thresh1 != b->nt_gc_thresh1);
- diff |= NT_DIFF(THRESH2, a->nt_gc_thresh2 != b->nt_gc_thresh2);
- diff |= NT_DIFF(THRESH3, a->nt_gc_thresh3 != b->nt_gc_thresh3);
- diff |= NT_DIFF(GC_INTERVAL, a->nt_gc_interval != b->nt_gc_interval);
+ diff |= NT_DIFF(FAMILY, a->nt_family != b->nt_family);
+ diff |= NT_DIFF(NAME, strcmp(a->nt_name, b->nt_name));
+ diff |= NT_DIFF(THRESH1, a->nt_gc_thresh1 != b->nt_gc_thresh1);
+ diff |= NT_DIFF(THRESH2, a->nt_gc_thresh2 != b->nt_gc_thresh2);
+ diff |= NT_DIFF(THRESH3, a->nt_gc_thresh3 != b->nt_gc_thresh3);
+ diff |= NT_DIFF(GC_INTERVAL, a->nt_gc_interval != b->nt_gc_interval);
#undef NT_DIFF
@@ -77,8 +71,7 @@
!(b->ce_mask & NEIGHTBL_ATTR_PARMS))
return diff;
- /* XXX: FIXME: Compare parameter table */
-
+ /* XXX: FIXME: Compare parameter table */
#if 0
#define REQ(F) (fp->ntp_mask & NEIGHTBLPARM_ATTR_##F)
@@ -106,17 +99,15 @@
return diff;
}
-
-static struct nla_policy neightbl_policy[NDTA_MAX+1] = {
- [NDTA_NAME] = { .type = NLA_STRING,
- .maxlen = NTBLNAMSIZ },
- [NDTA_THRESH1] = { .type = NLA_U32 },
- [NDTA_THRESH2] = { .type = NLA_U32 },
- [NDTA_THRESH3] = { .type = NLA_U32 },
- [NDTA_GC_INTERVAL] = { .type = NLA_U32 },
- [NDTA_CONFIG] = { .minlen = sizeof(struct ndt_config) },
- [NDTA_STATS] = { .minlen = sizeof(struct ndt_stats) },
- [NDTA_PARMS] = { .type = NLA_NESTED },
+static struct nla_policy neightbl_policy[NDTA_MAX + 1] = {
+ [NDTA_NAME] = { .type = NLA_STRING, .maxlen = NTBLNAMSIZ },
+ [NDTA_THRESH1] = { .type = NLA_U32 },
+ [NDTA_THRESH2] = { .type = NLA_U32 },
+ [NDTA_THRESH3] = { .type = NLA_U32 },
+ [NDTA_GC_INTERVAL] = { .type = NLA_U32 },
+ [NDTA_CONFIG] = { .minlen = sizeof(struct ndt_config) },
+ [NDTA_STATS] = { .minlen = sizeof(struct ndt_stats) },
+ [NDTA_PARMS] = { .type = NLA_NESTED },
};
static int neightbl_msg_parser(struct nl_cache_ops *ops,
@@ -191,11 +182,11 @@
if (err < 0)
goto errout;
-#define COPY_ENTRY(name, var) \
- if (tbp[NDTPA_ ##name]) { \
- p->ntp_ ##var = nla_get_u32(tbp[NDTPA_ ##name]); \
- p->ntp_mask |= NEIGHTBLPARM_ATTR_ ##name; \
- }
+#define COPY_ENTRY(name, var) \
+ if (tbp[NDTPA_##name]) { \
+ p->ntp_##var = nla_get_u32(tbp[NDTPA_##name]); \
+ p->ntp_mask |= NEIGHTBLPARM_ATTR_##name; \
+ }
COPY_ENTRY(IFINDEX, ifindex);
COPY_ENTRY(REFCNT, refcnt);
@@ -217,7 +208,7 @@
ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
}
- err = pp->pp_cb((struct nl_object *) ntbl, pp);
+ err = pp->pp_cb((struct nl_object *)ntbl, pp);
errout:
rtnl_neightbl_put(ntbl);
return err;
@@ -228,10 +219,9 @@
return nl_rtgen_request(h, RTM_GETNEIGHTBL, AF_UNSPEC, NLM_F_DUMP);
}
-
static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p)
{
- struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
+ struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *)arg;
nl_dump_line(p, "%s", ntbl->nt_name);
@@ -267,101 +257,102 @@
nl_dump(p, "\n");
}
-static void neightbl_dump_details(struct nl_object *arg, struct nl_dump_params *p)
+static void neightbl_dump_details(struct nl_object *arg,
+ struct nl_dump_params *p)
{
char x[32], y[32], z[32];
- struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
+ struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *)arg;
neightbl_dump_line(arg, p);
if (ntbl->ce_mask & NEIGHTBL_ATTR_CONFIG) {
nl_dump_line(p, " key-len %u entry-size %u last-flush %s\n",
- ntbl->nt_config.ndtc_key_len,
- ntbl->nt_config.ndtc_entry_size,
- nl_msec2str(ntbl->nt_config.ndtc_last_flush,
- x, sizeof(x)));
+ ntbl->nt_config.ndtc_key_len,
+ ntbl->nt_config.ndtc_entry_size,
+ nl_msec2str(ntbl->nt_config.ndtc_last_flush, x,
+ sizeof(x)));
- nl_dump_line(p, " gc threshold %u/%u/%u interval %s " \
- "chain-position %u\n",
- ntbl->nt_gc_thresh1, ntbl->nt_gc_thresh2,
- ntbl->nt_gc_thresh3,
- nl_msec2str(ntbl->nt_gc_interval, x, sizeof(x)),
- ntbl->nt_config.ndtc_hash_chain_gc);
+ nl_dump_line(p,
+ " gc threshold %u/%u/%u interval %s "
+ "chain-position %u\n",
+ ntbl->nt_gc_thresh1, ntbl->nt_gc_thresh2,
+ ntbl->nt_gc_thresh3,
+ nl_msec2str(ntbl->nt_gc_interval, x, sizeof(x)),
+ ntbl->nt_config.ndtc_hash_chain_gc);
nl_dump_line(p, " hash-rand 0x%08X/0x%08X last-rand %s\n",
- ntbl->nt_config.ndtc_hash_rnd,
- ntbl->nt_config.ndtc_hash_mask,
- nl_msec2str(ntbl->nt_config.ndtc_last_rand,
- x, sizeof(x)));
+ ntbl->nt_config.ndtc_hash_rnd,
+ ntbl->nt_config.ndtc_hash_mask,
+ nl_msec2str(ntbl->nt_config.ndtc_last_rand, x,
+ sizeof(x)));
}
if (ntbl->ce_mask & NEIGHTBL_ATTR_PARMS) {
struct rtnl_neightbl_parms *pa = &ntbl->nt_parms;
- nl_dump_line(p, " refcnt %u pending-queue-limit %u " \
- "proxy-delayed-queue-limit %u\n",
- pa->ntp_refcnt,
- pa->ntp_queue_len,
- pa->ntp_proxy_qlen);
+ nl_dump_line(p,
+ " refcnt %u pending-queue-limit %u "
+ "proxy-delayed-queue-limit %u\n",
+ pa->ntp_refcnt, pa->ntp_queue_len,
+ pa->ntp_proxy_qlen);
- nl_dump_line(p, " num-userspace-probes %u num-unicast-probes " \
- "%u num-multicast-probes %u\n",
- pa->ntp_app_probes,
- pa->ntp_ucast_probes,
- pa->ntp_mcast_probes);
+ nl_dump_line(p,
+ " num-userspace-probes %u num-unicast-probes "
+ "%u num-multicast-probes %u\n",
+ pa->ntp_app_probes, pa->ntp_ucast_probes,
+ pa->ntp_mcast_probes);
- nl_dump_line(p, " min-age %s base-reachable-time %s " \
- "stale-check-interval %s\n",
- nl_msec2str(pa->ntp_locktime, x, sizeof(x)),
- nl_msec2str(pa->ntp_base_reachable_time,
- y, sizeof(y)),
- nl_msec2str(pa->ntp_gc_stale_time, z, sizeof(z)));
+ nl_dump_line(p,
+ " min-age %s base-reachable-time %s "
+ "stale-check-interval %s\n",
+ nl_msec2str(pa->ntp_locktime, x, sizeof(x)),
+ nl_msec2str(pa->ntp_base_reachable_time, y,
+ sizeof(y)),
+ nl_msec2str(pa->ntp_gc_stale_time, z, sizeof(z)));
- nl_dump_line(p, " initial-probe-delay %s answer-delay %s " \
- "proxy-answer-delay %s\n",
- nl_msec2str(pa->ntp_probe_delay, x, sizeof(x)),
- nl_msec2str(pa->ntp_anycast_delay, y, sizeof(y)),
- nl_msec2str(pa->ntp_proxy_delay, z, sizeof(z)));
+ nl_dump_line(p,
+ " initial-probe-delay %s answer-delay %s "
+ "proxy-answer-delay %s\n",
+ nl_msec2str(pa->ntp_probe_delay, x, sizeof(x)),
+ nl_msec2str(pa->ntp_anycast_delay, y, sizeof(y)),
+ nl_msec2str(pa->ntp_proxy_delay, z, sizeof(z)));
}
}
static void neightbl_dump_stats(struct nl_object *arg, struct nl_dump_params *p)
{
- struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
+ struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *)arg;
neightbl_dump_details(arg, p);
if (!(ntbl->ce_mask & NEIGHTBL_ATTR_STATS))
return;
- nl_dump_line(p, " " \
- " lookups %" PRIu64 \
- " hits %" PRIu64 \
- " failed %" PRIu64 \
- " allocations %" PRIu64 \
- " destroys %" PRIu64 \
- "\n",
- ntbl->nt_stats.ndts_lookups,
- ntbl->nt_stats.ndts_hits,
- ntbl->nt_stats.ndts_res_failed,
- ntbl->nt_stats.ndts_allocs,
- ntbl->nt_stats.ndts_destroys);
+ nl_dump_line(p,
+ " "
+ " lookups %llu hits %llu failed %llu"
+ " allocations %llu destroys %llu\n",
+ (long long unsigned)ntbl->nt_stats.ndts_lookups,
+ (long long unsigned)ntbl->nt_stats.ndts_hits,
+ (long long unsigned)ntbl->nt_stats.ndts_res_failed,
+ (long long unsigned)ntbl->nt_stats.ndts_allocs,
+ (long long unsigned)ntbl->nt_stats.ndts_destroys);
- nl_dump_line(p, " " \
- " hash-grows %" PRIu64 \
- " forced-gc-runs %" PRIu64 \
- " periodic-gc-runs %" PRIu64 \
- "\n",
- ntbl->nt_stats.ndts_hash_grows,
- ntbl->nt_stats.ndts_forced_gc_runs,
- ntbl->nt_stats.ndts_periodic_gc_runs);
+ nl_dump_line(p,
+ " "
+ " hash-grows %llu forced-gc-runs %llu"
+ " periodic-gc-runs %llu\n",
+ (long long unsigned)ntbl->nt_stats.ndts_hash_grows,
+ (long long unsigned)ntbl->nt_stats.ndts_forced_gc_runs,
+ (long long unsigned)ntbl->nt_stats.ndts_periodic_gc_runs);
- nl_dump_line(p, " " \
- " rcv-unicast-probes %" PRIu64 \
- " rcv-multicast-probes %" PRIu64 \
- "\n",
- ntbl->nt_stats.ndts_rcv_probes_ucast,
- ntbl->nt_stats.ndts_rcv_probes_mcast);
+ nl_dump_line(p,
+ " "
+ " rcv-unicast-probes %llu"
+ " rcv-multicast-probes %llu"
+ "\n",
+ (long long unsigned)ntbl->nt_stats.ndts_rcv_probes_ucast,
+ (long long unsigned)ntbl->nt_stats.ndts_rcv_probes_mcast);
}
/**
@@ -371,12 +362,12 @@
struct rtnl_neightbl *rtnl_neightbl_alloc(void)
{
- return (struct rtnl_neightbl *) nl_object_alloc(&neightbl_obj_ops);
+ return (struct rtnl_neightbl *)nl_object_alloc(&neightbl_obj_ops);
}
void rtnl_neightbl_put(struct rtnl_neightbl *neightbl)
{
- nl_object_put((struct nl_object *) neightbl);
+ nl_object_put((struct nl_object *)neightbl);
}
/** @} */
@@ -423,11 +414,11 @@
if (cache->c_ops != &rtnl_neightbl_ops)
return NULL;
- nl_list_for_each_entry(nt, &cache->c_items, ce_list) {
+ nl_list_for_each_entry (nt, &cache->c_items, ce_list) {
if (!strcasecmp(nt->nt_name, name) &&
((!ifindex && !nt->nt_parms.ntp_ifindex) ||
(ifindex && ifindex == nt->nt_parms.ntp_ifindex))) {
- nl_object_get((struct nl_object *) nt);
+ nl_object_get((struct nl_object *)nt);
return nt;
}
}
@@ -486,8 +477,7 @@
NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
if (tmpl->ce_mask & NEIGHTBL_ATTR_GC_INTERVAL)
- NLA_PUT_U64(m, NDTA_GC_INTERVAL,
- tmpl->nt_gc_interval);
+ NLA_PUT_U64(m, NDTA_GC_INTERVAL, tmpl->nt_gc_interval);
if (tmpl->ce_mask & NEIGHTBL_ATTR_PARMS) {
struct rtnl_neightbl_parms *p = &tmpl->nt_parms;
@@ -498,8 +488,7 @@
if (old->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX)
NLA_PUT_U32(parms, NDTPA_IFINDEX,
- old->nt_parms.ntp_ifindex);
-
+ old->nt_parms.ntp_ifindex);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_QUEUE_LEN)
NLA_PUT_U32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
@@ -516,8 +505,7 @@
p->ntp_mcast_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_QLEN)
- NLA_PUT_U32(parms, NDTPA_PROXY_QLEN,
- p->ntp_proxy_qlen);
+ NLA_PUT_U32(parms, NDTPA_PROXY_QLEN, p->ntp_proxy_qlen);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME)
NLA_PUT_U64(parms, NDTPA_BASE_REACHABLE_TIME,
@@ -541,7 +529,7 @@
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_DELAY)
NLA_PUT_U64(parms, NDTPA_PROXY_DELAY,
- p->ntp_proxy_delay);
+ p->ntp_proxy_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_LOCKTIME)
NLA_PUT_U64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
@@ -580,7 +568,7 @@
{
struct nl_msg *msg;
int err;
-
+
if ((err = rtnl_neightbl_build_change_request(old, tmpl, &msg)) < 0)
return err;
@@ -631,7 +619,7 @@
void rtnl_neightbl_set_name(struct rtnl_neightbl *ntbl, const char *name)
{
- strncpy(ntbl->nt_name, name, sizeof(ntbl->nt_name) - 1);
+ _nl_strncpy_trunc(ntbl->nt_name, name, sizeof(ntbl->nt_name));
ntbl->ce_mask |= NEIGHTBL_ATTR_NAME;
}
diff --git a/lib/route/netconf.c b/lib/route/netconf.c
index a11ad0e..50c91bf 100644
--- a/lib/route/netconf.c
+++ b/lib/route/netconf.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/netconf.c netconf
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2017 David Ahern <dsa@cumulusnetworks.com>
*/
@@ -81,16 +74,6 @@
return (struct rtnl_netconf *) nl_object_alloc(&netconf_obj_ops);
}
-static int netconf_clone(struct nl_object *_dst, struct nl_object *_src)
-{
- struct rtnl_netconf *dst = nl_object_priv(_dst);
- struct rtnl_netconf *src = nl_object_priv(_src);
-
- *dst = *src;
-
- return 0;
-}
-
static int netconf_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
@@ -535,7 +518,6 @@
static struct nl_object_ops netconf_obj_ops = {
.oo_name = "route/netconf",
.oo_size = sizeof(struct rtnl_netconf),
- .oo_clone = netconf_clone,
.oo_dump = {
[NL_DUMP_LINE] = netconf_dump_line,
[NL_DUMP_DETAILS] = netconf_dump_line,
diff --git a/lib/route/nexthop.c b/lib/route/nexthop.c
index 7a9904c..6835137 100644
--- a/lib/route/nexthop.c
+++ b/lib/route/nexthop.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/nexthop.c Routing Nexthop
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -351,10 +344,6 @@
{
struct nl_addr *old = nh->rtnh_newdst;
- if (!nl_addr_valid(nl_addr_get_binary_addr(addr),
- nl_addr_get_len(addr)))
- return -NLE_INVAL;
-
if (addr) {
nh->rtnh_newdst = nl_addr_get(addr);
nh->ce_mask |= NH_ATTR_NEWDST;
@@ -378,10 +367,6 @@
{
struct nl_addr *old = nh->rtnh_via;
- if (!nl_addr_valid(nl_addr_get_binary_addr(addr),
- nl_addr_get_len(addr)))
- return -NLE_INVAL;
-
if (addr) {
nh->rtnh_via = nl_addr_get(addr);
nh->ce_mask |= NH_ATTR_VIA;
diff --git a/lib/route/nexthop_encap.c b/lib/route/nexthop_encap.c
index 21f647a..2382886 100644
--- a/lib/route/nexthop_encap.c
+++ b/lib/route/nexthop_encap.c
@@ -31,10 +31,13 @@
void nh_encap_dump(struct rtnl_nh_encap *rtnh_encap, struct nl_dump_params *dp)
{
+ if (!rtnh_encap->ops)
+ return;
+
nl_dump(dp, " encap %s ",
nh_encap_type2str(rtnh_encap->ops->encap_type));
- if (rtnh_encap->ops && rtnh_encap->ops->dump)
+ if (rtnh_encap->ops->dump)
rtnh_encap->ops->dump(rtnh_encap->priv, dp);
}
@@ -55,7 +58,7 @@
goto nla_put_failure;
err = rtnh_encap->ops->build_msg(msg, rtnh_encap->priv);
- if (err)
+ if (err < 0)
return err;
nla_nest_end(msg, encap);
diff --git a/lib/route/nh_encap_mpls.c b/lib/route/nh_encap_mpls.c
index 081661e..d30acc2 100644
--- a/lib/route/nh_encap_mpls.c
+++ b/lib/route/nh_encap_mpls.c
@@ -34,7 +34,7 @@
return 0;
nla_put_failure:
- return -NLE_MSGSIZE;
+ return -NLE_MSGSIZE;
}
static void mpls_encap_destructor(void *priv)
@@ -56,9 +56,8 @@
uint8_t ttl = 0;
int err;
-
err = nla_parse_nested(tb, MPLS_IPTUNNEL_MAX, nla, mpls_encap_policy);
- if (err)
+ if (err < 0)
return err;
if (!tb[MPLS_IPTUNNEL_DST])
@@ -109,10 +108,6 @@
if (!addr)
return -NLE_INVAL;
- if (!nl_addr_valid(nl_addr_get_binary_addr(addr),
- nl_addr_get_len(addr)))
- return -NLE_INVAL;
-
rtnh_encap = calloc(1, sizeof(*rtnh_encap));
if (!rtnh_encap)
return -NLE_NOMEM;
@@ -133,3 +128,31 @@
return 0;
}
+
+struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *nh)
+{
+ struct mpls_iptunnel_encap *mpls_encap;
+
+ if (!nh->rtnh_encap || nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
+ return NULL;
+
+ mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
+ if (!mpls_encap)
+ return NULL;
+
+ return mpls_encap->dst;
+}
+
+uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *nh)
+{
+ struct mpls_iptunnel_encap *mpls_encap;
+
+ if (!nh->rtnh_encap || nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
+ return 0;
+
+ mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
+ if (!mpls_encap)
+ return 0;
+
+ return mpls_encap->ttl;
+}
diff --git a/lib/route/pktloc.c b/lib/route/pktloc.c
index 9462c6e..599e593 100644
--- a/lib/route/pktloc.c
+++ b/lib/route/pktloc.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/pktloc.c Packet Location Aliasing
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
*/
@@ -124,7 +117,7 @@
nl_init_list_head(&pktloc_name_ht[i]);
}
- if ((err = pktloc_lex_init(&scanner)) < 0) {
+ if (pktloc_lex_init(&scanner) < 0) {
err = -NLE_FAILURE;
goto errout_close;
}
diff --git a/lib/route/pktloc_syntax.y b/lib/route/pktloc_syntax.y
index 25d8710..3c9326f 100644
--- a/lib/route/pktloc_syntax.y
+++ b/lib/route/pktloc_syntax.y
@@ -24,6 +24,7 @@
%{
extern int pktloc_lex(YYSTYPE *, YYLTYPE *, void *);
+#define pktloc_error yyerror
static void yyerror(YYLTYPE *locp, void *scanner, const char *msg)
{
NL_DBG(1, "Error while parsing packet location file: %s\n", msg);
diff --git a/lib/route/qdisc.c b/lib/route/qdisc.c
index 7413cf7..62c4390 100644
--- a/lib/route/qdisc.c
+++ b/lib/route/qdisc.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc.c Queueing Disciplines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -404,6 +397,38 @@
}
/**
+ * Search qdisc by kind
+ * @arg cache Qdisc cache
+ * @arg ifindex Interface index
+ * @arg kind Qdisc kind (tbf, htb, cbq, etc)
+ *
+ * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache()
+ * and searches for a qdisc matching the interface index and kind.
+ *
+ * The reference counter is incremented before returning the qdisc, therefore
+ * the reference must be given back with rtnl_qdisc_put() after usage.
+ *
+ * @return pointer to qdisc inside the cache or NULL if no match was found.
+ */
+struct rtnl_qdisc *rtnl_qdisc_get_by_kind(struct nl_cache *cache,
+ int ifindex, char *kind)
+{
+ struct rtnl_qdisc *q;
+
+ if (cache->c_ops != &rtnl_qdisc_ops)
+ return NULL;
+
+ nl_list_for_each_entry(q, &cache->c_items, ce_list) {
+ if ((q->q_ifindex == ifindex) && (!strcmp(q->q_kind, kind))) {
+ nl_object_get((struct nl_object *) q);
+ return q;
+ }
+ }
+
+ return NULL;
+}
+
+/**
* Search qdisc by interface index and handle
* @arg cache Qdisc cache
* @arg ifindex Interface index
diff --git a/lib/route/qdisc/blackhole.c b/lib/route/qdisc/blackhole.c
index 339cf78..c24507a 100644
--- a/lib/route/qdisc/blackhole.c
+++ b/lib/route/qdisc/blackhole.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/blackhole.c Blackhole Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/cbq.c b/lib/route/qdisc/cbq.c
index 118f893..62af823 100644
--- a/lib/route/qdisc/cbq.c
+++ b/lib/route/qdisc/cbq.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/cbq.c Class Based Queueing
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/dsmark.c b/lib/route/qdisc/dsmark.c
index fd9553d..07f938c 100644
--- a/lib/route/qdisc/dsmark.c
+++ b/lib/route/qdisc/dsmark.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/dsmark.c DSMARK
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/fifo.c b/lib/route/qdisc/fifo.c
index d94c007..dc6d189 100644
--- a/lib/route/qdisc/fifo.c
+++ b/lib/route/qdisc/fifo.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/fifo.c (p|b)fifo
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/fq_codel.c b/lib/route/qdisc/fq_codel.c
index ade20e5..34f6b44 100644
--- a/lib/route/qdisc/fq_codel.c
+++ b/lib/route/qdisc/fq_codel.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/fq_codel.c fq_codel
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/route/qdisc/hfsc.c b/lib/route/qdisc/hfsc.c
index ddd1242..0167e97 100644
--- a/lib/route/qdisc/hfsc.c
+++ b/lib/route/qdisc/hfsc.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/hfsc.c HFSC Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2014 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c
index e426a14..ebe38f9 100644
--- a/lib/route/qdisc/htb.c
+++ b/lib/route/qdisc/htb.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/htb.c HTB Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2005-2006 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2005-2006 Siemens AG Oesterreich
diff --git a/lib/route/qdisc/ingress.c b/lib/route/qdisc/ingress.c
index 1a63f36..73d2440 100644
--- a/lib/route/qdisc/ingress.c
+++ b/lib/route/qdisc/ingress.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/ingress.c ingress
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
diff --git a/lib/route/qdisc/mqprio.c b/lib/route/qdisc/mqprio.c
index 0d07247..c165404 100644
--- a/lib/route/qdisc/mqprio.c
+++ b/lib/route/qdisc/mqprio.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/mqprio.c MQPRIO Qdisc/Class
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
*/
@@ -271,14 +265,15 @@
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
return -NLE_MISSING_ATTR;
- if ((len / sizeof(uint8_t)) > (TC_QOPT_BITMASK+1))
+ if (len > TC_QOPT_BITMASK + 1)
return -NLE_RANGE;
- for (i = 0; i <= TC_QOPT_BITMASK; i++) {
+ for (i = 0; i < len; i++) {
if (priomap[i] > mqprio->qm_num_tc)
return -NLE_RANGE;
}
+ memset(mqprio->qm_prio_map, 0, sizeof(mqprio->qm_prio_map));
memcpy(mqprio->qm_prio_map, priomap, len * sizeof(uint8_t));
mqprio->qm_mask |= SCH_MQPRIO_ATTR_PRIOMAP;
@@ -366,9 +361,11 @@
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
return -NLE_MISSING_ATTR;
- if ((len / sizeof(uint16_t)) > TC_QOPT_MAX_QUEUE)
+ if (len < 0 || len > TC_QOPT_MAX_QUEUE)
return -NLE_RANGE;
+ memset(mqprio->qm_count, 0, sizeof(mqprio->qm_count));
+ memset(mqprio->qm_offset, 0, sizeof(mqprio->qm_offset));
memcpy(mqprio->qm_count, count, len * sizeof(uint16_t));
memcpy(mqprio->qm_offset, offset, len * sizeof(uint16_t));
mqprio->qm_mask |= SCH_MQPRIO_ATTR_QUEUE;
@@ -499,9 +496,10 @@
if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
return -NLE_INVAL;
- if ((len / sizeof(uint64_t)) > TC_QOPT_MAX_QUEUE)
+ if (len < 0 || len > TC_QOPT_MAX_QUEUE)
return -NLE_RANGE;
+ memset(mqprio->qm_min_rate, 0, sizeof(mqprio->qm_min_rate));
memcpy(mqprio->qm_min_rate, min, len * sizeof(uint64_t));
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
@@ -548,9 +546,10 @@
if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
return -NLE_INVAL;
- if ((len / sizeof(uint64_t)) > TC_QOPT_MAX_QUEUE)
+ if (len < 0 || len > TC_QOPT_MAX_QUEUE)
return -NLE_RANGE;
+ memset(mqprio->qm_max_rate, 0, sizeof(mqprio->qm_max_rate));
memcpy(mqprio->qm_max_rate, max, len * sizeof(uint64_t));
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
diff --git a/lib/route/qdisc/netem.c b/lib/route/qdisc/netem.c
index 17dee3b..0ca1d57 100644
--- a/lib/route/qdisc/netem.c
+++ b/lib/route/qdisc/netem.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/netem.c Network Emulator Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -26,6 +20,8 @@
#include <netlink/route/qdisc.h>
#include <netlink/route/qdisc/netem.h>
+#include "netlink-private/utils.h"
+
/** @cond SKIP */
#define SCH_NETEM_ATTR_LATENCY 0x0001
#define SCH_NETEM_ATTR_LIMIT 0x0002
@@ -165,39 +161,39 @@
nl_dump(p, " jitter %s", buf);
if (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR && netem->qnm_corr.nmc_delay > 0)
- nl_dump(p, " %d%", netem->qnm_corr.nmc_delay);
+ nl_dump(p, " %d", netem->qnm_corr.nmc_delay);
}
}
if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS && netem->qnm_loss > 0) {
- nl_dump(p, " loss %d%", netem->qnm_loss);
+ nl_dump(p, " loss %d", netem->qnm_loss);
if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR && netem->qnm_corr.nmc_loss > 0)
- nl_dump(p, " %d%", netem->qnm_corr.nmc_loss);
+ nl_dump(p, " %d", netem->qnm_corr.nmc_loss);
}
if (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE && netem->qnm_duplicate > 0) {
- nl_dump(p, " duplicate %d%", netem->qnm_duplicate);
+ nl_dump(p, " duplicate %d", netem->qnm_duplicate);
if (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR && netem->qnm_corr.nmc_duplicate > 0)
- nl_dump(p, " %d%", netem->qnm_corr.nmc_duplicate);
+ nl_dump(p, " %d", netem->qnm_corr.nmc_duplicate);
}
if (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB && netem->qnm_ro.nmro_probability > 0) {
- nl_dump(p, " reorder %d%", netem->qnm_ro.nmro_probability);
+ nl_dump(p, " reorder %d", netem->qnm_ro.nmro_probability);
if (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR && netem->qnm_ro.nmro_correlation > 0)
- nl_dump(p, " %d%", netem->qnm_ro.nmro_correlation);
+ nl_dump(p, " %d", netem->qnm_ro.nmro_correlation);
if (netem->qnm_mask & SCH_NETEM_ATTR_GAP && netem->qnm_gap > 0)
nl_dump(p, " gap %d", netem->qnm_gap);
}
if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB && netem->qnm_crpt.nmcr_probability > 0) {
- nl_dump(p, " reorder %d%", netem->qnm_crpt.nmcr_probability);
+ nl_dump(p, " reorder %d", netem->qnm_crpt.nmcr_probability);
if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR && netem->qnm_crpt.nmcr_correlation > 0)
- nl_dump(p, " %d%", netem->qnm_crpt.nmcr_correlation);
+ nl_dump(p, " %d", netem->qnm_crpt.nmcr_correlation);
}
}
}
@@ -911,10 +907,10 @@
int n = 0;
size_t i;
size_t len = 2048;
- char *line;
+ _nl_auto_free char *line = NULL;
char name[NAME_MAX];
char dist_suffix[] = ".dist";
- int16_t *data;
+ _nl_auto_free int16_t *data = NULL;
char *test_suffix;
/* Check several locations for the dist file */
@@ -940,9 +936,12 @@
if (f == NULL)
return -nl_syserr2nlerr(errno);
- data = (int16_t *) calloc (MAXDIST, sizeof(int16_t));
-
- line = (char *) calloc (sizeof(char), len + 1);
+ data = (int16_t *) calloc(MAXDIST, sizeof(int16_t));
+ line = (char *) calloc(sizeof(char), len + 1);
+ if (!data || !line) {
+ fclose(f);
+ return -NLE_NOMEM;
+ }
while (getline(&line, &len, f) != -1) {
char *p, *endp;
@@ -955,7 +954,6 @@
if (endp == p) break;
if (n >= MAXDIST) {
- free(line);
fclose(f);
return -NLE_INVAL;
}
@@ -963,11 +961,8 @@
}
}
- free(line);
fclose(f);
-
i = rtnl_netem_set_delay_distribution_data(qdisc, data, n);
- free(data);
return i;
}
diff --git a/lib/route/qdisc/plug.c b/lib/route/qdisc/plug.c
index 9f53637..38c1c1a 100644
--- a/lib/route/qdisc/plug.c
+++ b/lib/route/qdisc/plug.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/plug.c PLUG Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2012 Shriram Rajagopalan <rshriram@cs.ubc.ca>
*/
diff --git a/lib/route/qdisc/prio.c b/lib/route/qdisc/prio.c
index 5a21729..28242a0 100644
--- a/lib/route/qdisc/prio.c
+++ b/lib/route/qdisc/prio.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/prio.c PRIO Qdisc/Class
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/red.c b/lib/route/qdisc/red.c
index f05626e..ccab947 100644
--- a/lib/route/qdisc/red.c
+++ b/lib/route/qdisc/red.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/red.c RED Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/sfq.c b/lib/route/qdisc/sfq.c
index acbb4ef..f52452e 100644
--- a/lib/route/qdisc/sfq.c
+++ b/lib/route/qdisc/sfq.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/sfq.c SFQ Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/qdisc/tbf.c b/lib/route/qdisc/tbf.c
index 23cc845..ba8e304 100644
--- a/lib/route/qdisc/tbf.c
+++ b/lib/route/qdisc/tbf.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/qdisc/tbf.c TBF Qdisc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -121,9 +115,9 @@
cl = nl_cancel_down_bits(1 << tbf->qt_peakrate.rs_cell_log,
&clu);
- nl_dump_line(p, " peak-rate %.2f%s/s (%.0f%s) "
- "bucket-size %.1f%s cell-size %.1f%s"
- "latency %.1f%s",
+ nl_dump_line(p,
+ " peak-rate %.2f%s/s (%.0f%s) "
+ "bucket-size %.1f%s cell-size %.1f%s",
pr, pru, prb, prbu, bs, bsu, cl, clu);
}
}
diff --git a/lib/route/route.c b/lib/route/route.c
index 0900b77..fcc7459 100644
--- a/lib/route/route.c
+++ b/lib/route/route.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/route.c Routes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -18,6 +11,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink-private/nl-auto.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
@@ -131,6 +125,32 @@
result);
}
+int rtnl_route_lookup(struct nl_sock *sk, struct nl_addr *dst,
+ struct rtnl_route **result)
+{
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
+ _nl_auto_rtnl_route struct rtnl_route *tmpl = NULL;
+ struct nl_object *obj;
+ int err;
+
+ tmpl = rtnl_route_alloc();
+ rtnl_route_set_dst(tmpl, dst);
+ err = build_route_msg(tmpl, RTM_GETROUTE, 0, &msg);
+ if (err < 0)
+ return err;
+
+ err = nl_send_auto(sk, msg);
+ if (err < 0)
+ return err;
+
+ if ((err = nl_pickup(sk, route_msg_parser, &obj)) < 0)
+ return err;
+
+ *result = (struct rtnl_route *)obj;
+ wait_for_ack(sk);
+ return 0;
+}
+
int rtnl_route_add(struct nl_sock *sk, struct rtnl_route *route, int flags)
{
struct nl_msg *msg;
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
index bacabe8..9441b77 100644
--- a/lib/route/route_obj.c
+++ b/lib/route/route_obj.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/route_obj.c Route Object
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
@@ -105,22 +98,27 @@
struct rtnl_route *src = (struct rtnl_route *) _src;
struct rtnl_nexthop *nh, *new;
- if (src->rt_dst)
- if (!(dst->rt_dst = nl_addr_clone(src->rt_dst)))
- return -NLE_NOMEM;
-
- if (src->rt_src)
- if (!(dst->rt_src = nl_addr_clone(src->rt_src)))
- return -NLE_NOMEM;
-
- if (src->rt_pref_src)
- if (!(dst->rt_pref_src = nl_addr_clone(src->rt_pref_src)))
- return -NLE_NOMEM;
-
- /* Will be inc'ed again while adding the nexthops of the source */
+ dst->rt_dst = NULL;
+ dst->rt_src = NULL;
+ dst->rt_pref_src = NULL;
+ nl_init_list_head(&dst->rt_nexthops);
dst->rt_nr_nh = 0;
- nl_init_list_head(&dst->rt_nexthops);
+ if (src->rt_dst) {
+ if (!(dst->rt_dst = nl_addr_clone(src->rt_dst)))
+ return -NLE_NOMEM;
+ }
+
+ if (src->rt_src) {
+ if (!(dst->rt_src = nl_addr_clone(src->rt_src)))
+ return -NLE_NOMEM;
+ }
+
+ if (src->rt_pref_src) {
+ if (!(dst->rt_pref_src = nl_addr_clone(src->rt_pref_src)))
+ return -NLE_NOMEM;
+ }
+
nl_list_for_each_entry(nh, &src->rt_nexthops, rtnh_list) {
new = rtnl_route_nh_clone(nh);
if (!new)
@@ -211,8 +209,8 @@
static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
{
+ _nl_auto_nl_cache struct nl_cache *link_cache = NULL;
struct rtnl_route *r = (struct rtnl_route *) a;
- struct nl_cache *link_cache;
char buf[256];
int i;
@@ -282,9 +280,6 @@
r->rt_metrics[i]);
nl_dump(p, "]\n");
}
-
- if (link_cache)
- nl_cache_put(link_cache);
}
static void route_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
@@ -310,13 +305,13 @@
struct rtnl_route *route = (struct rtnl_route *) obj;
unsigned int rkey_sz;
struct nl_addr *addr = NULL;
- struct route_hash_key {
+ _nl_auto_free struct route_hash_key {
uint8_t rt_family;
uint8_t rt_tos;
uint32_t rt_table;
uint32_t rt_prio;
char rt_addr[0];
- } __attribute__((packed)) *rkey;
+ } __attribute__((packed)) *rkey = NULL;
#ifdef NL_DEBUG
char buf[INET6_ADDRSTRLEN+5];
#endif
@@ -348,8 +343,6 @@
rkey->rt_table, nl_addr2str(addr, buf, sizeof(buf)),
rkey_sz, *hashkey);
- free(rkey);
-
return;
}
@@ -512,6 +505,16 @@
switch(action) {
case RTM_NEWROUTE : {
struct rtnl_nexthop *cloned_nh;
+ struct rtnl_nexthop *old_nh;
+
+ /*
+ * Do not add the nexthop to old route if it was already added before
+ */
+ nl_list_for_each_entry(old_nh, &old_route->rt_nexthops, rtnh_list) {
+ if (!rtnl_route_nh_compare(old_nh, new_nh, ~0, 0)) {
+ return 0;
+ }
+ }
/*
* Add the nexthop to old route
@@ -1022,12 +1025,13 @@
static int parse_multipath(struct rtnl_route *route, struct nlattr *attr)
{
- struct rtnl_nexthop *nh = NULL;
struct rtnexthop *rtnh = nla_data(attr);
size_t tlen = nla_len(attr);
int err;
while (tlen >= sizeof(*rtnh) && tlen >= rtnh->rtnh_len) {
+ _nl_auto_rtnl_nexthop struct rtnl_nexthop *nh = NULL;
+
nh = rtnl_route_nh_alloc();
if (!nh)
return -NLE_NOMEM;
@@ -1044,20 +1048,17 @@
rtnh->rtnh_len - sizeof(*rtnh),
route_policy);
if (err < 0)
- goto errout;
+ return err;
if (ntb[RTA_GATEWAY]) {
- struct nl_addr *addr;
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
addr = nl_addr_alloc_attr(ntb[RTA_GATEWAY],
route->rt_family);
- if (!addr) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!addr)
+ return -NLE_NOMEM;
rtnl_route_nh_set_gateway(nh, addr);
- nl_addr_put(addr);
}
if (ntb[RTA_FLOW]) {
@@ -1068,72 +1069,67 @@
}
if (ntb[RTA_NEWDST]) {
- struct nl_addr *addr;
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
addr = nl_addr_alloc_attr(ntb[RTA_NEWDST],
route->rt_family);
if (!addr)
- goto errout;
+ return -NLE_NOMEM;
err = rtnl_route_nh_set_newdst(nh, addr);
- nl_addr_put(addr);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
if (ntb[RTA_VIA]) {
- struct nl_addr *addr;
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
addr = rtnl_route_parse_via(ntb[RTA_VIA]);
if (!addr)
- goto errout;
+ return -NLE_NOMEM;
err = rtnl_route_nh_set_via(nh, addr);
- nl_addr_put(addr);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
if (ntb[RTA_ENCAP] && ntb[RTA_ENCAP_TYPE]) {
err = nh_encap_parse_msg(ntb[RTA_ENCAP],
ntb[RTA_ENCAP_TYPE],
nh);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
}
- rtnl_route_add_nexthop(route, nh);
+ rtnl_route_add_nexthop(route, _nl_steal_pointer(&nh));
tlen -= RTNH_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
}
- err = 0;
-errout:
- if (err && nh)
- rtnl_route_nh_free(nh);
-
- return err;
+ return 0;
}
int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
{
- struct rtmsg *rtm;
- struct rtnl_route *route;
+ _nl_auto_rtnl_route struct rtnl_route *route = NULL;
+ _nl_auto_rtnl_nexthop struct rtnl_nexthop *old_nh = NULL;
+ _nl_auto_nl_addr struct nl_addr *src = NULL;
+ _nl_auto_nl_addr struct nl_addr *dst = NULL;
struct nlattr *tb[RTA_MAX + 1];
- struct nl_addr *src = NULL, *dst = NULL, *addr;
- struct rtnl_nexthop *old_nh = NULL;
- int err, family;
+ struct rtmsg *rtm;
+ int family;
+ int err;
route = rtnl_route_alloc();
if (!route)
- goto errout_nomem;
+ return -NLE_NOMEM;
route->ce_msgtype = nlh->nlmsg_type;
err = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX, route_policy);
if (err < 0)
- goto errout;
+ return err;
rtm = nlmsg_data(nlh);
route->rt_family = family = rtm->rtm_family;
@@ -1158,31 +1154,28 @@
if (tb[RTA_DST]) {
if (!(dst = nl_addr_alloc_attr(tb[RTA_DST], family)))
- goto errout_nomem;
+ return -NLE_NOMEM;
} else {
if (!(dst = nl_addr_alloc(0)))
- goto errout_nomem;
+ return -NLE_NOMEM;
nl_addr_set_family(dst, rtm->rtm_family);
}
nl_addr_set_prefixlen(dst, rtm->rtm_dst_len);
err = rtnl_route_set_dst(route, dst);
if (err < 0)
- goto errout;
-
- nl_addr_put(dst);
+ return err;
if (tb[RTA_SRC]) {
if (!(src = nl_addr_alloc_attr(tb[RTA_SRC], family)))
- goto errout_nomem;
+ return -NLE_NOMEM;
} else if (rtm->rtm_src_len)
if (!(src = nl_addr_alloc(0)))
- goto errout_nomem;
+ return -NLE_NOMEM;
if (src) {
nl_addr_set_prefixlen(src, rtm->rtm_src_len);
rtnl_route_set_src(route, src);
- nl_addr_put(src);
}
if (tb[RTA_TABLE])
@@ -1195,10 +1188,11 @@
rtnl_route_set_priority(route, nla_get_u32(tb[RTA_PRIORITY]));
if (tb[RTA_PREFSRC]) {
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
+
if (!(addr = nl_addr_alloc_attr(tb[RTA_PREFSRC], family)))
- goto errout_nomem;
+ return -NLE_NOMEM;
rtnl_route_set_pref_src(route, addr);
- nl_addr_put(addr);
}
if (tb[RTA_METRICS]) {
@@ -1207,7 +1201,7 @@
err = nla_parse_nested(mtb, RTAX_MAX, tb[RTA_METRICS], NULL);
if (err < 0)
- goto errout;
+ return err;
for (i = 1; i <= RTAX_MAX; i++) {
if (mtb[i] && nla_len(mtb[i]) >= sizeof(uint32_t)) {
@@ -1215,14 +1209,15 @@
err = rtnl_route_set_metric(route, i, m);
if (err < 0)
- goto errout;
+ return err;
}
}
}
- if (tb[RTA_MULTIPATH])
+ if (tb[RTA_MULTIPATH]) {
if ((err = parse_multipath(route, tb[RTA_MULTIPATH])) < 0)
- goto errout;
+ return err;
+ }
if (tb[RTA_CACHEINFO]) {
nla_memcpy(&route->rt_cacheinfo, tb[RTA_CACHEINFO],
@@ -1232,60 +1227,60 @@
if (tb[RTA_OIF]) {
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
rtnl_route_nh_set_ifindex(old_nh, nla_get_u32(tb[RTA_OIF]));
}
if (tb[RTA_GATEWAY]) {
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
+
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
if (!(addr = nl_addr_alloc_attr(tb[RTA_GATEWAY], family)))
- goto errout_nomem;
+ return -NLE_NOMEM;
rtnl_route_nh_set_gateway(old_nh, addr);
- nl_addr_put(addr);
}
if (tb[RTA_FLOW]) {
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
rtnl_route_nh_set_realms(old_nh, nla_get_u32(tb[RTA_FLOW]));
}
if (tb[RTA_NEWDST]) {
- struct nl_addr *addr;
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
addr = nl_addr_alloc_attr(tb[RTA_NEWDST], route->rt_family);
if (!addr)
- goto errout_nomem;
+ return -NLE_NOMEM;
err = rtnl_route_nh_set_newdst(old_nh, addr);
- nl_addr_put(addr);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
if (tb[RTA_VIA]) {
int alen = nla_len(tb[RTA_VIA]) - offsetof(struct rtvia, rtvia_addr);
+ _nl_auto_nl_addr struct nl_addr *addr = NULL;
struct rtvia *via = nla_data(tb[RTA_VIA]);
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
addr = nl_addr_build(via->rtvia_family, via->rtvia_addr, alen);
if (!addr)
- goto errout_nomem;
+ return -NLE_NOMEM;
err = rtnl_route_nh_set_via(old_nh, addr);
- nl_addr_put(addr);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
if (tb[RTA_TTL_PROPAGATE]) {
@@ -1295,12 +1290,12 @@
if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]) {
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
- goto errout_nomem;
+ return -NLE_NOMEM;
err = nh_encap_parse_msg(tb[RTA_ENCAP],
tb[RTA_ENCAP_TYPE], old_nh);
- if (err)
- goto errout;
+ if (err < 0)
+ return err;
}
if (old_nh) {
@@ -1309,7 +1304,7 @@
/* If no nexthops have been provided via RTA_MULTIPATH
* we add it as regular nexthop to maintain backwards
* compatibility */
- rtnl_route_add_nexthop(route, old_nh);
+ rtnl_route_add_nexthop(route, _nl_steal_pointer(&old_nh));
} else {
/* Kernel supports new style nexthop configuration,
* verify that it is a duplicate and discard nexthop. */
@@ -1323,27 +1318,13 @@
if (rtnl_route_nh_compare(old_nh, first,
old_nh->ce_mask, 0)) {
- err = -NLE_INVAL;
- goto errout;
+ return -NLE_INVAL;
}
-
- rtnl_route_nh_free(old_nh);
}
- old_nh = NULL;
}
- *result = route;
+ *result = _nl_steal_pointer(&route);
return 0;
-
-errout:
- if (old_nh)
- rtnl_route_nh_free(old_nh);
- rtnl_route_put(route);
- return err;
-
-errout_nomem:
- err = -NLE_NOMEM;
- goto errout;
}
int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
diff --git a/lib/route/route_utils.c b/lib/route/route_utils.c
index 6337f72..2a196f2 100644
--- a/lib/route/route_utils.c
+++ b/lib/route/route_utils.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/route_utils.c Routing Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/rtnl.c b/lib/route/rtnl.c
index f280a48..f28ebf3 100644
--- a/lib/route/rtnl.c
+++ b/lib/route/rtnl.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/rtnl.c Routing Netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/route/rule.c b/lib/route/rule.c
index a0ba42e..b3a60e1 100644
--- a/lib/route/rule.c
+++ b/lib/route/rule.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/rule.c Routing Rules
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -66,6 +59,9 @@
struct rtnl_rule *dst = nl_object_priv(_dst);
struct rtnl_rule *src = nl_object_priv(_src);
+ dst->r_src = NULL;
+ dst->r_dst = NULL;
+
if (src->r_src)
if (!(dst->r_src = nl_addr_clone(src->r_src)))
return -NLE_NOMEM;
diff --git a/lib/route/tc.c b/lib/route/tc.c
index 35303f5..a06a478 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/route/tc.c Traffic Control
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
@@ -536,7 +529,7 @@
|| strlen (kind) >= sizeof (tc->tc_kind))
return -NLE_INVAL;
- _nl_strncpy(tc->tc_kind, kind, sizeof(tc->tc_kind));
+ _nl_strncpy_assert(tc->tc_kind, kind, sizeof(tc->tc_kind));
tc->ce_mask |= TCA_ATTR_KIND;
@@ -815,14 +808,17 @@
struct rtnl_tc *src = TC_CAST(srcobj);
struct rtnl_tc_ops *ops;
+ dst->tc_opts = NULL;
+ dst->tc_xstats = NULL;
+ dst->tc_subdata = NULL;
+ dst->tc_link = NULL;
+ dst->tc_ops = NULL;
+
if (src->tc_link) {
nl_object_get(OBJ_CAST(src->tc_link));
dst->tc_link = src->tc_link;
}
- dst->tc_opts = NULL;
- dst->tc_xstats = NULL;
- dst->tc_subdata = NULL;
dst->ce_mask &= ~(TCA_ATTR_OPTS |
TCA_ATTR_XSTATS);
@@ -844,18 +840,19 @@
if (!(dst->tc_subdata = nl_data_clone(src->tc_subdata))) {
return -NLE_NOMEM;
}
- }
- ops = rtnl_tc_get_ops(src);
- if (ops && ops->to_clone) {
- void *a = rtnl_tc_data(dst), *b = rtnl_tc_data(src);
+ /* Warning: if the data contains pointer, then at this point, dst->tc_subdata
+ * will alias those pointers.
+ *
+ * ops->to_clone() MUST fix that.
+ *
+ * If the type is actually "struct rtnl_act", then to_clone() must also
+ * fix dangling "a_next" pointer. */
- if (!a)
- return 0;
- else if (!b)
- return -NLE_NOMEM;
-
- return ops->to_clone(a, b);
+ ops = rtnl_tc_get_ops(src);
+ if (ops && ops->to_clone) {
+ return ops->to_clone(rtnl_tc_data(dst), rtnl_tc_data(src));
+ }
}
return 0;
@@ -952,22 +949,19 @@
res = nl_cancel_down_bytes(tc->tc_stats[RTNL_TC_BYTES], &unit);
- nl_dump_line(p,
- " %10.2f %3s %10u %-10u %-10u %-10u %-10u\n",
- res, unit,
- tc->tc_stats[RTNL_TC_PACKETS],
- tc->tc_stats[RTNL_TC_DROPS],
- tc->tc_stats[RTNL_TC_OVERLIMITS],
- tc->tc_stats[RTNL_TC_QLEN],
- tc->tc_stats[RTNL_TC_BACKLOG]);
+ nl_dump_line(
+ p,
+ " %10.2f %3s %10llu %-10llu %-10llu %-10llu %-10llu\n",
+ res, unit, (long long unsigned)tc->tc_stats[RTNL_TC_PACKETS],
+ (long long unsigned)tc->tc_stats[RTNL_TC_DROPS],
+ (long long unsigned)tc->tc_stats[RTNL_TC_OVERLIMITS],
+ (long long unsigned)tc->tc_stats[RTNL_TC_QLEN],
+ (long long unsigned)tc->tc_stats[RTNL_TC_BACKLOG]);
res = nl_cancel_down_bytes(tc->tc_stats[RTNL_TC_RATE_BPS], &unit);
- nl_dump_line(p,
- " %10.2f %3s/s %10u/s\n",
- res,
- unit,
- tc->tc_stats[RTNL_TC_RATE_PPS]);
+ nl_dump_line(p, " %10.2f %3s/s %10llu/s\n", res, unit,
+ (long long unsigned)tc->tc_stats[RTNL_TC_RATE_PPS]);
}
uint64_t rtnl_tc_compare(struct nl_object *aobj, struct nl_object *bobj,
diff --git a/lib/socket.c b/lib/socket.c
index cfb0743..99cd36d 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/socket.c Netlink Socket
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -66,7 +59,8 @@
static uint32_t generate_local_port(void)
{
- int i, j, n, m;
+ int i, j, m;
+ uint16_t n;
static uint16_t idx_state = 0;
uint32_t pid = getpid() & 0x3FFFFF;
@@ -98,7 +92,7 @@
continue;
for (m = 0; m < 32; m++) {
- n = (n + 13) % 32;
+ n = (n + 13u) % 32u;
if (1UL & (used_ports_map[i] >> n))
continue;
@@ -111,7 +105,7 @@
nl_write_unlock(&port_map_lock);
/* ensure we don't return zero. */
- pid = pid + (((uint32_t)n) << 22);
+ pid = pid + (n << 22);
return pid ? pid : 1024;
}
}
diff --git a/lib/utils.c b/lib/utils.c
index 496bf3b..a20f36c 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/utils.c Utility Functions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
@@ -475,7 +468,7 @@
else if ((ev = getenv("PROC_ROOT")))
snprintf(name, sizeof(name), "%s/net/psched", ev);
else
- strncpy(name, "/proc/net/psched", sizeof(name) - 1);
+ _nl_strncpy_assert(name, "/proc/net/psched", sizeof(name));
if ((fd = fopen(name, "re"))) {
unsigned int ns_per_usec, ns_per_tick, nom, denom;
@@ -1224,6 +1217,15 @@
NL_CAPABILITY_VERSION_3_4_0,
NL_CAPABILITY_ROUTE_FIX_VLAN_SET_EGRESS_MAP,
NL_CAPABILITY_VERSION_3_5_0,
+ NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL,
+ NL_CAPABILITY_VERSION_3_6_0),
+ _NL_SET (4,
+ NL_CAPABILITY_VERSION_3_7_0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
0,
0),
/* IMPORTANT: these capability numbers are intended to be universal and stable
diff --git a/lib/version.c b/lib/version.c
index 4faae1c..ffde260 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * lib/version.c Run-time version information
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/lib/xfrm/ae.c b/lib/xfrm/ae.c
index c7baf35..3af872f 100644
--- a/lib/xfrm/ae.c
+++ b/lib/xfrm/ae.c
@@ -164,17 +164,23 @@
struct xfrmnl_ae* dst = nl_object_priv(_dst);
struct xfrmnl_ae* src = nl_object_priv(_src);
- if (src->sa_id.daddr)
+ dst->sa_id.daddr = NULL;
+ dst->saddr = NULL;
+ dst->replay_state_esn = NULL;
+
+ if (src->sa_id.daddr) {
if ((dst->sa_id.daddr = nl_addr_clone (src->sa_id.daddr)) == NULL)
return -NLE_NOMEM;
+ }
- if (src->saddr)
+ if (src->saddr) {
if ((dst->saddr = nl_addr_clone (src->saddr)) == NULL)
return -NLE_NOMEM;
+ }
- if (src->replay_state_esn)
- {
+ if (src->replay_state_esn) {
uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * src->replay_state_esn->bmp_len);
+
if ((dst->replay_state_esn = malloc (len)) == NULL)
return -NLE_NOMEM;
memcpy (dst->replay_state_esn, src->replay_state_esn, len);
@@ -308,8 +314,9 @@
ae->flags, ae->mark.m, ae->mark.v);
nl_dump_line(p, "\tlifetime current: \n");
- nl_dump_line(p, "\t\tbytes %llu packets %llu \n", ae->lifetime_cur.bytes,
- ae->lifetime_cur.packets);
+ nl_dump_line(p, "\t\tbytes %llu packets %llu \n",
+ (long long unsigned)ae->lifetime_cur.bytes,
+ (long long unsigned)ae->lifetime_cur.packets);
if (ae->lifetime_cur.add_time != 0)
{
add_time = ae->lifetime_cur.add_time;
@@ -375,6 +382,8 @@
!(tmpl->ce_mask & XFRM_AE_ATTR_PROTO))
return -NLE_MISSING_ATTR;
+ memset(&ae_id, 0, sizeof(ae_id));
+
memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (tmpl->sa_id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->sa_id.daddr));
ae_id.sa_id.spi = htonl(tmpl->sa_id.spi);
ae_id.sa_id.family = tmpl->sa_id.family;
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 48265ba..a8bbced 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -78,6 +78,7 @@
#define XFRM_SA_ATTR_REPLAY_MAXDIFF 0x1000000
#define XFRM_SA_ATTR_REPLAY_STATE 0x2000000
#define XFRM_SA_ATTR_EXPIRE 0x4000000
+#define XFRM_SA_ATTR_OFFLOAD_DEV 0x8000000
static struct nl_cache_ops xfrmnl_sa_ops;
static struct nl_object_ops xfrm_sa_obj_ops;
@@ -125,6 +126,8 @@
free (sa->sec_ctx);
if (sa->replay_state_esn)
free (sa->replay_state_esn);
+ if (sa->user_offload)
+ free(sa->user_offload);
}
static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src)
@@ -133,6 +136,20 @@
struct xfrmnl_sa* src = nl_object_priv(_src);
uint32_t len = 0;
+ dst->sel = NULL;
+ dst->id.daddr = NULL;
+ dst->saddr = NULL;
+ dst->lft = NULL;
+ dst->aead = NULL;
+ dst->auth = NULL;
+ dst->crypt = NULL;
+ dst->comp = NULL;
+ dst->encap = NULL;
+ dst->coaddr = NULL;
+ dst->sec_ctx = NULL;
+ dst->replay_state_esn = NULL;
+ dst->user_offload = NULL;
+
if (src->sel)
if ((dst->sel = xfrmnl_sel_clone (src->sel)) == NULL)
return -NLE_NOMEM;
@@ -149,40 +166,35 @@
if ((dst->saddr = nl_addr_clone (src->saddr)) == NULL)
return -NLE_NOMEM;
- if (src->aead)
- {
+ if (src->aead) {
len = sizeof (struct xfrmnl_algo_aead) + ((src->aead->alg_key_len + 7) / 8);
if ((dst->aead = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->aead, (void *)src->aead, len);
}
- if (src->auth)
- {
+ if (src->auth) {
len = sizeof (struct xfrmnl_algo_auth) + ((src->auth->alg_key_len + 7) / 8);
if ((dst->auth = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->auth, (void *)src->auth, len);
}
- if (src->crypt)
- {
+ if (src->crypt) {
len = sizeof (struct xfrmnl_algo) + ((src->crypt->alg_key_len + 7) / 8);
if ((dst->crypt = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->crypt, (void *)src->crypt, len);
}
- if (src->comp)
- {
+ if (src->comp) {
len = sizeof (struct xfrmnl_algo) + ((src->comp->alg_key_len + 7) / 8);
if ((dst->comp = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->comp, (void *)src->comp, len);
}
- if (src->encap)
- {
+ if (src->encap) {
len = sizeof (struct xfrmnl_encap_tmpl);
if ((dst->encap = calloc (1, len)) == NULL)
return -NLE_NOMEM;
@@ -193,22 +205,26 @@
if ((dst->coaddr = nl_addr_clone (src->coaddr)) == NULL)
return -NLE_NOMEM;
- if (src->sec_ctx)
- {
+ if (src->sec_ctx) {
len = sizeof (*src->sec_ctx) + src->sec_ctx->ctx_len;
if ((dst->sec_ctx = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->sec_ctx, (void *)src->sec_ctx, len);
}
- if (src->replay_state_esn)
- {
+ if (src->replay_state_esn) {
len = sizeof (struct xfrmnl_replay_state_esn) + (src->replay_state_esn->bmp_len * sizeof (uint32_t));
if ((dst->replay_state_esn = calloc (1, len)) == NULL)
return -NLE_NOMEM;
memcpy ((void *)dst->replay_state_esn, (void *)src->replay_state_esn, len);
}
+ if (src->user_offload) {
+ dst->user_offload = _nl_memdup_ptr(src->user_offload);
+ if (!dst->user_offload)
+ return -NLE_NOMEM;
+ }
+
return 0;
}
@@ -333,6 +349,7 @@
__ADD(XFRM_SA_ATTR_REPLAY_MAXDIFF, replay_maxdiff),
__ADD(XFRM_SA_ATTR_REPLAY_STATE, replay_state),
__ADD(XFRM_SA_ATTR_EXPIRE, expire),
+ __ADD(XFRM_SA_ATTR_OFFLOAD_DEV, user_offload),
};
static char* xfrm_sa_attrs2str(int attrs, char *buf, size_t len)
@@ -430,14 +447,23 @@
sprintf (mode, "INF");
else
sprintf (mode, "%" PRIu64, sa->lft->hard_packet_limit);
- nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets)\n", flags, mode);
- nl_dump_line(p, "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n",
- sa->lft->soft_add_expires_seconds, sa->lft->soft_use_expires_seconds);
- nl_dump_line(p, "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n",
- sa->lft->hard_add_expires_seconds, sa->lft->hard_use_expires_seconds);
+ nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets)\n", flags,
+ mode);
+ nl_dump_line(
+ p,
+ "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n",
+ (long long unsigned)sa->lft->soft_add_expires_seconds,
+ (long long unsigned)sa->lft->soft_use_expires_seconds);
+ nl_dump_line(
+ p,
+ "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n",
+ (long long unsigned)sa->lft->hard_add_expires_seconds,
+ (long long unsigned)sa->lft->hard_use_expires_seconds);
nl_dump_line(p, "\tlifetime current: \n");
- nl_dump_line(p, "\t\t%llu bytes, %llu packets\n", sa->curlft.bytes, sa->curlft.packets);
+ nl_dump_line(p, "\t\t%llu bytes, %llu packets\n",
+ (long long unsigned)sa->curlft.bytes,
+ (long long unsigned)sa->curlft.packets);
if (sa->curlft.add_time != 0)
{
add_time = sa->curlft.add_time;
@@ -639,6 +665,7 @@
[XFRMA_SEC_CTX] = { .minlen = sizeof(struct xfrm_sec_ctx) },
[XFRMA_LTIME_VAL] = { .minlen = sizeof(struct xfrm_lifetime_cur) },
[XFRMA_REPLAY_VAL] = { .minlen = sizeof(struct xfrm_replay_state) },
+ [XFRMA_OFFLOAD_DEV] = { .minlen = sizeof(struct xfrm_user_offload) },
[XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
[XFRMA_ETIMER_THRESH] = { .type = NLA_U32 },
[XFRMA_SRCADDR] = { .minlen = sizeof(xfrm_address_t) },
@@ -650,11 +677,7 @@
static int xfrm_sa_request_update(struct nl_cache *c, struct nl_sock *h)
{
- struct xfrm_id sa_id;
-
- memset (&sa_id, 0, sizeof (sa_id));
- return nl_send_simple (h, XFRM_MSG_GETSA, NLM_F_DUMP,
- &sa_id, sizeof (sa_id));
+ return nl_send_simple (h, XFRM_MSG_GETSA, NLM_F_DUMP, NULL, 0);
}
int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
@@ -699,6 +722,8 @@
addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.daddr.a6, sizeof (sa_info->sel.daddr.a6));
nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_d);
xfrmnl_sel_set_daddr (sa->sel, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_sel_set_prefixlen_d (sa->sel, sa_info->sel.prefixlen_d);
if (sa_info->sel.family == AF_INET)
@@ -707,6 +732,8 @@
addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.saddr.a6, sizeof (sa_info->sel.saddr.a6));
nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_s);
xfrmnl_sel_set_saddr (sa->sel, addr);
+ /* Drop the reference count from the above set operation */
+ nl_addr_put(addr);
xfrmnl_sel_set_prefixlen_s (sa->sel, sa_info->sel.prefixlen_s);
xfrmnl_sel_set_dport (sa->sel, ntohs(sa_info->sel.dport));
@@ -913,6 +940,22 @@
sa->replay_state_esn = NULL;
}
+ if (tb[XFRMA_OFFLOAD_DEV]) {
+ struct xfrm_user_offload *offload;
+
+ len = sizeof(struct xfrmnl_user_offload);
+
+ if ((sa->user_offload = calloc(1, len)) == NULL) {
+ err = -NLE_NOMEM;
+ goto errout;
+ }
+
+ offload = nla_data(tb[XFRMA_OFFLOAD_DEV]);
+ sa->user_offload->ifindex = offload->ifindex;
+ sa->user_offload->flags = offload->flags;
+ sa->ce_mask |= XFRM_SA_ATTR_OFFLOAD_DEV;
+ }
+
*result = sa;
return 0;
@@ -1192,8 +1235,7 @@
return -NLE_NOMEM;
}
- strncpy(auth->alg_name, tmpl->auth->alg_name, sizeof(auth->alg_name));
- auth->alg_name[sizeof(auth->alg_name) - 1] = '\0';
+ _nl_strncpy_assert(auth->alg_name, tmpl->auth->alg_name, sizeof(auth->alg_name));
auth->alg_key_len = tmpl->auth->alg_key_len;
memcpy(auth->alg_key, tmpl->auth->alg_key, (tmpl->auth->alg_key_len + 7) / 8);
if (nla_put(msg, XFRMA_ALG_AUTH, len, auth) < 0) {
@@ -1264,6 +1306,21 @@
}
}
+ if (tmpl->ce_mask & XFRM_SA_ATTR_OFFLOAD_DEV) {
+ struct xfrm_user_offload *offload;
+ struct nlattr *attr;
+
+ len = sizeof(struct xfrm_user_offload);
+ attr = nla_reserve(msg, XFRMA_OFFLOAD_DEV, len);
+
+ if (!attr)
+ goto nla_put_failure;
+
+ offload = nla_data(attr);
+ offload->ifindex = tmpl->user_offload->ifindex;
+ offload->flags = tmpl->user_offload->flags;
+ }
+
*result = msg;
return 0;
@@ -1336,6 +1393,7 @@
!(tmpl->ce_mask & XFRM_SA_ATTR_PROTO))
return -NLE_MISSING_ATTR;
+ memset(&sa_id, 0, sizeof(struct xfrm_usersa_id));
memcpy (&sa_id.daddr, nl_addr_get_binary_addr (tmpl->id.daddr),
sizeof (uint8_t) * nl_addr_get_len (tmpl->id.daddr));
sa_id.family = nl_addr_get_family (tmpl->id.daddr);
@@ -2156,6 +2214,57 @@
}
+/**
+ * Get interface id and flags from xfrm_user_offload.
+ *
+ * @arg sa The xfrmnl_sa object.
+ * @arg ifindex An optional output value for the offload interface index.
+ * @arg flags An optional output value for the offload flags.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int xfrmnl_sa_get_user_offload(struct xfrmnl_sa *sa, int *ifindex, uint8_t *flags)
+{
+ int ret = -1;
+
+ if (sa->ce_mask & XFRM_SA_ATTR_OFFLOAD_DEV && sa->user_offload) {
+ if (ifindex)
+ *ifindex = sa->user_offload->ifindex;
+ if (flags)
+ *flags = sa->user_offload->flags;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+/**
+ * Set interface id and flags for xfrm_user_offload.
+ *
+ * @arg sa The xfrmnl_sa object.
+ * @arg ifindex Id of the offload interface.
+ * @arg flags Offload flags for the state.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int xfrmnl_sa_set_user_offload(struct xfrmnl_sa *sa, int ifindex, uint8_t flags)
+{
+ _nl_auto_free struct xfrmnl_user_offload *b = NULL;
+
+ if (!(b = calloc(1, sizeof(*b))))
+ return -1;
+
+ b->ifindex = ifindex;
+ b->flags = flags;
+
+ free(sa->user_offload);
+ sa->user_offload = _nl_steal_pointer(&b);
+ sa->ce_mask |= XFRM_SA_ATTR_OFFLOAD_DEV;
+
+ return 0;
+}
+
int xfrmnl_sa_is_hardexpiry_reached (struct xfrmnl_sa* sa)
{
if (sa->ce_mask & XFRM_SA_ATTR_EXPIRE)
diff --git a/lib/xfrm/sp.c b/lib/xfrm/sp.c
index 99b6a4c..df9e2fb 100644
--- a/lib/xfrm/sp.c
+++ b/lib/xfrm/sp.c
@@ -93,9 +93,8 @@
xfrmnl_sel_put (sp->sel);
xfrmnl_ltime_cfg_put (sp->lft);
- if(sp->sec_ctx)
- {
- free (sp->sec_ctx);
+ if (sp->sec_ctx) {
+ free(sp->sec_ctx);
}
nl_list_for_each_entry_safe(utmpl, tmp, &sp->usertmpl_list, utmpl_list) {
@@ -106,33 +105,38 @@
static int xfrm_sp_clone(struct nl_object *_dst, struct nl_object *_src)
{
- struct xfrmnl_sp* dst = nl_object_priv(_dst);
- struct xfrmnl_sp* src = nl_object_priv(_src);
- uint32_t len = 0;
- struct xfrmnl_user_tmpl *utmpl, *new;
+ struct xfrmnl_sp* dst = nl_object_priv(_dst);
+ struct xfrmnl_sp* src = nl_object_priv(_src);
+ struct xfrmnl_user_tmpl *utmpl;
+ struct xfrmnl_user_tmpl *new;
- if (src->sel)
+ dst->sel = NULL;
+ dst->lft = NULL;
+ dst->sec_ctx = NULL;
+ nl_init_list_head(&dst->usertmpl_list);
+
+ if (src->sel) {
if ((dst->sel = xfrmnl_sel_clone (src->sel)) == NULL)
return -NLE_NOMEM;
-
- if (src->lft)
- if ((dst->lft = xfrmnl_ltime_cfg_clone (src->lft)) == NULL)
- return -NLE_NOMEM;
-
- if(src->sec_ctx)
- {
- len = sizeof (struct xfrmnl_user_sec_ctx) + src->sec_ctx->ctx_len;
- if ((dst->sec_ctx = calloc (1, len)) == NULL)
- return -NLE_NOMEM;
- memcpy ((void *)dst->sec_ctx, (void *)src->sec_ctx, len);
}
- nl_init_list_head(&dst->usertmpl_list);
+ if (src->lft) {
+ if ((dst->lft = xfrmnl_ltime_cfg_clone (src->lft)) == NULL)
+ return -NLE_NOMEM;
+ }
+
+ if (src->sec_ctx) {
+ uint32_t len = sizeof (struct xfrmnl_user_sec_ctx) + src->sec_ctx->ctx_len;
+
+ if ((dst->sec_ctx = malloc (len)) == NULL)
+ return -NLE_NOMEM;
+ memcpy(dst->sec_ctx, src->sec_ctx, len);
+ }
+
nl_list_for_each_entry(utmpl, &src->usertmpl_list, utmpl_list) {
new = xfrmnl_user_tmpl_clone (utmpl);
if (!new)
return -NLE_NOMEM;
-
xfrmnl_sp_add_usertemplate(dst, new);
}
@@ -357,15 +361,25 @@
sprintf (share, "INF");
else
sprintf (share, "%" PRIu64, sp->lft->hard_packet_limit);
- nl_dump_line(p, "\t\tsoft limit: %s (bytes), %s (packets) \n", dir, action);
- nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets) \n", flags, share);
- nl_dump_line(p, "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n",
- sp->lft->soft_add_expires_seconds, sp->lft->soft_use_expires_seconds);
- nl_dump_line(p, "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n",
- sp->lft->hard_add_expires_seconds, sp->lft->hard_use_expires_seconds);
+ nl_dump_line(p, "\t\tsoft limit: %s (bytes), %s (packets) \n", dir,
+ action);
+ nl_dump_line(p, "\t\thard limit: %s (bytes), %s (packets) \n", flags,
+ share);
+ nl_dump_line(
+ p,
+ "\t\tsoft add_time: %llu (seconds), soft use_time: %llu (seconds) \n",
+ (long long unsigned)sp->lft->soft_add_expires_seconds,
+ (long long unsigned)sp->lft->soft_use_expires_seconds);
+ nl_dump_line(
+ p,
+ "\t\thard add_time: %llu (seconds), hard use_time: %llu (seconds) \n",
+ (long long unsigned)sp->lft->hard_add_expires_seconds,
+ (long long unsigned)sp->lft->hard_use_expires_seconds);
nl_dump_line(p, "\tlifetime current: \n");
- nl_dump_line(p, "\t\t%llu bytes, %llu packets\n", sp->curlft.bytes, sp->curlft.packets);
+ nl_dump_line(p, "\t\t%llu bytes, %llu packets\n",
+ (long long unsigned)sp->curlft.bytes,
+ (long long unsigned)sp->curlft.packets);
if (sp->curlft.add_time != 0)
{
@@ -508,11 +522,7 @@
static int xfrm_sp_request_update(struct nl_cache *c, struct nl_sock *h)
{
- struct xfrm_userpolicy_id sp_id;
-
- memset (&sp_id, 0, sizeof (sp_id));
- return nl_send_simple (h, XFRM_MSG_GETPOLICY, NLM_F_DUMP,
- &sp_id, sizeof (sp_id));
+ return nl_send_simple (h, XFRM_MSG_GETPOLICY, NLM_F_DUMP, NULL, 0);
}
int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
@@ -1090,16 +1100,16 @@
return 0;
}
-int xfrmnl_sp_get_curlifetime (struct xfrmnl_sp* sa, unsigned long long int* curr_bytes,
+int xfrmnl_sp_get_curlifetime (struct xfrmnl_sp* sp, unsigned long long int* curr_bytes,
unsigned long long int* curr_packets, unsigned long long int* curr_add_time, unsigned long long int* curr_use_time)
{
- if (sa == NULL || curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL)
+ if (sp == NULL || curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL)
return -1;
- *curr_bytes = sa->curlft.bytes;
- *curr_packets = sa->curlft.packets;
- *curr_add_time = sa->curlft.add_time;
- *curr_use_time = sa->curlft.use_time;
+ *curr_bytes = sp->curlft.bytes;
+ *curr_packets = sp->curlft.packets;
+ *curr_add_time = sp->curlft.add_time;
+ *curr_use_time = sp->curlft.use_time;
return 0;
}
diff --git a/libnl-3.0.pc.in b/libnl-3.0.pc.in
index b87e3dc..ddbc999 100644
--- a/libnl-3.0.pc.in
+++ b/libnl-3.0.pc.in
@@ -7,4 +7,5 @@
Description: Convenience library for netlink sockets
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lnl-@MAJ_VERSION@
+Libs.private: @LIBS@
Cflags: -I${includedir}/libnl@MAJ_VERSION@
diff --git a/libnl-3.sym b/libnl-3.sym
index 82d2f07..95100b1 100644
--- a/libnl-3.sym
+++ b/libnl-3.sym
@@ -363,3 +363,8 @@
global:
nla_nest_end_keep_empty;
} libnl_3_2_29;
+
+libnl_3_6 {
+global:
+ rtnl_link_info_ops_get;
+} libnl_3_5;
diff --git a/libnl-nf-3.sym b/libnl-nf-3.sym
index 504e2dd..013c1ee 100644
--- a/libnl-nf-3.sym
+++ b/libnl-nf-3.sym
@@ -314,3 +314,32 @@
local:
*;
};
+
+libnl_3_6 {
+global:
+ nfnl_log_msg_get_ct;
+ nfnl_log_msg_get_ct_info;
+ nfnl_log_msg_get_hwheader;
+ nfnl_log_msg_get_hwlen;
+ nfnl_log_msg_get_hwtype;
+ nfnl_log_msg_get_vlan_cfi;
+ nfnl_log_msg_get_vlan_id;
+ nfnl_log_msg_get_vlan_prio;
+ nfnl_log_msg_get_vlan_proto;
+ nfnl_log_msg_get_vlan_tag;
+ nfnl_log_msg_set_ct;
+ nfnl_log_msg_set_ct_info;
+ nfnl_log_msg_set_hwheader;
+ nfnl_log_msg_set_hwlen;
+ nfnl_log_msg_set_hwtype;
+ nfnl_log_msg_set_vlan_proto;
+ nfnl_log_msg_set_vlan_tag;
+ nfnl_log_msg_test_ct;
+ nfnl_log_msg_test_ct_info;
+ nfnl_log_msg_test_hwheader;
+ nfnl_log_msg_test_hwlen;
+ nfnl_log_msg_test_hwtype;
+ nfnl_log_msg_test_vlan_proto;
+ nfnl_log_msg_test_vlan_tag;
+ nfnlmsg_ct_parse_nested;
+} libnl_3;
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 4a65503..e54bc6d 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1150,3 +1150,121 @@
rtnl_vlan_set_vlan_id;
rtnl_vlan_set_vlan_prio;
} libnl_3_4;
+
+libnl_3_6 {
+global:
+ rtnl_cls_find_by_handle;
+ rtnl_cls_find_by_prio;
+ rtnl_flower_append_action;
+ rtnl_flower_del_action;
+ rtnl_flower_get_action;
+ rtnl_flower_get_dst_mac;
+ rtnl_flower_get_ip_dscp;
+ rtnl_flower_get_proto;
+ rtnl_flower_get_src_mac;
+ rtnl_flower_get_vlan_id;
+ rtnl_flower_get_vlan_prio;
+ rtnl_flower_set_dst_mac;
+ rtnl_flower_set_flags;
+ rtnl_flower_set_ip_dscp;
+ rtnl_flower_set_proto;
+ rtnl_flower_set_src_mac;
+ rtnl_flower_set_vlan_ethtype;
+ rtnl_flower_set_vlan_id;
+ rtnl_flower_set_vlan_prio;
+ rtnl_link_can_get_data_bittiming;
+ rtnl_link_can_get_data_bittiming_const;
+ rtnl_link_can_set_data_bittiming;
+ rtnl_link_can_set_data_bittiming_const;
+ rtnl_link_ip6_tnl_get_fwmark;
+ rtnl_link_ip6_tnl_set_fwmark;
+ rtnl_link_ip6gre_add;
+ rtnl_link_ip6gre_alloc;
+ rtnl_link_ip6gre_get_encaplimit;
+ rtnl_link_ip6gre_get_flags;
+ rtnl_link_ip6gre_get_flowinfo;
+ rtnl_link_ip6gre_get_fwmark;
+ rtnl_link_ip6gre_get_iflags;
+ rtnl_link_ip6gre_get_ikey;
+ rtnl_link_ip6gre_get_link;
+ rtnl_link_ip6gre_get_local;
+ rtnl_link_ip6gre_get_oflags;
+ rtnl_link_ip6gre_get_okey;
+ rtnl_link_ip6gre_get_remote;
+ rtnl_link_ip6gre_get_ttl;
+ rtnl_link_ip6gre_set_encaplimit;
+ rtnl_link_ip6gre_set_flags;
+ rtnl_link_ip6gre_set_flowinfo;
+ rtnl_link_ip6gre_set_fwmark;
+ rtnl_link_ip6gre_set_iflags;
+ rtnl_link_ip6gre_set_ikey;
+ rtnl_link_ip6gre_set_link;
+ rtnl_link_ip6gre_set_local;
+ rtnl_link_ip6gre_set_oflags;
+ rtnl_link_ip6gre_set_okey;
+ rtnl_link_ip6gre_set_remote;
+ rtnl_link_ip6gre_set_ttl;
+ rtnl_link_ip6vti_add;
+ rtnl_link_ip6vti_alloc;
+ rtnl_link_ip6vti_get_fwmark;
+ rtnl_link_ip6vti_get_ikey;
+ rtnl_link_ip6vti_get_link;
+ rtnl_link_ip6vti_get_local;
+ rtnl_link_ip6vti_get_okey;
+ rtnl_link_ip6vti_get_remote;
+ rtnl_link_ip6vti_set_fwmark;
+ rtnl_link_ip6vti_set_ikey;
+ rtnl_link_ip6vti_set_link;
+ rtnl_link_ip6vti_set_local;
+ rtnl_link_ip6vti_set_okey;
+ rtnl_link_ip6vti_set_remote;
+ rtnl_link_ipgre_get_fwmark;
+ rtnl_link_ipgre_set_fwmark;
+ rtnl_link_ipip_get_fwmark;
+ rtnl_link_ipip_set_fwmark;
+ rtnl_link_ipvti_get_fwmark;
+ rtnl_link_ipvti_set_fwmark;
+ rtnl_link_is_ip6gre;
+ rtnl_link_is_ip6vti;
+ rtnl_link_macsec_get_offload;
+ rtnl_link_macsec_set_offload;
+ rtnl_link_sit_get_fwmark;
+ rtnl_link_sit_set_fwmark;
+ rtnl_link_team_add;
+ rtnl_link_team_alloc;
+ rtnl_mdb_add_entry;
+ rtnl_mdb_alloc_cache;
+ rtnl_mdb_alloc_cache_flags;
+ rtnl_mdb_entry_get_addr;
+ rtnl_mdb_entry_get_ifindex;
+ rtnl_mdb_entry_get_proto;
+ rtnl_mdb_entry_get_state;
+ rtnl_mdb_entry_get_vid;
+ rtnl_mdb_foreach_entry;
+ rtnl_mdb_get_ifindex;
+ rtnl_netconf_alloc_cache;
+ rtnl_netconf_get_ignore_routes_linkdown;
+ rtnl_netconf_get_proxy_neigh;
+ rtnl_qdisc_get_by_kind;
+ rtnl_route_lookup;
+ rtnl_route_nh_get_encap_mpls_dst;
+ rtnl_route_nh_get_encap_mpls_ttl;
+} libnl_3_5;
+
+libnl_3_7 {
+global:
+ rtnl_flower_get_ipv4_dst;
+ rtnl_flower_get_ipv4_src;
+ rtnl_flower_set_ipv4_dst;
+ rtnl_flower_set_ipv4_src;
+ rtnl_nat_get_action;
+ rtnl_nat_get_flags;
+ rtnl_nat_get_mask;
+ rtnl_nat_get_new_addr;
+ rtnl_nat_get_old_addr;
+ rtnl_nat_set_action;
+ rtnl_nat_set_flags;
+ rtnl_nat_set_mask;
+ rtnl_nat_set_new_addr;
+ rtnl_nat_set_old_addr;
+} libnl_3_6;
diff --git a/libnl-xfrm-3.sym b/libnl-xfrm-3.sym
index 3706f33..7f5858f 100644
--- a/libnl-xfrm-3.sym
+++ b/libnl-xfrm-3.sym
@@ -244,3 +244,8 @@
local:
*;
};
+
+libnl_3_6 {
+ xfrmnl_sa_get_user_offload;
+ xfrmnl_sa_set_user_offload;
+} libnl_3;
diff --git a/m4/.gitignore b/m4/.gitignore
index 8d0c756..e69de29 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1,2 +0,0 @@
-/lt*.m4
-/libtool.m4
diff --git a/python/.gitignore b/python/.gitignore
deleted file mode 100644
index a83b942..0000000
--- a/python/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-build
-capi_wrap.c
-capi.py
-setup.py
diff --git a/python/examples/iface.py b/python/examples/iface.py
index 7021882..ddf5f12 100644
--- a/python/examples/iface.py
+++ b/python/examples/iface.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import netlink.capi as nl
import netlink.genl.capi as genl
import nl80211
@@ -6,7 +7,7 @@
class test_class:
def __init__(self):
- self.done = 1;
+ self.done = 1
def msg_handler(m, a):
try:
@@ -16,7 +17,7 @@
thiswiphy = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY])
print("phy#%d" % thiswiphy)
if nl80211.NL80211_ATTR_IFNAME in attr:
- print("\tinterface %s" % nl.nla_get_string(attr[nl80211.NL80211_ATTR_IFNAME]));
+ print("\tinterface %s" % nl.nla_get_string(attr[nl80211.NL80211_ATTR_IFNAME]))
if nl80211.NL80211_ATTR_IFINDEX in attr:
print("\tifindex %d" % nl.nla_get_u32(attr[nl80211.NL80211_ATTR_IFINDEX]))
if nl80211.NL80211_ATTR_WDEV in attr:
@@ -31,7 +32,7 @@
if nl80211.NL80211_ATTR_WIPHY_FREQ in attr:
freq = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY_FREQ])
- sys.stdout.write("\tfreq %d MHz" % freq);
+ sys.stdout.write("\tfreq %d MHz" % freq)
if nl80211.NL80211_ATTR_CHANNEL_WIDTH in attr:
chanw = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_CHANNEL_WIDTH])
@@ -44,13 +45,13 @@
nl.nla_get_u32(attr[nl80211.NL80211_ATTR_CENTER_FREQ2]))
elif nl80211.NL80211_ATTR_WIPHY_CHANNEL_TYPE in attr:
channel_type = nl.nla_get_u32(attr[nl80211.NL80211_ATTR_WIPHY_CHANNEL_TYPE])
- sys.stdout.write(" %s" % nl80211.nl80211_channel_type2str(channel_type));
+ sys.stdout.write(" %s" % nl80211.nl80211_channel_type2str(channel_type))
- sys.stdout.write("\n");
- return nl.NL_SKIP;
+ sys.stdout.write("\n")
+ return nl.NL_SKIP
except Exception as e:
(t,v,tb) = sys.exc_info()
- print v.message
+ print(v.message)
traceback.print_tb(tb)
def error_handler(err, a):
@@ -69,10 +70,10 @@
tx_cb = nl.nl_cb_alloc(nl.NL_CB_DEFAULT)
rx_cb = nl.nl_cb_clone(tx_cb)
s = nl.nl_socket_alloc_cb(tx_cb)
- nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd);
+ nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd)
genl.genl_connect(s)
family = genl.genl_ctrl_resolve(s, 'nl80211')
@@ -80,14 +81,14 @@
genl.genlmsg_put(m, 0, 0, family, 0, 0, nl80211.NL80211_CMD_GET_INTERFACE, 0)
nl.nla_put_u32(m, nl80211.NL80211_ATTR_IFINDEX, nl.if_nametoindex('wlan0'))
- err = nl.nl_send_auto_complete(s, m);
+ err = nl.nl_send_auto_complete(s, m)
if err < 0:
- nl.nlmsg_free(msg)
+ nl.nlmsg_free(m)
while cbd.done > 0 and not err < 0:
err = nl.nl_recvmsgs(s, rx_cb)
except Exception as e:
(t, v, tb) = sys.exc_info()
- print v.message
+ print(v.message)
traceback.print_tb(tb)
diff --git a/python/examples/wiphy.py b/python/examples/wiphy.py
index 73e2d4d..6601883 100644
--- a/python/examples/wiphy.py
+++ b/python/examples/wiphy.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import netlink.capi as nl
import netlink.genl.capi as genl
import nl80211
@@ -6,23 +7,23 @@
class test_class:
def __init__(self):
- self.done = 1;
+ self.done = 1
def freq_to_ch(freq):
if freq == 2484:
- return 14;
+ return 14
if freq < 2484:
- return (freq - 2407) / 5;
+ return (freq - 2407) / 5
# FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2)
if freq < 45000:
- return freq/5 - 1000;
+ return freq/5 - 1000
if freq >= 58320 and freq <= 64800:
- return (freq - 56160) / 2160;
+ return (freq - 56160) / 2160
- return 0;
+ return 0
def handle_freq(attr, pol):
e, fattr = nl.py_nla_parse_nested(nl80211.NL80211_FREQUENCY_ATTR_MAX, attr, pol)
@@ -83,7 +84,7 @@
ciphers = nl.nla_data(attr[nl80211.NL80211_ATTR_CIPHER_SUITES])
num = len(ciphers) / 4
if num > 0:
- print("\tSupported Ciphers:");
+ print("\tSupported Ciphers:")
for i in range(0, num, 4):
print("\t\t* %s" % cipher_name(ciphers[i:i+4]))
if nl80211.NL80211_ATTR_SUPPORTED_IFTYPES in attr:
@@ -99,7 +100,7 @@
return nl.NL_SKIP
except Exception as e:
(t,v,tb) = sys.exc_info()
- print v.message
+ print(v.message)
traceback.print_tb(tb)
def error_handler(err, a):
@@ -118,10 +119,10 @@
tx_cb = nl.nl_cb_alloc(nl.NL_CB_DEFAULT)
rx_cb = nl.nl_cb_clone(tx_cb)
s = nl.nl_socket_alloc_cb(tx_cb)
- nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd);
- nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd);
+ nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd)
+ nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd)
genl.genl_connect(s)
family = genl.genl_ctrl_resolve(s, 'nl80211')
@@ -129,13 +130,13 @@
genl.genlmsg_put(m, 0, 0, family, 0, 0, nl80211.NL80211_CMD_GET_WIPHY, 0)
nl.nla_put_u32(m, nl80211.NL80211_ATTR_WIPHY, 7)
- err = nl.nl_send_auto_complete(s, m);
+ err = nl.nl_send_auto_complete(s, m)
if err < 0:
- nl.nlmsg_free(msg)
+ nl.nlmsg_free(m)
while cbd.done > 0 and not err < 0:
err = nl.nl_recvmsgs(s, rx_cb)
except Exception as e:
(t, v, tb) = sys.exc_info()
- print v.message
+ print(v.message)
traceback.print_tb(tb)
diff --git a/python/netlink/core.py b/python/netlink/core.py
index e5864cf..1a8ea8f 100644
--- a/python/netlink/core.py
+++ b/python/netlink/core.py
@@ -127,7 +127,7 @@
capi.nlmsg_free(self._msg)
def __len__(self):
- return capi.nlmsg_len(nlmsg_hdr(self._msg))
+ return capi.nlmsg_len(capi.nlmsg_hdr(self._msg))
@property
def protocol(self):
diff --git a/python/netlink/route/link.py b/python/netlink/route/link.py
index 5ec14b2..e3a6bd3 100644
--- a/python/netlink/route/link.py
+++ b/python/netlink/route/link.py
@@ -40,7 +40,6 @@
__all__ = [
'LinkCache',
'Link',
- 'get_from_kernel',
]
import socket
@@ -159,7 +158,7 @@
if exc_type is None:
self.change()
else:
- return false
+ return False
@classmethod
def from_capi(cls, obj):
diff --git a/python/netlink/route/links/bridge.py b/python/netlink/route/links/bridge.py
index 549b092..cf4e764 100644
--- a/python/netlink/route/links/bridge.py
+++ b/python/netlink/route/links/bridge.py
@@ -7,6 +7,7 @@
"""
from __future__ import absolute_import
+from __future__ import print_function
from ... import core as netlink
from .. import capi as capi
@@ -19,10 +20,10 @@
def bridge_assert_ext_info(self):
if self._has_ext_info == False:
- print """
+ print("""
Please update your kernel to be able to call this method.
Your current kernel bridge version is too old to support this extention.
- """
+ """)
raise RuntimeWarning()
def port_state2str(self, state):
@@ -51,12 +52,12 @@
def priority(self):
"""bridge prio
"""
- bridge_assert_ext_info()
+ self.bridge_assert_ext_info()
return capi.rtnl_link_bridge_get_prio(self._link)
@priority.setter
def priority(self, prio):
- bridge_assert_ext_info()
+ self.bridge_assert_ext_info()
if prio < 0 or prio >= 2**16:
raise ValueError()
capi.rtnl_link_bridge_set_prio(self._link, int(prio))
@@ -66,12 +67,12 @@
def cost(self):
"""bridge prio
"""
- bridge_assert_ext_info()
+ self.bridge_assert_ext_info()
return capi.rtnl_link_bridge_get_cost(self._link)
@cost.setter
def cost(self, cost):
- bridge_assert_ext_info()
+ self.bridge_assert_ext_info()
if cost < 0 or cost >= 2**32:
raise ValueError()
capi.rtnl_link_bridge_set_cost(self._link, int(cost))
diff --git a/python/netlink/route/links/inet.py b/python/netlink/route/links/inet.py
index f5f45cb..d4de07b 100644
--- a/python/netlink/route/links/inet.py
+++ b/python/netlink/route/links/inet.py
@@ -8,9 +8,7 @@
from __future__ import absolute_import
-__all__ = [
- '',
-]
+__all__ = []
from ... import core as netlink
from .. import capi as capi
diff --git a/python/tests/test-create-bridge.py b/python/tests/test-create-bridge.py
index 216b249..3b91556 100644
--- a/python/tests/test-create-bridge.py
+++ b/python/tests/test-create-bridge.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import netlink.core as netlink
import netlink.route.capi as capi
import netlink.route.link as link
@@ -8,21 +9,21 @@
cache.refill(sock)
testtap1 = cache['testtap1']
-print testtap1
+print(testtap1)
lbr = link.Link()
lbr.type = 'bridge'
lbr.name = 'testbridge'
-print lbr
+print(lbr)
lbr.add()
cache.refill(sock)
lbr = cache['testbridge']
-print lbr
+print(lbr)
lbr.enslave(testtap1)
cache.refill(sock)
testtap1 = cache['testtap1']
-print capi.rtnl_link_is_bridge(lbr._rtnl_link)
-print capi.rtnl_link_get_master(testtap1._rtnl_link)
+print(capi.rtnl_link_is_bridge(lbr._rtnl_link))
+print(capi.rtnl_link_get_master(testtap1._rtnl_link))
diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644
index e53eb3d..0000000
--- a/src/.gitignore
+++ /dev/null
@@ -1,47 +0,0 @@
-genl-ctrl-list
-idiag-socket-details
-nf-ct-add
-nf-ct-events
-nf-ct-list
-nf-exp-add
-nf-exp-delete
-nf-exp-list
-nf-log
-nf-monitor
-nf-queue
-nl-addr-add
-nl-addr-delete
-nl-addr-list
-nl-class-add
-nl-class-delete
-nl-class-list
-nl-classid-lookup
-nl-cls-add
-nl-cls-delete
-nl-cls-list
-nl-fib-lookup
-nl-link-enslave
-nl-link-ifindex2name
-nl-link-list
-nl-link-name2ifindex
-nl-link-release
-nl-link-set
-nl-link-stats
-nl-list-caches
-nl-list-sockets
-nl-monitor
-nl-neigh-add
-nl-neigh-delete
-nl-neigh-list
-nl-neightbl-list
-nl-pktloc-lookup
-nl-qdisc-add
-nl-qdisc-delete
-nl-qdisc-list
-nl-route-add
-nl-route-delete
-nl-route-get
-nl-route-list
-nl-rule-list
-nl-tctree-list
-nl-util-addr
diff --git a/src/genl-ctrl-list.c b/src/genl-ctrl-list.c
index d3279a8..62bed3c 100644
--- a/src/genl-ctrl-list.c
+++ b/src/genl-ctrl-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/genl-ctrl-list.c List Generic Netlink Families
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/idiag-socket-details.c b/src/idiag-socket-details.c
index 2d7dd4b..6f03627 100644
--- a/src/idiag-socket-details.c
+++ b/src/idiag-socket-details.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * src/idiag-socket-details.c List socket details
- *
- * This library 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 version 2 of the License.
- *
* Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
*/
diff --git a/src/lib/addr.c b/src/lib/addr.c
index 5d39f7c..a79e9b4 100644
--- a/src/lib/addr.c
+++ b/src/lib/addr.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/addr.c Address Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/class.c b/src/lib/class.c
index 162e542..d7312c3 100644
--- a/src/lib/class.c
+++ b/src/lib/class.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/class.c CLI Class Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/cls.c b/src/lib/cls.c
index a5ac925..d8fd1a8 100644
--- a/src/lib/cls.c
+++ b/src/lib/cls.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/cls.c CLI Classifier Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/ct.c b/src/lib/ct.c
index e6732ae..c00c0fb 100644
--- a/src/lib/ct.c
+++ b/src/lib/ct.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/ct.c CLI Conntrack Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/exp.c b/src/lib/exp.c
index 732843f..48d4ea0 100644
--- a/src/lib/exp.c
+++ b/src/lib/exp.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/exp.c CLI Expectation Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2012 Rich Fought <rich.fought@watchguard.com>
*/
diff --git a/src/lib/link.c b/src/lib/link.c
index ae367e4..d1c3e4b 100644
--- a/src/lib/link.c
+++ b/src/lib/link.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/link.c CLI Link Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/neigh.c b/src/lib/neigh.c
index 75862c7..5b44f47 100644
--- a/src/lib/neigh.c
+++ b/src/lib/neigh.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/neigh.c CLI Neighbour Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/qdisc.c b/src/lib/qdisc.c
index ea047c2..beb83cc 100644
--- a/src/lib/qdisc.c
+++ b/src/lib/qdisc.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/qdisc.c CLI QDisc Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/route.c b/src/lib/route.c
index 9d0fbe8..7297a2f 100644
--- a/src/lib/route.c
+++ b/src/lib/route.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/route.c CLI Route Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/rule.c b/src/lib/rule.c
index 213eca2..6ef9321 100644
--- a/src/lib/rule.c
+++ b/src/lib/rule.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/rule.c CLI Routing Rule Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/tc.c b/src/lib/tc.c
index 5d3a203..ba3de18 100644
--- a/src/lib/tc.c
+++ b/src/lib/tc.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/lib/tc.c CLI Traffic Control Helpers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/lib/utils.c b/src/lib/utils.c
index 3aa2a90..cbcdafe 100644
--- a/src/lib/utils.c
+++ b/src/lib/utils.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/utils.c Utilities
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
@@ -236,10 +229,13 @@
{
void *handle;
- if (!(handle = dlopen(path, RTLD_NOW))) {
+ handle = dlopen(path, RTLD_NOW);
+ if (!handle) {
nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n",
path, dlerror());
}
+ /* We intentionally leak the dlopen handle. */
+ /* coverity[RESOURCE_LEAK] */
}
#else
nl_cli_fatal(ENOTSUP, "Unable to load module \"%s\": built without dynamic libraries support\n",
diff --git a/src/nf-ct-add.c b/src/nf-ct-add.c
index eec9b86..632acd9 100644
--- a/src/nf-ct-add.c
+++ b/src/nf-ct-add.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-ct-add.c Add Conntrack Entry
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-ct-events.c b/src/nf-ct-events.c
index 87f2da9..68f9ac0 100644
--- a/src/nf-ct-events.c
+++ b/src/nf-ct-events.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-ct-events.c Listen on Conntrack Events
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2018 Avast software
*/
diff --git a/src/nf-ct-list.c b/src/nf-ct-list.c
index c512027..692c24b 100644
--- a/src/nf-ct-list.c
+++ b/src/nf-ct-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-ct-list.c List Conntrack Entries
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-exp-add.c b/src/nf-exp-add.c
index 1f71cd5..ae74528 100644
--- a/src/nf-exp-add.c
+++ b/src/nf-exp-add.c
@@ -1,17 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-exp-add.c Create an expectation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
* Copyright (c) 2012 Rich Fought <rich.fought@watchguard.com>
- *
*/
#include <netlink/cli/utils.h>
diff --git a/src/nf-exp-delete.c b/src/nf-exp-delete.c
index c6e478c..9d1eea9 100644
--- a/src/nf-exp-delete.c
+++ b/src/nf-exp-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-exp-delete.c Delete an expectation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-exp-list.c b/src/nf-exp-list.c
index 0993a98..25fd51f 100644
--- a/src/nf-exp-list.c
+++ b/src/nf-exp-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-exp-list.c List Expectation Entries
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-log.c b/src/nf-log.c
index c8a40bf..c9ad560 100644
--- a/src/nf-log.c
+++ b/src/nf-log.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-log.c Monitor netfilter log events
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-monitor.c b/src/nf-monitor.c
index 4afbdb2..1f67289 100644
--- a/src/nf-monitor.c
+++ b/src/nf-monitor.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-monitor.c Monitor netfilter events
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
diff --git a/src/nf-queue.c b/src/nf-queue.c
index f46abc2..ec15f63 100644
--- a/src/nf-queue.c
+++ b/src/nf-queue.c
@@ -1,17 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nf-queue.c Monitor netfilter queue events
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
* Copyright (c) 2010 Karl Hiramoto <karl@hiramoto.org>
*/
-
#include <netlink/cli/utils.h>
#include <netlink/cli/link.h>
#include <netinet/in.h>
diff --git a/src/nl-addr-add.c b/src/nl-addr-add.c
index e6ebefe..3560f4d 100644
--- a/src/nl-addr-add.c
+++ b/src/nl-addr-add.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * src/nl-addr-add.c Add addresses
- *
- * This library 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 version 2 of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-addr-delete.c b/src/nl-addr-delete.c
index 9d017f4..a8887ac 100644
--- a/src/nl-addr-delete.c
+++ b/src/nl-addr-delete.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * src/nl-addr-delete.c Delete addresses
- *
- * This library 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 version 2 of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-addr-list.c b/src/nl-addr-list.c
index c5258bd..d80d862 100644
--- a/src/nl-addr-list.c
+++ b/src/nl-addr-list.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * src/nl-addr-list.c List addresses
- *
- * This library 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 version 2 of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-class-add.c b/src/nl-class-add.c
index a1ccf4e..d3f9230 100644
--- a/src/nl-class-add.c
+++ b/src/nl-class-add.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-class-add.c Add/Update/Replace Traffic Class
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-class-delete.c b/src/nl-class-delete.c
index 5627821..1747a65 100644
--- a/src/nl-class-delete.c
+++ b/src/nl-class-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-class-delete.c Delete Traffic Classes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-class-list.c b/src/nl-class-list.c
index 0ce4ab2..ba8e154 100644
--- a/src/nl-class-list.c
+++ b/src/nl-class-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-class-list.c List Traffic Classes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-classid-lookup.c b/src/nl-classid-lookup.c
index 4ddc842..7b82c37 100644
--- a/src/nl-classid-lookup.c
+++ b/src/nl-classid-lookup.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-classid-lookup.c Lookup classid
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-cls-add.c b/src/nl-cls-add.c
index c2ad717..a29beb7 100644
--- a/src/nl-cls-add.c
+++ b/src/nl-cls-add.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * src/nl-cls-add.c Add classifier
- *
- * This library 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 version 2 of the License.
- *
* Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-cls-delete.c b/src/nl-cls-delete.c
index a2a93a7..20079a2 100644
--- a/src/nl-cls-delete.c
+++ b/src/nl-cls-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-cls-delete.c Delete Classifier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-cls-list.c b/src/nl-cls-list.c
index 5d4faa0..65757d0 100644
--- a/src/nl-cls-list.c
+++ b/src/nl-cls-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-cls-list.c List classifiers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-fib-lookup.c b/src/nl-fib-lookup.c
index a649687..4239063 100644
--- a/src/nl-fib-lookup.c
+++ b/src/nl-fib-lookup.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-fib-lookup.c FIB Route Lookup
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-enslave.c b/src/nl-link-enslave.c
index 4e368c3..ba4817a 100644
--- a/src/nl-link-enslave.c
+++ b/src/nl-link-enslave.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-enslave.c Enslave a link
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-ifindex2name.c b/src/nl-link-ifindex2name.c
index 0cb3cbe..05eb788 100644
--- a/src/nl-link-ifindex2name.c
+++ b/src/nl-link-ifindex2name.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-ifindex2name.c Transform a interface index to its name
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-list.c b/src/nl-link-list.c
index d382076..e07bd43 100644
--- a/src/nl-link-list.c
+++ b/src/nl-link-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-dump.c Dump link attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-name2ifindex.c b/src/nl-link-name2ifindex.c
index d3e8399..3ff774e 100644
--- a/src/nl-link-name2ifindex.c
+++ b/src/nl-link-name2ifindex.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-name2ifindex.c Transform a interface name to its index
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-release.c b/src/nl-link-release.c
index abe8cdb..1c869ad 100644
--- a/src/nl-link-release.c
+++ b/src/nl-link-release.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-release.c release a link
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-set.c b/src/nl-link-set.c
index fc0f5a7..5b54da0 100644
--- a/src/nl-link-set.c
+++ b/src/nl-link-set.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-set.c Set link attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-link-stats.c b/src/nl-link-stats.c
index 85719c1..d993f71 100644
--- a/src/nl-link-stats.c
+++ b/src/nl-link-stats.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-link-stats.c Retrieve link statistics
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-list-caches.c b/src/nl-list-caches.c
index c59f95b..966f13a 100644
--- a/src/nl-list-caches.c
+++ b/src/nl-list-caches.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * nl-list-caches.c List registered cache types
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-list-sockets.c b/src/nl-list-sockets.c
index e7d4703..b69b2c2 100644
--- a/src/nl-list-sockets.c
+++ b/src/nl-list-sockets.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * nl-list-sockets.c Pretty-print /proc/net/netlink
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-monitor.c b/src/nl-monitor.c
index a6f21b4..86294fb 100644
--- a/src/nl-monitor.c
+++ b/src/nl-monitor.c
@@ -1,17 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-monitor.c Monitor events
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
#include <netlink/cli/utils.h>
#include <netlink/cli/link.h>
+#include <netlink/cli/mdb.h>
#include <linux/rtnetlink.h>
@@ -36,6 +30,7 @@
{ RTNLGRP_IPV4_NETCONF, "ipv4-netconf" },
{ RTNLGRP_IPV6_NETCONF, "ipv6-netconf" },
{ RTNLGRP_MPLS_NETCONF, "mpls-netconf" },
+ { RTNLGRP_MDB, "mdb" },
{ RTNLGRP_NONE, NULL }
};
@@ -61,6 +56,7 @@
"Usage: nl-monitor [OPTION] [<groups>]\n"
"\n"
"Options\n"
+ " -d, --debug=LEVEL Set libnl debug level { 0 - 7 }\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help.\n"
"\n"
@@ -91,15 +87,20 @@
for (;;) {
int c, optidx = 0;
static struct option long_opts[] = {
+ { "debug", 1, 0, 'd' },
{ "format", 1, 0, 'f' },
+ { "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};
- c = getopt_long(argc, argv, "f:h", long_opts, &optidx);
+ c = getopt_long(argc, argv, "d:f:h", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
+ case 'd':
+ nl_debug = atoi(optarg);
+ break;
case 'f':
dp.dp_type = nl_cli_parse_dumptype(optarg);
break;
diff --git a/src/nl-neigh-add.c b/src/nl-neigh-add.c
index 585639a..cd6063e 100644
--- a/src/nl-neigh-add.c
+++ b/src/nl-neigh-add.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/ nl-neigh-add.c Add a neighbour
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-neigh-delete.c b/src/nl-neigh-delete.c
index 826c1c5..6f1ffef 100644
--- a/src/nl-neigh-delete.c
+++ b/src/nl-neigh-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-neigh-delete.c Delete a neighbour
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-neigh-list.c b/src/nl-neigh-list.c
index a926208..2664c8f 100644
--- a/src/nl-neigh-list.c
+++ b/src/nl-neigh-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-neigh-list.c List Neighbours
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-neightbl-list.c b/src/nl-neightbl-list.c
index 10d7ed4..5a5b0a0 100644
--- a/src/nl-neightbl-list.c
+++ b/src/nl-neightbl-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-neightbl-list.c Dump neighbour tables
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-pktloc-lookup.c b/src/nl-pktloc-lookup.c
index 8b1272c..606b2db 100644
--- a/src/nl-pktloc-lookup.c
+++ b/src/nl-pktloc-lookup.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-pktloc-lookup.c Lookup packet location alias
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
@@ -14,6 +7,8 @@
#include <netlink/route/pktloc.h>
#include <linux/tc_ematch/tc_em_cmp.h>
+#include "netlink-private/utils.h"
+
static void print_usage(void)
{
printf(
@@ -52,8 +47,19 @@
[TCF_LAYER_TRANSPORT] = "tcp"
};
+static const char *get_align_txt(struct rtnl_pktloc *loc, char buf[static 16])
+{
+ if (loc->align < _NL_N_ELEMENTS(align_txt))
+ return align_txt[loc->align];
+
+ snprintf(buf, 16, "%u", loc->align);
+ return buf;
+}
+
static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value)
{
+ char buf[16];
+
if (loc->align > 4)
nl_cli_fatal(EINVAL, "u32 only supports alignments u8|u16|u32.");
@@ -64,37 +70,35 @@
if (loc->shift > 0)
nl_cli_fatal(EINVAL, "u32 does not support shifting.");
- printf("%s %x %x at %s%u\n",
- align_txt[loc->align],
- value, loc->mask ? loc->mask : align_mask[loc->align],
- loc->layer == TCF_LAYER_TRANSPORT ? "nexthdr+" : "",
- loc->offset);
-}
-
-static char *get_align_txt(struct rtnl_pktloc *loc)
-{
- static char buf[16];
-
- if (loc->align <= 4)
- strcpy(buf, align_txt[loc->align]);
- else
- snprintf(buf, sizeof(buf), "%u", loc->align);
-
- return buf;
+ printf("%s %x %x at %s%u\n", get_align_txt(loc, buf), value,
+ loc->mask ? loc->mask :
+ (loc->align < _NL_N_ELEMENTS(align_mask) ?
+ align_mask[loc->align] :
+ 0),
+ loc->layer == TCF_LAYER_TRANSPORT ? "nexthdr+" : "",
+ loc->offset);
}
static void dump_loc(struct rtnl_pktloc *loc)
{
- printf("%s = %s at %s+%u & %#x >> %u\n",
- loc->name, get_align_txt(loc), layer_txt[loc->layer],
- loc->offset, loc->mask, loc->shift);
+ char buf[16];
+
+ printf("%s = %s at %s+%u & %#x >> %u\n", loc->name,
+ get_align_txt(loc, buf),
+ loc->layer < _NL_N_ELEMENTS(layer_txt) ? layer_txt[loc->layer] :
+ "???",
+ loc->offset, loc->mask, loc->shift);
}
static void list_cb(struct rtnl_pktloc *loc, void *arg)
{
- printf("%-26s %-5s %3s+%-4u %#-10x %-8u %u\n",
- loc->name, get_align_txt(loc), layer_txt[loc->layer],
- loc->offset, loc->mask, loc->shift, loc->refcnt);
+ char buf[16];
+
+ printf("%-26s %-5s %3s+%-4u %#-10x %-8u %u\n", loc->name,
+ get_align_txt(loc, buf),
+ loc->layer < _NL_N_ELEMENTS(layer_txt) ? layer_txt[loc->layer] :
+ "???",
+ loc->offset, loc->mask, loc->shift, loc->refcnt);
}
static void do_list(void)
diff --git a/src/nl-qdisc-add.c b/src/nl-qdisc-add.c
index 38903f3..8cd317c 100644
--- a/src/nl-qdisc-add.c
+++ b/src/nl-qdisc-add.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-qdisc-add.c Add Queueing Discipline
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-qdisc-delete.c b/src/nl-qdisc-delete.c
index 7c5926b..299fd48 100644
--- a/src/nl-qdisc-delete.c
+++ b/src/nl-qdisc-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-qdisc-delete.c Delete Queuing Disciplines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-qdisc-list.c b/src/nl-qdisc-list.c
index 6796ca5..d1825da 100644
--- a/src/nl-qdisc-list.c
+++ b/src/nl-qdisc-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-qdisc-list.c List Queueing Disciplines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-route-add.c b/src/nl-route-add.c
index ed2c4e2..4e96ab0 100644
--- a/src/nl-route-add.c
+++ b/src/nl-route-add.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-route-add.c Route addition utility
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-route-delete.c b/src/nl-route-delete.c
index 750b57f..9b4366c 100644
--- a/src/nl-route-delete.c
+++ b/src/nl-route-delete.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-route-delete.c Delete Routes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-route-get.c b/src/nl-route-get.c
index 564fc16..b49ba4c 100644
--- a/src/nl-route-get.c
+++ b/src/nl-route-get.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-route-get.c Get Route Attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-route-list.c b/src/nl-route-list.c
index b6c4270..1b293ed 100644
--- a/src/nl-route-list.c
+++ b/src/nl-route-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-route-list.c List route attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-rule-list.c b/src/nl-rule-list.c
index b923184..fe87dfe 100644
--- a/src/nl-rule-list.c
+++ b/src/nl-rule-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-rule-dump.c Dump rule attributes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-tctree-list.c b/src/nl-tctree-list.c
index 9e03038..16f6f00 100644
--- a/src/nl-tctree-list.c
+++ b/src/nl-tctree-list.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-tctree-list.c List Traffic Control Tree
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/src/nl-util-addr.c b/src/nl-util-addr.c
index 6a81166..de92302 100644
--- a/src/nl-util-addr.c
+++ b/src/nl-util-addr.c
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * src/nl-util-addr.c Address Helper
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
*/
diff --git a/tests/.gitignore b/tests/.gitignore
deleted file mode 100644
index 90af67a..0000000
--- a/tests/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-/check-all
-/check-all.log
-/check-all.trs
-/test-*.log
-/test-*.trs
-/test-cache-mngr
-/test-complex-HTB-with-hash-filters
-/test-create-bond
-/test-create-bridge
-/test-create-geneve
-/test-create-ifb
-/test-create-ip6tnl
-/test-create-ipgre
-/test-create-ipgretap
-/test-create-ipip
-/test-create-ipvlan
-/test-create-ipvti
-/test-create-macsec
-/test-create-macvlan
-/test-create-macvtap
-/test-create-sit
-/test-create-veth
-/test-create-vlan
-/test-create-vrf
-/test-create-vxlan
-/test-create-xfrmi
-/test-delete-link
-/test-genl
-/test-loopback-up-down
-/test-nf-cache-mngr
-/test-socket-creation
-/test-suite.log
-/test-u32-filter-with-actions
diff --git a/tests/check-addr.c b/tests/check-addr.c
deleted file mode 100644
index 48a2d93..0000000
--- a/tests/check-addr.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * tests/check-addr.c nl_addr unit tests
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
- * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
- */
-
-#include <check.h>
-#include <netlink/addr.h>
-
-#include "util.h"
-
-START_TEST(addr_alloc)
-{
- struct nl_addr *addr;
-
- addr = nl_addr_alloc(16);
- fail_if(addr == NULL,
- "Allocation should not return NULL");
-
- fail_if(nl_addr_iszero(addr) == 0,
- "New empty address should be all zeros");
-
- fail_if(nl_addr_get_family(addr) != AF_UNSPEC,
- "New empty address should have family AF_UNSPEC");
-
- fail_if(nl_addr_get_prefixlen(addr) != 0,
- "New empty address should have prefix length 0");
-
- fail_if(nl_addr_shared(addr),
- "New empty address should not be shared");
-
- fail_if(nl_addr_get(addr) != addr,
- "nl_addr_get() should return pointer to address");
-
- fail_if(nl_addr_shared(addr) == 0,
- "Address should be shared after call to nl_addr_get()");
-
- nl_addr_put(addr);
-
- fail_if(nl_addr_shared(addr),
- "Address should not be shared after call to nl_addr_put()");
-
- fail_if(nl_addr_fill_sockaddr(addr, NULL, 0) == 0,
- "Socket address filling should fail for empty address");
-
- nl_addr_put(addr);
-}
-END_TEST
-
-START_TEST(addr_binary_addr)
-{
- struct nl_addr *addr, *addr2;
- char baddr[4] = { 0x1, 0x2, 0x3, 0x4 };
- char baddr2[6] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 };
-
- addr = nl_addr_alloc(4);
- fail_if(addr == NULL,
- "Allocation should not return NULL");
-
- fail_if(nl_addr_set_binary_addr(addr, baddr, 4) < 0,
- "Valid binary address should be settable");
-
- fail_if(nl_addr_get_prefixlen(addr) != 0,
- "Prefix length should be unchanged after nl_addr_set_binary_addr()");
-
- fail_if(nl_addr_get_len(addr) != 4,
- "Address length should be 4");
-
- fail_if(nl_addr_set_binary_addr(addr, baddr2, 6) == 0,
- "Should not be able to set binary address exceeding maximum length");
-
- fail_if(nl_addr_get_len(addr) != 4,
- "Address length should still be 4");
-
- fail_if(nl_addr_guess_family(addr) != AF_INET,
- "Binary address of length 4 should be guessed as AF_INET");
-
- fail_if(memcmp(baddr, nl_addr_get_binary_addr(addr), 4) != 0,
- "Binary address mismatches");
-
- addr2 = nl_addr_build(AF_UNSPEC, baddr, 4);
- fail_if(addr2 == NULL,
- "Building of address should not fail");
-
- nl_addr_set_prefixlen(addr, 32);
- fail_if(nl_addr_get_prefixlen(addr) != 32,
- "Prefix length should be successful changed after nl_addr_set_prefixlen()");
-
- fail_if(nl_addr_cmp(addr, addr2),
- "Addresses built from same binary address should match");
-
- nl_addr_put(addr);
- nl_addr_put(addr2);
-}
-END_TEST
-
-START_TEST(addr_parse4)
-{
- struct nl_addr *addr4, *clone;
- struct sockaddr_in sin;
- socklen_t len = sizeof(sin);
- char *addr_str = "10.0.0.1/16";
- char buf[128];
-
- fail_if(nl_addr_parse(addr_str, AF_INET6, &addr4) == 0,
- "Should not be able to parse IPv4 address in IPv6 mode");
-
- fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr4) != 0,
- "Should be able to parse \"%s\"", addr_str);
-
- fail_if(nl_addr_get_family(addr4) != AF_INET,
- "Address family should be AF_INET");
-
- fail_if(nl_addr_get_prefixlen(addr4) != 16,
- "Prefix length should be 16");
-
- fail_if(nl_addr_iszero(addr4),
- "Address should not be all zeroes");
-
- clone = nl_addr_clone(addr4);
- fail_if(clone == NULL,
- "Cloned address should not be NULL");
-
- fail_if(nl_addr_cmp(addr4, clone) != 0,
- "Cloned address should not mismatch original");
-
- fail_if(nl_addr_fill_sockaddr(addr4, (struct sockaddr *) &sin, &len) != 0,
- "Should be able to fill socketaddr");
-
- fail_if(strcmp(nl_addr2str(addr4, buf, sizeof(buf)), addr_str),
- "Address translated back to string does not match original");
-
- nl_addr_put(addr4);
- nl_addr_put(clone);
-}
-END_TEST
-
-START_TEST(addr_parse6)
-{
- struct nl_addr *addr6, *clone;
- struct sockaddr_in6 sin;
- socklen_t len = sizeof(sin);
- char *addr_str = "2001:1:2::3/64";
- char buf[128];
-
- fail_if(nl_addr_parse(addr_str, AF_INET, &addr6) == 0,
- "Should not be able to parse IPv6 address in IPv4 mode");
-
- fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr6) != 0,
- "Should be able to parse \"%s\"", addr_str);
-
- fail_if(nl_addr_get_family(addr6) != AF_INET6,
- "Address family should be AF_INET6");
-
- fail_if(nl_addr_get_prefixlen(addr6) != 64,
- "Prefix length should be 64");
-
- fail_if(nl_addr_iszero(addr6),
- "Address should not be all zeroes");
-
- clone = nl_addr_clone(addr6);
- fail_if(clone == NULL,
- "Cloned address should not be NULL");
-
- fail_if(nl_addr_cmp(addr6, clone) != 0,
- "Cloned address should not mismatch original");
-
- fail_if(nl_addr_fill_sockaddr(addr6, (struct sockaddr *) &sin, &len) != 0,
- "Should be able to fill socketaddr");
-
- fail_if(strcmp(nl_addr2str(addr6, buf, sizeof(buf)), addr_str),
- "Address translated back to string does not match original");
-
- nl_addr_put(addr6);
- nl_addr_put(clone);
-}
-END_TEST
-
-START_TEST(addr_info)
-{
- struct nl_addr *addr;
- char *addr_str = "127.0.0.1";
- struct addrinfo *result;
-
- fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr) != 0,
- "Parsing of valid address should not fail");
-
- fail_if(nl_addr_info(addr, &result) != 0,
- "getaddrinfo() on loopback address should work");
-
- freeaddrinfo(result);
- nl_addr_put(addr);
-}
-END_TEST
-
-Suite *make_nl_addr_suite(void)
-{
- Suite *suite = suite_create("Abstract addresses");
-
- TCase *tc_addr = tcase_create("Core");
- tcase_add_test(tc_addr, addr_alloc);
- tcase_add_test(tc_addr, addr_binary_addr);
- tcase_add_test(tc_addr, addr_parse4);
- tcase_add_test(tc_addr, addr_parse6);
- tcase_add_test(tc_addr, addr_info);
- suite_add_tcase(suite, tc_addr);
-
- return suite;
-}
diff --git a/tests/check-all.c b/tests/check-all.c
index 7b738da..aff16cb 100644
--- a/tests/check-all.c
+++ b/tests/check-all.c
@@ -1,17 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * tests/check-all.c overall unit test program
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#include <check.h>
-#include "util.h"
+#include "cksuite-all.h"
static Suite *main_suite(void)
{
@@ -24,16 +18,13 @@
{
SRunner *runner;
int nfailed;
-
- runner = srunner_create(main_suite());
- /* Add testsuites below */
+ runner = srunner_create(main_suite());
srunner_add_suite(runner, make_nl_addr_suite());
srunner_add_suite(runner, make_nl_attr_suite());
srunner_add_suite(runner, make_nl_ematch_tree_clone_suite());
-
- /* Do not add testsuites below this line */
+ srunner_add_suite(runner, make_nl_netns_suite());
srunner_run_all(runner, CK_ENV);
diff --git a/tests/check-attr.c b/tests/check-attr.c
deleted file mode 100644
index 0390997..0000000
--- a/tests/check-attr.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * tests/check-attr.c nla_attr unit tests
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
- * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
- */
-
-#include "util.h"
-#include <netlink/attr.h>
-#include <netlink/msg.h>
-
-#include <linux/netlink.h>
-
-START_TEST(attr_size)
-{
- fail_if(nla_attr_size(0) != NLA_HDRLEN,
- "Length of empty attribute should match header size");
- fail_if(nla_attr_size(1) != NLA_HDRLEN + 1,
- "Length of 1 bytes payload should be NLA_HDRLEN + 1");
- fail_if(nla_attr_size(2) != NLA_HDRLEN + 2,
- "Length of 2 bytes payload should be NLA_HDRLEN + 2");
- fail_if(nla_attr_size(3) != NLA_HDRLEN + 3,
- "Length of 3 bytes payload should be NLA_HDRLEN + 3");
- fail_if(nla_attr_size(4) != NLA_HDRLEN + 4,
- "Length of 4 bytes payload should be NLA_HDRLEN + 4");
-
- fail_if(nla_total_size(1) != NLA_HDRLEN + 4,
- "Total size of 1 bytes payload should result in 8 bytes");
- fail_if(nla_total_size(2) != NLA_HDRLEN + 4,
- "Total size of 2 bytes payload should result in 8 bytes");
- fail_if(nla_total_size(3) != NLA_HDRLEN + 4,
- "Total size of 3 bytes payload should result in 8 bytes");
- fail_if(nla_total_size(4) != NLA_HDRLEN + 4,
- "Total size of 4 bytes payload should result in 8 bytes");
-
- fail_if(nla_padlen(1) != 3,
- "2 bytes of payload should result in 3 padding bytes");
- fail_if(nla_padlen(2) != 2,
- "2 bytes of payload should result in 2 padding bytes");
- fail_if(nla_padlen(3) != 1,
- "3 bytes of payload should result in 1 padding bytes");
- fail_if(nla_padlen(4) != 0,
- "4 bytes of payload should result in 0 padding bytes");
- fail_if(nla_padlen(5) != 3,
- "5 bytes of payload should result in 3 padding bytes");
-}
-END_TEST
-
-START_TEST(msg_construct)
-{
- struct nl_msg *msg;
- struct nlmsghdr *nlh;
- struct nlattr *a;
- int i, rem;
-
- msg = nlmsg_alloc();
- fail_if(!msg, "Unable to allocate netlink message");
-
- for (i = 1; i < 256; i++) {
- fail_if(nla_put_u32(msg, i, i+1) != 0,
- "Unable to add attribute %d", i);
- }
-
- nlh = nlmsg_hdr(msg);
- i = 1;
- nlmsg_for_each_attr(a, nlh, 0, rem) {
- fail_if(nla_type(a) != i, "Expected attribute %d", i);
- i++;
- fail_if(nla_get_u32(a) != i, "Expected attribute value %d", i);
- }
-
- nlmsg_free(msg);
-}
-END_TEST
-
-Suite *make_nl_attr_suite(void)
-{
- Suite *suite = suite_create("Netlink attributes");
-
- TCase *nl_attr = tcase_create("Core");
- tcase_add_test(nl_attr, attr_size);
- tcase_add_test(nl_attr, msg_construct);
- suite_add_tcase(suite, nl_attr);
-
- return suite;
-}
diff --git a/tests/check-direct.c b/tests/check-direct.c
new file mode 100644
index 0000000..f40bcee
--- /dev/null
+++ b/tests/check-direct.c
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#include <check.h>
+
+#include "linux/snmp.h"
+#include "netlink-private/utils.h"
+#include "netlink-private/route/utils.h"
+
+#include "netlink/route/link.h"
+
+START_TEST(static_checks)
+{
+ int i, j;
+ char strbuf[100];
+
+ _NL_STATIC_ASSERT(RTNL_LINK_RX_PACKETS == 0);
+ assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[0] ==
+ RTNL_LINK_RX_PACKETS);
+ for (i = 1; i < __IPSTATS_MIB_MAX; i++) {
+ assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] > 0);
+ assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] <
+ __RTNL_LINK_STATS_MAX);
+ for (j = 1; j < i; j++)
+ assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] !=
+ _nltst_map_stat_id_from_IPSTATS_MIB_v2[j]);
+ }
+
+ for (i = 0; i <= RTNL_LINK_STATS_MAX + 1; i++) {
+ const char *s;
+
+ s = rtnl_link_stat2str(i, strbuf, sizeof(strbuf));
+ assert(s);
+ assert(s == strbuf);
+ assert(strlen(s) < sizeof(strbuf));
+ if (strncmp(s, "0x", 2) == 0) {
+ assert(i == RTNL_LINK_STATS_MAX + 1);
+ ck_assert_int_eq(strtoll(&s[2], NULL, 16), i);
+ } else
+ ck_assert_int_le(i, RTNL_LINK_STATS_MAX);
+ ck_assert_int_eq(i, rtnl_link_str2stat(s));
+ }
+}
+END_TEST
+
+static Suite *make_suite(void)
+{
+ Suite *suite = suite_create("Direct");
+ TCase *tc = tcase_create("Core");
+
+ tcase_add_test(tc, static_checks);
+ suite_add_tcase(suite, tc);
+ return suite;
+}
+
+int main(int argc, char *argv[])
+{
+ SRunner *runner;
+ int nfailed;
+
+ runner = srunner_create(suite_create("main"));
+
+ srunner_add_suite(runner, make_suite());
+
+ srunner_run_all(runner, CK_ENV);
+
+ nfailed = srunner_ntests_failed(runner);
+ srunner_free(runner);
+ return nfailed != 0;
+}
diff --git a/tests/cksuite-all-addr.c b/tests/cksuite-all-addr.c
new file mode 100644
index 0000000..f395351
--- /dev/null
+++ b/tests/cksuite-all-addr.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <check.h>
+#include <netlink/addr.h>
+#include <netlink/route/addr.h>
+
+#include "cksuite-all.h"
+
+START_TEST(addr_alloc)
+{
+ struct nl_addr *addr;
+
+ addr = nl_addr_alloc(16);
+ ck_assert_msg(addr, "Allocation should not return NULL");
+
+ ck_assert_msg(nl_addr_iszero(addr) != 0,
+ "New empty address should be all zeros");
+
+ ck_assert_msg(nl_addr_get_family(addr) == AF_UNSPEC,
+ "New empty address should have family AF_UNSPEC");
+
+ ck_assert_msg(nl_addr_get_prefixlen(addr) == 0,
+ "New empty address should have prefix length 0");
+
+ ck_assert_msg(!nl_addr_shared(addr),
+ "New empty address should not be shared");
+
+ ck_assert_msg(nl_addr_get(addr) == addr,
+ "nl_addr_get() should return pointer to address");
+
+ ck_assert_msg(nl_addr_shared(addr) != 0,
+ "Address should be shared after call to nl_addr_get()");
+
+ nl_addr_put(addr);
+
+ ck_assert_msg(
+ !nl_addr_shared(addr),
+ "Address should not be shared after call to nl_addr_put()");
+
+ ck_assert_msg(nl_addr_fill_sockaddr(addr, NULL, 0) != 0,
+ "Socket address filling should fail for empty address");
+
+ nl_addr_put(addr);
+}
+END_TEST
+
+START_TEST(addr_binary_addr)
+{
+ struct nl_addr *addr, *addr2;
+ char baddr[4] = { 0x1, 0x2, 0x3, 0x4 };
+ char baddr2[6] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 };
+
+ addr = nl_addr_alloc(4);
+ ck_assert_msg(addr != NULL, "Allocation should not return NULL");
+
+ ck_assert_msg(nl_addr_set_binary_addr(addr, baddr, 4) >= 0,
+ "Valid binary address should be settable");
+
+ ck_assert_msg(
+ nl_addr_get_prefixlen(addr) == 0,
+ "Prefix length should be unchanged after nl_addr_set_binary_addr()");
+
+ ck_assert_msg(nl_addr_get_len(addr) == 4, "Address length should be 4");
+
+ ck_assert_msg(
+ nl_addr_set_binary_addr(addr, baddr2, 6) != 0,
+ "Should not be able to set binary address exceeding maximum length");
+
+ ck_assert_msg(nl_addr_get_len(addr) == 4,
+ "Address length should still be 4");
+
+ ck_assert_msg(
+ nl_addr_guess_family(addr) == AF_INET,
+ "Binary address of length 4 should be guessed as AF_INET");
+
+ ck_assert_msg(memcmp(baddr, nl_addr_get_binary_addr(addr), 4) == 0,
+ "Binary address mismatches");
+
+ addr2 = nl_addr_build(AF_UNSPEC, baddr, 4);
+ ck_assert_msg(addr2 != NULL, "Building of address should not fail");
+
+ nl_addr_set_prefixlen(addr, 32);
+ ck_assert_msg(
+ nl_addr_get_prefixlen(addr) == 32,
+ "Prefix length should be successful changed after nl_addr_set_prefixlen()");
+
+ ck_assert_msg(!nl_addr_cmp(addr, addr2),
+ "Addresses built from same binary address should match");
+
+ nl_addr_put(addr);
+ nl_addr_put(addr2);
+}
+END_TEST
+
+START_TEST(addr_parse4)
+{
+ struct nl_addr *addr4, *clone;
+ struct sockaddr_in sin;
+ socklen_t len = sizeof(sin);
+ char *addr_str = "10.0.0.1/16";
+ char buf[128];
+
+ ck_assert_msg(nl_addr_parse(addr_str, AF_INET6, &addr4) != 0,
+ "Should not be able to parse IPv4 address in IPv6 mode");
+
+ ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr4) == 0,
+ "Should be able to parse \"%s\"", addr_str);
+
+ ck_assert_msg(nl_addr_get_family(addr4) == AF_INET,
+ "Address family should be AF_INET");
+
+ ck_assert_msg(nl_addr_get_prefixlen(addr4) == 16,
+ "Prefix length should be 16");
+
+ ck_assert_msg(!nl_addr_iszero(addr4),
+ "Address should not be all zeroes");
+
+ clone = nl_addr_clone(addr4);
+ ck_assert_msg(clone != NULL, "Cloned address should not be NULL");
+
+ ck_assert_msg(nl_addr_cmp(addr4, clone) == 0,
+ "Cloned address should not mismatch original");
+
+ ck_assert_msg(nl_addr_fill_sockaddr(addr4, (struct sockaddr *)&sin,
+ &len) == 0,
+ "Should be able to fill socketaddr");
+
+ ck_assert_msg(
+ !strcmp(nl_addr2str(addr4, buf, sizeof(buf)), addr_str),
+ "Address translated back to string does not match original");
+
+ nl_addr_put(addr4);
+ nl_addr_put(clone);
+}
+END_TEST
+
+START_TEST(addr_parse6)
+{
+ struct nl_addr *addr6, *clone;
+ struct sockaddr_in6 sin;
+ socklen_t len = sizeof(sin);
+ char *addr_str = "2001:1:2::3/64";
+ char buf[128];
+
+ ck_assert_msg(nl_addr_parse(addr_str, AF_INET, &addr6) != 0,
+ "Should not be able to parse IPv6 address in IPv4 mode");
+
+ ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr6) == 0,
+ "Should be able to parse \"%s\"", addr_str);
+
+ ck_assert_msg(nl_addr_get_family(addr6) == AF_INET6,
+ "Address family should be AF_INET6");
+
+ ck_assert_msg(nl_addr_get_prefixlen(addr6) == 64,
+ "Prefix length should be 64");
+
+ ck_assert_msg(!nl_addr_iszero(addr6),
+ "Address should not be all zeroes");
+
+ clone = nl_addr_clone(addr6);
+ ck_assert_msg(clone != NULL, "Cloned address should not be NULL");
+
+ ck_assert_msg(nl_addr_cmp(addr6, clone) == 0,
+ "Cloned address should not mismatch original");
+
+ ck_assert_msg(nl_addr_fill_sockaddr(addr6, (struct sockaddr *)&sin,
+ &len) == 0,
+ "Should be able to fill socketaddr");
+
+ ck_assert_msg(
+ !strcmp(nl_addr2str(addr6, buf, sizeof(buf)), addr_str),
+ "Address translated back to string does not match original");
+
+ nl_addr_put(addr6);
+ nl_addr_put(clone);
+}
+END_TEST
+
+START_TEST(addr_info)
+{
+ struct nl_addr *addr;
+ char *addr_str = "127.0.0.1";
+ struct addrinfo *result;
+
+ ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr) == 0,
+ "Parsing of valid address should not fail");
+
+ ck_assert_msg(nl_addr_info(addr, &result) == 0,
+ "getaddrinfo() on loopback address should work");
+
+ freeaddrinfo(result);
+ nl_addr_put(addr);
+}
+END_TEST
+
+START_TEST(addr_flags2str)
+{
+ int ifa_flags = IFA_F_TENTATIVE | IFA_F_DADFAILED;
+ int ifa_flags2;
+ char buf[128];
+
+ rtnl_addr_flags2str(ifa_flags, buf, sizeof(buf));
+ ck_assert_str_eq(buf, "dadfailed,tentative");
+
+ ifa_flags2 = rtnl_addr_str2flags(buf);
+ ck_assert_int_eq(ifa_flags2, ifa_flags);
+}
+END_TEST
+
+Suite *make_nl_addr_suite(void)
+{
+ Suite *suite = suite_create("Abstract addresses");
+ TCase *tc = tcase_create("Core");
+
+ tcase_add_test(tc, addr_alloc);
+ tcase_add_test(tc, addr_binary_addr);
+ tcase_add_test(tc, addr_parse4);
+ tcase_add_test(tc, addr_parse6);
+ tcase_add_test(tc, addr_info);
+ tcase_add_test(tc, addr_flags2str);
+ suite_add_tcase(suite, tc);
+
+ return suite;
+}
diff --git a/tests/cksuite-all-attr.c b/tests/cksuite-all-attr.c
new file mode 100644
index 0000000..824a596
--- /dev/null
+++ b/tests/cksuite-all-attr.c
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <linux/netlink.h>
+#include <linux/if_ether.h>
+
+#include "cksuite-all.h"
+#include "netlink/attr.h"
+#include "netlink/msg.h"
+#include "netlink/route/cls/u32.h"
+#include "netlink-private/route/tc-api.h"
+#include "netlink-private/nl-auto.h"
+
+START_TEST(attr_size)
+{
+ ck_assert_msg(nla_attr_size(0) == NLA_HDRLEN,
+ "Length of empty attribute should match header size");
+ ck_assert_msg(nla_attr_size(1) == NLA_HDRLEN + 1,
+ "Length of 1 bytes payload should be NLA_HDRLEN + 1");
+ ck_assert_msg(nla_attr_size(2) == NLA_HDRLEN + 2,
+ "Length of 2 bytes payload should be NLA_HDRLEN + 2");
+ ck_assert_msg(nla_attr_size(3) == NLA_HDRLEN + 3,
+ "Length of 3 bytes payload should be NLA_HDRLEN + 3");
+ ck_assert_msg(nla_attr_size(4) == NLA_HDRLEN + 4,
+ "Length of 4 bytes payload should be NLA_HDRLEN + 4");
+
+ ck_assert_msg(nla_total_size(1) == NLA_HDRLEN + 4,
+ "Total size of 1 bytes payload should result in 8 bytes");
+ ck_assert_msg(nla_total_size(2) == NLA_HDRLEN + 4,
+ "Total size of 2 bytes payload should result in 8 bytes");
+ ck_assert_msg(nla_total_size(3) == NLA_HDRLEN + 4,
+ "Total size of 3 bytes payload should result in 8 bytes");
+ ck_assert_msg(nla_total_size(4) == NLA_HDRLEN + 4,
+ "Total size of 4 bytes payload should result in 8 bytes");
+
+ ck_assert_msg(nla_padlen(1) == 3,
+ "2 bytes of payload should result in 3 padding bytes");
+ ck_assert_msg(nla_padlen(2) == 2,
+ "2 bytes of payload should result in 2 padding bytes");
+ ck_assert_msg(nla_padlen(3) == 1,
+ "3 bytes of payload should result in 1 padding bytes");
+ ck_assert_msg(nla_padlen(4) == 0,
+ "4 bytes of payload should result in 0 padding bytes");
+ ck_assert_msg(nla_padlen(5) == 3,
+ "5 bytes of payload should result in 3 padding bytes");
+}
+END_TEST
+
+START_TEST(msg_construct)
+{
+ struct nl_msg *msg;
+ struct nlmsghdr *nlh;
+ struct nlattr *a;
+ int i, rem;
+
+ msg = nlmsg_alloc();
+ ck_assert_msg(msg, "Unable to allocate netlink message");
+
+ for (i = 1; i < 256; i++) {
+ ck_assert_msg(nla_put_u32(msg, i, i + 1) == 0,
+ "Unable to add attribute %d", i);
+ }
+
+ nlh = nlmsg_hdr(msg);
+ i = 1;
+ nlmsg_for_each_attr (a, nlh, 0, rem) {
+ ck_assert_msg(nla_type(a) == i, "Expected attribute %d", i);
+ i++;
+ ck_assert_msg(nla_get_u32(a) == i,
+ "Expected attribute value %d", i);
+ }
+
+ nlmsg_free(msg);
+}
+END_TEST
+
+START_TEST(clone_cls_u32)
+{
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ _nl_auto_rtnl_cls struct rtnl_cls *cls = NULL;
+ _nl_auto_rtnl_cls struct rtnl_cls *cls2 = NULL;
+ int r;
+ const uint32_t direction = 16;
+
+ link = rtnl_link_alloc();
+ ck_assert(link);
+
+ rtnl_link_set_ifindex(link, 5);
+
+ cls = rtnl_cls_alloc();
+ ck_assert(cls);
+
+ rtnl_tc_set_link(TC_CAST(cls), link);
+
+ r = rtnl_tc_set_kind(TC_CAST(cls), "u32");
+ ck_assert(r == 0);
+
+ rtnl_cls_set_prio(cls, 1);
+ rtnl_cls_set_protocol(cls, ETH_P_IP);
+
+ rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
+
+ rtnl_u32_set_hashtable(cls, 5);
+
+ rtnl_u32_add_key_uint32(cls, 0x0a000914, 0xffffffff, direction, 0);
+
+ rtnl_u32_set_hashmask(cls, 0xff000000, direction);
+
+ rtnl_u32_add_mark(cls, 55, 66);
+
+ rtnl_u32_set_link(cls, 44);
+
+ cls2 = (struct rtnl_cls *)nl_object_clone((struct nl_object *)cls);
+ ck_assert(cls2);
+}
+END_TEST
+
+/*****************************************************************************/
+
+START_TEST(test_nltst_strtok)
+{
+#define _assert_strtok(str, ...) \
+ do { \
+ const char *const _expected[] = { NULL, ##__VA_ARGS__, NULL }; \
+ _nltst_auto_strfreev char **_tokens = NULL; \
+ \
+ _tokens = _nltst_strtokv(str); \
+ _nltst_assert_strv_equal(_tokens, &_expected[1]); \
+ } while (0)
+
+ _assert_strtok("");
+ _assert_strtok(" \n");
+ _assert_strtok("a", "a");
+ _assert_strtok(" a ", "a");
+ _assert_strtok(" a\\ b", "a\\ ", "b");
+ _assert_strtok(" a\\ b cc\\d", "a\\ ", "b", "cc\\d");
+ _assert_strtok(" a\\ b\\ cc\\d", "a\\ ", "b\\ ", "cc\\d");
+}
+END_TEST
+
+/*****************************************************************************/
+
+Suite *make_nl_attr_suite(void)
+{
+ Suite *suite = suite_create("Netlink attributes");
+ TCase *tc = tcase_create("Core");
+
+ tcase_add_test(tc, attr_size);
+ tcase_add_test(tc, msg_construct);
+ tcase_add_test(tc, clone_cls_u32);
+ tcase_add_test(tc, test_nltst_strtok);
+ suite_add_tcase(suite, tc);
+
+ return suite;
+}
diff --git a/tests/check-ematch-tree-clone.c b/tests/cksuite-all-ematch-tree-clone.c
similarity index 75%
rename from tests/check-ematch-tree-clone.c
rename to tests/cksuite-all-ematch-tree-clone.c
index 9c35c52..f9d17a9 100644
--- a/tests/check-ematch-tree-clone.c
+++ b/tests/cksuite-all-ematch-tree-clone.c
@@ -1,23 +1,20 @@
-#include <netlink-private/types.h>
-#include <netlink/route/cls/ematch.h>
-
#include <linux/netlink.h>
-
#include <stdio.h>
#include <time.h>
-
#include <check.h>
-#include "util.h"
-#define MAX_DEPTH 6
-#define MAX_CHILDREN 5
+#include "netlink-private/types.h"
+#include "netlink/route/cls/ematch.h"
+#include "cksuite-all.h"
+#include "netlink-private/nl-auto.h"
+
+#define MAX_DEPTH 6
+#define MAX_CHILDREN 5
static int current_depth = 0;
static int id = 1;
static long long array_size = 0;
-static int *src_result = NULL, *dst_result = NULL;
-
static long long my_pow(long long x, long long y)
{
int ret = x;
@@ -28,7 +25,7 @@
if (y < 0 || x == 0)
return 0;
- while(--y) {
+ while (--y) {
ret *= x;
}
@@ -79,7 +76,7 @@
{
struct rtnl_ematch *pos = NULL;
- nl_list_for_each_entry(pos, head, e_list) {
+ nl_list_for_each_entry (pos, head, e_list) {
if (!nl_list_empty(&pos->e_childs))
dump_ematch_list(&pos->e_childs, result, index);
result[*index] = pos->e_id;
@@ -87,7 +84,8 @@
}
}
-static void dump_ematch_tree(struct rtnl_ematch_tree *tree, int *result, int *index)
+static void dump_ematch_tree(struct rtnl_ematch_tree *tree, int *result,
+ int *index)
{
if (!tree)
return;
@@ -107,8 +105,12 @@
START_TEST(ematch_tree_clone)
{
- struct rtnl_ematch_tree *src = NULL, *dst = NULL;
- int i = 0, j = 0;
+ _nl_auto_rtnl_ematch_tree struct rtnl_ematch_tree *src = NULL;
+ _nl_auto_rtnl_ematch_tree struct rtnl_ematch_tree *dst = NULL;
+ _nl_auto_free int *src_result = NULL;
+ _nl_auto_free int *dst_result = NULL;
+ int i = 0;
+ int j = 0;
array_size = (MAX_DEPTH * my_pow(MAX_CHILDREN, MAX_DEPTH)) / 2;
src_result = calloc(4, array_size);
@@ -122,22 +124,19 @@
dst = rtnl_ematch_tree_clone(src);
dump_ematch_tree(dst, dst_result, &j);
- fail_if(!dst);
- fail_if(i != j);
- fail_if(compare(src_result, dst_result, i));
-
- free(src_result);
- free(dst_result);
+ ck_assert(dst);
+ ck_assert(i == j);
+ ck_assert(!compare(src_result, dst_result, i));
}
END_TEST
Suite *make_nl_ematch_tree_clone_suite(void)
{
Suite *suite = suite_create("Clone ematch tree");
+ TCase *tc = tcase_create("Core");
- TCase *ematch_tree = tcase_create("Core");
- tcase_add_test(ematch_tree, ematch_tree_clone);
- suite_add_tcase(suite, ematch_tree);
+ tcase_add_test(tc, ematch_tree_clone);
+ suite_add_tcase(suite, tc);
return suite;
}
diff --git a/tests/cksuite-all-netns.c b/tests/cksuite-all-netns.c
new file mode 100644
index 0000000..97f3a70
--- /dev/null
+++ b/tests/cksuite-all-netns.c
@@ -0,0 +1,319 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+/*
+ * Author: Susant Sahani <susant@redhat.com>
+ * Copyright (c) 2018 Red Hat, Inc.
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <linux/netlink.h>
+
+#include "netlink-private/utils.h"
+#include "netlink/route/link.h"
+#include "netlink/route/link/sit.h"
+#include <netlink/route/link/bonding.h>
+#include <netlink/route/link/bridge.h>
+#include <netlink/route/link/ip6tnl.h>
+#include <netlink/route/link/ipgre.h>
+#include <netlink/route/link/ipip.h>
+#include <netlink/route/link/ipvlan.h>
+#include <netlink/route/link/ipvti.h>
+#include <netlink/route/link/macsec.h>
+#include <netlink/route/link/macvlan.h>
+#include <netlink/route/link/macvtap.h>
+#include <netlink/route/link/veth.h>
+#include <netlink/route/link/vlan.h>
+#include <netlink/route/link/vrf.h>
+#include <netlink/route/link/vxlan.h>
+
+#include "cksuite-all.h"
+
+/*****************************************************************************/
+
+static void _nltst_delete_link2(const char *ifname)
+{
+ _nltst_delete_link(NULL, ifname);
+}
+#define _nltst_auto_delete_link _nl_auto(_nltst_auto_delete_link_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(const char *, _nltst_auto_delete_link_fcn,
+ _nltst_delete_link2);
+
+/*****************************************************************************/
+
+START_TEST(cache_and_clone)
+{
+ _nl_auto_nl_socket struct nl_sock *sk = NULL;
+ _nl_auto_nl_cache struct nl_cache *link_cache = NULL;
+ _nl_auto_free struct nl_object **links_all = NULL;
+ static const struct {
+ const char *ifname;
+ const char *kind;
+ bool add;
+ } links[] = {
+ {
+ .ifname = "xbr0",
+ .kind = "bridge",
+ .add = true,
+ },
+ {
+ .ifname = "xdummy0",
+ .kind = "dummy",
+ .add = true,
+ },
+ {
+ .ifname = "xbond0",
+ .kind = "bond",
+ .add = true,
+ },
+ {
+ .ifname = "lo",
+ .kind = NULL,
+ .add = false,
+ },
+ };
+ int i;
+ int r;
+
+ for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
+ if (links[i].add)
+ _nltst_add_link(NULL, links[i].ifname, links[i].kind,
+ NULL);
+ }
+
+ sk = _nltst_socket(NETLINK_ROUTE);
+
+ r = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache);
+ ck_assert_int_eq(r, 0);
+
+ r = nl_cache_refill(sk, link_cache);
+ ck_assert_int_eq(r, 0);
+
+ for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
+ _nl_auto_rtnl_link struct rtnl_link *link_clone = NULL;
+ struct rtnl_link *link;
+
+ link = _nltst_cache_get_link(link_cache, links[i].ifname);
+ ck_assert_ptr_nonnull(link);
+
+ ck_assert_str_eq(rtnl_link_get_name(link), links[i].ifname);
+
+ if (_nl_streq(links[i].ifname, "lo"))
+ ck_assert_int_eq(rtnl_link_get_ifindex(link), 1);
+ else
+ ck_assert_int_gt(rtnl_link_get_ifindex(link), 1);
+
+ link_clone = (struct rtnl_link *)nl_object_clone(
+ (struct nl_object *)link);
+ ck_assert(link_clone);
+
+ _nltst_object_identical(link, link_clone);
+ }
+
+ links_all = _nltst_cache_get_all(link_cache, NULL);
+ for (i = 0; links_all[i]; i++) {
+ struct rtnl_link *link = (struct rtnl_link *)links_all[i];
+ _nl_auto_rtnl_link struct rtnl_link *link_clone = NULL;
+
+ link_clone = (struct rtnl_link *)nl_object_clone(
+ (struct nl_object *)link);
+ ck_assert(link_clone);
+
+ _nltst_object_identical(link, link_clone);
+ }
+}
+END_TEST
+
+/*****************************************************************************/
+
+START_TEST(test_create_iface)
+{
+ const int TEST_IDX = _i;
+ _nl_auto_nl_socket struct nl_sock *sk = _nltst_socket(NETLINK_ROUTE);
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ _nl_auto_rtnl_link struct rtnl_link *link2 = NULL;
+ _nl_auto_rtnl_link struct rtnl_link *peer = NULL;
+ _nltst_auto_delete_link const char *IFNAME_DUMMY = NULL;
+ _nltst_auto_delete_link const char *IFNAME = "ifname";
+ int ifindex_dummy;
+ uint32_t u32;
+ int r;
+
+ switch (TEST_IDX) {
+ case 0:
+ link = _nltst_assert(rtnl_link_bridge_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ break;
+ case 1:
+ link = _nltst_assert(rtnl_link_vxlan_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_vxlan_set_id(link, 128));
+ break;
+ case 2:
+ link = _nltst_assert(rtnl_link_alloc());
+ rtnl_link_set_type(link, "ifb");
+ rtnl_link_set_name(link, IFNAME);
+ break;
+ case 3:
+ link = _nltst_assert(rtnl_link_ipgre_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_ipgre_set_local(
+ link, _nltst_inet4("192.168.254.12")));
+ _nltst_assert_retcode(rtnl_link_ipgre_set_remote(
+ link, _nltst_inet4("192.168.254.13")));
+ _nltst_assert_retcode(rtnl_link_ipgre_set_ttl(link, 64));
+ break;
+ case 4:
+ link = _nltst_assert(rtnl_link_ip6_tnl_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_ip6_tnl_set_local(
+ link, _nltst_inet6p("2607:f0d0:1002:51::4")));
+ _nltst_assert_retcode(rtnl_link_ip6_tnl_set_remote(
+ link, _nltst_inet6p("2607:f0d0:1002:52::5")));
+ break;
+ case 5:
+ link = _nltst_assert(rtnl_link_ipgretap_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_ipgre_set_local(
+ link, _nltst_inet4("10.211.55.10")));
+ _nltst_assert_retcode(rtnl_link_ipgre_set_remote(
+ link, _nltst_inet4("10.133.6.33")));
+ _nltst_assert_retcode(rtnl_link_ipgre_set_ttl(link, 64));
+ break;
+ case 6:
+ link = _nltst_assert(rtnl_link_ipvti_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_ipvti_set_local(
+ link, _nltst_inet4("192.168.254.12")));
+ _nltst_assert_retcode(rtnl_link_ipvti_set_remote(
+ link, _nltst_inet4("192.168.254.13")));
+ break;
+ case 7:
+ link = _nltst_assert(rtnl_link_sit_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_sit_set_local(
+ link, _nltst_inet4("192.168.254.12")));
+ _nltst_assert_retcode(rtnl_link_sit_set_remote(
+ link, _nltst_inet4("192.168.254.13")));
+ _nltst_assert_retcode(rtnl_link_sit_set_ttl(link, 64));
+ break;
+ case 8:
+ link = _nltst_assert(rtnl_link_ipip_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_ipip_set_local(
+ link, _nltst_inet4("192.168.254.12")));
+ _nltst_assert_retcode(rtnl_link_ipip_set_remote(
+ link, _nltst_inet4("192.168.254.13")));
+ _nltst_assert_retcode(rtnl_link_ipip_set_ttl(link, 64));
+ break;
+ case 9:
+ link = _nltst_assert(rtnl_link_bond_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ break;
+ case 10:
+ IFNAME_DUMMY = "ci-dummy";
+ _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
+
+ link = _nltst_assert(rtnl_link_macvtap_alloc());
+ rtnl_link_set_link(link, ifindex_dummy);
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_macvtap_set_mode(
+ link, rtnl_link_macvtap_str2mode("bridge")));
+ break;
+ case 11:
+ IFNAME_DUMMY = "ci-dummy";
+ _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
+
+ link = _nltst_assert(rtnl_link_macvlan_alloc());
+ rtnl_link_set_link(link, ifindex_dummy);
+ rtnl_link_set_name(link, IFNAME);
+ break;
+ case 12:
+ IFNAME_DUMMY = "ci-dummy";
+ _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
+
+ link = _nltst_assert(rtnl_link_vlan_alloc());
+ rtnl_link_set_link(link, ifindex_dummy);
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_vlan_set_id(link, 10));
+ break;
+ case 13:
+ IFNAME_DUMMY = "ci-dummy";
+ _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
+
+ link = _nltst_assert(rtnl_link_macsec_alloc());
+ rtnl_link_set_link(link, ifindex_dummy);
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_macsec_set_port(link, 10));
+ _nltst_assert_retcode(rtnl_link_macsec_set_encrypt(link, 1));
+ _nltst_assert_retcode(
+ rtnl_link_macsec_set_replay_protect(link, 1));
+ _nltst_assert_retcode(rtnl_link_macsec_set_window(link, 200));
+ break;
+ case 14:
+ IFNAME_DUMMY = "ci-dummy";
+ _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
+
+ link = _nltst_assert(rtnl_link_ipvlan_alloc());
+ rtnl_link_set_link(link, ifindex_dummy);
+ _nltst_assert_retcode(rtnl_link_ipvlan_set_mode(
+ link, rtnl_link_ipvlan_str2mode("l2")));
+ rtnl_link_set_name(link, IFNAME);
+ break;
+ case 15:
+ link = _nltst_assert(rtnl_link_vrf_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ _nltst_assert_retcode(rtnl_link_vrf_set_tableid(link, 10));
+ break;
+ case 16: {
+ link = _nltst_assert(rtnl_link_veth_alloc());
+ rtnl_link_set_name(link, IFNAME);
+ peer = _nltst_assert(rtnl_link_veth_get_peer(link));
+ rtnl_link_set_name(peer, "ci-veth-peer");
+ } break;
+ default:
+ ck_assert_msg(0, "unexpected TEST_IDX=%d", _i);
+ break;
+ }
+
+ r = rtnl_link_add(sk, link, NLM_F_CREATE);
+ if (r == -NLE_OPNOTSUPP) {
+ /* Hm, no kernel module? Skip the test. */
+ _nltst_assert_link_not_exists(IFNAME);
+ IFNAME = NULL;
+ return;
+ }
+ _nltst_assert_retcode(r);
+
+ _nltst_assert_link_exists(IFNAME);
+
+ switch (TEST_IDX) {
+ case 15:
+ _nltst_get_link(sk, IFNAME, NULL, &link2);
+ _nltst_assert_retcode(rtnl_link_vrf_get_tableid(link2, &u32));
+ ck_assert_int_eq(u32, 10);
+ break;
+ case 16:
+ _nltst_assert_link_exists("ci-veth-peer");
+ if (_nltst_rand_bool())
+ IFNAME = "ci-veth-peer";
+ break;
+ }
+}
+END_TEST
+
+/*****************************************************************************/
+
+Suite *make_nl_netns_suite(void)
+{
+ Suite *suite = suite_create("netns");
+ TCase *tc = tcase_create("Core");
+
+ tcase_add_checked_fixture(tc, nltst_netns_fixture_setup,
+ nltst_netns_fixture_teardown);
+ tcase_add_test(tc, cache_and_clone);
+ tcase_add_loop_test(tc, test_create_iface, 0, 17);
+
+ suite_add_tcase(suite, tc);
+
+ return suite;
+}
diff --git a/tests/cksuite-all.h b/tests/cksuite-all.h
new file mode 100644
index 0000000..c4b1d8e
--- /dev/null
+++ b/tests/cksuite-all.h
@@ -0,0 +1,12 @@
+#ifndef __LIBNL3_TESTS_CHECK_ALL_H__
+#define __LIBNL3_TESTS_CHECK_ALL_H__
+
+#include <check.h>
+#include "nl-test-util.h"
+
+Suite *make_nl_attr_suite(void);
+Suite *make_nl_addr_suite(void);
+Suite *make_nl_ematch_tree_clone_suite(void);
+Suite *make_nl_netns_suite(void);
+
+#endif /* __LIBNL3_TESTS_CHECK_ALL_H__ */
diff --git a/tests/nl-test-util.c b/tests/nl-test-util.c
new file mode 100644
index 0000000..1f67ac8
--- /dev/null
+++ b/tests/nl-test-util.c
@@ -0,0 +1,657 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#include "nl-test-util.h"
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <sched.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <unistd.h>
+
+#include "netlink-private/utils.h"
+#include "netlink/netlink.h"
+#include "netlink/route/link.h"
+#include "netlink/route/route.h"
+#include "netlink/socket.h"
+
+/*****************************************************************************/
+
+void _nltst_get_urandom(void *ptr, size_t len)
+{
+ int fd;
+ ssize_t nread;
+
+ ck_assert_int_gt(len, 0);
+ ck_assert_ptr_nonnull(ptr);
+
+ fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY);
+ _nltst_assert_errno(fd >= 0);
+
+ nread = read(fd, ptr, len);
+ _nltst_assert_errno(nread == len);
+
+ _nltst_close(fd);
+}
+
+uint32_t _nltst_rand_u32(void)
+{
+ _nl_thread_local static unsigned short entropy[3];
+ _nl_thread_local static bool has_entropy = false;
+
+ if (!has_entropy) {
+ unsigned long long seed;
+ uint64_t seed64;
+ const char *s;
+ char *s_end;
+
+ memset(entropy, 0, sizeof(entropy));
+ s = getenv("NLTST_SEED_RAND");
+ if (!s)
+ seed = 0;
+ else if (s[0] != '\0') {
+ errno = 0;
+ seed = strtoull(s, &s_end, 10);
+ if (errno != 0 || s_end[0] != '\0') {
+ ck_assert_msg(
+ 0,
+ "invalid NLTST_SEED_RAND=\"%s\". Must be an integer to seed the random numbers",
+ s);
+ }
+ } else
+ _nltst_get_urandom(&seed, sizeof(seed));
+
+ seed64 = seed;
+ printf("runs with NLTST_SEED_RAND=%" PRIu64 "\n", seed64);
+
+ entropy[0] = (seed64 >> 0) ^ (seed64 >> 48);
+ entropy[1] = (seed64 >> 16) ^ (seed64 >> 0);
+ entropy[2] = (seed64 >> 32) ^ (seed64 >> 16);
+ has_entropy = true;
+ }
+
+ _NL_STATIC_ASSERT(sizeof(long) >= sizeof(uint32_t));
+ return jrand48(entropy);
+}
+
+/*****************************************************************************/
+
+#define _CANARY 539339
+
+struct nltst_netns {
+ int canary;
+};
+
+/*****************************************************************************/
+
+#define _assert_nltst_netns(nsdata) \
+ do { \
+ const struct nltst_netns *_nsdata = (nsdata); \
+ \
+ ck_assert_ptr_nonnull(_nsdata); \
+ ck_assert_int_eq(_nsdata->canary, _CANARY); \
+ } while (0)
+
+static struct {
+ struct nltst_netns *nsdata;
+} _netns_fixture_global;
+
+void nltst_netns_fixture_setup(void)
+{
+ ck_assert(!_netns_fixture_global.nsdata);
+
+ _netns_fixture_global.nsdata = nltst_netns_enter();
+ _assert_nltst_netns(_netns_fixture_global.nsdata);
+}
+
+void nltst_netns_fixture_teardown(void)
+{
+ _assert_nltst_netns(_netns_fixture_global.nsdata);
+ _nl_clear_pointer(&_netns_fixture_global.nsdata, nltst_netns_leave);
+}
+
+/*****************************************************************************/
+
+static void unshare_user(void)
+{
+ const uid_t uid = geteuid();
+ const gid_t gid = getegid();
+ FILE *f;
+ int r;
+
+ /* Become a root in new user NS. */
+ r = unshare(CLONE_NEWUSER);
+ _nltst_assert_errno(r == 0);
+
+ /* Since Linux 3.19 we have to disable setgroups() in order to map users.
+ * Just proceed if the file is not there. */
+ f = fopen("/proc/self/setgroups", "we");
+ if (f) {
+ r = fprintf(f, "deny");
+ _nltst_assert_errno(r > 0);
+ _nltst_fclose(f);
+ }
+
+ /* Map current UID to root in NS to be created. */
+ f = fopen("/proc/self/uid_map", "we");
+ if (!f) {
+ if (errno == EACCES) {
+ /* Accessing uid_map might fail due to sandboxing.
+ * We ignore that error and proceed with the test. It will probably
+ * still work. */
+ return;
+ }
+ _nltst_assert_errno(f);
+ }
+ r = fprintf(f, "0 %d 1", uid);
+ _nltst_assert_errno(r > 0);
+ _nltst_fclose(f);
+
+ /* Map current GID to root in NS to be created. */
+ f = fopen("/proc/self/gid_map", "we");
+ _nltst_assert_errno(f);
+ r = fprintf(f, "0 %d 1", gid);
+ _nltst_assert_errno(r > 0);
+ _nltst_fclose(f);
+}
+
+struct nltst_netns *nltst_netns_enter(void)
+{
+ struct nltst_netns *nsdata;
+ int r;
+
+ nsdata = calloc(1, sizeof(struct nltst_netns));
+ ck_assert(nsdata);
+
+ nsdata->canary = _CANARY;
+
+ unshare_user();
+
+ r = unshare(CLONE_NEWNET | CLONE_NEWNS);
+ _nltst_assert_errno(r == 0);
+
+ /* We need a read-only /sys so that the platform knows there's no udev. */
+ mount(NULL, "/sys", "sysfs", MS_SLAVE, NULL);
+ r = mount("sys", "/sys", "sysfs", MS_RDONLY, NULL);
+ _nltst_assert_errno(r == 0);
+
+ return nsdata;
+}
+
+void nltst_netns_leave(struct nltst_netns *nsdata)
+{
+ ck_assert(nsdata);
+ ck_assert_int_eq(nsdata->canary, _CANARY);
+
+ /* nltst_netns_leave() was supposed to enter the original namespaces again
+ * and undo enter.
+ *
+ * However, I could get it to work (setns() always fails with EPERM)
+ * and valgrind on current Ubuntu seems not to support setns() call.
+ *
+ * So, do nothing. It's not really a problem, because the next test
+ * either should unshare yet another namespace, or not care about
+ * such things. */
+
+ free(nsdata);
+}
+
+/*****************************************************************************/
+
+void _nltst_object_identical(const void *a, const void *b)
+{
+ struct nl_object *o_a = (void *)a;
+ struct nl_object *o_b = (void *)b;
+
+ ck_assert(a);
+ ck_assert(b);
+
+ ck_assert_int_eq(nl_object_identical(o_a, o_b), 1);
+ ck_assert_int_eq(nl_object_identical(o_b, o_a), 1);
+ ck_assert_int_eq(nl_object_diff64(o_b, o_a), 0);
+ ck_assert_int_eq(nl_object_diff64(o_a, o_b), 0);
+ ck_assert_int_eq(nl_object_diff(o_a, o_b), 0);
+ ck_assert_int_eq(nl_object_diff(o_b, o_a), 0);
+}
+
+/*****************************************************************************/
+
+char *_nltst_object_to_string(struct nl_object *obj)
+{
+ size_t L = 1024;
+ size_t l;
+ char *s;
+
+ if (!obj)
+ return strdup("(null)");
+
+ s = malloc(L);
+ ck_assert_ptr_nonnull(s);
+
+ nl_object_dump_buf(obj, s, L);
+ l = strlen(s);
+ ck_assert_int_lt(l, L);
+ s = realloc(s, l + 1);
+ ck_assert_ptr_nonnull(s);
+ return s;
+}
+
+struct cache_get_all_data {
+ struct nl_object **arr;
+ size_t len;
+ size_t idx;
+};
+
+static void _cache_get_all_fcn(struct nl_object *obj, void *user_data)
+{
+ struct cache_get_all_data *data = user_data;
+ size_t i;
+
+ ck_assert(obj);
+ ck_assert_int_lt(data->idx, data->len);
+
+ for (i = 0; i < data->idx; i++)
+ ck_assert_ptr_ne(data->arr[i], obj);
+
+ data->arr[data->idx++] = obj;
+}
+
+struct nl_object **_nltst_cache_get_all(struct nl_cache *cache, size_t *out_len)
+{
+ int nitems;
+ struct cache_get_all_data data = {
+ .idx = 0,
+ .len = 0,
+ };
+ size_t len2 = 0;
+ size_t i;
+ size_t j;
+
+ ck_assert(cache);
+
+ nitems = nl_cache_nitems(cache);
+ ck_assert_int_ge(nitems, 0);
+
+ data.len = nitems;
+ data.arr = malloc(sizeof(struct nl_object *) * (data.len + 1));
+ ck_assert_ptr_nonnull(data.arr);
+
+ nl_cache_foreach(cache, _cache_get_all_fcn, &data);
+
+ ck_assert_int_eq(data.idx, data.len);
+
+ ck_assert_int_le(data.len, SSIZE_MAX);
+
+ data.arr[data.len] = NULL;
+ if (out_len)
+ *out_len = data.len;
+
+ /* double check the result. */
+ for (struct nl_object *obj = nl_cache_get_first(cache); obj;
+ obj = nl_cache_get_next(obj)) {
+ ck_assert_ptr_eq(data.arr[len2], obj);
+ len2++;
+ }
+ ck_assert_ptr_null(data.arr[len2]);
+
+ for (i = 0; i < data.len; i++) {
+ ck_assert_ptr_nonnull(data.arr[i]);
+ for (j = i + 1; j < data.len; j++)
+ ck_assert_ptr_ne(data.arr[i], data.arr[j]);
+ }
+
+ return data.arr;
+}
+
+struct rtnl_link *_nltst_cache_get_link(struct nl_cache *cache,
+ const char *ifname)
+{
+ _nl_auto_free struct nl_object **objs = NULL;
+ struct rtnl_link *link = NULL;
+ size_t i;
+
+ ck_assert_ptr_nonnull(cache);
+ ck_assert_ptr_nonnull(ifname);
+
+ objs = _nltst_cache_get_all(cache, NULL);
+ for (i = 0; objs[i]; i++) {
+ if (_nl_streq(rtnl_link_get_name((struct rtnl_link *)objs[i]),
+ ifname)) {
+ ck_assert_ptr_null(link);
+ link = (struct rtnl_link *)objs[i];
+ }
+ }
+
+ if (_nltst_rand_u32_range(5) == 0) {
+ _nl_auto_rtnl_link struct rtnl_link *link2 = NULL;
+
+ link2 = rtnl_link_get_by_name(cache, ifname);
+ ck_assert_ptr_eq(link2, link);
+ }
+
+ return link;
+}
+
+/*****************************************************************************/
+
+struct nl_sock *_nltst_socket(int protocol)
+{
+ struct nl_sock *sk;
+ int r;
+
+ sk = nl_socket_alloc();
+ ck_assert(sk);
+
+ r = nl_connect(sk, protocol);
+ ck_assert_int_eq(r, 0);
+
+ if (_nltst_rand_u32_range(5) == 0)
+ nl_cache_free(_nltst_rtnl_link_alloc_cache(sk, AF_UNSPEC, 0));
+
+ if (_nltst_rand_u32_range(5) == 0)
+ nl_cache_free(_nltst_rtnl_route_alloc_cache(
+ sk, _nltst_rand_select(AF_UNSPEC, AF_INET, AF_INET6)));
+
+ return sk;
+}
+
+void _nltst_add_link(struct nl_sock *sk, const char *ifname, const char *kind,
+ int *out_ifindex)
+{
+ _nl_auto_nl_socket struct nl_sock *sk_free = NULL;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ _nl_auto_nl_cache struct nl_cache *cache = NULL;
+ struct rtnl_link *link2;
+ int ifindex;
+ int r;
+
+ ck_assert(ifname);
+ ck_assert(kind);
+
+ if (_nltst_rand_u32_range(5) == 0)
+ _nltst_assert_link_not_exists(ifname);
+
+ if (!sk) {
+ sk = _nltst_socket(NETLINK_ROUTE);
+ sk_free = sk;
+ }
+
+ link = rtnl_link_alloc();
+ ck_assert(link);
+
+ r = rtnl_link_set_type(link, kind);
+ ck_assert_int_eq(r, 0);
+
+ rtnl_link_set_name(link, ifname);
+
+ r = rtnl_link_add(sk, link, NLM_F_CREATE);
+ ck_assert_int_eq(r, 0);
+
+ if (!out_ifindex && _nltst_rand_u32_range(5) != 0)
+ return;
+
+ cache = _nltst_rtnl_link_alloc_cache(sk, AF_UNSPEC, 0);
+
+ link2 = _nltst_cache_get_link(cache, ifname);
+ ck_assert_ptr_nonnull(link2);
+
+ ifindex = rtnl_link_get_ifindex(link2);
+ ck_assert_int_gt(ifindex, 0);
+
+ if (out_ifindex)
+ *out_ifindex = ifindex;
+}
+
+void _nltst_delete_link(struct nl_sock *sk, const char *ifname)
+{
+ _nl_auto_nl_socket struct nl_sock *sk_free = NULL;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+
+ _nltst_assert_link_exists(ifname);
+
+ if (!sk) {
+ sk = _nltst_socket(NETLINK_ROUTE);
+ sk_free = sk;
+ }
+
+ if (_nltst_rand_u32_range(5) == 0) {
+ _nl_auto_nl_cache struct nl_cache *cache = NULL;
+
+ cache = _nltst_rtnl_link_alloc_cache(sk, AF_UNSPEC, 0);
+ ck_assert_ptr_nonnull(_nltst_cache_get_link(cache, ifname));
+ }
+
+ link = rtnl_link_alloc();
+ ck_assert_ptr_nonnull(link);
+
+ rtnl_link_set_name(link, ifname);
+
+ _nltst_assert_retcode(rtnl_link_delete(sk, link));
+
+ _nltst_assert_link_not_exists(ifname);
+}
+
+void _nltst_get_link(struct nl_sock *sk, const char *ifname, int *out_ifindex,
+ struct rtnl_link **out_link)
+{
+ _nl_auto_nl_cache struct nl_cache *cache = NULL;
+ struct rtnl_link *link;
+
+ if (_nltst_rand_u32_range(5) == 0)
+ _nltst_assert_link_exists(ifname);
+
+ cache = _nltst_rtnl_link_alloc_cache(sk, AF_UNSPEC, 0);
+
+ link = _nltst_cache_get_link(cache, ifname);
+ ck_assert(link);
+
+ if (out_ifindex)
+ *out_ifindex = rtnl_link_get_ifindex(link);
+
+ if (out_link) {
+ nl_object_get((struct nl_object *)link);
+ *out_link = link;
+ }
+}
+
+struct nl_cache *_nltst_rtnl_link_alloc_cache(struct nl_sock *sk,
+ int addr_family, unsigned flags)
+{
+ _nl_auto_nl_socket struct nl_sock *sk_free = NULL;
+ struct nl_cache *cache;
+ int r;
+
+ if (!sk) {
+ sk = _nltst_socket(NETLINK_ROUTE);
+ sk_free = sk;
+ }
+
+ if (flags == 0 && _nltst_rand_bool())
+ r = rtnl_link_alloc_cache(sk, addr_family, &cache);
+ else
+ r = rtnl_link_alloc_cache_flags(sk, addr_family, &cache, flags);
+
+ _nltst_assert_retcode(r);
+
+ if (_nltst_rand_u32_range(5) == 0)
+ free(_nltst_cache_get_all(cache, NULL));
+
+ return _nltst_assert(cache);
+}
+
+struct nl_cache *_nltst_rtnl_route_alloc_cache(struct nl_sock *sk,
+ int addr_family)
+{
+ struct nl_cache *cache;
+
+ ck_assert_ptr_nonnull(sk);
+ ck_assert(addr_family == AF_UNSPEC || addr_family == AF_INET ||
+ addr_family == AF_INET6);
+
+ _nltst_assert_retcode(
+ rtnl_route_alloc_cache(sk, addr_family, 0, &cache));
+
+ if (_nltst_rand_u32_range(5) == 0)
+ free(_nltst_cache_get_all(cache, NULL));
+
+ return _nltst_assert(cache);
+}
+
+/*****************************************************************************/
+
+char *_nltst_strtok(const char **p_str)
+{
+ const char *str;
+ _nl_auto_free char *dst = NULL;
+ size_t dst_len = 0;
+ size_t dst_alloc = 0;
+ size_t i;
+
+ ck_assert_ptr_nonnull(p_str);
+
+ str = _nltst_str_skip_space(*p_str);
+
+ if (str[0] == '\0') {
+ *p_str = str;
+ return NULL;
+ }
+
+ dst_len = 0;
+ dst_alloc = 10;
+ dst = malloc(dst_alloc);
+ ck_assert_ptr_nonnull(dst);
+
+ i = 0;
+ while (true) {
+ char ch1 = '\0';
+ char ch2 = '\0';
+
+ /* We take the first word, up until whitespace. Note that backslash
+ * escape is honored, so you can backslash escape spaces. The returned
+ * string will NOT have backslashes removed. */
+
+ if (str[i] == '\0') {
+ *p_str = &str[i];
+ break;
+ }
+ if (_nltst_char_is_space(str[i])) {
+ *p_str = _nltst_str_skip_space(&str[i + 1]);
+ break;
+ }
+ ch1 = str[i];
+ if (str[i] == '\\') {
+ if (str[i + 1] != '\0') {
+ ch2 = str[i + 1];
+ i += 2;
+ } else
+ i += 1;
+ } else
+ i += 1;
+
+ if (dst_len + 3 >= dst_alloc) {
+ dst_alloc *= 2;
+ dst = realloc(dst, dst_alloc);
+ ck_assert_ptr_nonnull(dst);
+ }
+ dst[dst_len++] = ch1;
+ if (ch2 != '\0')
+ dst[dst_len++] = ch2;
+ }
+
+ ck_assert_int_gt(dst_len, 0);
+ return strndup(dst, dst_len);
+}
+
+char **_nltst_strtokv(const char *str)
+{
+ _nl_auto_free char *s = NULL;
+ _nltst_auto_strfreev char **result = NULL;
+ size_t r_len = 0;
+ size_t r_alloc = 0;
+
+ if (!str)
+ return NULL;
+
+ r_alloc = 4;
+ result = malloc(sizeof(char *) * r_alloc);
+ ck_assert_ptr_nonnull(result);
+
+ while ((s = _nltst_strtok(&str))) {
+ if (r_len + 2 >= r_alloc) {
+ r_alloc *= 2;
+ result = realloc(result, sizeof(char *) * r_alloc);
+ ck_assert_ptr_nonnull(result);
+ }
+ result[r_len++] = _nl_steal_pointer(&s);
+ }
+ ck_assert_int_lt(r_len, r_alloc);
+ result[r_len] = NULL;
+ return _nl_steal_pointer(&result);
+}
+
+/*****************************************************************************/
+
+void _nltst_assert_link_exists_full(const char *ifname, bool exists)
+{
+ _nl_auto_nl_cache struct nl_cache *cache = NULL;
+ _nl_auto_rtnl_link struct rtnl_link *link_clone = NULL;
+ struct rtnl_link *link;
+ char path[100];
+ struct stat st;
+ int rnd;
+ int r;
+
+ ck_assert_pstr_ne(ifname, NULL);
+ ck_assert_int_lt(strlen(ifname), IFNAMSIZ);
+
+ strcpy(path, "/sys/class/net/");
+ strcat(path, ifname);
+ ck_assert_int_lt(strlen(path), sizeof(path));
+
+ r = stat(path, &st);
+ if (exists) {
+ if (r != 0) {
+ const int errsv = (errno);
+
+ ck_assert_msg(
+ 0,
+ "link(%s) does not exist (stat(%s) failed with r=%d, errno=%d (%s)",
+ ifname, path, r, errsv, strerror(errsv));
+ }
+ } else {
+ if (r != -1 && errno != ENOENT) {
+ const int errsv = (errno);
+
+ ck_assert_msg(
+ 0,
+ "link(%s) should not exist but stat(%s) gave r=%d, errno=%d (%s)",
+ ifname, path, r, errsv, strerror(errsv));
+ }
+ }
+
+ rnd = _nltst_rand_u32_range(3);
+
+ if (rnd == 0)
+ return;
+
+ cache = _nltst_rtnl_link_alloc_cache(NULL, AF_UNSPEC, 0);
+
+ link = _nltst_cache_get_link(cache, ifname);
+ if (exists)
+ ck_assert_ptr_nonnull(link);
+ else
+ ck_assert_ptr_null(link);
+
+ if (!link || rnd == 1)
+ return;
+
+ link_clone =
+ (struct rtnl_link *)nl_object_clone((struct nl_object *)link);
+ ck_assert(link_clone);
+
+ /* FIXME: we would expect that the cloned object is identical. It is not. */
+ /* _nltst_object_identical(link, link_clone); */
+}
diff --git a/tests/nl-test-util.h b/tests/nl-test-util.h
new file mode 100644
index 0000000..0ff9752
--- /dev/null
+++ b/tests/nl-test-util.h
@@ -0,0 +1,400 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef __NL_TEST_UTIL_H__
+#define __NL_TEST_UTIL_H__
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <check.h>
+#include <string.h>
+#include <stdbool.h>
+#include <arpa/inet.h>
+
+#include "netlink/object.h"
+#include "netlink/cache.h"
+
+#include "netlink-private/nl-auto.h"
+#include "netlink-private/utils.h"
+
+/*****************************************************************************/
+
+static inline void _nltst_strfreev(char **strv)
+{
+ size_t i;
+
+ if (strv) {
+ for (i = 0; strv[i]; i++)
+ free(strv[i]);
+ free(strv);
+ }
+}
+
+#define _nltst_auto_strfreev _nl_auto(_nltst_auto_strfreev_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(char **, _nltst_auto_strfreev_fcn, _nltst_strfreev);
+
+/*****************************************************************************/
+
+#ifndef ck_assert_ptr_nonnull
+#define ck_assert_ptr_nonnull(ptr) ck_assert(ptr)
+#endif
+
+#ifndef ck_assert_pstr_ne
+#define ck_assert_pstr_ne(a, b) \
+ do { \
+ const char *_a = (a); \
+ const char *_b = (b); \
+ \
+ ck_assert(!(_a == _b || (_a && _b && strcmp(_a, _b) == 0))); \
+ } while (0)
+#endif
+
+#ifndef ck_assert_ptr_null
+#define ck_assert_ptr_null(ptr) ck_assert(!(ptr))
+#endif
+
+/*****************************************************************************/
+
+void _nltst_get_urandom(void *ptr, size_t len);
+
+uint32_t _nltst_rand_u32(void);
+
+static inline uint32_t _nltst_rand_u32_range(uint32_t n)
+{
+ uint32_t rem;
+ uint32_t i;
+
+ if (n == 0)
+ return _nltst_rand_u32();
+ if (n == 1)
+ return 0;
+
+ rem = UINT32_MAX % n;
+ for (;;) {
+ i = _nltst_rand_u32();
+ if (i < (UINT32_MAX - rem))
+ return i % n;
+ }
+}
+
+static inline bool _nltst_rand_bool(void)
+{
+ return _nltst_rand_u32() % 2 == 0;
+}
+
+#define _nltst_rand_select(a, ...) \
+ ({ \
+ const typeof(a) _lst[] = { (a), ##__VA_ARGS__ }; \
+ \
+ _lst[_nltst_rand_u32_range(_NL_N_ELEMENTS(_lst))]; \
+ })
+
+/*****************************************************************************/
+
+#define _nltst_assert(expr) \
+ ({ \
+ typeof(expr) _expr = (expr); \
+ \
+ if (!_expr) { \
+ ck_assert_msg(0, "assert(%s) failed", #expr); \
+ } \
+ _expr; \
+ })
+
+#define _nltst_assert_errno(expr) \
+ do { \
+ if (expr) { \
+ } else { \
+ const int _errno = (errno); \
+ \
+ ck_assert_msg(0, "assert(%s) failed (errno=%d, %s)", \
+ #expr, _errno, strerror(_errno)); \
+ } \
+ } while (0)
+
+#define _nltst_assert_retcode(expr) \
+ do { \
+ const int _r = (expr); \
+ \
+ if (_r < 0) { \
+ ck_assert_msg( \
+ 0, "command(%s) failed with return code %d", \
+ #expr, _r); \
+ } \
+ if (_r > 0) { \
+ ck_assert_msg( \
+ 0, \
+ "command(%s) has unexpected positive return code %d", \
+ #expr, _r); \
+ } \
+ } while (0)
+
+#define _nltst_close(fd) \
+ do { \
+ int _r; \
+ \
+ _r = _nl_close((fd)); \
+ _nltst_assert_errno(_r == 0); \
+ } while (0)
+
+#define _nltst_fclose(f) \
+ do { \
+ int _r; \
+ \
+ _r = fclose((f)); \
+ _nltst_assert_errno(_r == 0); \
+ } while (0)
+
+void _nltst_assert_link_exists_full(const char *ifname, bool exists);
+
+#define _nltst_assert_link_exists(ifname) \
+ _nltst_assert_link_exists_full((ifname), true)
+
+#define _nltst_assert_link_not_exists(ifname) \
+ _nltst_assert_link_exists_full((ifname), false)
+
+/*****************************************************************************/
+
+typedef union {
+ in_addr_t addr4;
+ struct in_addr a4;
+ struct in6_addr a6;
+} NLTstIPAddr;
+
+static inline char *_nltst_inet_ntop(int addr_family, const void *addr,
+ char buf[static INET_ADDRSTRLEN])
+{
+ char *r;
+
+ ck_assert(addr_family == AF_INET || addr_family == AF_INET6);
+ ck_assert(addr);
+
+ r = (char *)inet_ntop(addr_family, addr, buf,
+ (addr_family == AF_INET) ? INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN);
+ ck_assert_ptr_eq(r, buf);
+ ck_assert_int_lt(strlen(r), (addr_family == AF_INET) ?
+ INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN);
+ return r;
+}
+
+static inline char *_nltst_inet_ntop_dup(int addr_family, const void *addr)
+{
+ return (char *)_nltst_inet_ntop(addr_family, addr,
+ malloc((addr_family == AF_INET) ?
+ INET_ADDRSTRLEN :
+ INET6_ADDRSTRLEN));
+}
+
+static inline bool _nltst_inet_pton(int addr_family, const char *str,
+ int *out_addr_family, void *out_addr)
+{
+ NLTstIPAddr a;
+ int r;
+
+ ck_assert(addr_family == AF_UNSPEC || addr_family == AF_INET ||
+ addr_family == AF_INET6);
+
+ /* when requesting @out_addr, then the addr-family must either be
+ * pre-determined or requested too. */
+ ck_assert(!out_addr || out_addr_family || addr_family != AF_UNSPEC);
+
+ if (!str)
+ return false;
+
+ if (addr_family == AF_UNSPEC)
+ addr_family = strchr(str, ':') ? AF_INET6 : AF_INET;
+
+ r = inet_pton(addr_family, str, &a);
+ if (r != 1)
+ return false;
+
+ if (out_addr) {
+ memcpy(out_addr, &a,
+ addr_family == AF_INET ? sizeof(in_addr_t) :
+ sizeof(struct in6_addr));
+ }
+ if (out_addr_family)
+ *out_addr_family = addr_family;
+
+ return true;
+}
+
+static inline bool _nltst_inet_valid(int addr_family, const char *addr)
+{
+ return _nltst_inet_pton(addr_family, addr, NULL, NULL);
+}
+
+static inline in_addr_t _nltst_inet4(const char *addr)
+{
+ in_addr_t addr_bin = 0;
+
+ _nltst_assert(_nltst_inet_pton(AF_INET, addr, NULL, &addr_bin));
+ return addr_bin;
+}
+
+static inline struct in6_addr *_nltst_inet6p(const char *addr)
+{
+ _nl_thread_local static struct in6_addr addr_bin;
+
+ ck_assert(_nltst_inet_pton(AF_INET6, addr, NULL, &addr_bin));
+ return &addr_bin;
+}
+
+static inline struct in6_addr _nltst_inet6(const char *addr)
+{
+ struct in6_addr addr_bin;
+
+ ck_assert(_nltst_inet_pton(AF_INET6, addr, NULL, &addr_bin));
+ return addr_bin;
+}
+
+static inline int _nltst_inet_addr_family(int addr_family, const char *addr)
+{
+ if (!_nltst_inet_pton(addr_family, addr, &addr_family, NULL))
+ return AF_UNSPEC;
+ return addr_family;
+}
+
+static inline char *_nltst_inet_normalize(int addr_family, const char *addr,
+ char buf[static INET_ADDRSTRLEN])
+{
+ NLTstIPAddr a;
+
+ buf[0] = '\0';
+ if (!_nltst_inet_pton(addr_family, addr, &addr_family, &a))
+ return NULL;
+ return _nltst_inet_ntop(addr_family, &a, buf);
+}
+
+/*****************************************************************************/
+
+char *_nltst_strtok(const char **p_str);
+
+char **_nltst_strtokv(const char *str);
+
+#define _nltst_assert_strv_equal(strv1, strv2) \
+ do { \
+ typeof(strv1) _strv1 = (strv1); \
+ typeof(strv2) _strv2 = (strv2); \
+ _nl_unused const void *_strv1_typecheck1 = _strv1; \
+ _nl_unused const void *_strv2_typecheck1 = _strv2; \
+ _nl_unused const char *_strv1_typecheck2 = \
+ _strv1 ? _strv1[0] : NULL; \
+ _nl_unused const char *_strv2_typecheck2 = \
+ _strv2 ? _strv2[0] : NULL; \
+ size_t _i; \
+ \
+ ck_assert_int_eq(!!_strv1, !!_strv2); \
+ if (_strv1) { \
+ for (_i = 0; _strv1[_i] || _strv2[_i]; _i++) { \
+ ck_assert_str_eq(_strv1[_i], _strv2[_i]); \
+ } \
+ } \
+ } while (0)
+
+#define _NLTST_CHARSET_SPACE " \n\r\t"
+
+#define _nltst_char_is(ch, charset) (!!(strchr("" charset "", (ch))))
+
+#define _nltst_char_is_space(ch) _nltst_char_is(ch, _NLTST_CHARSET_SPACE)
+
+#define _nltst_str_skip_predicate(s, ch, predicate) \
+ ({ \
+ typeof(s) _s1 = (s); \
+ _nl_unused const char *_s1_typecheck = (_s1); \
+ \
+ if (_s1) { \
+ while (({ \
+ const char ch = _s1[0]; \
+ \
+ (ch != '\0') && (predicate); \
+ })) \
+ _s1++; \
+ } \
+ _s1; \
+ })
+
+#define _nltst_str_skip_charset(s, charset) \
+ _nltst_str_skip_predicate(s, _ch, _nltst_char_is(_ch, "" charset ""))
+
+#define _nltst_str_skip_space(s) \
+ _nltst_str_skip_charset(s, _NLTST_CHARSET_SPACE)
+
+#define _nltst_str_has_prefix_and_space(s, prefix) \
+ ({ \
+ typeof(s) _s2 = (s); \
+ _nl_unused const char *_s2_typecheck = (_s2); \
+ const size_t _l = strlen("" prefix ""); \
+ \
+ if (_s2) { \
+ if ((strncmp(_s2, "" prefix "", _l)) == 0 && \
+ _nltst_char_is_space(_s2[_l])) \
+ _s2 = _nltst_str_skip_space(&_s2[_l + 1]); \
+ else \
+ _s2 = NULL; \
+ } \
+ _s2; \
+ })
+
+#define _nltst_str_find_first_not_from_charset(s, charset) \
+ ({ \
+ typeof(s) _s3 = (s); \
+ _nl_unused const char *_s3_typecheck = (_s3); \
+ size_t _l3; \
+ \
+ _l3 = strspn(_s3, "" charset ""); \
+ \
+ &_s3[_l3]; \
+ })
+
+#define _nltst_str_find_first_from_charset(s, charset) \
+ ({ \
+ typeof(s) _s3 = (s); \
+ _nl_unused const char *_s3_typecheck = (_s3); \
+ size_t _l3; \
+ \
+ _l3 = strcspn(_s3, "" charset ""); \
+ \
+ &_s3[_l3]; \
+ })
+
+/*****************************************************************************/
+
+void nltst_netns_fixture_setup(void);
+void nltst_netns_fixture_teardown(void);
+
+struct nltst_netns;
+
+struct nltst_netns *nltst_netns_enter(void);
+void nltst_netns_leave(struct nltst_netns *nsdata);
+
+/*****************************************************************************/
+
+void _nltst_object_identical(const void *a, const void *b);
+
+char *_nltst_object_to_string(struct nl_object *obj);
+
+struct nl_object **_nltst_cache_get_all(struct nl_cache *cache,
+ size_t *out_len);
+
+struct rtnl_link *_nltst_cache_get_link(struct nl_cache *cache,
+ const char *ifname);
+
+struct nl_cache *_nltst_rtnl_link_alloc_cache(struct nl_sock *sk,
+ int addr_family, unsigned flags);
+
+struct nl_cache *_nltst_rtnl_route_alloc_cache(struct nl_sock *sk,
+ int addr_family);
+
+struct nl_sock *_nltst_socket(int protocol);
+
+void _nltst_add_link(struct nl_sock *sk, const char *ifname, const char *kind,
+ int *out_ifindex);
+
+void _nltst_delete_link(struct nl_sock *sk, const char *ifname);
+
+void _nltst_get_link(struct nl_sock *sk, const char *ifname, int *out_ifindex,
+ struct rtnl_link **out_link);
+
+#endif /* __NL_TEST_UTIL_H__ */
diff --git a/tests/test-complex-HTB-with-hash-filters.c b/tests/test-complex-HTB-with-hash-filters.c
index b1bf36e..016d467 100644
--- a/tests/test-complex-HTB-with-hash-filters.c
+++ b/tests/test-complex-HTB-with-hash-filters.c
@@ -1,11 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * test/test-complex-HTB-with-hash-filters.c Add HTB qdisc, HTB classes and creates some hash filters
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
* Copyright (c) 2011 Adrian Ban <adrian.ban@mantech.ro>
*/
diff --git a/tests/test-u32-filter-with-actions.c b/tests/test-u32-filter-with-actions.c
index e9910e3..17e7bdc 100644
--- a/tests/test-u32-filter-with-actions.c
+++ b/tests/test-u32-filter-with-actions.c
@@ -1,14 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
/*
- * test/tests-u32-with-actions.c Add ingress qdisc, create some hash filters, and add redirect action
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
+ * Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*
* Stolen from tests/test-complex-HTB-with-hash-filters.c
- *
- * Copyright (c) 2013 Cong Wang <xiyou.wangcong@gmail.com>
*/
#include <netlink/route/link.h>
diff --git a/tests/util.h b/tests/util.h
deleted file mode 100644
index 8c9acf1..0000000
--- a/tests/util.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <check.h>
-
-#define nl_fail_if(condition, error, message) \
- fail_if((condition), "nlerr=%d (%s): %s", \
- (error), nl_geterror(error), (message))
-
-Suite *make_nl_attr_suite(void);
-Suite *make_nl_addr_suite(void);
-Suite *make_nl_ematch_tree_clone_suite(void);
-
diff --git a/tools/build_release.sh b/tools/build_release.sh
index ca63be8..2c77d24 100755
--- a/tools/build_release.sh
+++ b/tools/build_release.sh
@@ -56,7 +56,9 @@
for F in "libnl-$V.tar.gz" "libnl-doc-$V.tar.gz"; do
md5sum "./$F" > "./$F.md5sum"
sha256sum "./$F" > "./$F.sha256sum"
- gpg ${GPG_USER--u thaller@redhat.com} --armor --verbose -o "./$F.sig" --detach-sign "./$F"
+ if [ "$NO_GPG_SIGN" != 1 ]; then
+ gpg ${GPG_USER--u thaller@redhat.com} --armor --verbose -o "./$F.sig" --detach-sign "./$F"
+ fi
done
)
tar -cvf "./$REL.tar" "./$REL/"
@@ -64,8 +66,8 @@
}
BuildAll() {
- Build || return
- Copy || return
+ Build
+ Copy
echo "BuildAll: success"
}