network: Implement B.A.T.M.A.N. Advanced interface type
This commit is contained in:
committed by
Yu Watanabe
parent
2aaf376597
commit
c0267a592a
@@ -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,
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user