]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: Implement B.A.T.M.A.N. Advanced interface type
authorAnnika Wickert <aw@awlnx.space>
Fri, 2 Oct 2020 19:43:05 +0000 (21:43 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 24 Feb 2021 16:57:29 +0000 (01:57 +0900)
23 files changed:
man/systemd.netdev.xml
man/systemd.network.xml
src/basic/linux/batman_adv.h [new file with mode: 0644]
src/libsystemd/sd-netlink/generic-netlink.c
src/libsystemd/sd-netlink/netlink-types.c
src/libsystemd/sd-netlink/netlink-types.h
src/network/meson.build
src/network/netdev/batadv.c [new file with mode: 0644]
src/network/netdev/batadv.h [new file with mode: 0644]
src/network/netdev/netdev-gperf.gperf
src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/systemd/sd-netlink.h
test/fuzz/fuzz-netdev-parser/28-batadv.netdev [new file with mode: 0644]
test/fuzz/fuzz-netdev-parser/directives.netdev
test/fuzz/fuzz-network-parser/directives.network
test/test-network/conf/25-batadv.netdev [new file with mode: 0644]
test/test-network/conf/netdev-link-local-addressing-yes.network
test/test-network/systemd-networkd-tests.py

index a18d9aba073fb6280d38fb82823bb5dce56be082..aeb03ee030428438cf924c8b9a7190c65aa7bf85 100644 (file)
 
           <row><entry><varname>bareudp</varname></entry>
           <entry> Bare UDP tunnels provide a generic L3 encapsulation support for tunnelling different L3 protocols like MPLS, IP etc. inside of an UDP tunnel.</entry></row>
+
+          <row><entry><varname>batadv</varname></entry>
+          <entry> (<ulink url="https://www.open-mesh.org/projects/open-mesh/wiki">B.A.T.M.A.N. Advanced</ulink>) is a routing protocol for multi-hop mobile ad hoc networks which operates on layer2.</entry></row>
         </tbody>
       </tgroup>
     </table>
     </variablelist>
   </refsect1>
 
+  <refsect1>
+    <title>[BatmanAdvanced] Section Options</title>
+    <para>The [BatmanAdvanced] section only applies for
+    netdevs of kind <literal>batadv</literal> and accepts the
+    following keys:</para>
+
+    <variablelist class='network-directives'>
+      <varlistentry>
+        <term><varname>GatewayMode=</varname></term>
+        <listitem>
+          <para>Takes one of <literal>off</literal>, <literal>server</literal>, or <literal>client</literal>.
+          A batman-adv node can either run in server mode (sharing its internet
+          connection with the mesh) or in client mode (searching for the most suitable internet connection
+          in the mesh) or having the gateway support turned off entirely (which is the default setting).
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>Aggregation=</varname></term>
+        <listitem>
+          <para>Takes a boolean value. Enables or disables aggregation of originator messages. Defaults to
+           true.
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>BridgeLoopAvoidance=</varname></term>
+        <listitem>
+          <para>Takes a boolean value. Enables or disables avoidance of loops on bridges. Defaults to true.
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>DistributedArpTable=</varname></term>
+        <listitem>
+          <para>Takes a boolean value. Enables or disables the distributed ARP table. Defaults to true.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>Fragmentation=</varname></term>
+        <listitem>
+          <para>Takes a boolean value. Enables or disables fragmentation. Defaults to true.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>HopPenalty=</varname></term>
+        <listitem>
+          <para>The hop penalty setting allows to modify
+          <citerefentry><refentrytitle>batctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+          preference for multihop routes vs. short routes. This interger value is applied to the
+          TQ (Transmit Quality) of each forwarded OGM (Originator Message), thereby propagating the
+          cost of an extra hop (the packet has to be received and retransmitted which costs airtime).
+          A higher hop penalty will make it more unlikely that other nodes will choose this node as
+          intermediate hop towards any given destination. The default hop penalty of '15' is a reasonable
+          value for most setups and probably does not need to be changed. However, mobile nodes could
+          choose a value of 255 (maximum value) to avoid being chosen as a router by other nodes.
+          The minimum value is 0.
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>OriginatorIntervalSec=</varname></term>
+        <listitem>
+          <para>The value specifies the interval in seconds, unless another time unit is specified in which
+          batman-adv floods the network with its protocol information.
+          See <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+          for more information.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>GatewayBandwidthDown=</varname></term>
+        <listitem>
+          <para>If the node is a server, this
+          parameter is used to inform other nodes in the network about
+          this node's internet connection download bandwidth in bits per second. Just enter any number
+          suffixed with K, M, G or T (base 1000) and the batman-adv
+          module will propagate the entered value in the mesh.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>GatewayBandwidthUp=</varname></term>
+        <listitem>
+          <para>If the node is a server, this
+          parameter is used to inform other nodes in the network about
+          this node's internet connection upload bandwidth in bits per second. Just enter any number
+          suffixed with K, M, G or T (base 1000) and the batman-adv
+          module will propagate the entered value in the mesh.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>RoutingAlgorithm=</varname></term>
+        <listitem>
+          <para>This can be either <literal>batman-v</literal> or <literal>batman-iv</literal> and describes which routing_algo
+          of <citerefentry><refentrytitle>batctl</refentrytitle><manvolnum>8</manvolnum></citerefentry> to use. The algorithm
+          cannot be changed after interface creation. Defaults to <literal>batman-v</literal>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
   <refsect1>
     <title>Examples</title>
     <example>
index 2df7910690637609b0c77100e99b145ef395fb8b..abf8ea0a6f2dedb7cc73088ad4d8f9188152b505 100644 (file)
@@ -1014,7 +1014,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           </para>
         </listitem>
       </varlistentry>
-
+      <varlistentry>
+          <term><varname>BatmanAdvanced=</varname></term>
+          <listitem>
+            <para>The name of the B.A.T.M.A.N. Advanced interface to add the link to. See
+            <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+            </para>
+          </listitem>
+        </varlistentry>
       </variablelist>
 
   </refsect1>
diff --git a/src/basic/linux/batman_adv.h b/src/basic/linux/batman_adv.h
new file mode 100644 (file)
index 0000000..d035e4c
--- /dev/null
@@ -0,0 +1,704 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright (C) 2016-2020  B.A.T.M.A.N. contributors:
+ *
+ * Matthias Schiffer
+ */
+
+#ifndef _UAPI_LINUX_BATMAN_ADV_H_
+#define _UAPI_LINUX_BATMAN_ADV_H_
+
+#define BATADV_NL_NAME "batadv"
+
+#define BATADV_NL_MCAST_GROUP_CONFIG   "config"
+#define BATADV_NL_MCAST_GROUP_TPMETER  "tpmeter"
+
+/**
+ * enum batadv_tt_client_flags - TT client specific flags
+ *
+ * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire.
+ * Bits from 8 to 15 are called _local flags_ because they are used for local
+ * computations only.
+ *
+ * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with
+ * the other nodes in the network. To achieve this goal these flags are included
+ * in the TT CRC computation.
+ */
+enum batadv_tt_client_flags {
+        /**
+         * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table
+         */
+        BATADV_TT_CLIENT_DEL     = (1 << 0),
+
+        /**
+         * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and
+         * the new update telling its new real location has not been
+         * received/sent yet
+         */
+        BATADV_TT_CLIENT_ROAM    = (1 << 1),
+
+        /**
+         * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi
+         * interface. This information is used by the "AP Isolation" feature
+         */
+        BATADV_TT_CLIENT_WIFI    = (1 << 4),
+
+        /**
+         * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This
+         * information is used by the Extended Isolation feature
+         */
+        BATADV_TT_CLIENT_ISOLA  = (1 << 5),
+
+        /**
+         * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from
+         * the table
+         */
+        BATADV_TT_CLIENT_NOPURGE = (1 << 8),
+
+        /**
+         * @BATADV_TT_CLIENT_NEW: this client has been added to the local table
+         * but has not been announced yet
+         */
+        BATADV_TT_CLIENT_NEW     = (1 << 9),
+
+        /**
+         * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it
+         * is kept in the table for one more originator interval for consistency
+         * purposes
+         */
+        BATADV_TT_CLIENT_PENDING = (1 << 10),
+
+        /**
+         * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be
+         * part of the network but no node has already announced it
+         */
+        BATADV_TT_CLIENT_TEMP   = (1 << 11),
+};
+
+/**
+ * enum batadv_mcast_flags_priv - Private, own multicast flags
+ *
+ * These are internal, multicast related flags. Currently they describe certain
+ * multicast related attributes of the segment this originator bridges into the
+ * mesh.
+ *
+ * Those attributes are used to determine the public multicast flags this
+ * originator is going to announce via TT.
+ *
+ * For netlink, if BATADV_MCAST_FLAGS_BRIDGED is unset then all querier
+ * related flags are undefined.
+ */
+enum batadv_mcast_flags_priv {
+        /**
+         * @BATADV_MCAST_FLAGS_BRIDGED: There is a bridge on top of the mesh
+         * interface.
+         */
+        BATADV_MCAST_FLAGS_BRIDGED                     = (1 << 0),
+
+        /**
+         * @BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS: Whether an IGMP querier
+         * exists in the mesh
+         */
+        BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS         = (1 << 1),
+
+        /**
+         * @BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS: Whether an MLD querier
+         * exists in the mesh
+         */
+        BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS         = (1 << 2),
+
+        /**
+         * @BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING: If an IGMP querier
+         * exists, whether it is potentially shadowing multicast listeners
+         * (i.e. querier is behind our own bridge segment)
+         */
+        BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING      = (1 << 3),
+
+        /**
+         * @BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING: If an MLD querier
+         * exists, whether it is potentially shadowing multicast listeners
+         * (i.e. querier is behind our own bridge segment)
+         */
+        BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING      = (1 << 4),
+};
+
+/**
+ * enum batadv_gw_modes - gateway mode of node
+ */
+enum batadv_gw_modes {
+        /** @BATADV_GW_MODE_OFF: gw mode disabled */
+        BATADV_GW_MODE_OFF,
+
+        /** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */
+        BATADV_GW_MODE_CLIENT,
+
+        /** @BATADV_GW_MODE_SERVER: announce itself as gateway server */
+        BATADV_GW_MODE_SERVER,
+};
+
+/**
+ * enum batadv_nl_attrs - batman-adv netlink attributes
+ */
+enum batadv_nl_attrs {
+        /**
+         * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors
+         */
+        BATADV_ATTR_UNSPEC,
+
+        /**
+         * @BATADV_ATTR_VERSION: batman-adv version string
+         */
+        BATADV_ATTR_VERSION,
+
+        /**
+         * @BATADV_ATTR_ALGO_NAME: name of routing algorithm
+         */
+        BATADV_ATTR_ALGO_NAME,
+
+        /**
+         * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface
+         */
+        BATADV_ATTR_MESH_IFINDEX,
+
+        /**
+         * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface
+         */
+        BATADV_ATTR_MESH_IFNAME,
+
+        /**
+         * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface
+         */
+        BATADV_ATTR_MESH_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface
+         */
+        BATADV_ATTR_HARD_IFINDEX,
+
+        /**
+         * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface
+         */
+        BATADV_ATTR_HARD_IFNAME,
+
+        /**
+         * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv
+         * interface
+         */
+        BATADV_ATTR_HARD_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_ORIG_ADDRESS: originator mac address
+         */
+        BATADV_ATTR_ORIG_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_TPMETER_RESULT: result of run (see
+         * batadv_tp_meter_status)
+         */
+        BATADV_ATTR_TPMETER_RESULT,
+
+        /**
+         * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took
+         */
+        BATADV_ATTR_TPMETER_TEST_TIME,
+
+        /**
+         * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run
+         */
+        BATADV_ATTR_TPMETER_BYTES,
+
+        /**
+         * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session
+         */
+        BATADV_ATTR_TPMETER_COOKIE,
+
+        /**
+         * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment
+         */
+        BATADV_ATTR_PAD,
+
+        /**
+         * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active
+         */
+        BATADV_ATTR_ACTIVE,
+
+        /**
+         * @BATADV_ATTR_TT_ADDRESS: Client MAC address
+         */
+        BATADV_ATTR_TT_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_TT_TTVN: Translation table version
+         */
+        BATADV_ATTR_TT_TTVN,
+
+        /**
+         * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version
+         */
+        BATADV_ATTR_TT_LAST_TTVN,
+
+        /**
+         * @BATADV_ATTR_TT_CRC32: CRC32 over translation table
+         */
+        BATADV_ATTR_TT_CRC32,
+
+        /**
+         * @BATADV_ATTR_TT_VID: VLAN ID
+         */
+        BATADV_ATTR_TT_VID,
+
+        /**
+         * @BATADV_ATTR_TT_FLAGS: Translation table client flags
+         */
+        BATADV_ATTR_TT_FLAGS,
+
+        /**
+         * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best
+         */
+        BATADV_ATTR_FLAG_BEST,
+
+        /**
+         * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen
+         */
+        BATADV_ATTR_LAST_SEEN_MSECS,
+
+        /**
+         * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address
+         */
+        BATADV_ATTR_NEIGH_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_TQ: TQ to neighbour
+         */
+        BATADV_ATTR_TQ,
+
+        /**
+         * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour
+         */
+        BATADV_ATTR_THROUGHPUT,
+
+        /**
+         * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth
+         */
+        BATADV_ATTR_BANDWIDTH_UP,
+
+        /**
+         * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth
+         */
+        BATADV_ATTR_BANDWIDTH_DOWN,
+
+        /**
+         * @BATADV_ATTR_ROUTER: Gateway router MAC address
+         */
+        BATADV_ATTR_ROUTER,
+
+        /**
+         * @BATADV_ATTR_BLA_OWN: Flag indicating own originator
+         */
+        BATADV_ATTR_BLA_OWN,
+
+        /**
+         * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address
+         */
+        BATADV_ATTR_BLA_ADDRESS,
+
+        /**
+         * @BATADV_ATTR_BLA_VID: BLA VLAN ID
+         */
+        BATADV_ATTR_BLA_VID,
+
+        /**
+         * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address
+         */
+        BATADV_ATTR_BLA_BACKBONE,
+
+        /**
+         * @BATADV_ATTR_BLA_CRC: BLA CRC
+         */
+        BATADV_ATTR_BLA_CRC,
+
+        /**
+         * @BATADV_ATTR_DAT_CACHE_IP4ADDRESS: Client IPv4 address
+         */
+        BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
+
+        /**
+         * @BATADV_ATTR_DAT_CACHE_HWADDRESS: Client MAC address
+         */
+        BATADV_ATTR_DAT_CACHE_HWADDRESS,
+
+        /**
+         * @BATADV_ATTR_DAT_CACHE_VID: VLAN ID
+         */
+        BATADV_ATTR_DAT_CACHE_VID,
+
+        /**
+         * @BATADV_ATTR_MCAST_FLAGS: Per originator multicast flags
+         */
+        BATADV_ATTR_MCAST_FLAGS,
+
+        /**
+         * @BATADV_ATTR_MCAST_FLAGS_PRIV: Private, own multicast flags
+         */
+        BATADV_ATTR_MCAST_FLAGS_PRIV,
+
+        /**
+         * @BATADV_ATTR_VLANID: VLAN id on top of soft interface
+         */
+        BATADV_ATTR_VLANID,
+
+        /**
+         * @BATADV_ATTR_AGGREGATED_OGMS_ENABLED: whether the batman protocol
+         *  messages of the mesh interface shall be aggregated or not.
+         */
+        BATADV_ATTR_AGGREGATED_OGMS_ENABLED,
+
+        /**
+         * @BATADV_ATTR_AP_ISOLATION_ENABLED: whether the data traffic going
+         *  from a wireless client to another wireless client will be silently
+         *  dropped.
+         */
+        BATADV_ATTR_AP_ISOLATION_ENABLED,
+
+        /**
+         * @BATADV_ATTR_ISOLATION_MARK: the isolation mark which is used to
+         *  classify clients as "isolated" by the Extended Isolation feature.
+         */
+        BATADV_ATTR_ISOLATION_MARK,
+
+        /**
+         * @BATADV_ATTR_ISOLATION_MASK: the isolation (bit)mask which is used to
+         *  classify clients as "isolated" by the Extended Isolation feature.
+         */
+        BATADV_ATTR_ISOLATION_MASK,
+
+        /**
+         * @BATADV_ATTR_BONDING_ENABLED: whether the data traffic going through
+         *  the mesh will be sent using multiple interfaces at the same time.
+         */
+        BATADV_ATTR_BONDING_ENABLED,
+
+        /**
+         * @BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED: whether the bridge loop
+         *  avoidance feature is enabled. This feature detects and avoids loops
+         *  between the mesh and devices bridged with the soft interface
+         */
+        BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
+
+        /**
+         * @BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED: whether the distributed
+         *  arp table feature is enabled. This feature uses a distributed hash
+         *  table to answer ARP requests without flooding the request through
+         *  the whole mesh.
+         */
+        BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
+
+        /**
+         * @BATADV_ATTR_FRAGMENTATION_ENABLED: whether the data traffic going
+         *  through the mesh will be fragmented or silently discarded if the
+         *  packet size exceeds the outgoing interface MTU.
+         */
+        BATADV_ATTR_FRAGMENTATION_ENABLED,
+
+        /**
+         * @BATADV_ATTR_GW_BANDWIDTH_DOWN: defines the download bandwidth which
+         *  is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
+         *  to 'server'.
+         */
+        BATADV_ATTR_GW_BANDWIDTH_DOWN,
+
+        /**
+         * @BATADV_ATTR_GW_BANDWIDTH_UP: defines the upload bandwidth which
+         *  is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
+         *  to 'server'.
+         */
+        BATADV_ATTR_GW_BANDWIDTH_UP,
+
+        /**
+         * @BATADV_ATTR_GW_MODE: defines the state of the gateway features.
+         * Possible values are specified in enum batadv_gw_modes
+         */
+        BATADV_ATTR_GW_MODE,
+
+        /**
+         * @BATADV_ATTR_GW_SEL_CLASS: defines the selection criteria this node
+         *  will use to choose a gateway if gw_mode was set to 'client'.
+         */
+        BATADV_ATTR_GW_SEL_CLASS,
+
+        /**
+         * @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied
+         *  to an originator message's tq-field on every hop and/or per
+         *  hard interface
+         */
+        BATADV_ATTR_HOP_PENALTY,
+
+        /**
+         * @BATADV_ATTR_LOG_LEVEL: bitmask with to define which debug messages
+         *  should be send to the debug log/trace ring buffer
+         */
+        BATADV_ATTR_LOG_LEVEL,
+
+        /**
+         * @BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED: whether multicast
+         *  optimizations should be replaced by simple broadcast-like flooding
+         *  of multicast packets. If set to non-zero then all nodes in the mesh
+         *  are going to use classic flooding for any multicast packet with no
+         *  optimizations.
+         */
+        BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED,
+
+        /**
+         * @BATADV_ATTR_NETWORK_CODING_ENABLED: whether Network Coding (using
+         *  some magic to send fewer wifi packets but still the same content) is
+         *  enabled or not.
+         */
+        BATADV_ATTR_NETWORK_CODING_ENABLED,
+
+        /**
+         * @BATADV_ATTR_ORIG_INTERVAL: defines the interval in milliseconds in
+         *  which batman sends its protocol messages.
+         */
+        BATADV_ATTR_ORIG_INTERVAL,
+
+        /**
+         * @BATADV_ATTR_ELP_INTERVAL: defines the interval in milliseconds in
+         *  which batman emits probing packets for neighbor sensing (ELP).
+         */
+        BATADV_ATTR_ELP_INTERVAL,
+
+        /**
+         * @BATADV_ATTR_THROUGHPUT_OVERRIDE: defines the throughput value to be
+         *  used by B.A.T.M.A.N. V when estimating the link throughput using
+         *  this interface. If the value is set to 0 then batman-adv will try to
+         *  estimate the throughput by itself.
+         */
+        BATADV_ATTR_THROUGHPUT_OVERRIDE,
+
+        /**
+         * @BATADV_ATTR_MULTICAST_FANOUT: defines the maximum number of packet
+         * copies that may be generated for a multicast-to-unicast conversion.
+         * Once this limit is exceeded distribution will fall back to broadcast.
+         */
+        BATADV_ATTR_MULTICAST_FANOUT,
+
+        /* add attributes above here, update the policy in netlink.c */
+
+        /**
+         * @__BATADV_ATTR_AFTER_LAST: internal use
+         */
+        __BATADV_ATTR_AFTER_LAST,
+
+        /**
+         * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
+         */
+        NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
+
+        /**
+         * @BATADV_ATTR_MAX: highest attribute number currently defined
+         */
+        BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum batadv_nl_commands - supported batman-adv netlink commands
+ */
+enum batadv_nl_commands {
+        /**
+         * @BATADV_CMD_UNSPEC: unspecified command to catch errors
+         */
+        BATADV_CMD_UNSPEC,
+
+        /**
+         * @BATADV_CMD_GET_MESH: Get attributes from softif/mesh
+         */
+        BATADV_CMD_GET_MESH,
+
+        /**
+         * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH
+         */
+        BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH,
+
+        /**
+         * @BATADV_CMD_TP_METER: Start a tp meter session
+         */
+        BATADV_CMD_TP_METER,
+
+        /**
+         * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session
+         */
+        BATADV_CMD_TP_METER_CANCEL,
+
+        /**
+         * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms.
+         */
+        BATADV_CMD_GET_ROUTING_ALGOS,
+
+        /**
+         * @BATADV_CMD_GET_HARDIF: Get attributes from a hardif of the
+         *  current softif
+         */
+        BATADV_CMD_GET_HARDIF,
+
+        /**
+         * @BATADV_CMD_GET_HARDIFS: Alias for @BATADV_CMD_GET_HARDIF
+         */
+        BATADV_CMD_GET_HARDIFS = BATADV_CMD_GET_HARDIF,
+
+        /**
+         * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations
+         */
+        BATADV_CMD_GET_TRANSTABLE_LOCAL,
+
+        /**
+         * @BATADV_CMD_GET_TRANSTABLE_GLOBAL: Query list of global translations
+         */
+        BATADV_CMD_GET_TRANSTABLE_GLOBAL,
+
+        /**
+         * @BATADV_CMD_GET_ORIGINATORS: Query list of originators
+         */
+        BATADV_CMD_GET_ORIGINATORS,
+
+        /**
+         * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours
+         */
+        BATADV_CMD_GET_NEIGHBORS,
+
+        /**
+         * @BATADV_CMD_GET_GATEWAYS: Query list of gateways
+         */
+        BATADV_CMD_GET_GATEWAYS,
+
+        /**
+         * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims
+         */
+        BATADV_CMD_GET_BLA_CLAIM,
+
+        /**
+         * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance
+         * backbones
+         */
+        BATADV_CMD_GET_BLA_BACKBONE,
+
+        /**
+         * @BATADV_CMD_GET_DAT_CACHE: Query list of DAT cache entries
+         */
+        BATADV_CMD_GET_DAT_CACHE,
+
+        /**
+         * @BATADV_CMD_GET_MCAST_FLAGS: Query list of multicast flags
+         */
+        BATADV_CMD_GET_MCAST_FLAGS,
+
+        /**
+         * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh
+         */
+        BATADV_CMD_SET_MESH,
+
+        /**
+         * @BATADV_CMD_SET_HARDIF: Set attributes for hardif of the
+         *  current softif
+         */
+        BATADV_CMD_SET_HARDIF,
+
+        /**
+         * @BATADV_CMD_GET_VLAN: Get attributes from a VLAN of the
+         *  current softif
+         */
+        BATADV_CMD_GET_VLAN,
+
+        /**
+         * @BATADV_CMD_SET_VLAN: Set attributes for VLAN of the
+         *  current softif
+         */
+        BATADV_CMD_SET_VLAN,
+
+        /* add new commands above here */
+
+        /**
+         * @__BATADV_CMD_AFTER_LAST: internal use
+         */
+        __BATADV_CMD_AFTER_LAST,
+
+        /**
+         * @BATADV_CMD_MAX: highest used command number
+         */
+        BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
+};
+
+/**
+ * enum batadv_tp_meter_reason - reason of a tp meter test run stop
+ */
+enum batadv_tp_meter_reason {
+        /**
+         * @BATADV_TP_REASON_COMPLETE: sender finished tp run
+         */
+        BATADV_TP_REASON_COMPLETE              = 3,
+
+        /**
+         * @BATADV_TP_REASON_CANCEL: sender was stopped during run
+         */
+        BATADV_TP_REASON_CANCEL                        = 4,
+
+        /* error status >= 128 */
+
+        /**
+         * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or
+         * didn't answer
+         */
+        BATADV_TP_REASON_DST_UNREACHABLE       = 128,
+
+        /**
+         * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit
+         */
+        BATADV_TP_REASON_RESEND_LIMIT          = 129,
+
+        /**
+         * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node
+         * already ongoing
+         */
+        BATADV_TP_REASON_ALREADY_ONGOING       = 130,
+
+        /**
+         * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory
+         */
+        BATADV_TP_REASON_MEMORY_ERROR          = 131,
+
+        /**
+         * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface
+         */
+        BATADV_TP_REASON_CANT_SEND             = 132,
+
+        /**
+         * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions
+         */
+        BATADV_TP_REASON_TOO_MANY              = 133,
+};
+
+/**
+ * enum batadv_ifla_attrs - batman-adv ifla nested attributes
+ */
+enum batadv_ifla_attrs {
+        /**
+         * @IFLA_BATADV_UNSPEC: unspecified attribute which is not parsed by
+         *  rtnetlink
+         */
+        IFLA_BATADV_UNSPEC,
+
+        /**
+         * @IFLA_BATADV_ALGO_NAME: routing algorithm (name) which should be
+         *  used by the newly registered batadv net_device.
+         */
+        IFLA_BATADV_ALGO_NAME,
+
+        /* add attributes above here, update the policy in soft-interface.c */
+
+        /**
+         * @__IFLA_BATADV_MAX: internal use
+         */
+        __IFLA_BATADV_MAX,
+};
+
+#define IFLA_BATADV_MAX (__IFLA_BATADV_MAX - 1)
+
+#endif /* _UAPI_LINUX_BATMAN_ADV_H_ */
index d4ec268806e5b0540d7d1c9ec0f7c2df6fdd45cb..9710ed0f16319e5838bf252ffd7ae8bac646b5af 100644 (file)
@@ -20,6 +20,7 @@ static const genl_family genl_families[] = {
         [SD_GENL_L2TP]      = { .name = "l2tp",      .version = 1 },
         [SD_GENL_MACSEC]    = { .name = "macsec",    .version = 1 },
         [SD_GENL_NL80211]   = { .name = "nl80211",   .version = 1 },
+        [SD_GENL_BATADV]    = { .name = "batadv",    .version = 1 },
 };
 
 int sd_genl_socket_open(sd_netlink **ret) {
index 4acf6a7ff8b787ea9bcd047418a6c1fe56c59c50..ed7b9a8cd166f0b0d5af4b4bdae9105174c5d160 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/genetlink.h>
 #include <linux/ip.h>
 #include <linux/if.h>
+#include <linux/batman_adv.h>
 #include <linux/can/netlink.h>
 #include <linux/fib_rules.h>
 #include <linux/fou.h>
@@ -82,6 +83,10 @@ static const NLTypeSystem empty_type_system = {
         .types = empty_types,
 };
 
+static const NLType rtnl_link_info_data_batadv_types[] = {
+        [IFLA_BATADV_ALGO_NAME] = { .type = NETLINK_TYPE_STRING, .size = 20 },
+};
+
 static const NLType rtnl_link_info_data_veth_types[] = {
         [VETH_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
 };
@@ -403,6 +408,7 @@ static const char* const nl_union_link_info_data_table[] = {
         [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm",
         [NL_UNION_LINK_INFO_DATA_IFB] = "ifb",
         [NL_UNION_LINK_INFO_DATA_BAREUDP] = "bareudp",
+        [NL_UNION_LINK_INFO_DATA_BATADV] = "batadv",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
@@ -460,6 +466,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
                                                        .types = rtnl_link_info_data_xfrm_types },
         [NL_UNION_LINK_INFO_DATA_BAREUDP] =          { .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types),
                                                        .types = rtnl_link_info_data_bareudp_types },
+        [NL_UNION_LINK_INFO_DATA_BATADV] =           { .count = ELEMENTSOF(rtnl_link_info_data_batadv_types),
+                                                       .types = rtnl_link_info_data_batadv_types },
 };
 
 static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
@@ -1326,6 +1334,83 @@ static const NLTypeSystem genl_nl80211_cmds_type_system = {
         .types = genl_nl80211_cmds,
 };
 
+static const NLType genl_batadv_types[] = {
+        [BATADV_ATTR_VERSION]                       = { .type = NETLINK_TYPE_STRING },
+        [BATADV_ATTR_ALGO_NAME]                     = { .type = NETLINK_TYPE_STRING },
+        [BATADV_ATTR_MESH_IFINDEX]                  = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_MESH_IFNAME]                   = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ },
+        [BATADV_ATTR_MESH_ADDRESS]                  = { .size = ETH_ALEN },
+        [BATADV_ATTR_HARD_IFINDEX]                  = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_HARD_IFNAME]                   = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ },
+        [BATADV_ATTR_HARD_ADDRESS]                  = { .size = ETH_ALEN },
+        [BATADV_ATTR_ORIG_ADDRESS]                  = { .size = ETH_ALEN },
+        [BATADV_ATTR_TPMETER_RESULT]                = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_TPMETER_TEST_TIME]             = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_TPMETER_BYTES]                 = { .type = NETLINK_TYPE_U64 },
+        [BATADV_ATTR_TPMETER_COOKIE]                = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_PAD]                           = { .type = NETLINK_TYPE_UNSPEC },
+        [BATADV_ATTR_ACTIVE]                        = { .type = NETLINK_TYPE_FLAG },
+        [BATADV_ATTR_TT_ADDRESS]                    = { .size = ETH_ALEN },
+        [BATADV_ATTR_TT_TTVN]                       = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_TT_LAST_TTVN]                  = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_TT_CRC32]                      = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_TT_VID]                        = { .type = NETLINK_TYPE_U16 },
+        [BATADV_ATTR_TT_FLAGS]                      = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_FLAG_BEST]                     = { .type = NETLINK_TYPE_FLAG },
+        [BATADV_ATTR_LAST_SEEN_MSECS]               = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_NEIGH_ADDRESS]                 = { .size = ETH_ALEN },
+        [BATADV_ATTR_TQ]                            = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_THROUGHPUT]                    = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_BANDWIDTH_UP]                  = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_BANDWIDTH_DOWN]                = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_ROUTER]                        = { .size = ETH_ALEN },
+        [BATADV_ATTR_BLA_OWN]                       = { .type = NETLINK_TYPE_FLAG },
+        [BATADV_ATTR_BLA_ADDRESS]                   = { .size = ETH_ALEN },
+        [BATADV_ATTR_BLA_VID]                       = { .type = NETLINK_TYPE_U16 },
+        [BATADV_ATTR_BLA_BACKBONE]                  = { .size = ETH_ALEN },
+        [BATADV_ATTR_BLA_CRC]                       = { .type = NETLINK_TYPE_U16 },
+        [BATADV_ATTR_DAT_CACHE_IP4ADDRESS]          = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_DAT_CACHE_HWADDRESS]           = { .size = ETH_ALEN },
+        [BATADV_ATTR_DAT_CACHE_VID]                 = { .type = NETLINK_TYPE_U16 },
+        [BATADV_ATTR_MCAST_FLAGS]                   = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_MCAST_FLAGS_PRIV]              = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_VLANID]                        = { .type = NETLINK_TYPE_U16 },
+        [BATADV_ATTR_AGGREGATED_OGMS_ENABLED]       = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_AP_ISOLATION_ENABLED]          = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_ISOLATION_MARK]                = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_ISOLATION_MASK]                = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_BONDING_ENABLED]               = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_FRAGMENTATION_ENABLED]         = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_GW_BANDWIDTH_DOWN]             = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_GW_BANDWIDTH_UP]               = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_GW_MODE]                       = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_GW_SEL_CLASS]                  = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_HOP_PENALTY]                   = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_LOG_LEVEL]                     = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]  = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_MULTICAST_FANOUT]              = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_NETWORK_CODING_ENABLED]        = { .type = NETLINK_TYPE_U8 },
+        [BATADV_ATTR_ORIG_INTERVAL]                 = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_ELP_INTERVAL]                  = { .type = NETLINK_TYPE_U32 },
+        [BATADV_ATTR_THROUGHPUT_OVERRIDE]           = { .type = NETLINK_TYPE_U32 },
+};
+
+static const NLTypeSystem genl_batadv_type_system = {
+        .count = ELEMENTSOF(genl_batadv_types),
+        .types = genl_batadv_types,
+};
+
+static const NLType genl_batadv_cmds[] = {
+        [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system },
+};
+
+static const NLTypeSystem genl_batadv_cmds_type_system = {
+        .count = ELEMENTSOF(genl_batadv_cmds),
+        .types = genl_batadv_cmds,
+};
+
 static const NLType genl_families[] = {
         [SD_GENL_ID_CTRL]   = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system },
         [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system },
@@ -1333,6 +1418,7 @@ static const NLType genl_families[] = {
         [SD_GENL_L2TP]      = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system },
         [SD_GENL_MACSEC]    = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system },
         [SD_GENL_NL80211]   = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system },
+        [SD_GENL_BATADV]    = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system },
 };
 
 static const NLType nfnl_nft_table_types[] = {
index a4cd4ab56cb4dfae3639410ee0a735eeb5f5ad72..316d7f1b87755f7ec1f809d36eeaf05108ba7b9d 100644 (file)
@@ -92,6 +92,7 @@ typedef enum NLUnionLinkInfoData {
         NL_UNION_LINK_INFO_DATA_XFRM,
         NL_UNION_LINK_INFO_DATA_IFB,
         NL_UNION_LINK_INFO_DATA_BAREUDP,
+        NL_UNION_LINK_INFO_DATA_BATADV,
         _NL_UNION_LINK_INFO_DATA_MAX,
         _NL_UNION_LINK_INFO_DATA_INVALID = -EINVAL,
 } NLUnionLinkInfoData;
index 5993db8d06a4e972cea5437e43fed775a107981b..3ff04467b0d16ccc3adb94c8d84a1acfd2306b71 100644 (file)
@@ -3,6 +3,8 @@
 sources = files('''
         netdev/bareudp.c
         netdev/bareudp.h
+        netdev/batadv.c
+        netdev/batadv.h
         netdev/bond.c
         netdev/bond.h
         netdev/bridge.c
diff --git a/src/network/netdev/batadv.c b/src/network/netdev/batadv.c
new file mode 100644 (file)
index 0000000..86cd1f1
--- /dev/null
@@ -0,0 +1,204 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <inttypes.h>
+#include <linux/genetlink.h>
+
+#include "batadv.h"
+#include "fileio.h"
+#include "netlink-util.h"
+#include "network-internal.h"
+#include "networkd-manager.h"
+#include "parse-util.h"
+#include "stdio-util.h"
+#include "string-table.h"
+#include "string-util.h"
+
+static void batadv_init(NetDev *n) {
+        BatmanAdvanced *b;
+
+        b = BATADV(n);
+
+        /* Set defaults */
+        b->aggregation            = true;
+        b->gateway_bandwidth_down = 10000;
+        b->gateway_bandwidth_up   = 2000;
+        b->bridge_loop_avoidance  = true;
+        b->distributed_arp_table  = true;
+        b->fragmentation          = true;
+        b->hop_penalty            = 15;
+        b->originator_interval    = 1000;
+        b->routing_algorithm      = BATADV_ROUTING_ALGORITHM_BATMAN_V;
+}
+
+static const char* const batadv_gateway_mode_table[_BATADV_GATEWAY_MODE_MAX] = {
+        [BATADV_GATEWAY_MODE_OFF]    = "off",
+        [BATADV_GATEWAY_MODE_CLIENT] = "client",
+        [BATADV_GATEWAY_MODE_SERVER] = "server",
+};
+
+static const char* const batadv_routing_algorithm_table[_BATADV_ROUTING_ALGORITHM_MAX] = {
+        [BATADV_ROUTING_ALGORITHM_BATMAN_V]  = "batman-v",
+        [BATADV_ROUTING_ALGORITHM_BATMAN_IV] = "batman-iv",
+};
+
+static const char* const batadv_routing_algorithm_kernel_table[_BATADV_ROUTING_ALGORITHM_MAX] = {
+        [BATADV_ROUTING_ALGORITHM_BATMAN_V]  = "BATMAN_V",
+        [BATADV_ROUTING_ALGORITHM_BATMAN_IV] = "BATMAN_IV",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(batadv_gateway_mode, BatadvGatewayModes);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_batadv_gateway_mode, batadv_gateway_mode, BatadvGatewayModes,
+                         "Failed to parse GatewayMode=");
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(batadv_routing_algorithm, BatadvRoutingAlgorithm);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_batadv_routing_algorithm, batadv_routing_algorithm, BatadvRoutingAlgorithm,
+                         "Failed to parse RoutingAlgorithm=");
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(batadv_routing_algorithm_kernel, BatadvRoutingAlgorithm);
+
+int config_parse_badadv_bandwidth (
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        uint64_t k;
+        uint32_t *bandwidth = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        r = parse_size(rvalue, 1000, &k);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+
+        if (k/1000/100 > UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "The value of '%s=', is outside of 0...429496729500000 range: %s",
+                           lvalue, rvalue);
+        }
+
+        *bandwidth = k/1000/100;
+
+        return 0;
+}
+
+/* callback for batman netdev's parameter set */
+static int netdev_batman_set_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
+        int r;
+
+        assert(netdev);
+        assert(m);
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0) {
+                log_netdev_warning_errno(netdev, r, "BATADV parameters could not be set: %m");
+                return 1;
+        }
+
+        log_netdev_debug(netdev, "BATADV parameters set success");
+
+        return 1;
+}
+
+static int netdev_batadv_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+        BatmanAdvanced *b;
+        int r;
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
+
+        assert(netdev);
+
+        b = BATADV(netdev);
+        assert(b);
+
+        r = sd_genl_message_new(netdev->manager->genl, SD_GENL_BATADV, BATADV_CMD_SET_MESH, &message);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m");
+
+        r = sd_netlink_message_append_u32(message, BATADV_ATTR_MESH_IFINDEX, netdev->ifindex);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set ifindex: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_GW_MODE, b->gateway_mode);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set gateway_mode: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, b->aggregation);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set aggregation: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, b->bridge_loop_avoidance);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set bridge_loop_avoidance: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, b->distributed_arp_table);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set distributed_arp_table: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_FRAGMENTATION_ENABLED, b->fragmentation);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set fragmentation: %m");
+
+        r = sd_netlink_message_append_u8(message, BATADV_ATTR_HOP_PENALTY, b->hop_penalty);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set hop_penalty: %m");
+
+        r = sd_netlink_message_append_u32(message, BATADV_ATTR_ORIG_INTERVAL, DIV_ROUND_UP(b->originator_interval, USEC_PER_MSEC));
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set orig_interval: %m");
+
+        r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_DOWN, b->gateway_bandwidth_down);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set gateway_bandwidth_down: %m");
+
+        r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_UP, b->gateway_bandwidth_up);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Failed to set gateway_bandwidth_up: %m");
+
+        r = netlink_call_async(netdev->manager->genl, NULL, message, netdev_batman_set_handler,
+                               netdev_destroy_callback, netdev);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Could not send batman device message: %m");
+
+        netdev_ref(netdev);
+
+        return r;
+}
+
+static int netdev_batadv_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+        BatmanAdvanced *b;
+        int r;
+
+        assert(netdev);
+        assert(m);
+
+        b = BATADV(netdev);
+        assert(b);
+
+        r = sd_netlink_message_append_string(m, IFLA_BATADV_ALGO_NAME, batadv_routing_algorithm_kernel_to_string(b->routing_algorithm));
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Could not append IFLA_BATADV_ALGO_NAME attribute: %m");
+
+        return r;
+}
+
+const NetDevVTable batadv_vtable = {
+        .object_size = sizeof(BatmanAdvanced),
+        .init = batadv_init,
+        .sections = NETDEV_COMMON_SECTIONS "BatmanAdvanced\0",
+        .fill_message_create = netdev_batadv_fill_message_create,
+        .post_create = netdev_batadv_post_create,
+        .create_type = NETDEV_CREATE_MASTER,
+};
diff --git a/src/network/netdev/batadv.h b/src/network/netdev/batadv.h
new file mode 100644 (file)
index 0000000..f1f9b46
--- /dev/null
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#pragma once
+
+#include <linux/batman_adv.h>
+
+#include "conf-parser.h"
+#include "netdev.h"
+
+#define BATADV_GENL_NAME "batadv"
+
+typedef enum BatadvGatewayModes {
+        BATADV_GATEWAY_MODE_OFF = BATADV_GW_MODE_OFF,
+        BATADV_GATEWAY_MODE_CLIENT = BATADV_GW_MODE_CLIENT,
+        BATADV_GATEWAY_MODE_SERVER = BATADV_GW_MODE_SERVER,
+        _BATADV_GATEWAY_MODE_MAX,
+        _BATADV_GATEWAY_MODE_INVALID = -EINVAL,
+} BatadvGatewayModes;
+
+typedef enum BatadvRoutingAlgorithm {
+        BATADV_ROUTING_ALGORITHM_BATMAN_V,
+        BATADV_ROUTING_ALGORITHM_BATMAN_IV,
+        _BATADV_ROUTING_ALGORITHM_MAX,
+        _BATADV_ROUTING_ALGORITHM_INVALID = -EINVAL,
+} BatadvRoutingAlgorithm;
+
+typedef struct Batadv {
+        NetDev meta;
+
+        BatadvGatewayModes gateway_mode;
+        uint32_t gateway_bandwidth_down;
+        uint32_t gateway_bandwidth_up;
+        uint8_t hop_penalty;
+        BatadvRoutingAlgorithm routing_algorithm;
+        usec_t originator_interval;
+        bool aggregation;
+        bool bridge_loop_avoidance;
+        bool distributed_arp_table;
+        bool fragmentation;
+} BatmanAdvanced;
+
+DEFINE_NETDEV_CAST(BATADV, BatmanAdvanced);
+extern const NetDevVTable batadv_vtable;
+
+CONFIG_PARSER_PROTOTYPE(config_parse_batadv_gateway_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_batadv_routing_algorithm);
+CONFIG_PARSER_PROTOTYPE(config_parse_badadv_bandwidth);
index fd02c6689be7c10e64ab5e2747549675bc5ee9a4..8abe04489002ae8a45603c9575af9aba655b3808 100644 (file)
@@ -5,6 +5,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #endif
 #include <stddef.h>
 #include "bareudp.h"
+#include "batadv.h"
 #include "bond.h"
 #include "bridge.h"
 #include "conf-parser.h"
@@ -235,3 +236,13 @@ WireGuardPeer.PresharedKeyFile,           config_parse_wireguard_preshared_key_f
 WireGuardPeer.PersistentKeepalive,        config_parse_wireguard_keepalive,          0,                             0
 Xfrm.InterfaceId,                         config_parse_uint32,                       0,                             offsetof(Xfrm, if_id)
 Xfrm.Independent,                         config_parse_bool,                         0,                             offsetof(Xfrm, independent)
+BatmanAdvanced.Aggregation,               config_parse_bool,                         0,                             offsetof(BatmanAdvanced, aggregation)
+BatmanAdvanced.BridgeLoopAvoidance,       config_parse_bool,                         0,                             offsetof(BatmanAdvanced, bridge_loop_avoidance)
+BatmanAdvanced.DistributedArpTable,       config_parse_bool,                         0,                             offsetof(BatmanAdvanced, distributed_arp_table)
+BatmanAdvanced.Fragmentation,             config_parse_bool,                         0,                             offsetof(BatmanAdvanced, fragmentation)
+BatmanAdvanced.GatewayMode,               config_parse_batadv_gateway_mode,          0,                             offsetof(BatmanAdvanced, gateway_mode)
+BatmanAdvanced.GatewayBandwithDown,       config_parse_badadv_bandwidth,             0,                             offsetof(BatmanAdvanced, gateway_bandwidth_down)
+BatmanAdvanced.GatewayBandwithUp,         config_parse_badadv_bandwidth,             0,                             offsetof(BatmanAdvanced, gateway_bandwidth_up)
+BatmanAdvanced.HopPenalty,                config_parse_uint8,                        0,                             offsetof(BatmanAdvanced, hop_penalty)
+BatmanAdvanced.OriginatorIntervalSec,     config_parse_sec,                          0,                             offsetof(BatmanAdvanced, originator_interval)
+BatmanAdvanced.RoutingAlgorithm,          config_parse_batadv_routing_algorithm,     0,                             offsetof(BatmanAdvanced, routing_algorithm)
index 36d6c5168a178d2a54da83040293d699ed59a7d5..fb0353486932596363ae00d4ed3ae6f72ba02275 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "alloc-util.h"
 #include "bareudp.h"
+#include "batadv.h"
 #include "bond.h"
 #include "bridge.h"
 #include "conf-files.h"
@@ -43,6 +44,7 @@
 #include "xfrm.h"
 
 const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
+        [NETDEV_KIND_BATADV] = &batadv_vtable,
         [NETDEV_KIND_BRIDGE] = &bridge_vtable,
         [NETDEV_KIND_BOND] = &bond_vtable,
         [NETDEV_KIND_VLAN] = &vlan_vtable,
@@ -82,6 +84,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
 
 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_BAREUDP] = "bareudp",
+        [NETDEV_KIND_BATADV] = "batadv",
         [NETDEV_KIND_BRIDGE] = "bridge",
         [NETDEV_KIND_BOND] = "bond",
         [NETDEV_KIND_VLAN] = "vlan",
@@ -262,7 +265,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, link_netlink_message
         assert(netdev->state == NETDEV_STATE_READY);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
-        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF, NETDEV_KIND_BATADV));
         assert(link);
         assert(callback);
 
@@ -353,7 +356,7 @@ static int netdev_enslave(NetDev *netdev, Link *link, link_netlink_message_handl
         assert(netdev);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
-        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF, NETDEV_KIND_BATADV));
 
         if (netdev->state == NETDEV_STATE_READY) {
                 r = netdev_enslave_ready(netdev, link, callback);
index c13542ae80661a23a5b9971373fec93f323006c8..6d149da2e9c39ded66346c8369880f6768785827 100644 (file)
@@ -12,6 +12,7 @@
 /* This is the list of known sections. We need to ignore them in the initial parsing phase. */
 #define NETDEV_OTHER_SECTIONS                     \
         "-BareUDP\0"                              \
+        "-BatmanAdvanced\0"                       \
         "-Bond\0"                                 \
         "-Bridge\0"                               \
         "-FooOverUDP\0"                           \
@@ -83,6 +84,7 @@ typedef enum NetDevKind {
         NETDEV_KIND_XFRM,
         NETDEV_KIND_IFB,
         NETDEV_KIND_BAREUDP,
+        NETDEV_KIND_BATADV,
         _NETDEV_KIND_MAX,
         _NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */
         _NETDEV_KIND_INVALID = -EINVAL,
index 182c075a5399f264afdeefc3a7f4881cdbed4c94..96d4d9235b8fd53fb0a855b6bcd1e87099fdf1d5 100644 (file)
@@ -7,6 +7,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "batadv.h"
 #include "bond.h"
 #include "bridge.h"
 #include "bus-util.h"
@@ -265,6 +266,7 @@ void link_update_operstate(Link *link, bool also_update_master) {
                 link_dirty(link);
 
         if (also_update_master && link->network) {
+                link_update_master_operstate(link, link->network->batadv);
                 link_update_master_operstate(link, link->network->bond);
                 link_update_master_operstate(link, link->network->bridge);
         }
@@ -929,7 +931,7 @@ static int link_set_nomaster(Link *link) {
         assert(link->manager->rtnl);
 
         /* set it free if not enslaved with networkd */
-        if (link->network->bridge || link->network->bond || link->network->vrf)
+        if (link->network->batadv || link->network->bridge || link->network->bond || link->network->vrf)
                 return 0;
 
         log_link_debug(link, "Setting nomaster");
@@ -1740,6 +1742,7 @@ void link_drop(Link *link) {
         link_free_carrier_maps(link);
 
         if (link->network) {
+                link_drop_from_master(link, link->network->batadv);
                 link_drop_from_master(link, link->network->bridge);
                 link_drop_from_master(link, link->network->bond);
         }
@@ -1893,6 +1896,25 @@ static int link_enter_join_netdev(Link *link) {
                 }
         }
 
+        if (link->network->batadv) {
+                log_struct(LOG_DEBUG,
+                           LOG_LINK_INTERFACE(link),
+                           LOG_NETDEV_INTERFACE(link->network->batadv),
+                           LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->batadv->ifname));
+
+                link->enslaving++;
+
+                r = netdev_join(link->network->batadv, link, netdev_join_handler);
+                if (r < 0) {
+                        log_struct_errno(LOG_WARNING, r,
+                                         LOG_LINK_INTERFACE(link),
+                                         LOG_NETDEV_INTERFACE(link->network->batadv),
+                                         LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->batadv->ifname));
+                        link_enter_failed(link);
+                        return r;
+                }
+        }
+
         if (link->network->bridge) {
                 log_struct(LOG_DEBUG,
                            LOG_LINK_INTERFACE(link),
index b31224413eeb1e09bf4437ac641ec14ea55da37a..a6111340687a1a370df612ba2dc06daee7d08ef4 100644 (file)
@@ -77,6 +77,7 @@ SR-IOV.Trust,                                config_parse_sr_iov_boolean,
 SR-IOV.LinkState,                            config_parse_sr_iov_link_state,                           0,                             0
 SR-IOV.MACAddress,                           config_parse_sr_iov_mac,                                  0,                             0
 Network.Description,                         config_parse_string,                                      0,                             offsetof(Network, description)
+Network.BatmanAdvanced,                      config_parse_ifname,                                      0,                             offsetof(Network, batadv_name)
 Network.Bridge,                              config_parse_ifname,                                      0,                             offsetof(Network, bridge_name)
 Network.Bond,                                config_parse_ifname,                                      0,                             offsetof(Network, bond_name)
 Network.VLAN,                                config_parse_stacked_netdev,                              NETDEV_KIND_VLAN,              offsetof(Network, stacked_netdev_names)
index e3c138411ed5349b993185a9725e5f05977d958f..9865ebd2552a2ac5e738cfd1314eb2d9a211c31f 100644 (file)
@@ -171,12 +171,14 @@ int network_verify(Network *network) {
                                        "%s: Conditions in the file do not match the system environment, skipping.",
                                        network->filename);
 
+        (void) network_resolve_netdev_one(network, network->batadv_name, NETDEV_KIND_BATADV, &network->batadv);
         (void) network_resolve_netdev_one(network, network->bond_name, NETDEV_KIND_BOND, &network->bond);
         (void) network_resolve_netdev_one(network, network->bridge_name, NETDEV_KIND_BRIDGE, &network->bridge);
         (void) network_resolve_netdev_one(network, network->vrf_name, NETDEV_KIND_VRF, &network->vrf);
         (void) network_resolve_stacked_netdevs(network);
 
         /* Free unnecessary entries. */
+        network->batadv_name = mfree(network->batadv_name);
         network->bond_name = mfree(network->bond_name);
         network->bridge_name = mfree(network->bridge_name);
         network->vrf_name = mfree(network->vrf_name);
@@ -633,6 +635,7 @@ static Network *network_free(Network *network) {
         set_free_free(network->ndisc_deny_listed_route_prefix);
         set_free_free(network->ndisc_allow_listed_route_prefix);
 
+        free(network->batadv_name);
         free(network->bridge_name);
         free(network->bond_name);
         free(network->vrf_name);
index 48419c27fecf17aba4a7ba0325e6defa2c6f147c..e859b590c624e49d785e3f902794d3157f3acfae 100644 (file)
@@ -81,11 +81,13 @@ struct Network {
         LIST_HEAD(Condition, conditions);
 
         /* Master or stacked netdevs */
+        NetDev *batadv;
         NetDev *bridge;
         NetDev *bond;
         NetDev *vrf;
         NetDev *xfrm;
         Hashmap *stacked_netdevs;
+        char *batadv_name;
         char *bridge_name;
         char *bond_name;
         char *vrf_name;
index 276108b38d92013485e2be7a6cc7ec045702e7a7..bc572f9b8478f2a6bef685a7a3ecb1b97fce955e 100644 (file)
@@ -44,6 +44,7 @@ typedef enum sd_genl_family_t {
         SD_GENL_L2TP,
         SD_GENL_MACSEC,
         SD_GENL_NL80211,
+        SD_GENL_BATADV,
         _SD_GENL_FAMILY_MAX,
         _SD_GENL_FAMILY_INVALID = -EINVAL,
         _SD_ENUM_FORCE_S64(GENL_FAMILY)
diff --git a/test/fuzz/fuzz-netdev-parser/28-batadv.netdev b/test/fuzz/fuzz-netdev-parser/28-batadv.netdev
new file mode 100644 (file)
index 0000000..2a9d92e
--- /dev/null
@@ -0,0 +1,16 @@
+[NetDev]
+Name=bat0
+Kind=batadv
+Description=Batman test
+
+[BatmanAdvanced]
+GatewayMode=server
+Aggregation=1
+BridgeLoopAvoidance=1
+DistributedArpTable=1
+Fragmentation=1
+HopPenalty=10
+OriginatorIntervalSec=1
+GatewayBandwithDown=100K
+GatewayBandwithUp=12K
+RoutingAlgorithm=batman-v
index 050078520723438f6477877dc56eaa54be4dcdb8..d4e5598409c2148a31f3d3d5edbecee353f42ac4 100644 (file)
@@ -223,3 +223,14 @@ InterfaceId=
 [BareUDP]
 DestinationPort=
 EtherType=
+[BatmanAdvanced]
+GatewayMode=
+Aggregation=
+BridgeLoopAvoidance=
+DistributedArpTable=
+Fragmentation=
+HopPenalty=
+OriginatorIntervalSec=
+GatewayBandwithDown=
+GatewayBandwithUp=
+RoutingAlgorithm=
index 48f0ca895153e29bcd162e79cefe4b0ead03eb2d..8352ecb563d360e8a81f07a0d9bc56a49c07c83b 100644 (file)
@@ -226,6 +226,7 @@ VRF=
 IgnoreCarrierLoss=
 KeepConfiguration=
 DHCPv6PrefixDelegation=
+BatmanAdvanced=
 [IPv6Prefix]
 Prefix=
 OnLink=
diff --git a/test/test-network/conf/25-batadv.netdev b/test/test-network/conf/25-batadv.netdev
new file mode 100644 (file)
index 0000000..6197d70
--- /dev/null
@@ -0,0 +1,14 @@
+[NetDev]
+Name=batadv99
+Kind=batadv
+Description=Batman test
+
+[BatmanAdvanced]
+GatewayMode=server
+RoutingAlgorithm=batman-iv
+DistributedArpTable=1
+Fragmentation=0
+HopPenalty=10
+OriginatorIntervalSec=1000ms
+GatewayBandwithDown=205M
+GatewayBandwithUp=2G
index 1a22390a33182c62f1fae5d6ad81c35bd4850d8d..ee18bea72e97d0955eac183c5073d8dff71d1207 100644 (file)
@@ -1,5 +1,6 @@
 [Match]
 Name=bareudp99
+Name=batadv99
 Name=ipvlan99
 Name=ipvtap99
 Name=macvlan99
index 70285d2a89533c800de9424069f66ddf1780f37c..fc88fefd0f0875666106127d9f883e9650b6a5fe 100755 (executable)
@@ -779,6 +779,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
     links = [
         '6rdtun99',
         'bareudp99',
+        'batadv99',
         'bond98',
         'bond99',
         'bridge99',
@@ -855,6 +856,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         '21-vlan.network',
         '25-6rd-tunnel.netdev',
         '25-bareudp.netdev',
+        '25-batadv.netdev',
         '25-bond.netdev',
         '25-bond-balanced-tlb.netdev',
         '25-bridge.netdev',
@@ -1014,6 +1016,17 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         self.assertRegex(output, 'dstport 1000 ')
         self.assertRegex(output, 'ethertype ip ')
 
+    @expectedFailureIfModuleIsNotAvailable('batman-adv')
+    def test_batadv(self):
+        copy_unit_to_networkd_unit_path('25-batadv.netdev', 'netdev-link-local-addressing-yes.network')
+        start_networkd()
+
+        self.wait_online(['batadv99:degraded'])
+
+        output = check_output('ip -d link show batadv99')
+        print(output)
+        self.assertRegex(output, 'batadv')
+
     def test_bridge(self):
         copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge-configure-without-carrier.network')
         start_networkd()