summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:12:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:12:28 +0000
commit6b8312f5be79bdf27d8d2623aacc05d3a721f173 (patch)
treec3f5bbb44c1db5edd68bb4db506435012b92eeff
parent083e67d2c8d40f21df5c05c31eaa350a02822691 (diff)
parent65a8683b07ce5587dd2e3c9d0cdb40c40e6f7687 (diff)
downloadlibnl-android14-mainline-uwb-release.tar.gz
Change-Id: I2fb6ca805434764648bba8429f3fe44f3a2f3275
-rw-r--r--.clang-format131
-rw-r--r--.github/workflows/ci.yml112
-rw-r--r--.gitignore133
-rw-r--r--.travis.yml8
-rwxr-xr-x.travis/run.sh17
-rw-r--r--Android.bp13
-rw-r--r--ChangeLog14
-rw-r--r--METADATA12
-rw-r--r--Makefile.am88
-rw-r--r--configure.ac14
-rw-r--r--doc/.gitignore8
-rw-r--r--doc/COPYING8
-rw-r--r--doc/README2
-rw-r--r--doc/api/.gitignore9
-rw-r--r--doc/configure.ac10
-rw-r--r--doc/core.txt108
-rwxr-xr-xdoc/doxygen-link.py2
-rw-r--r--doc/images/.gitignore3
-rwxr-xr-xdoc/resolve-asciidoc-refs.py4
-rw-r--r--doc/route.txt176
-rw-r--r--include/linux-private/linux/if_bridge.h1
-rw-r--r--include/linux-private/linux/if_link.h1
-rw-r--r--include/linux-private/linux/if_vlan.h9
-rw-r--r--include/linux-private/linux/netfilter/nfnetlink_log.h11
-rw-r--r--include/linux-private/linux/tc_act/tc_nat.h27
-rw-r--r--include/netlink-private/cache-api.h8
-rw-r--r--include/netlink-private/genl.h8
-rw-r--r--include/netlink-private/netlink.h9
-rw-r--r--include/netlink-private/nl-auto.h102
-rw-r--r--include/netlink-private/object-api.h8
-rw-r--r--include/netlink-private/route/link/api.h9
-rw-r--r--include/netlink-private/route/link/sriov.h8
-rw-r--r--include/netlink-private/route/tc-api.h8
-rw-r--r--include/netlink-private/route/utils.h8
-rw-r--r--include/netlink-private/socket.h8
-rw-r--r--include/netlink-private/tc.h8
-rw-r--r--include/netlink-private/types.h61
-rw-r--r--include/netlink-private/utils.h216
-rw-r--r--include/netlink/.gitignore1
-rw-r--r--include/netlink/addr.h8
-rw-r--r--include/netlink/attr.h8
-rw-r--r--include/netlink/cache-api.h8
-rw-r--r--include/netlink/cache.h8
-rw-r--r--include/netlink/cli/addr.h16
-rw-r--r--include/netlink/cli/class.h16
-rw-r--r--include/netlink/cli/cls.h16
-rw-r--r--include/netlink/cli/ct.h16
-rw-r--r--include/netlink/cli/exp.h15
-rw-r--r--include/netlink/cli/link.h16
-rw-r--r--include/netlink/cli/mdb.h11
-rw-r--r--include/netlink/cli/neigh.h16
-rw-r--r--include/netlink/cli/qdisc.h16
-rw-r--r--include/netlink/cli/route.h16
-rw-r--r--include/netlink/cli/rule.h16
-rw-r--r--include/netlink/cli/tc.h16
-rw-r--r--include/netlink/cli/utils.h8
-rw-r--r--include/netlink/data.h8
-rw-r--r--include/netlink/errno.h8
-rw-r--r--include/netlink/fib_lookup/lookup.h8
-rw-r--r--include/netlink/fib_lookup/request.h8
-rw-r--r--include/netlink/genl/ctrl.h8
-rw-r--r--include/netlink/genl/family.h8
-rw-r--r--include/netlink/genl/genl.h8
-rw-r--r--include/netlink/genl/mngt.h8
-rw-r--r--include/netlink/handlers.h14
-rw-r--r--include/netlink/hashtable.h8
-rw-r--r--include/netlink/idiag/idiagnl.h8
-rw-r--r--include/netlink/idiag/meminfo.h8
-rw-r--r--include/netlink/idiag/msg.h8
-rw-r--r--include/netlink/idiag/req.h8
-rw-r--r--include/netlink/idiag/vegasinfo.h8
-rw-r--r--include/netlink/list.h8
-rw-r--r--include/netlink/msg.h8
-rw-r--r--include/netlink/netfilter/ct.h10
-rw-r--r--include/netlink/netfilter/exp.h8
-rw-r--r--include/netlink/netfilter/log.h9
-rw-r--r--include/netlink/netfilter/log_msg.h39
-rw-r--r--include/netlink/netfilter/netfilter.h8
-rw-r--r--include/netlink/netfilter/nfnl.h8
-rw-r--r--include/netlink/netfilter/queue.h8
-rw-r--r--include/netlink/netfilter/queue_msg.h8
-rw-r--r--include/netlink/netlink-compat.h8
-rw-r--r--include/netlink/netlink.h8
-rw-r--r--include/netlink/object-api.h8
-rw-r--r--include/netlink/object.h8
-rw-r--r--include/netlink/route/act/gact.h8
-rw-r--r--include/netlink/route/act/mirred.h8
-rw-r--r--include/netlink/route/act/nat.h35
-rw-r--r--include/netlink/route/act/skbedit.h8
-rw-r--r--include/netlink/route/act/vlan.h8
-rw-r--r--include/netlink/route/action.h8
-rw-r--r--include/netlink/route/addr.h12
-rw-r--r--include/netlink/route/class.h8
-rw-r--r--include/netlink/route/classifier.h12
-rw-r--r--include/netlink/route/cls/basic.h8
-rw-r--r--include/netlink/route/cls/cgroup.h8
-rw-r--r--include/netlink/route/cls/ematch.h8
-rw-r--r--include/netlink/route/cls/ematch/cmp.h8
-rw-r--r--include/netlink/route/cls/ematch/meta.h8
-rw-r--r--include/netlink/route/cls/ematch/nbyte.h8
-rw-r--r--include/netlink/route/cls/ematch/text.h8
-rw-r--r--include/netlink/route/cls/flower.h59
-rw-r--r--include/netlink/route/cls/fw.h8
-rw-r--r--include/netlink/route/cls/matchall.h8
-rw-r--r--include/netlink/route/cls/police.h8
-rw-r--r--include/netlink/route/cls/u32.h8
-rw-r--r--include/netlink/route/link.h325
-rw-r--r--include/netlink/route/link/api.h8
-rw-r--r--include/netlink/route/link/bonding.h8
-rw-r--r--include/netlink/route/link/bridge.h8
-rw-r--r--include/netlink/route/link/can.h23
-rw-r--r--include/netlink/route/link/geneve.h8
-rw-r--r--include/netlink/route/link/inet.h8
-rw-r--r--include/netlink/route/link/inet6.h8
-rw-r--r--include/netlink/route/link/info-api.h8
-rw-r--r--include/netlink/route/link/ip6gre.h58
-rw-r--r--include/netlink/route/link/ip6tnl.h11
-rw-r--r--include/netlink/route/link/ip6vti.h40
-rw-r--r--include/netlink/route/link/ipgre.h11
-rw-r--r--include/netlink/route/link/ipip.h11
-rw-r--r--include/netlink/route/link/ipvlan.h8
-rw-r--r--include/netlink/route/link/ipvti.h11
-rw-r--r--include/netlink/route/link/macsec.h11
-rw-r--r--include/netlink/route/link/macvlan.h8
-rw-r--r--include/netlink/route/link/macvtap.h8
-rw-r--r--include/netlink/route/link/ppp.h8
-rw-r--r--include/netlink/route/link/sit.h11
-rw-r--r--include/netlink/route/link/sriov.h8
-rw-r--r--include/netlink/route/link/team.h26
-rw-r--r--include/netlink/route/link/veth.h8
-rw-r--r--include/netlink/route/link/vlan.h8
-rw-r--r--include/netlink/route/link/vrf.h8
-rw-r--r--include/netlink/route/link/vxlan.h8
-rw-r--r--include/netlink/route/link/xfrmi.h8
-rw-r--r--include/netlink/route/mdb.h42
-rw-r--r--include/netlink/route/neighbour.h8
-rw-r--r--include/netlink/route/neightbl.h8
-rw-r--r--include/netlink/route/netconf.h8
-rw-r--r--include/netlink/route/nexthop.h10
-rw-r--r--include/netlink/route/pktloc.h8
-rw-r--r--include/netlink/route/qdisc.h10
-rw-r--r--include/netlink/route/qdisc/cbq.h8
-rw-r--r--include/netlink/route/qdisc/dsmark.h8
-rw-r--r--include/netlink/route/qdisc/fifo.h8
-rw-r--r--include/netlink/route/qdisc/fq_codel.h8
-rw-r--r--include/netlink/route/qdisc/hfsc.h8
-rw-r--r--include/netlink/route/qdisc/htb.h8
-rw-r--r--include/netlink/route/qdisc/mqprio.h8
-rw-r--r--include/netlink/route/qdisc/netem.h8
-rw-r--r--include/netlink/route/qdisc/plug.h8
-rw-r--r--include/netlink/route/qdisc/prio.h8
-rw-r--r--include/netlink/route/qdisc/red.h8
-rw-r--r--include/netlink/route/qdisc/sfq.h8
-rw-r--r--include/netlink/route/qdisc/tbf.h8
-rw-r--r--include/netlink/route/route.h11
-rw-r--r--include/netlink/route/rtnl.h8
-rw-r--r--include/netlink/route/rule.h8
-rw-r--r--include/netlink/route/tc-api.h8
-rw-r--r--include/netlink/route/tc.h8
-rw-r--r--include/netlink/socket.h8
-rw-r--r--include/netlink/types.h8
-rw-r--r--include/netlink/utils.h37
-rw-r--r--include/netlink/version.h.in8
-rw-r--r--include/netlink/xfrm/sa.h3
-rw-r--r--lib/.gitignore3
-rw-r--r--lib/addr.c7
-rw-r--r--lib/attr.c16
-rw-r--r--lib/cache.c41
-rw-r--r--lib/cache_mngr.c7
-rw-r--r--lib/cache_mngt.c7
-rw-r--r--lib/cli/cls/basic.c8
-rw-r--r--lib/cli/cls/cgroup.c8
-rw-r--r--lib/cli/qdisc/bfifo.c8
-rw-r--r--lib/cli/qdisc/blackhole.c8
-rw-r--r--lib/cli/qdisc/fq_codel.c8
-rw-r--r--lib/cli/qdisc/hfsc.c8
-rw-r--r--lib/cli/qdisc/htb.c8
-rw-r--r--lib/cli/qdisc/ingress.c9
-rw-r--r--lib/cli/qdisc/pfifo.c9
-rw-r--r--lib/cli/qdisc/plug.c9
-rw-r--r--lib/data.c7
-rw-r--r--lib/error.c7
-rw-r--r--lib/fib_lookup/lookup.c17
-rw-r--r--lib/fib_lookup/request.c12
-rw-r--r--lib/genl/ctrl.c7
-rw-r--r--lib/genl/family.c14
-rw-r--r--lib/genl/genl.c7
-rw-r--r--lib/genl/mngt.c11
-rw-r--r--lib/handlers.c7
-rw-r--r--lib/hashtable.c62
-rw-r--r--lib/idiag/idiag.c7
-rw-r--r--lib/idiag/idiag_meminfo_obj.c7
-rw-r--r--lib/idiag/idiag_msg_obj.c9
-rw-r--r--lib/idiag/idiag_req_obj.c10
-rw-r--r--lib/idiag/idiag_vegasinfo_obj.c7
-rw-r--r--lib/msg.c7
-rw-r--r--lib/netfilter/ct.c110
-rw-r--r--lib/netfilter/ct_obj.c19
-rw-r--r--lib/netfilter/exp.c12
-rw-r--r--lib/netfilter/exp_obj.c24
-rw-r--r--lib/netfilter/log.c12
-rw-r--r--lib/netfilter/log_msg.c73
-rw-r--r--lib/netfilter/log_msg_obj.c258
-rw-r--r--lib/netfilter/log_obj.c13
-rw-r--r--lib/netfilter/netfilter.c7
-rw-r--r--lib/netfilter/nfnl.c7
-rw-r--r--lib/netfilter/queue.c7
-rw-r--r--lib/netfilter/queue_msg.c7
-rw-r--r--lib/netfilter/queue_msg_obj.c37
-rw-r--r--lib/netfilter/queue_obj.c7
-rw-r--r--lib/nl.c7
-rw-r--r--lib/object.c54
-rw-r--r--lib/route/.gitignore4
-rw-r--r--lib/route/act.c17
-rw-r--r--lib/route/act/gact.c32
-rw-r--r--lib/route/act/mirred.c31
-rw-r--r--lib/route/act/nat.c288
-rw-r--r--lib/route/act/skbedit.c22
-rw-r--r--lib/route/act/vlan.c18
-rw-r--r--lib/route/addr.c21
-rw-r--r--lib/route/class.c7
-rw-r--r--lib/route/classid.c9
-rw-r--r--lib/route/cls.c79
-rw-r--r--lib/route/cls/.gitignore2
-rw-r--r--lib/route/cls/basic.c10
-rw-r--r--lib/route/cls/cgroup.c23
-rw-r--r--lib/route/cls/ematch.c12
-rw-r--r--lib/route/cls/ematch/cmp.c8
-rw-r--r--lib/route/cls/ematch/container.c8
-rw-r--r--lib/route/cls/ematch/meta.c12
-rw-r--r--lib/route/cls/ematch/nbyte.c8
-rw-r--r--lib/route/cls/ematch/text.c12
-rw-r--r--lib/route/cls/ematch_grammar.l8
-rw-r--r--lib/route/cls/ematch_syntax.y9
-rw-r--r--lib/route/cls/flower.c896
-rw-r--r--lib/route/cls/fw.c13
-rw-r--r--lib/route/cls/mall.c18
-rw-r--r--lib/route/cls/police.c8
-rw-r--r--lib/route/cls/u32.c124
-rw-r--r--lib/route/link.c343
-rw-r--r--lib/route/link/api.c37
-rw-r--r--lib/route/link/bonding.c11
-rw-r--r--lib/route/link/bridge.c11
-rw-r--r--lib/route/link/can.c149
-rw-r--r--lib/route/link/dummy.c8
-rw-r--r--lib/route/link/geneve.c25
-rw-r--r--lib/route/link/ifb.c8
-rw-r--r--lib/route/link/inet.c8
-rw-r--r--lib/route/link/inet6.c27
-rw-r--r--lib/route/link/ip6gre.c886
-rw-r--r--lib/route/link/ip6tnl.c78
-rw-r--r--lib/route/link/ip6vti.c554
-rw-r--r--lib/route/link/ipgre.c64
-rw-r--r--lib/route/link/ipip.c64
-rw-r--r--lib/route/link/ipvlan.c11
-rw-r--r--lib/route/link/ipvti.c64
-rw-r--r--lib/route/link/macsec.c64
-rw-r--r--lib/route/link/macvlan.c20
-rw-r--r--lib/route/link/ppp.c11
-rw-r--r--lib/route/link/sit.c60
-rw-r--r--lib/route/link/sriov.c24
-rw-r--r--lib/route/link/team.c102
-rw-r--r--lib/route/link/veth.c11
-rw-r--r--lib/route/link/vlan.c12
-rw-r--r--lib/route/link/vrf.c15
-rw-r--r--lib/route/link/vxlan.c38
-rw-r--r--lib/route/link/xfrmi.c8
-rw-r--r--lib/route/mdb.c466
-rw-r--r--lib/route/neigh.c12
-rw-r--r--lib/route/neightbl.c272
-rw-r--r--lib/route/netconf.c18
-rw-r--r--lib/route/nexthop.c15
-rw-r--r--lib/route/nexthop_encap.c7
-rw-r--r--lib/route/nh_encap_mpls.c37
-rw-r--r--lib/route/pktloc.c9
-rw-r--r--lib/route/pktloc_syntax.y1
-rw-r--r--lib/route/qdisc.c39
-rw-r--r--lib/route/qdisc/blackhole.c8
-rw-r--r--lib/route/qdisc/cbq.c8
-rw-r--r--lib/route/qdisc/dsmark.c8
-rw-r--r--lib/route/qdisc/fifo.c8
-rw-r--r--lib/route/qdisc/fq_codel.c8
-rw-r--r--lib/route/qdisc/hfsc.c8
-rw-r--r--lib/route/qdisc/htb.c8
-rw-r--r--lib/route/qdisc/ingress.c8
-rw-r--r--lib/route/qdisc/mqprio.c23
-rw-r--r--lib/route/qdisc/netem.c45
-rw-r--r--lib/route/qdisc/plug.c8
-rw-r--r--lib/route/qdisc/prio.c8
-rw-r--r--lib/route/qdisc/red.c8
-rw-r--r--lib/route/qdisc/sfq.c8
-rw-r--r--lib/route/qdisc/tbf.c14
-rw-r--r--lib/route/route.c34
-rw-r--r--lib/route/route_obj.c193
-rw-r--r--lib/route/route_utils.c7
-rw-r--r--lib/route/rtnl.c7
-rw-r--r--lib/route/rule.c10
-rw-r--r--lib/route/tc.c64
-rw-r--r--lib/socket.c14
-rw-r--r--lib/utils.c18
-rw-r--r--lib/version.c7
-rw-r--r--lib/xfrm/ae.c21
-rw-r--r--lib/xfrm/sa.c163
-rw-r--r--lib/xfrm/sp.c78
-rw-r--r--libnl-3.0.pc.in1
-rw-r--r--libnl-3.sym5
-rw-r--r--libnl-nf-3.sym29
-rw-r--r--libnl-route-3.sym118
-rw-r--r--libnl-xfrm-3.sym5
-rw-r--r--m4/.gitignore2
-rw-r--r--python/.gitignore4
-rw-r--r--python/examples/iface.py29
-rw-r--r--python/examples/wiphy.py31
-rw-r--r--python/netlink/core.py2
-rw-r--r--python/netlink/route/link.py3
-rw-r--r--python/netlink/route/links/bridge.py13
-rw-r--r--python/netlink/route/links/inet.py4
-rw-r--r--python/tests/test-create-bridge.py11
-rw-r--r--src/.gitignore47
-rw-r--r--src/genl-ctrl-list.c7
-rw-r--r--src/idiag-socket-details.c8
-rw-r--r--src/lib/addr.c7
-rw-r--r--src/lib/class.c7
-rw-r--r--src/lib/cls.c7
-rw-r--r--src/lib/ct.c7
-rw-r--r--src/lib/exp.c7
-rw-r--r--src/lib/link.c7
-rw-r--r--src/lib/neigh.c7
-rw-r--r--src/lib/qdisc.c7
-rw-r--r--src/lib/route.c7
-rw-r--r--src/lib/rule.c7
-rw-r--r--src/lib/tc.c7
-rw-r--r--src/lib/utils.c12
-rw-r--r--src/nf-ct-add.c7
-rw-r--r--src/nf-ct-events.c7
-rw-r--r--src/nf-ct-list.c7
-rw-r--r--src/nf-exp-add.c8
-rw-r--r--src/nf-exp-delete.c7
-rw-r--r--src/nf-exp-list.c7
-rw-r--r--src/nf-log.c7
-rw-r--r--src/nf-monitor.c7
-rw-r--r--src/nf-queue.c8
-rw-r--r--src/nl-addr-add.c8
-rw-r--r--src/nl-addr-delete.c8
-rw-r--r--src/nl-addr-list.c8
-rw-r--r--src/nl-class-add.c7
-rw-r--r--src/nl-class-delete.c7
-rw-r--r--src/nl-class-list.c7
-rw-r--r--src/nl-classid-lookup.c7
-rw-r--r--src/nl-cls-add.c8
-rw-r--r--src/nl-cls-delete.c7
-rw-r--r--src/nl-cls-list.c7
-rw-r--r--src/nl-fib-lookup.c7
-rw-r--r--src/nl-link-enslave.c7
-rw-r--r--src/nl-link-ifindex2name.c7
-rw-r--r--src/nl-link-list.c7
-rw-r--r--src/nl-link-name2ifindex.c7
-rw-r--r--src/nl-link-release.c7
-rw-r--r--src/nl-link-set.c7
-rw-r--r--src/nl-link-stats.c7
-rw-r--r--src/nl-list-caches.c7
-rw-r--r--src/nl-list-sockets.c7
-rw-r--r--src/nl-monitor.c17
-rw-r--r--src/nl-neigh-add.c7
-rw-r--r--src/nl-neigh-delete.c7
-rw-r--r--src/nl-neigh-list.c7
-rw-r--r--src/nl-neightbl-list.c7
-rw-r--r--src/nl-pktloc-lookup.c64
-rw-r--r--src/nl-qdisc-add.c7
-rw-r--r--src/nl-qdisc-delete.c7
-rw-r--r--src/nl-qdisc-list.c7
-rw-r--r--src/nl-route-add.c7
-rw-r--r--src/nl-route-delete.c7
-rw-r--r--src/nl-route-get.c7
-rw-r--r--src/nl-route-list.c7
-rw-r--r--src/nl-rule-list.c7
-rw-r--r--src/nl-tctree-list.c7
-rw-r--r--src/nl-util-addr.c7
-rw-r--r--tests/.gitignore33
-rw-r--r--tests/check-addr.c214
-rw-r--r--tests/check-all.c17
-rw-r--r--tests/check-attr.c90
-rw-r--r--tests/check-direct.c69
-rw-r--r--tests/cksuite-all-addr.c227
-rw-r--r--tests/cksuite-all-attr.c157
-rw-r--r--tests/cksuite-all-ematch-tree-clone.c (renamed from tests/check-ematch-tree-clone.c)47
-rw-r--r--tests/cksuite-all-netns.c319
-rw-r--r--tests/cksuite-all.h12
-rw-r--r--tests/nl-test-util.c657
-rw-r--r--tests/nl-test-util.h400
-rw-r--r--tests/test-complex-HTB-with-hash-filters.c8
-rw-r--r--tests/test-u32-filter-with-actions.c10
-rw-r--r--tests/util.h10
-rwxr-xr-xtools/build_release.sh8
394 files changed, 9289 insertions, 3997 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..bed344c2
--- /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 00000000..ef0afada
--- /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 c22a603c..da3eb81d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,18 +10,137 @@ Makefile
Makefile.in
defs.h.in
defs.h.in~
-/lib/stamp-h1
-test-suite.log
-
-/libnl-1.pc
-/lib/defs.h
cscope.*
-/tags
+test-suite.log
+/*.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 efc8ae5a..00000000
--- 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 afa17020..00000000
--- 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 9b01e6f5..efd663eb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -55,10 +55,7 @@ cc_library {
},
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 @@ cc_library {
"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 cdd78a86..3d93d1cc 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 @@ Summary of Changes from 1.0-pre6 to 1.0-pre7
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 @@ Summary of Changes from 1.0-pre1 to 1.0-pre2
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 @@ Summary of Changes from 1.0-pre1 to 1.0-pre2
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 @@ Summary of Changes from 0.5.0 to 1.0-pre1
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 @@ Summary of Changes from 0.4.4 to 0.5.0
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 536465db..cb610c1e 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 @@ third_party {
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 b2e87379..ef0f82d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -105,6 +105,7 @@ libnlinclude_netlink_route_HEADERS = \
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_actdir = $(libnlincludedir)/netlink/route/act
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 @@ libnlinclude_netlink_route_cls_HEADERS = \
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 @@ libnlinclude_netlink_route_link_HEADERS = \
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 @@ libnlinclude_netlink_route_link_HEADERS = \
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 @@ libnlinclude_netlink_cli_HEADERS = \
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 @@ noinst_HEADERS = \
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 @@ noinst_HEADERS = \
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_libnl_route_3_la_SOURCES = \
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_libnl_route_3_la_SOURCES = \
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_libnl_route_3_la_SOURCES = \
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_libnl_route_3_la_SOURCES = \
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 @@ tests_ldadd = \
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 @@ tests_test_u32_filter_with_actions_LDADD = $(tests_ldadd)
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 @@ check_programs += tests/check-all
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_CPPFLAGS = \
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 @@ EXTRA_DIST += \
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 ee44d895..b6bdceca 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 @@ else
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 f7cb70da..00000000
--- 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 94a9ed02..f288702d 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 @@ the "copyright" line and a pointer to where the full notice is found.
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 @@ might be different; for a GUI interface, you would use an "about box".
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 ddcdf14f..dbca8f56 100644
--- a/doc/README
+++ b/doc/README
@@ -4,7 +4,7 @@ mscgen
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 cdef49d7..e69de29b 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 187447c9..4fb3cc3d 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 042369d3..56d87491 100644
--- a/doc/core.txt
+++ b/doc/core.txt
@@ -13,10 +13,10 @@ Thomas Graf <tgraf@suug.ch>
== 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 @@ msc {
--------
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 @@ messages. A multipart message has the flag +NLM_F_MULTI+ set and the
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 @@ protocols.
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 @@ struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk);
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 @@ higher level interfaces and the behaviour of nl_send() is to your
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 @@ by an own implementation using the function nl_cb_overwrite_recv().
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 @@ protocol and its message format.
.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 @@ nlmsg_for_each(hdr, stream, length) {
.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_data(nlh) ---------------^ ^
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 @@ int nlmsg_parse(struct nlmsghdr *hdr, int hdrlen, struct nlattr **attrs,
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 @@ struct nl_msg *nlmsg_alloc_size(size_t max);
--------
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 @@ struct nlmsghdr *nlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seqnr,
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 nlmsghdr *hdr;
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 @@ msg = nlmsg_alloc();
* 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 @@ memcpy(nlmsg_data(hdr), &hdr, sizeof(hdr));
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 @@ NOTE: `nlmsg_append()` will *not* align the start of the data. Any
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 @@ the message format will never ever change in the future.
[[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 @@ expectations. See <<core_attr_validation>>
[[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 @@ for most basic datatypes such as integers or flags. The +maxlen+
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 @@ to parse the message and its attributes in one step. See
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 @@ NOTE: `nla_find()` and `nlmsg_find_attr()` will *not* search in nested
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 @@ attribute is properly aligned.
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 @@ exception based variants.
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_U32:: 32bit integer
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 @@ integer when filling out a struct nla_policy array. It will
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 @@ NOTE: When validating the attributes using nlmsg_validate(),
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 @@ if (attrs[ATTR_OPTS]) {
.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 @@ nla_put_failure:
==== 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 @@ struct nl_msg *build_msg(int ifindex, struct nl_addr *lladdr, int mtu)
/* 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 @@ int parse_message(struct nlmsghdr *hdr)
* 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 @@ errout:
== 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 @@ Callback functions may return the following return codes:
.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 @@ void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
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 @@ The following criteras must be met for an own `nl_recv()`
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 @@ Abstract addresses use reference counting to account for all users of
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 @@ int nl_addr_cmp_prefix(struct nl_addr *addr, struct nl_addr *addr);
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 @@ int nl_addr_guess_family(struct nl_addr *addr);
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 @@ int nl_addr_valid(char *addr, int family);
=== 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 910b8f8d..1f3f67c7 100755
--- a/doc/doxygen-link.py
+++ b/doc/doxygen-link.py
@@ -11,7 +11,7 @@ rc_script = re.compile(r'\s*(.*\S)?\s*')
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 efcc7e23..00000000
--- 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 54187473..7999156e 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 @@ def translate(match):
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 9d4c23aa..cd3ea8f3 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -138,7 +138,7 @@ but all links may be updated.
*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 @@ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **resu
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 @@ NOTE: While using this function can save a substantial amount of bandwidth
==== 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_DEBUG:: Tell driver to do debugging (currently unused)
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 uint8_t rtnl_link_ipip_get_tos(struct rtnl_link *link);
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 uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link);
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 uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link);
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 uint32_t rtnl_link_ipvti_get_local(struct rtnl_link *link);
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_flowinfo(struct rtnl_link *link, uint32_t flowi
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 @@ rtnl_link_put(link);
-----
+[[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 @@ uint32_t rtnl_tc_get_overhead(struct rtnl_tc *tc);
-----
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 @@ modules may provide additional statistics via their own APIs.
| 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 @@ qlen = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_QLEN);
-------
==== Rate Table Calculations
+TODO
[[tc_qdisc]]
=== Queueing Discipline (qdisc)
@@ -1555,7 +1692,7 @@ qlen = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_QLEN);
.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 @@ creating traffic classes and enforce bandwidth limitations for each
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_handle(TC_CAST(qdisc), TC_HANDLE(1, 0));
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 @@ int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio);
-----
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 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t ceil);
-----
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 @@ TODO
+
[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 @@ TODO
+
[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 bdfecf94..e206aa8f 100644
--- a/include/linux-private/linux/if_bridge.h
+++ b/include/linux-private/linux/if_bridge.h
@@ -243,6 +243,7 @@ struct br_mdb_entry {
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 f4a97151..47ccf7f6 100644
--- a/include/linux-private/linux/if_link.h
+++ b/include/linux-private/linux/if_link.h
@@ -455,6 +455,7 @@ enum {
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 18a15dad..04bca79d 100644
--- a/include/linux-private/linux/if_vlan.h
+++ b/include/linux-private/linux/if_vlan.h
@@ -32,10 +32,11 @@ enum vlan_ioctl_cmds {
};
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 20983cb1..45c8d3b0 100644
--- a/include/linux-private/linux/netfilter/nfnetlink_log.h
+++ b/include/linux-private/linux/netfilter/nfnetlink_log.h
@@ -33,6 +33,15 @@ struct nfulnl_msg_packet_timestamp {
__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 @@ enum nfulnl_attr_type {
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 00000000..21399c2c
--- /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 c684e797..38662b71 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 5b93db3c..ac592bd8 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 5f6e3f79..d86a55d9 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 00000000..4092782b
--- /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 517e6720..a2838fd4 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 6d30bf7c..189f3615 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 @@ struct rtnl_link_info_ops
};
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 ac653ed1..f7c027a7 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 7158ce5c..1eb27dca 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 00000000..65ff5312
--- /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 9ceecfd1..5fe77fa5 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 b0f9c506..5f5d1ffb 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 97af3e51..b8f785af 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 @@ struct rtnl_mall
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 @@ struct nfnl_log_msg {
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 xfrmnl_encap_tmpl {
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_sa {
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 @@ struct rtnl_vlan
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 f33a2f84..93a04c94 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_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_auto_free _nl_auto(_nl_auto_free_fcn)
-_NL_AUTO_DEFINE_FCN_VOID0 (void *, _nl_auto_free_fcn, free)
+#define _NL_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
/*****************************************************************************/
@@ -163,11 +209,21 @@ extern const char *nl_strerror_l(int err);
/*****************************************************************************/
+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 @@ _nl_strncpy_trunc(char *dst, const char *src, size_t len)
}
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 67020331..00000000
--- a/include/netlink/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-version.h
diff --git a/include/netlink/addr.h b/include/netlink/addr.h
index 00ca7846..851e9403 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 e47aa5d5..2cd32ee1 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 e43c7ca0..851eca0b 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 c0797d01..abeeccbd 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 d0fd0551..5fcf7347 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_broadcast(struct rtnl_addr *, char *);
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 5001e428..95523740 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 a2707b8e..602b1982 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 ebe7c9dc..a50b430f 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_tcp_state(struct nfnl_ct *, char *);
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 b2418f8d..64d3b089 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_id(struct nfnl_exp *, int, char *);
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 f2c720ba..fb6c0a43 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_txqlen(struct rtnl_link *, char *);
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 00000000..cd37604a
--- /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 1c1be91b..89a336c0 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_dev(struct rtnl_neigh *, struct nl_cache *, char
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 b102da4f..d70e5591 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 089c6582..3650d8b4 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_protocol(struct rtnl_route *, char *);
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 61cd63e3..82bf067a 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 77042c71..7d4ed7a1 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 struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *);
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 7d69543a..7047d2e0 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 45010fe6..c9c76a11 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 35710cf6..6a5b4de3 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 b3c7b5f4..81fa435d 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 60e8820f..ed7cdd83 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 017b8fdf..92d60b37 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 5432b594..2e9f9fd4 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 c4ac137d..f1e3a658 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 8a51ccdd..af9edb3d 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 4fac1481..2043844f 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 @@ struct nl_msg;
* 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 @@ typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla,
* @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 @@ enum nl_cb_type {
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 3b40d86c..32578dc8 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 b69cbf17..7385d5f1 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 19223953..8a27647e 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 01e30db0..f2a79ce0 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 b63a4ce0..fb75b960 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 792b5c16..890c175b 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 2f206347..7ab1438f 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 51d9aebc..84aaa607 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 ef5d0355..ddf13732 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 nfnl_ct_alloc_cache(struct nl_sock *, struct nl_cache **);
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 736af24e..bd805144 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 e48eddff..a8ca81d6 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_copy_mode {
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 63b0f642..b3672da6 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 @@ extern "C" {
struct nlmsghdr;
struct nfnl_log_msg;
+struct nfnl_ct;
extern struct nl_object_ops log_msg_obj_ops;
@@ -90,6 +85,36 @@ extern void nfnl_log_msg_set_seq_global(struct nfnl_log_msg *, uint32_t);
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 dd3589c0..f365a218 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 8da4ba16..6e349ad3 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 224d4696..f393f4e7 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 86f4b862..dc333e01 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 2839ed03..ed71ed4e 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 41d48c68..c5ec3503 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 75f29cb5..d08bafa6 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 b0c32c98..7448df61 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 9538711b..b3a57f72 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 d65ed378..14fe9888 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 00000000..41295ce7
--- /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 69829e83..3e662ad4 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 3dcce7c7..f5001ba1 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 7d4c1857..fed491ff 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 56c12e78..240ae485 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 38333397..91252f16 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 18832ada..d92652b8 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 void rtnl_cls_put(struct rtnl_cls *);
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 51232ae0..98bbe678 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 9cd48454..8452f6cb 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 f4dac1df..4362423b 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 7afb7923..8aacb51e 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 2fe58990..b197246a 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 014c719b..6bcf7f23 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 e599abf0..1493b097 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 00000000..1a772a85
--- /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 2e1bade0..57d7c3f6 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 19556943..bfe1e7c5 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 cd1efb07..9c18b87c 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 2443f513..b8f0223f 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 8fd0994f..add464be 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 @@ struct rtnl_link;
* @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 @@ typedef enum {
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 @@ extern void rtnl_link_unset_vf_list(struct rtnl_link *);
/* 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 03b1e5e5..abdd8b29 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 5c34662d..09d495eb 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 f2e16e34..e606bd48 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 1979a714..7df50e3d 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_tx(struct rtnl_link *);
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_get_ctrlmode(struct rtnl_link *, uint32_t *);
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 aaba1f90..cf37c4e9 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 506542f6..2e93cc5b 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 666a9b83..cf257ca0 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 1087ad48..11cffcfa 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 00000000..28385925
--- /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 87ab164f..865d9738 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 "C" {
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 00000000..bfe33d31
--- /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 4c5f86b0..09a49571 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 "C" {
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 a7f51583..65d9f187 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 "C" {
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 d13bcbbc..09b1d2db 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 c97e57f8..8e31dab9 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 "C" {
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 ace4de2d..3139b478 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_get_protect(struct rtnl_link *, uint8_t *);
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 15a6cc1c..7c133cb3 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 affcddc7..6fff30d6 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 4ff811d1..d65582a0 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 d6f58519..f41e101d 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 @@ extern "C" {
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 3f7cacf7..36d66bf1 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 00000000..a55cdf9e
--- /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..66a0d931 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 4ec751e5..2729d6ed 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 0a56d91e..5d494371 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 a929a9fa..6321b09d 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 6e4cda7b..094ea118 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 00000000..a65ea849
--- /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 0f17b66e..37604149 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 6c6c9a57..8bcdab25 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 19934381..7006c6ee 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 5b422ddf..c4a2604a 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_str2flags(const char *);
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 c3768ce9..ab838211 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 10b85c5d..7d963a5c 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 *
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 3dbdd2dc..3af6d88d 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 06bd9d38..b8c358f1 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 c0334273..291aac50 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 d2c3d25e..1a69cd87 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 4c338099..d6a64172 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 5d7ca452..b7518554 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 1a38aeb2..0b26fdb1 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 47c9dd83..5012ef57 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 40f7e53b..f14c0436 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 636a8f92..28bcc1b8 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 accb8d94..51d38ed7 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 77d2e293..38ee0cef 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 ce31c548..b6c4f3dd 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 824dae35..38247628 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 void rtnl_route_get(struct rtnl_route *);
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 f551a5d3..6cae88f0 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 d0c335fc..26f5b52d 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 b7771b50..3f400baa 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 51d670ae..ee55555f 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 9a68cad9..2bd98c37 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 09cc5bd9..1e3a9a93 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 b05ce661..c62df828 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 @@ extern int nl_str2ip_proto(const char *);
/* 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 @@ enum {
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 35bf2aa8..7fccc95b 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 7362c361..cd5e552d 100644
--- a/include/netlink/xfrm/sa.h
+++ b/include/netlink/xfrm/sa.h
@@ -164,6 +164,9 @@ extern int xfrmnl_sa_set_replay_state_esn (struct xfrmnl_sa
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 e1abf186..00000000
--- 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 06f31383..fae12934 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 a4f58527..6838dba3 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 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
if (policy) {
err = validate_nla(nla, maxtype, policy);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[type])
@@ -267,13 +260,12 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
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 4bb10d19..eadce571 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 @@ static int __nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
* @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 @@ int nl_cache_pickup_checkdup(struct nl_sock *sk, struct nl_cache *cache)
* @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 @@ void nl_cache_dump(struct nl_cache *cache, struct nl_dump_params *params)
/**
* 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 @@ void nl_cache_dump_filter(struct nl_cache *cache,
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 = &params_copy;
+ }
+
+ type = params->dp_type;
+
if (type > NL_DUMP_MAX || type < 0)
BUG();
@@ -1235,7 +1246,7 @@ void nl_cache_dump_filter(struct nl_cache *cache,
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 380834f9..dd119f23 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 4178e43d..f5069767 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 1a6b1887..90ef5545 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 9e1443c2..43536b56 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 6b0206f2..7e535416 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 372855f8..2425ab73 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 a592f903..90e609e4 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 619befcf..cbbc1007 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 628e6ccb..235701cb 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 8892a64c..3c2a6c05 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 7aac7df9..fbda6ebd 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 227082d4..549db0b5 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 fea3060e..87df30f0 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 1106cb0a..bd0b92d8 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 fbd62917..e258546b 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 @@ static int result_clone(struct nl_object *_dst, struct nl_object *_src)
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 7749a070..0773c3b0 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 @@ static int request_clone(struct nl_object *_dst, struct nl_object *_src)
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 2d5d6f2a..65b5f05e 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 ed8b08b8..e8e0c9e0 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 @@ static int family_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ char *genl_family_get_name(struct genl_family *family)
*/
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 @@ int genl_family_add_grp(struct genl_family *family, uint32_t id,
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 b4f37b5b..4fd79622 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 28326cdb..1dcddbc5 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 @@ char *genl_op2name(int family, int op, char *buf, size_t len)
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 85cb3c63..e6fca0e6 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 db4ed8b6..1b332baf 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 @@ void nl_hash_table_free(nl_hash_table_t *ht)
int i;
for(i = 0; i < ht->size; i++) {
- 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);
- }
+ 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);
+ }
}
free(ht->nodes);
@@ -94,9 +88,9 @@ struct nl_object* nl_hash_table_lookup(nl_hash_table_t *ht,
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 @@ int nl_hash_table_add(nl_hash_table_t *ht, struct nl_object *obj)
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 @@ int nl_hash_table_del(nl_hash_table_t *ht, struct nl_object *obj)
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 23a8413a..38c3a6b3 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 0ada71ee..55ff8ccf 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 a1beb2c7..f42bd59d 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 @@ static int idiagnl_msg_clone(struct nl_object *_dst, struct nl_object *_src)
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 c825e403..e88fbc27 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 @@ static int idiagnl_req_clone(struct nl_object *_dst, struct nl_object *_src)
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 9a8f9935..ff9213d5 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 c08b3a40..17ca8126 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 98aaafc2..d5725f4c 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,40 +308,25 @@ static int ct_parse_timestamp(struct nfnl_ct *ct, struct nlattr *attr)
return 0;
}
-int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
+static int _nfnlmsg_ct_parse(struct nlattr **tb, struct nfnl_ct *ct)
{
- struct nfnl_ct *ct;
- struct nlattr *tb[CTA_MAX+1];
int err;
- ct = nfnl_ct_alloc();
- if (!ct)
- return -NLE_NOMEM;
-
- ct->ce_msgtype = nlh->nlmsg_type;
-
- err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX,
- ct_policy);
- if (err < 0)
- goto errout;
-
- 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;
+ return err;
}
if (tb[CTA_TUPLE_REPLY]) {
err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[CTA_PROTOINFO]) {
err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[CTA_STATUS])
@@ -367,24 +345,80 @@ int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
if (tb[CTA_COUNTERS_ORIG]) {
err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[CTA_COUNTERS_REPLY]) {
err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
if (err < 0)
- goto errout;
+ return err;
}
if (tb[CTA_TIMESTAMP]) {
err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]);
if (err < 0)
- goto errout;
+ return err;
}
+ return 0;
+}
+
+int nfnlmsg_ct_parse(struct nlmsghdr *nlh, 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;
+
+ ct->ce_msgtype = nlh->nlmsg_type;
+
+ err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX,
+ ct_policy);
+ if (err < 0)
+ goto errout;
+
+ 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;
+}
+
+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 @@ static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags,
{
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 08aa9459..86cbc17c 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 @@ static int ct_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static void ct_dump_line(struct nl_object *a, struct nl_dump_params *p)
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 @@ static void ct_dump_details(struct nl_object *a, struct nl_dump_params *p)
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 d4758614..05a6cdcc 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 @@ nla_put_failure:
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 @@ static int nfnl_exp_build_nat(struct nl_msg *msg, const struct nfnl_exp *exp)
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 8cd59eed..21311c98 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 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p)
}
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 17618085..c14a4ea2 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 @@ static int nfnl_log_build_request(const struct nfnl_log *log,
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 e1f92eb2..2b1b1258 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 @@ static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
[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 @@ int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
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 90b7bc93..6b26bc58 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 @@ static void log_msg_free_data(struct nl_object *c)
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 @@ static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p)
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 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p)
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 @@ const uint8_t *nfnl_log_msg_get_hwaddr(const struct nfnl_log_msg *msg, int *len)
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 @@ const void *nfnl_log_msg_get_payload(const struct nfnl_log_msg *msg, int *len)
int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix)
{
+ char *p = NULL;
+
+ if (prefix) {
+ p = strdup(prefix);
+ if (!p)
+ return -NLE_NOMEM;
+ }
+
free(msg->log_msg_prefix);
- msg->log_msg_prefix = strdup(prefix);
- if (!msg->log_msg_prefix)
- return -NLE_NOMEM;
+ msg->log_msg_prefix = p;
- msg->ce_mask |= LOG_MSG_ATTR_PREFIX;
+ if (p)
+ msg->ce_mask |= LOG_MSG_ATTR_PREFIX;
+ else
+ msg->ce_mask &= ~LOG_MSG_ATTR_PREFIX;
return 0;
}
@@ -445,6 +511,154 @@ uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *msg)
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 a33ef9f2..e26e5bd9 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 @@ void nfnl_log_unset_flags(struct nfnl_log *log, unsigned int flags)
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 dba435de..616c10c6 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 ac502fb4..f18e4989 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 d20dee5e..4ce3ad1b 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 68ed71e6..840b5e81 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 1e89cc49..251cd903 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 @@ static int nfnl_queue_msg_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ int nfnl_queue_msg_test_hwaddr(const struct nfnl_queue_msg *msg)
}
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 @@ const uint8_t *nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *msg,
}
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 (len < 0)
+ return -NLE_INVAL;
- if (new_payload == NULL)
+ 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 690b26e3..1ea461d8 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 bd8e3313..2a2f1eb1 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 4e14554e..bef0b6f2 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 @@ struct nl_object *nl_object_clone(struct nl_object *obj)
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 @@ void nl_object_dump_buf(struct nl_object *obj, char *buf, size_t len)
*/
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;
+ /* Can't judge unless we can compare */
+ if (ops->oo_compare == NULL)
+ 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;
+ 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 = ops->oo_id_attrs;
+ req_attrs_a = ops->oo_id_attrs;
+ req_attrs_b = req_attrs_a;
} else {
- req_attrs = 0xFFFFFFFF;
+ req_attrs_a = UINT64_MAX;
+ req_attrs_b = req_attrs_a;
}
- if (req_attrs == 0xFFFFFFFF)
- req_attrs = a->ce_mask & b->ce_mask;
+
+ 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 ((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)
+ if (req_attrs_a != req_attrs_b)
return 0;
- return !(ops->oo_compare(a, b, req_attrs, ID_COMPARISON));
+ return !(ops->oo_compare(a, b, req_attrs_a, ID_COMPARISON));
}
/**
@@ -366,7 +368,7 @@ uint64_t nl_object_diff64(struct nl_object *a, struct nl_object *b)
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 debf3b7c..00000000
--- 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 a0aff7fb..f7c0a78e 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 @@ int rtnl_act_fill(struct nl_msg *msg, int attrtype, struct rtnl_act *act)
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 @@ static int act_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 e37ef9f5..1a4bacb5 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 void gact_free_data(struct rtnl_tc *tc, void *data)
{
}
-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 @@ int rtnl_gact_set_action(struct rtnl_act *act, int action)
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 @@ static struct rtnl_tc_ops gact_ops = {
.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 b674fb8c..01da1346 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 void mirred_free_data(struct rtnl_tc *tc, void *data)
{
}
-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 @@ int rtnl_mirred_set_policy(struct rtnl_act *act, int policy)
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 @@ static struct rtnl_tc_ops mirred_ops = {
.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 00000000..21c42476
--- /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 d85265ee..24f57e56 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 void skbedit_free_data(struct rtnl_tc *tc, void *data)
{
}
-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 @@ int rtnl_skbedit_set_action(struct rtnl_act *act, int action)
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 @@ static struct rtnl_tc_ops skbedit_ops = {
.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 69b6f240..3d9fc334 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 void vlan_free_data(struct rtnl_tc *tc, void *data)
{
}
-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 @@ static struct rtnl_tc_ops vlan_ops = {
.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 f65e7e9b..28734499 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 @@ static int addr_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int addr_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static const struct trans_tbl addr_flags[] = {
__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 d1641126..76cfac99 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 9dcf993d..350962ac 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 @@ int rtnl_classid_generate(const char *name, uint32_t *result, uint32_t parent)
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 fa87cd40..8583103b 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 @@ void rtnl_cls_cache_set_tc_params(struct nl_cache *cache,
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 30f4521a..00000000
--- 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 3581c60f..93bf75d3 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 @@ static int basic_msg_parser(struct rtnl_tc *tc, void *data)
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 b1452618..ff993d18 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 struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
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 18f5be9f..90520302 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 @@ int rtnl_ematch_parse_expr(const char *expr, char **errp,
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 2e380c39..f5758669 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 813391ab..b23169bb 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 a26ed4c8..3f63cdea 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 @@ static void dump_value(struct rtnl_meta_value *v, struct nl_dump_params *p)
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 2942c0da..735dfc86 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 4dcd4f05..b5248332 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 @@ void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
{
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 e97f9fef..4f57951e 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 82d753d2..0c89603f 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 00000000..11bd7095
--- /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 b569d4f0..2952efc9 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 @@ static int fw_clone(void *_dst, void *_src)
{
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 e13ee92f..ded08c6e 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 @@ int rtnl_mall_append_action(struct rtnl_cls *cls, struct rtnl_act *act)
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 @@ static int mall_msg_parser(struct rtnl_tc *tc, void *data)
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 @@ static int mall_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
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 @@ static int mall_clone(void *_dst, void *_src)
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 14b5608d..f7771ae4 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 f06bc242..56952fb2 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 @@ static int u32_msg_parser(struct rtnl_tc *tc, void *data)
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 void u32_free_data(struct rtnl_tc *tc, void *data)
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;
+
+ dst->cu_pcnt = NULL;
+ dst->cu_selector = NULL;
+ dst->cu_mark = NULL;
+ dst->cu_act = NULL;
+ dst->cu_police = NULL;
+
+ if (src->cu_selector) {
+ if (!(selector = nl_data_clone(src->cu_selector)))
+ return -NLE_NOMEM;
+ }
- if (src->cu_selector &&
- !(dst->cu_selector = nl_data_clone(src->cu_selector)))
- return -NLE_NOMEM;
-
- if (src->cu_mark &&
- !(dst->cu_mark = nl_data_clone(src->cu_mark)))
- return -NLE_NOMEM;
+ if (src->cu_mark) {
+ if (!(mark = nl_data_clone(src->cu_mark)))
+ return -NLE_NOMEM;
+ }
if (src->cu_act) {
- if (!(dst->cu_act = rtnl_act_alloc()))
+ if (!(act = rtnl_act_alloc()))
return -NLE_NOMEM;
- memcpy(dst->cu_act, src->cu_act, sizeof(struct rtnl_act));
+ 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 && !(dst->cu_police = nl_data_clone(src->cu_police)))
- return -NLE_NOMEM;
+ if (src->cu_police) {
+ if (!(police = nl_data_clone(src->cu_police)))
+ return -NLE_NOMEM;
+ }
- if (src->cu_pcnt && !(dst->cu_pcnt = nl_data_clone(src->cu_pcnt)))
- 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 @@ static void print_selector(struct nl_dump_params *p, struct tc_u32_sel *sel,
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 @@ static void u32_dump_details(struct rtnl_tc *tc, void *data,
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 @@ static void u32_dump_stats(struct rtnl_tc *tc, void *data,
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 @@ static int u32_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
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 df01a71a..df8ea5bb 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 @@ static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link,
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 af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
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 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
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 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
err = rtnl_link_set_type(link, kind);
if (err < 0)
- goto errout;
-
- if ((af = nl_str2af(kind)) >= 0 &&
- !af_ops && (af_ops = af_lookup_and_alloc(link, af))) {
+ return err;
- 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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
/* 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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
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 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
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 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
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 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
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 @@ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache,
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 @@ int rtnl_link_build_get_request(int ifindex, const char *name,
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 @@ nla_put_failure:
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 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
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 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
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 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
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 @@ char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
*/
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 @@ nla_put_failure:
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 @@ static int build_link_msg(int cmd, struct ifinfomsg *hdr,
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 @@ int rtnl_link_build_change_request(struct rtnl_link *orig,
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 @@ errout:
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 @@ int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
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 @@ errout:
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 @@ int rtnl_link_build_delete_request(const struct rtnl_link *link,
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_put(struct rtnl_link *link)
*/
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 @@ void rtnl_link_set_family(struct rtnl_link *link, int family)
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_ifalias(struct rtnl_link *link, const char *alias)
*/
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_stat(struct rtnl_link *link, rtnl_link_stat_id_t id,
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 @@ int rtnl_link_set_type(struct rtnl_link *link, const char *type)
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 @@ pid_t rtnl_link_get_ns_pid(struct rtnl_link *link)
*/
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 @@ int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
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 @@ int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
return err;
if (rtnl_link_get_master(link) != master)
- err = -NLE_OPNOTSUPP;
-
-errout:
- rtnl_link_put(link);
+ return -NLE_OPNOTSUPP;
- return err;
+ return 0;
}
/**
@@ -3063,6 +3038,7 @@ static const struct trans_tbl link_stats[] = {
__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 @@ int rtnl_link_has_vf_list(struct rtnl_link *link) {
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_object_ops link_obj_ops = {
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 d406783e..cd2c42bb 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 @@ struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *name)
}
/**
+ * 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 @@ int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
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 @@ struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(const unsigned int family)
*/
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 11b6d3d1..90e64703 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 2d95faf8..bd042539 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 @@ static int bridge_compare(struct rtnl_link *_a, struct rtnl_link *_b,
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 884121f9..da8f092d 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_info {
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 @@ static struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
= { .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 @@ static int can_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static void can_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
}
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 @@ static int can_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
}
/**
- * 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 @@ int rtnl_link_can_get_bittiming(struct rtnl_link *link,
* @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 @@ int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
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 @@ static const struct trans_tbl can_ctrlmode[] = {
__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 1fd9f5a3..a6478d00 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 7232b07f..cab57cc0 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 @@ static void geneve_dump_details(struct rtnl_link *link, struct nl_dump_params *p
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 @@ static void geneve_dump_details(struct rtnl_link *link, struct nl_dump_params *p
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 @@ static struct rtnl_link_info_ops geneve_info_ops = {
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 524f5c6a..528647e0 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 6651bc38..2f95fb6e 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 f02792c8..afcbbceb 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 @@ static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = {
[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 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 @@ static void inet6_dump_stats(struct rtnl_link *link,
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 00000000..5d5c3a01
--- /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 085bf66f..cdc90241 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 @@ struct ip6_tnl_info
uint32_t flowinfo;
struct in6_addr local;
struct in6_addr remote;
+ uint32_t fwmark;
uint32_t ip6_tnl_mask;
};
@@ -67,6 +63,7 @@ static struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = {
[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 @@ static int ip6_tnl_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static int ip6_tnl_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params *
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 @@ static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params *
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 @@ uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link)
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 00000000..8c603abe
--- /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 a7665fef..f5a4998b 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 @@ struct ipgre_info
uint32_t link;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipgre_mask;
};
@@ -69,6 +65,7 @@ static struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
[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 @@ static int ipgre_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static int ipgre_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ static void ipgre_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ uint8_t rtnl_link_get_pmtudisc(struct rtnl_link *link)
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 3243b56b..e905ef99 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 @@ struct ipip_info
uint32_t link;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipip_mask;
};
@@ -57,6 +53,7 @@ static struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
[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 @@ static int ipip_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static int ipip_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ static void ipip_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link)
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 84ace435..020f2cb9 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 @@ static struct rtnl_link_info_ops ipvlan_info_ops = {
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 851d5665..9f9d3d68 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 @@ struct ipvti_info
uint32_t okey;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipvti_mask;
};
@@ -54,6 +50,7 @@ static struct nla_policy ipvti_policy[IFLA_VTI_MAX + 1] = {
[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 @@ static int ipvti_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static int ipvti_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ static void ipvti_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link)
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 fa115e27..16b65b04 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 @@ struct macsec_info {
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 @@ static struct nla_policy macsec_policy[IFLA_MACSEC_MAX+1] = {
[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 @@ static int macsec_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static void macsec_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ static void macsec_dump_details(struct rtnl_link *link, struct nl_dump_params *p
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 @@ static int macsec_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ int rtnl_link_macsec_get_encrypt(struct rtnl_link *link, uint8_t *encrypt)
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 @@ int rtnl_link_macsec_set_validation_type(struct rtnl_link *link, enum macsec_val
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 a23fe6d8..df61bb20 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 @@ static int macvlan_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static void macvlan_free(struct rtnl_link *link)
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 @@ static struct rtnl_link_info_ops macvtap_info_ops = {
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 @@ int rtnl_link_macvlan_del_macaddr(struct rtnl_link *link, struct nl_addr *addr)
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 b05e7f3f..a5fb400d 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 @@ static struct rtnl_link_info_ops ppp_info_ops = {
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 88565137..fabb811f 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 @@ struct sit_info
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 @@ static struct nla_policy sit_policy[IFLA_IPTUN_MAX + 1] = {
[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 @@ static int sit_parse(struct rtnl_link *link, struct nlattr *data,
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 @@ static int sit_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
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 @@ static void sit_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *pr
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 2a87cfe5..3a728147 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 @@ int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) {
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 @@ int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) {
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 @@ static void dump_vf_details(struct rtnl_link_vf *vf_data,
/* 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 @@ static void dump_vf_stats(struct rtnl_link_vf *vf_data,
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 @@ void rtnl_link_sriov_dump_stats(struct rtnl_link *link,
/* 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 @@ int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) {
}
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 @@ int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) {
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 00000000..1bcc86ed
--- /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 15859de8..37f43f69 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 @@ static struct rtnl_link_info_ops veth_info_ops = {
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 7c5aa069..36f88225 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 @@ static struct rtnl_link_info_ops vlan_info_ops = {
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 @@ static const struct trans_tbl vlan_flags[] = {
__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 8b6b451f..c4edd3ef 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 @@ static struct rtnl_link_info_ops vrf_info_ops = {
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 @@ int rtnl_link_vrf_set_tableid(struct rtnl_link *link, uint32_t id)
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 686ac31e..7b8429c8 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 @@ static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
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 @@ static struct rtnl_link_info_ops vxlan_info_ops = {
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 5a4a5630..92531f24 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 00000000..459959ee
--- /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 ca4f2b66..e1ef6a14 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 @@ static int neigh_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
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 96ca44a1..c4244fc6 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 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 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_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 struct nl_object_ops neightbl_obj_ops;
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 @@ static uint64_t neightbl_compare(struct nl_object *_a, struct nl_object *_b,
!(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 @@ static uint64_t neightbl_compare(struct nl_object *_a, struct nl_object *_b,
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 @@ static int neightbl_msg_parser(struct nl_cache_ops *ops,
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 @@ static int neightbl_msg_parser(struct nl_cache_ops *ops,
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 @@ static int neightbl_request_update(struct nl_cache *c, struct nl_sock *h)
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 @@ static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p)
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)));
-
- 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);
+ 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, " 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, " 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, " 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,
+ " 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,
+ " 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)));
}
}
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, " " \
- " 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, " " \
- " 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,
+ " "
+ " 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 %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 %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 @@ static void neightbl_dump_stats(struct nl_object *arg, struct nl_dump_params *p)
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 @@ struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *cache,
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 @@ int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
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 @@ int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
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 @@ int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
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 @@ int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
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 @@ int rtnl_neightbl_change(struct nl_sock *sk, struct rtnl_neightbl *old,
{
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_gc_tresh3(struct rtnl_neightbl *ntbl, int thresh)
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 a11ad0e2..50c91bfe 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 @@ static struct rtnl_netconf *rtnl_netconf_alloc(void)
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 @@ int rtnl_netconf_get_input(struct rtnl_netconf *nc, int *val)
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 7a9904c9..68351371 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 @@ int rtnl_route_nh_set_newdst(struct rtnl_nexthop *nh, struct nl_addr *addr)
{
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 @@ int rtnl_route_nh_set_via(struct rtnl_nexthop *nh, struct nl_addr *addr)
{
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 21f647a7..2382886a 100644
--- a/lib/route/nexthop_encap.c
+++ b/lib/route/nexthop_encap.c
@@ -31,10 +31,13 @@ static const char *nh_encap_type2str(unsigned int type)
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 @@ int nh_encap_build_msg(struct nl_msg *msg, struct rtnl_nh_encap *rtnh_encap)
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 081661e6..d30acc2c 100644
--- a/lib/route/nh_encap_mpls.c
+++ b/lib/route/nh_encap_mpls.c
@@ -34,7 +34,7 @@ static int mpls_encap_build_msg(struct nl_msg *msg, void *priv)
return 0;
nla_put_failure:
- return -NLE_MSGSIZE;
+ return -NLE_MSGSIZE;
}
static void mpls_encap_destructor(void *priv)
@@ -56,9 +56,8 @@ static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
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 @@ int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
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 @@ int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
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 9462c6e2..599e5930 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 @@ static int read_pktlocs(void)
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 25d87109..3c9326fe 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 7413cf7e..62c4390a 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 @@ struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *cache,
}
/**
+ * 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 339cf781..c24507af 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 118f893d..62af8235 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 fd9553dc..07f938c7 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 d94c0079..dc6d1895 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 ade20e50..34f6b444 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 ddd12425..0167e97e 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 e426a149..ebe38f90 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 1a63f364..73d2440e 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 0d072476..c1654041 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 @@ int rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
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 @@ int rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc *qdisc, uint16_t count[],
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 @@ int rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc *qdisc, uint64_t min[], int
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 @@ int rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc *qdisc, uint64_t max[], int
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 17dee3b7..0ca1d571 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 @@ static void netem_dump_details(struct rtnl_tc *tc, void *data,
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 rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist
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 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist
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 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist
if (endp == p) break;
if (n >= MAXDIST) {
- free(line);
fclose(f);
return -NLE_INVAL;
}
@@ -963,11 +961,8 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist
}
}
- 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 9f536375..38c1c1aa 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 5a217294..28242a08 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 f05626eb..ccab9471 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 acbb4ef8..f52452e1 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 23cc8454..ba8e304e 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 @@ static void tbf_dump_details(struct rtnl_tc *tc, void *data,
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 0900b774..fcc7459c 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 @@ int rtnl_route_build_add_request(struct rtnl_route *tmpl, int flags,
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 bacabe85..9441b77a 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 @@ static int route_clone(struct nl_object *_dst, struct nl_object *_src)
struct rtnl_route *src = (struct rtnl_route *) _src;
struct rtnl_nexthop *nh, *new;
- if (src->rt_dst)
+ 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;
+
+ if (src->rt_dst) {
if (!(dst->rt_dst = nl_addr_clone(src->rt_dst)))
return -NLE_NOMEM;
+ }
- if (src->rt_src)
+ if (src->rt_src) {
if (!(dst->rt_src = nl_addr_clone(src->rt_src)))
return -NLE_NOMEM;
+ }
- if (src->rt_pref_src)
+ 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_nr_nh = 0;
-
- nl_init_list_head(&dst->rt_nexthops);
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_line(struct nl_object *a, struct nl_dump_params *p)
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 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
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 @@ static void route_keygen(struct nl_object *obj, uint32_t *hashkey,
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 @@ static void route_keygen(struct nl_object *obj, uint32_t *hashkey,
rkey->rt_table, nl_addr2str(addr, buf, sizeof(buf)),
rkey_sz, *hashkey);
- free(rkey);
-
return;
}
@@ -512,6 +505,16 @@ static int route_update(struct nl_object *old_obj, struct nl_object *new_obj)
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 struct nla_policy route_policy[RTA_MAX+1] = {
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 @@ static int parse_multipath(struct rtnl_route *route, struct nlattr *attr)
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 @@ static int parse_multipath(struct rtnl_route *route, struct nlattr *attr)
}
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
/* 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 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
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 6337f72a..2a196f22 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 f280a489..f28ebf36 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 a0ba42ea..b3a60e14 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 @@ static int rule_clone(struct nl_object *_dst, struct nl_object *_src)
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 35303f59..a06a4789 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 @@ int rtnl_tc_set_kind(struct rtnl_tc *tc, const char *kind)
|| 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 @@ int rtnl_tc_clone(struct nl_object *dstobj, struct nl_object *srcobj)
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 @@ int rtnl_tc_clone(struct nl_object *dstobj, struct nl_object *srcobj)
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);
-
- if (!a)
- return 0;
- else if (!b)
- return -NLE_NOMEM;
- return ops->to_clone(a, b);
+ /* 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. */
+
+ 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 @@ void rtnl_tc_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
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 cfb07437..99cd36d0 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 NL_RW_LOCK(port_map_lock);
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 @@ static uint32_t generate_local_port(void)
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 @@ static uint32_t generate_local_port(void)
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 496bf3b3..a20f36c7 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 @@ static void get_psched_settings(void)
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 @@ int nl_has_capability (int capability)
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 4faae1c3..ffde260f 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 c7baf35d..3af872f3 100644
--- a/lib/xfrm/ae.c
+++ b/lib/xfrm/ae.c
@@ -164,17 +164,23 @@ static int xfrm_ae_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static void xfrm_ae_dump_line(struct nl_object *a, struct nl_dump_params *p)
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 @@ static int build_xfrm_ae_message(struct xfrmnl_ae *tmpl, int cmd, int flags,
!(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 48265ba4..a8bbced3 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 @@ static void xfrm_sa_free_data(struct nl_object *c)
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 @@ static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static int xfrm_sa_clone(struct nl_object *_dst, struct nl_object *_src)
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 @@ static const struct trans_tbl sa_attrs[] = {
__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 @@ static void xfrm_sa_dump_line(struct nl_object *a, struct nl_dump_params *p)
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 @@ static struct nla_policy xfrm_sa_policy[XFRMA_MAX+1] = {
[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 struct nla_policy xfrm_sa_policy[XFRMA_MAX+1] = {
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 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
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 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
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 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
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 @@ static int build_xfrm_sa_message(struct xfrmnl_sa *tmpl, int cmd, int flags, str
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 @@ static int build_xfrm_sa_message(struct xfrmnl_sa *tmpl, int cmd, int flags, str
}
}
+ 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 @@ static int build_xfrm_sa_delete_message(struct xfrmnl_sa *tmpl, int cmd, int fla
!(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 @@ int xfrmnl_sa_set_replay_state_esn (struct xfrmnl_sa* sa, unsigned int oseq, uns
}
+/**
+ * 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 99b6a4ce..df9e2fbe 100644
--- a/lib/xfrm/sp.c
+++ b/lib/xfrm/sp.c
@@ -93,9 +93,8 @@ static void xfrm_sp_free_data(struct nl_object *c)
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 void xfrm_sp_free_data(struct nl_object *c)
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 (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)
+ 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 ((void *)dst->sec_ctx, (void *)src->sec_ctx, len);
+ memcpy(dst->sec_ctx, src->sec_ctx, len);
}
- nl_init_list_head(&dst->usertmpl_list);
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 @@ static void xfrm_sp_dump_line(struct nl_object *a, struct nl_dump_params *p)
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 struct nla_policy xfrm_sp_policy[XFRMA_MAX+1] = {
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 @@ int xfrmnl_sp_set_lifetime_cfg (struct xfrmnl_sp* sp, struct xfrmnl_ltime_cfg* l
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 b87e3dcd..ddbc9993 100644
--- a/libnl-3.0.pc.in
+++ b/libnl-3.0.pc.in
@@ -7,4 +7,5 @@ Name: libnl
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 82d2f072..95100b1b 100644
--- a/libnl-3.sym
+++ b/libnl-3.sym
@@ -363,3 +363,8 @@ libnl_3_5 {
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 504e2dda..013c1ee7 100644
--- a/libnl-nf-3.sym
+++ b/libnl-nf-3.sym
@@ -314,3 +314,32 @@ global:
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 4a65503f..e54bc6dd 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1150,3 +1150,121 @@ global:
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 3706f33d..7f5858f5 100644
--- a/libnl-xfrm-3.sym
+++ b/libnl-xfrm-3.sym
@@ -244,3 +244,8 @@ global:
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 8d0c7563..e69de29b 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 a83b9429..00000000
--- 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 7021882a..ddf5f126 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 @@ import traceback
class test_class:
def __init__(self):
- self.done = 1;
+ self.done = 1
def msg_handler(m, a):
try:
@@ -16,7 +17,7 @@ def msg_handler(m, a):
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 @@ def msg_handler(m, a):
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 @@ def msg_handler(m, a):
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 @@ try:
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 @@ try:
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 73e2d4dc..66018831 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 @@ import traceback
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 @@ def msg_handler(m, a):
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 @@ def msg_handler(m, a):
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 @@ try:
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 @@ try:
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 e5864cf5..1a8ea8f9 100644
--- a/python/netlink/core.py
+++ b/python/netlink/core.py
@@ -127,7 +127,7 @@ class Message(object):
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 5ec14b26..e3a6bd3b 100644
--- a/python/netlink/route/link.py
+++ b/python/netlink/route/link.py
@@ -40,7 +40,6 @@ __version__ = '0.1'
__all__ = [
'LinkCache',
'Link',
- 'get_from_kernel',
]
import socket
@@ -159,7 +158,7 @@ class Link(netlink.Object):
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 549b0925..cf4e764c 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 @@ class BRIDGELink(object):
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 @@ class BRIDGELink(object):
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 @@ class BRIDGELink(object):
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 f5f45cb3..d4de07be 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 216b2491..3b91556c 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 = link.LinkCache()
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 e53eb3d1..00000000
--- 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 d3279a83..62bed3cf 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 2d7dd4bd..6f03627c 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 5d39f7cb..a79e9b4e 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 162e5427..d7312c38 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 a5ac9251..d8fd1a8b 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 e6732ae0..c00c0fbd 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 732843f9..48d4ea01 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 ae367e4a..d1c3e4b0 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 75862c7b..5b44f478 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 ea047c2f..beb83cc4 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 9d0fbe83..7297a2f6 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 213eca2a..6ef93214 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 5d3a2035..ba3de180 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 3aa2a90c..cbcdafe9 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 nl_cli_load_module(const char *prefix, const char *name)
{
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 eec9b869..632acd90 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 87f2da93..68f9ac0f 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 c512027b..692c24b1 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 1f71cd54..ae745286 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 c6e478c2..9d1eea94 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 0993a98f..25fd51f1 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 c8a40bfa..c9ad560e 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 4afbdb2b..1f67289f 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 f46abc26..ec15f63b 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 e6ebefe1..3560f4d1 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 9d017f42..a8887ac0 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 c5258bd4..d80d862a 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 a1ccf4e8..d3f92300 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 56278210..1747a65a 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 0ce4ab24..ba8e154c 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 4ddc8429..7b82c372 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 c2ad7173..a29beb78 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 a2a93a72..20079a2f 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 5d4faa0f..65757d08 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 a6496872..4239063e 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 4e368c38..ba4817a2 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 0cb3cbe2..05eb788f 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 d3820762..e07bd43a 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 d3e83998..3ff774e0 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 abe8cdb7..1c869adf 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 fc0f5a78..5b54da0b 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 85719c1c..d993f710 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 c59f95b1..966f13a3 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 e7d47038..b69b2c27 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 a6f21b4a..86294fbe 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 @@ static const struct {
{ 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 @@ static void print_usage(void)
"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 @@ int main(int argc, char *argv[])
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 585639a0..cd6063ed 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 826c1c5c..6f1ffeff 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 a9262083..2664c8fd 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 10d7ed41..5a5b0a04 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 8b1272cc..606b2db8 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 @@ static const char *layer_txt[] = {
[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 @@ static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value)
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 38903f3e..8cd317c3 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 7c5926b7..299fd48a 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 6796ca52..d1825da0 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 ed2c4e29..4e96ab01 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 750b57f4..9b4366c4 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 564fc166..b49ba4cb 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 b6c4270c..1b293ed9 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 b923184f..fe87dfe0 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 9e03038f..16f6f00d 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 6a811661..de923023 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 90af67ad..00000000
--- 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 48a2d931..00000000
--- 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 7b738daa..aff16cbb 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 @@ int main(int argc, char *argv[])
{
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 0390997c..00000000
--- 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 00000000..f40bcee9
--- /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 00000000..f395351b
--- /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 00000000..824a5960
--- /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
index 9c35c52e..f9d17a98 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 @@ static long long my_pow(long long x, long long y)
if (y < 0 || x == 0)
return 0;
- while(--y) {
+ while (--y) {
ret *= x;
}
@@ -79,7 +76,7 @@ static void dump_ematch_list(struct nl_list_head *head, int *result, int *index)
{
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_list(struct nl_list_head *head, int *result, int *index)
}
}
-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 @@ static int compare(int *r1, int *r2, int len)
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 @@ START_TEST(ematch_tree_clone)
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 00000000..97f3a702
--- /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 00000000..c4b1d8e5
--- /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 00000000..1f67ac88
--- /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 00000000..0ff97528
--- /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 b1bf36e5..016d467a 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 e9910e33..17e7bdc1 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 8c9acf12..00000000
--- 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 ca63be88..2c77d241 100755
--- a/tools/build_release.sh
+++ b/tools/build_release.sh
@@ -56,7 +56,9 @@ Copy() {
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 @@ Copy() {
}
BuildAll() {
- Build || return
- Copy || return
+ Build
+ Copy
echo "BuildAll: success"
}