diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index a18d9aba073..aeb03ee0304 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -185,6 +185,9 @@ bareudp Bare UDP tunnels provide a generic L3 encapsulation support for tunnelling different L3 protocols like MPLS, IP etc. inside of an UDP tunnel. + + batadv + (B.A.T.M.A.N. Advanced) is a routing protocol for multi-hop mobile ad hoc networks which operates on layer2. @@ -2020,6 +2023,107 @@ + + [BatmanAdvanced] Section Options + The [BatmanAdvanced] section only applies for + netdevs of kind batadv and accepts the + following keys: + + + + GatewayMode= + + Takes one of off, server, or client. + 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). + + + + + Aggregation= + + Takes a boolean value. Enables or disables aggregation of originator messages. Defaults to + true. + + + + + BridgeLoopAvoidance= + + Takes a boolean value. Enables or disables avoidance of loops on bridges. Defaults to true. + + + + + DistributedArpTable= + + Takes a boolean value. Enables or disables the distributed ARP table. Defaults to true. + + + + Fragmentation= + + Takes a boolean value. Enables or disables fragmentation. Defaults to true. + + + + HopPenalty= + + The hop penalty setting allows to modify + batctl8 + 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. + + + + + OriginatorIntervalSec= + + 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 systemd.time7 + for more information. + + + + GatewayBandwidthDown= + + 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. + + + + GatewayBandwidthUp= + + 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. + + + + RoutingAlgorithm= + + This can be either batman-v or batman-iv and describes which routing_algo + of batctl8 to use. The algorithm + cannot be changed after interface creation. Defaults to batman-v. + + + + + + Examples diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 2df79106906..abf8ea0a6f2 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1014,7 +1014,14 @@ IPv6Token=prefixstable:2002:da8:1:: - + + BatmanAdvanced= + + The name of the B.A.T.M.A.N. Advanced interface to add the link to. See + systemd.netdev5. + + + diff --git a/src/basic/linux/batman_adv.h b/src/basic/linux/batman_adv.h new file mode 100644 index 00000000000..d035e4cf344 --- /dev/null +++ b/src/basic/linux/batman_adv.h @@ -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_ */ diff --git a/src/libsystemd/sd-netlink/generic-netlink.c b/src/libsystemd/sd-netlink/generic-netlink.c index d4ec268806e..9710ed0f163 100644 --- a/src/libsystemd/sd-netlink/generic-netlink.c +++ b/src/libsystemd/sd-netlink/generic-netlink.c @@ -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) { diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 4acf6a7ff8b..ed7b9a8cd16 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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[] = { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index a4cd4ab56cb..316d7f1b877 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -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; diff --git a/src/network/meson.build b/src/network/meson.build index 5993db8d06a..3ff04467b0d 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -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 index 00000000000..86cd1f19b37 --- /dev/null +++ b/src/network/netdev/batadv.c @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include + +#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 index 00000000000..f1f9b468859 --- /dev/null +++ b/src/network/netdev/batadv.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#pragma once + +#include + +#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); diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index fd02c6689be..8abe0448900 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -5,6 +5,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #endif #include #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) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 36d6c5168a1..fb035348693 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -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); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index c13542ae806..6d149da2e9c 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -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, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 182c075a539..96d4d9235b8 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -7,6 +7,7 @@ #include #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), diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index b31224413ee..a6111340687 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index e3c138411ed..9865ebd2552 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 48419c27fec..e859b590c62 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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; diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 276108b38d9..bc572f9b847 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -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 index 00000000000..2a9d92e23b5 --- /dev/null +++ b/test/fuzz/fuzz-netdev-parser/28-batadv.netdev @@ -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 diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev index 05007852072..d4e5598409c 100644 --- a/test/fuzz/fuzz-netdev-parser/directives.netdev +++ b/test/fuzz/fuzz-netdev-parser/directives.netdev @@ -223,3 +223,14 @@ InterfaceId= [BareUDP] DestinationPort= EtherType= +[BatmanAdvanced] +GatewayMode= +Aggregation= +BridgeLoopAvoidance= +DistributedArpTable= +Fragmentation= +HopPenalty= +OriginatorIntervalSec= +GatewayBandwithDown= +GatewayBandwithUp= +RoutingAlgorithm= diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 48f0ca89515..8352ecb563d 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -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 index 00000000000..6197d701c61 --- /dev/null +++ b/test/test-network/conf/25-batadv.netdev @@ -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 diff --git a/test/test-network/conf/netdev-link-local-addressing-yes.network b/test/test-network/conf/netdev-link-local-addressing-yes.network index 1a22390a331..ee18bea72e9 100644 --- a/test/test-network/conf/netdev-link-local-addressing-yes.network +++ b/test/test-network/conf/netdev-link-local-addressing-yes.network @@ -1,5 +1,6 @@ [Match] Name=bareudp99 +Name=batadv99 Name=ipvlan99 Name=ipvtap99 Name=macvlan99 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 70285d2a895..fc88fefd0f0 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -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()