mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
Merge pull request #12925 from yuwata/network-generator
network-generator: introduce new tool systemd-network-generator
This commit is contained in:
commit
15bcd9fa09
@ -2710,6 +2710,14 @@ if conf.get('ENABLE_NETWORKD') == 1
|
||||
install : true,
|
||||
install_dir : rootbindir)
|
||||
public_programs += exe
|
||||
|
||||
executable('systemd-network-generator',
|
||||
network_generator_sources,
|
||||
include_directories : includes,
|
||||
link_with : [libshared],
|
||||
install_rpath : rootlibexecdir,
|
||||
install : true,
|
||||
install_dir : rootlibexecdir)
|
||||
endif
|
||||
|
||||
executable('systemd-sulogin-shell',
|
||||
|
206
src/network/generator/main.c
Normal file
206
src/network/generator/main.c
Normal file
@ -0,0 +1,206 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "generator.h"
|
||||
#include "macro.h"
|
||||
#include "main-func.h"
|
||||
#include "mkdir.h"
|
||||
#include "network-generator.h"
|
||||
#include "path-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
|
||||
#define NETWORKD_UNIT_DIRECTORY "/run/systemd/network"
|
||||
|
||||
static const char *arg_root = NULL;
|
||||
|
||||
static int network_save(Network *network, const char *dest_dir) {
|
||||
_cleanup_free_ char *filename = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(network);
|
||||
|
||||
r = asprintf(&filename, "%s-initrd-%s.network",
|
||||
isempty(network->ifname) ? "99" : "98",
|
||||
isempty(network->ifname) ? "default" : network->ifname);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
network_dump(network, f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdev_save(NetDev *netdev, const char *dest_dir) {
|
||||
_cleanup_free_ char *filename = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
|
||||
r = asprintf(&filename, "98-initrd-%s.netdev",
|
||||
netdev->ifname);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
netdev_dump(netdev, f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_save(Link *link, const char *dest_dir) {
|
||||
_cleanup_free_ char *filename = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = asprintf(&filename, "98-initrd-%s.link",
|
||||
link->ifname);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_dump(link, f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_save(Context *context) {
|
||||
Network *network;
|
||||
NetDev *netdev;
|
||||
Link *link;
|
||||
Iterator i;
|
||||
int k, r = 0;
|
||||
const char *p;
|
||||
|
||||
p = prefix_roota(arg_root, NETWORKD_UNIT_DIRECTORY);
|
||||
|
||||
r = mkdir_p(p, 0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create directory " NETWORKD_UNIT_DIRECTORY ": %m");
|
||||
|
||||
HASHMAP_FOREACH(network, context->networks_by_name, i) {
|
||||
k = network_save(network, p);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(netdev, context->netdevs_by_name, i) {
|
||||
k = netdev_save(netdev, p);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(link, context->links_by_name, i) {
|
||||
k = link_save(link, p);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s [OPTIONS...] [-- KERNEL_CMDLINE]\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
, program_invocation_short_name
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_ROOT,
|
||||
};
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{},
|
||||
};
|
||||
int c;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_ROOT:
|
||||
arg_root = optarg;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(context_clear) Context context = {};
|
||||
int i, r;
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (optind >= argc) {
|
||||
r = proc_cmdline_parse(parse_cmdline_item, &context, 0);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse kernel command line: %m");
|
||||
} else {
|
||||
for (i = optind; i < argc; i++) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char *value;
|
||||
|
||||
word = strdup(argv[i]);
|
||||
if (!word)
|
||||
return log_oom();
|
||||
|
||||
value = strchr(word, '=');
|
||||
if (value)
|
||||
*(value++) = 0;
|
||||
|
||||
r = parse_cmdline_item(word, value, &context);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse command line \"%s%s%s\": %m",
|
||||
word, value ? "=" : "", strempty(value));
|
||||
}
|
||||
}
|
||||
|
||||
r = context_merge_networks(&context);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to merge multiple command line options: %m");
|
||||
|
||||
return context_save(&context);
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION(run);
|
1234
src/network/generator/network-generator.c
Normal file
1234
src/network/generator/network-generator.c
Normal file
File diff suppressed because it is too large
Load Diff
108
src/network/generator/network-generator.h
Normal file
108
src/network/generator/network-generator.h
Normal file
@ -0,0 +1,108 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hashmap.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef enum DHCPType {
|
||||
DHCP_TYPE_NONE,
|
||||
DHCP_TYPE_OFF,
|
||||
DHCP_TYPE_ON,
|
||||
DHCP_TYPE_ANY,
|
||||
DHCP_TYPE_DHCP,
|
||||
DHCP_TYPE_DHCP6,
|
||||
DHCP_TYPE_AUTO6,
|
||||
DHCP_TYPE_EITHER6,
|
||||
DHCP_TYPE_IBFT,
|
||||
_DHCP_TYPE_MAX,
|
||||
_DHCP_TYPE_INVALID = -1,
|
||||
} DHCPType;
|
||||
|
||||
typedef struct Address Address;
|
||||
typedef struct Link Link;
|
||||
typedef struct NetDev NetDev;
|
||||
typedef struct Network Network;
|
||||
typedef struct Route Route;
|
||||
typedef struct Context Context;
|
||||
|
||||
struct Address {
|
||||
Network *network;
|
||||
|
||||
union in_addr_union address, peer;
|
||||
unsigned char prefixlen;
|
||||
int family;
|
||||
|
||||
LIST_FIELDS(Address, addresses);
|
||||
};
|
||||
|
||||
struct Route {
|
||||
Network *network;
|
||||
|
||||
union in_addr_union dest, gateway;
|
||||
unsigned char prefixlen;
|
||||
int family;
|
||||
|
||||
LIST_FIELDS(Route, routes);
|
||||
};
|
||||
|
||||
struct Network {
|
||||
/* [Match] */
|
||||
char *ifname;
|
||||
|
||||
/* [Link] */
|
||||
struct ether_addr mac;
|
||||
uint32_t mtu;
|
||||
|
||||
/* [Network] */
|
||||
DHCPType dhcp_type;
|
||||
char **dns;
|
||||
char *vlan;
|
||||
char *bridge;
|
||||
char *bond;
|
||||
|
||||
/* [DHCP] */
|
||||
char *hostname;
|
||||
int dhcp_use_dns;
|
||||
|
||||
LIST_HEAD(Address, addresses);
|
||||
LIST_HEAD(Route, routes);
|
||||
};
|
||||
|
||||
struct NetDev {
|
||||
/* [NetDev] */
|
||||
char *ifname;
|
||||
char *kind;
|
||||
uint32_t mtu;
|
||||
};
|
||||
|
||||
struct Link {
|
||||
/* [Match] */
|
||||
char *ifname;
|
||||
struct ether_addr mac;
|
||||
};
|
||||
|
||||
typedef struct Context {
|
||||
Hashmap *networks_by_name;
|
||||
Hashmap *netdevs_by_name;
|
||||
Hashmap *links_by_name;
|
||||
} Context;
|
||||
|
||||
int parse_cmdline_item(const char *key, const char *value, void *data);
|
||||
int context_merge_networks(Context *context);
|
||||
void context_clear(Context *context);
|
||||
|
||||
Network *network_get(Context *context, const char *ifname);
|
||||
void network_dump(Network *network, FILE *f);
|
||||
int network_format(Network *network, char **ret);
|
||||
|
||||
NetDev *netdev_get(Context *context, const char *ifname);
|
||||
void netdev_dump(NetDev *netdev, FILE *f);
|
||||
int netdev_format(NetDev *netdev, char **ret);
|
||||
|
||||
Link *link_get(Context *context, const char *ifname);
|
||||
void link_dump(Link *link, FILE *f);
|
||||
int link_format(Link *link, char **ret);
|
438
src/network/generator/test-network-generator.c
Normal file
438
src/network/generator/test-network-generator.c
Normal file
@ -0,0 +1,438 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "macro.h"
|
||||
#include "network-generator.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static void test_network_one(const char *ifname, const char *key, const char *value, const char *expected) {
|
||||
_cleanup_(context_clear) Context context = {};
|
||||
_cleanup_free_ char *output = NULL;
|
||||
Network *network;
|
||||
|
||||
printf("# %s=%s\n", key, value);
|
||||
assert_se(parse_cmdline_item(key, value, &context) >= 0);
|
||||
assert_se(network = network_get(&context, ifname));
|
||||
assert_se(network_format(network, &output) >= 0);
|
||||
puts(output);
|
||||
assert_se(streq(output, expected));
|
||||
}
|
||||
|
||||
static void test_network_two(const char *ifname,
|
||||
const char *key1, const char *value1,
|
||||
const char *key2, const char *value2,
|
||||
const char *expected) {
|
||||
_cleanup_(context_clear) Context context = {};
|
||||
_cleanup_free_ char *output = NULL;
|
||||
Network *network;
|
||||
|
||||
printf("# %s=%s\n", key1, value1);
|
||||
printf("# %s=%s\n", key2, value2);
|
||||
assert_se(parse_cmdline_item(key1, value1, &context) >= 0);
|
||||
assert_se(parse_cmdline_item(key2, value2, &context) >= 0);
|
||||
assert_se(context_merge_networks(&context) >= 0);
|
||||
assert_se(network = network_get(&context, ifname));
|
||||
assert_se(network_format(network, &output) >= 0);
|
||||
puts(output);
|
||||
assert_se(streq(output, expected));
|
||||
}
|
||||
|
||||
static void test_netdev_one(const char *ifname, const char *key, const char *value, const char *expected) {
|
||||
_cleanup_(context_clear) Context context = {};
|
||||
_cleanup_free_ char *output = NULL;
|
||||
NetDev *netdev;
|
||||
|
||||
printf("# %s=%s\n", key, value);
|
||||
assert_se(parse_cmdline_item(key, value, &context) >= 0);
|
||||
assert_se(netdev = netdev_get(&context, ifname));
|
||||
assert_se(netdev_format(netdev, &output) >= 0);
|
||||
puts(output);
|
||||
assert_se(streq(output, expected));
|
||||
}
|
||||
|
||||
static void test_link_one(const char *ifname, const char *key, const char *value, const char *expected) {
|
||||
_cleanup_(context_clear) Context context = {};
|
||||
_cleanup_free_ char *output = NULL;
|
||||
Link *link;
|
||||
|
||||
printf("# %s=%s\n", key, value);
|
||||
assert_se(parse_cmdline_item(key, value, &context) >= 0);
|
||||
assert_se(link = link_get(&context, ifname));
|
||||
assert_se(link_format(link, &output) >= 0);
|
||||
puts(output);
|
||||
assert_se(streq(output, expected));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_network_one("", "ip", "dhcp6",
|
||||
"[Match]\n"
|
||||
"Name=*\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=ipv6\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "eth0:dhcp",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=ipv4\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "eth0:dhcp:1530",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"MTUBytes=1530\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=ipv4\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "eth0:dhcp:1530:00:11:22:33:44:55",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"MACAddress=00:11:22:33:44:55\n"
|
||||
"MTUBytes=1530\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=ipv4\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0:hogehoge:eth0:on",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:1530",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"MTUBytes=1530\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:1530:00:11:22:33:44:55",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"MACAddress=00:11:22:33:44:55\n"
|
||||
"MTUBytes=1530\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10:10.10.10.11",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"DNS=10.10.10.11\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "[2001:1234:56:8f63::10]::[2001:1234:56:8f63::1]:64:hogehoge:eth0:on",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=2001:1234:56:8f63::10/64\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=2001:1234:56:8f63::1\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "ip", "[2001:1234:56:8f63::10]:[2001:1234:56:8f63::2]:[2001:1234:56:8f63::1]:64:hogehoge:eth0:on",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=2001:1234:56:8f63::10/64\n"
|
||||
"Peer=2001:1234:56:8f63::2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=2001:1234:56:8f63::1\n"
|
||||
);
|
||||
|
||||
test_network_one("", "rd.route", "10.1.2.3/16:10.0.2.3",
|
||||
"[Match]\n"
|
||||
"Name=*\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"\n[DHCP]\n"
|
||||
"\n[Route]\n"
|
||||
"Destination=10.1.2.3/16\n"
|
||||
"Gateway=10.0.2.3\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "rd.route", "10.1.2.3/16:10.0.2.3:eth0",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"\n[DHCP]\n"
|
||||
"\n[Route]\n"
|
||||
"Destination=10.1.2.3/16\n"
|
||||
"Gateway=10.0.2.3\n"
|
||||
);
|
||||
|
||||
test_network_one("", "nameserver", "10.1.2.3",
|
||||
"[Match]\n"
|
||||
"Name=*\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DNS=10.1.2.3\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("", "rd.peerdns", "0",
|
||||
"[Match]\n"
|
||||
"Name=*\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"\n[DHCP]\n"
|
||||
"UseDNS=no\n"
|
||||
);
|
||||
|
||||
test_network_one("", "rd.peerdns", "1",
|
||||
"[Match]\n"
|
||||
"Name=*\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"\n[DHCP]\n"
|
||||
"UseDNS=yes\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "vlan", "vlan99:eth0",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"VLAN=vlan99\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "bridge", "bridge99:eth0,eth1",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"Bridge=bridge99\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth1", "bridge", "bridge99:eth0,eth1",
|
||||
"[Match]\n"
|
||||
"Name=eth1\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"Bridge=bridge99\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth0", "bond", "bond99:eth0,eth1",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"Bond=bond99\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_network_one("eth1", "bond", "bond99:eth0,eth1::1530",
|
||||
"[Match]\n"
|
||||
"Name=eth1\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"Bond=bond99\n"
|
||||
"\n[DHCP]\n"
|
||||
);
|
||||
|
||||
test_netdev_one("bond99", "bond", "bond99:eth0,eth1::1530",
|
||||
"[NetDev]\n"
|
||||
"Kind=bond\n"
|
||||
"Name=bond99\n"
|
||||
"MTUBytes=1530\n"
|
||||
);
|
||||
|
||||
test_link_one("hogehoge", "ifname", "hogehoge:00:11:22:33:44:55",
|
||||
"[Match]\n"
|
||||
"MACAddress=00:11:22:33:44:55\n"
|
||||
"\n[Link]\n"
|
||||
"Name=hogehoge\n"
|
||||
);
|
||||
|
||||
test_network_two("eth0",
|
||||
"ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10:10.10.10.11",
|
||||
"rd.route", "10.1.2.3/16:10.0.2.3",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"DNS=10.10.10.11\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Destination=10.1.2.3/16\n"
|
||||
"Gateway=10.0.2.3\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_two("eth0",
|
||||
"ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on",
|
||||
"nameserver", "10.1.2.3",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.1.2.3\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_two("eth0",
|
||||
"ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10:10.10.10.11",
|
||||
"nameserver", "10.1.2.3",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"DNS=10.10.10.11\n"
|
||||
"DNS=10.1.2.3\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_two("eth0",
|
||||
"ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10:10.10.10.11",
|
||||
"rd.peerdns", "1",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"DNS=10.10.10.11\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"UseDNS=yes\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
test_network_two("eth0",
|
||||
"ip", "192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:hogehoge:eth0:on:10.10.10.10:10.10.10.11",
|
||||
"bridge", "bridge99:eth0,eth1",
|
||||
"[Match]\n"
|
||||
"Name=eth0\n"
|
||||
"\n[Link]\n"
|
||||
"\n[Network]\n"
|
||||
"DHCP=yes\n"
|
||||
"DNS=10.10.10.10\n"
|
||||
"DNS=10.10.10.11\n"
|
||||
"Bridge=bridge99\n"
|
||||
"\n[DHCP]\n"
|
||||
"Hostname=hogehoge\n"
|
||||
"\n[Address]\n"
|
||||
"Address=192.168.0.10/24\n"
|
||||
"Peer=192.168.0.2\n"
|
||||
"\n[Route]\n"
|
||||
"Gateway=192.168.0.1\n"
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
@ -114,6 +114,12 @@ systemd_networkd_wait_online_sources = files('''
|
||||
|
||||
networkctl_sources = files('networkctl.c')
|
||||
|
||||
network_generator_sources = files('''
|
||||
generator/main.c
|
||||
generator/network-generator.c
|
||||
generator/network-generator.h
|
||||
'''.split())
|
||||
|
||||
network_include_dir = include_directories('.')
|
||||
|
||||
if conf.get('ENABLE_NETWORKD') == 1
|
||||
@ -209,5 +215,11 @@ if conf.get('ENABLE_NETWORKD') == 1
|
||||
[threads],
|
||||
'', '', [],
|
||||
[network_include_dir] + libudev_core_includes],
|
||||
|
||||
[['src/network/generator/test-network-generator.c',
|
||||
'src/network/generator/network-generator.c',
|
||||
'src/network/generator/network-generator.h'],
|
||||
[libshared],
|
||||
[]],
|
||||
]
|
||||
endif
|
||||
|
1
test/TEST-35-NETWORK-GENERATOR/Makefile
Symbolic link
1
test/TEST-35-NETWORK-GENERATOR/Makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../TEST-01-BASIC/Makefile
|
@ -0,0 +1,11 @@
|
||||
# Automatically generated by systemd-network-generator
|
||||
|
||||
[Match]
|
||||
Name=*
|
||||
|
||||
[Link]
|
||||
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
|
||||
[DHCP]
|
1
test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.input
Normal file
1
test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.input
Normal file
@ -0,0 +1 @@
|
||||
ip=dhcp
|
@ -0,0 +1,5 @@
|
||||
# Automatically generated by systemd-network-generator
|
||||
|
||||
[NetDev]
|
||||
Kind=bridge
|
||||
Name=bridge99
|
@ -0,0 +1,13 @@
|
||||
# Automatically generated by systemd-network-generator
|
||||
|
||||
[Match]
|
||||
Name=bridge99
|
||||
|
||||
[Link]
|
||||
MACAddress=00:11:22:33:44:55
|
||||
MTUBytes=1530
|
||||
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
|
||||
[DHCP]
|
@ -0,0 +1,21 @@
|
||||
# Automatically generated by systemd-network-generator
|
||||
|
||||
[Match]
|
||||
Name=eth0
|
||||
|
||||
[Link]
|
||||
|
||||
[Network]
|
||||
DHCP=no
|
||||
DNS=10.10.10.10
|
||||
DNS=10.10.10.11
|
||||
Bridge=bridge99
|
||||
|
||||
[DHCP]
|
||||
Hostname=hogehoge
|
||||
|
||||
[Address]
|
||||
Address=192.168.0.10/24
|
||||
|
||||
[Route]
|
||||
Gateway=192.168.0.1
|
@ -0,0 +1,21 @@
|
||||
# Automatically generated by systemd-network-generator
|
||||
|
||||
[Match]
|
||||
Name=eth1
|
||||
|
||||
[Link]
|
||||
|
||||
[Network]
|
||||
DHCP=no
|
||||
DNS=10.10.10.10
|
||||
DNS=10.10.10.11
|
||||
Bridge=bridge99
|
||||
|
||||
[DHCP]
|
||||
Hostname=hogehoge
|
||||
|
||||
[Address]
|
||||
Address=192.168.0.11/24
|
||||
|
||||
[Route]
|
||||
Gateway=192.168.0.1
|
4
test/TEST-35-NETWORK-GENERATOR/test-02-bridge.input
Normal file
4
test/TEST-35-NETWORK-GENERATOR/test-02-bridge.input
Normal file
@ -0,0 +1,4 @@
|
||||
ip=192.168.0.10::192.168.0.1:255.255.255.0:hogehoge:eth0:off:10.10.10.10:10.10.10.11
|
||||
ip=192.168.0.11::192.168.0.1:255.255.255.0:hogehoge:eth1:off:10.10.10.10:10.10.10.11
|
||||
ip=bridge99:dhcp:1530:00:11:22:33:44:55
|
||||
bridge=bridge99:eth0,eth1
|
36
test/TEST-35-NETWORK-GENERATOR/test.sh
Executable file
36
test/TEST-35-NETWORK-GENERATOR/test.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
TEST_DESCRIPTION="network-generator tests"
|
||||
|
||||
. $TEST_BASE_DIR/test-functions
|
||||
|
||||
test_setup() {
|
||||
mkdir -p $TESTDIR/run/systemd/network
|
||||
}
|
||||
|
||||
test_run() {
|
||||
local generator
|
||||
|
||||
if [[ -x $BUILD_DIR/systemd-network-generator ]]; then
|
||||
generator=$BUILD_DIR/systemd-network-generator
|
||||
elif [[ -x /usr/lib/systemd/systemd-network-generator ]]; then
|
||||
generator=/usr/lib/systemd/systemd-network-generator
|
||||
elif [[ -x /lib/systemd/systemd-network-generator ]]; then
|
||||
generator=/lib/systemd/systemd-network-generator
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for f in test-*.input; do
|
||||
echo "*** Running $f"
|
||||
rm -f $TESTDIR/run/systemd/network/*
|
||||
$generator --root $TESTDIR -- $(cat $f)
|
||||
|
||||
if ! diff -u $TESTDIR/run/systemd/network ${f%.input}.expected; then
|
||||
echo "**** Unexpected output for $f"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
do_test "$@"
|
Loading…
x
Reference in New Issue
Block a user