Files
systemd/src/network/netdev/batadv.c
Yu Watanabe 1003093604 network/netdev: skip processing netdev if it is already detached
No functional change, as currently networkd detaches NetDev objects only
on stop (or invalid .netdev file is loaded).
Preparation for later commits.
2024-10-30 03:07:32 +09:00

210 lines
7.0 KiB
C

/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <inttypes.h>
#include <netinet/in.h>
#include <linux/genetlink.h>
#include <linux/if_arp.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 = 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);
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(batadv_routing_algorithm, BatadvRoutingAlgorithm);
DEFINE_CONFIG_PARSE_ENUM(config_parse_batadv_routing_algorithm, batadv_routing_algorithm, BatadvRoutingAlgorithm);
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_message(NetDev *netdev, sd_netlink_message *message) {
BatmanAdvanced *b = BATADV(netdev);
int r;
r = sd_netlink_message_append_u32(message, BATADV_ATTR_MESH_IFINDEX, netdev->ifindex);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_GW_MODE, b->gateway_mode);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, b->aggregation);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, b->bridge_loop_avoidance);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, b->distributed_arp_table);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_FRAGMENTATION_ENABLED, b->fragmentation);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(message, BATADV_ATTR_HOP_PENALTY, b->hop_penalty);
if (r < 0)
return r;
r = sd_netlink_message_append_u32(message, BATADV_ATTR_ORIG_INTERVAL, DIV_ROUND_UP(b->originator_interval, USEC_PER_MSEC));
if (r < 0)
return r;
r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_DOWN, b->gateway_bandwidth_down);
if (r < 0)
return r;
r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_UP, b->gateway_bandwidth_up);
if (r < 0)
return r;
return 0;
}
static int netdev_batadv_post_create(NetDev *netdev, Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
int r;
assert(netdev);
if (!netdev_is_managed(netdev))
return 0; /* Already detached, due to e.g. reloading .netdev files. */
r = sd_genl_message_new(netdev->manager->genl, BATADV_NL_NAME, BATADV_CMD_SET_MESH, &message);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not allocate netlink message: %m");
r = netdev_batadv_post_create_message(netdev, message);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not create netlink message: %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 netlink message: %m");
netdev_ref(netdev);
return r;
}
static int netdev_batadv_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
assert(m);
BatmanAdvanced *b = BATADV(netdev);
int r;
r = sd_netlink_message_append_string(m, IFLA_BATADV_ALGO_NAME, batadv_routing_algorithm_kernel_to_string(b->routing_algorithm));
if (r < 0)
return r;
return 0;
}
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_INDEPENDENT,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};