mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-23 09:56:59 +08:00
Read configuration files from /etc and /usr
Add support for the so called "stateless" configuration pattern (read from /etc, fall back to /usr), giving system administrators a way to define local configuration without changing any distro-provided files. In practice this means that each configuration file FOO is loaded from /usr/lib/iproute2/FOO unless /etc/iproute2/FOO exists. Signed-off-by: Gioele Barabucci <gioele@svario.it> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
parent
02ea021446
commit
0a0a8f12fa
10
Makefile
10
Makefile
@ -16,7 +16,8 @@ endif
|
||||
|
||||
PREFIX?=/usr
|
||||
SBINDIR?=/sbin
|
||||
CONFDIR?=/etc/iproute2
|
||||
CONF_ETC_DIR?=/etc/iproute2
|
||||
CONF_USR_DIR?=$(PREFIX)/lib/iproute2
|
||||
NETNS_RUN_DIR?=/var/run/netns
|
||||
NETNS_ETC_DIR?=/etc/netns
|
||||
DATADIR?=$(PREFIX)/share
|
||||
@ -37,7 +38,8 @@ ifneq ($(SHARED_LIBS),y)
|
||||
DEFINES+= -DNO_SHARED_LIBS
|
||||
endif
|
||||
|
||||
DEFINES+=-DCONFDIR=\"$(CONFDIR)\" \
|
||||
DEFINES+=-DCONF_USR_DIR=\"$(CONF_USR_DIR)\" \
|
||||
-DCONF_ETC_DIR=\"$(CONF_ETC_DIR)\" \
|
||||
-DNETNS_RUN_DIR=\"$(NETNS_RUN_DIR)\" \
|
||||
-DNETNS_ETC_DIR=\"$(NETNS_ETC_DIR)\"
|
||||
|
||||
@ -100,11 +102,11 @@ config.mk:
|
||||
|
||||
install: all
|
||||
install -m 0755 -d $(DESTDIR)$(SBINDIR)
|
||||
install -m 0755 -d $(DESTDIR)$(CONFDIR)
|
||||
install -m 0755 -d $(DESTDIR)$(CONF_USR_DIR)
|
||||
install -m 0755 -d $(DESTDIR)$(ARPDDIR)
|
||||
install -m 0755 -d $(DESTDIR)$(HDRDIR)
|
||||
@for i in $(SUBDIRS); do $(MAKE) -C $$i install; done
|
||||
install -m 0644 $(shell find etc/iproute2 -maxdepth 1 -type f) $(DESTDIR)$(CONFDIR)
|
||||
install -m 0644 $(shell find etc/iproute2 -maxdepth 1 -type f) $(DESTDIR)$(CONF_USR_DIR)
|
||||
install -m 0755 -d $(DESTDIR)$(BASH_COMPDIR)
|
||||
install -m 0644 bash-completion/tc $(DESTDIR)$(BASH_COMPDIR)
|
||||
install -m 0644 bash-completion/devlink $(DESTDIR)$(BASH_COMPDIR)
|
||||
|
@ -38,8 +38,11 @@ extern int numeric;
|
||||
extern bool do_all;
|
||||
extern int echo_request;
|
||||
|
||||
#ifndef CONFDIR
|
||||
#define CONFDIR "/etc/iproute2"
|
||||
#ifndef CONF_USR_DIR
|
||||
#define CONF_USR_DIR "/usr/lib/iproute2"
|
||||
#endif
|
||||
#ifndef CONF_ETC_DIR
|
||||
#define CONF_ETC_DIR "/etc/iproute2"
|
||||
#endif
|
||||
|
||||
#define SPRINT_BSIZE 64
|
||||
|
@ -2751,7 +2751,7 @@ static bool bpf_pinning_reserved(uint32_t pinning)
|
||||
}
|
||||
}
|
||||
|
||||
static void bpf_hash_init(struct bpf_elf_ctx *ctx, const char *db_file)
|
||||
static int bpf_hash_init(struct bpf_elf_ctx *ctx, const char *db_file)
|
||||
{
|
||||
struct bpf_hash_entry *entry;
|
||||
char subpath[PATH_MAX] = {};
|
||||
@ -2761,14 +2761,14 @@ static void bpf_hash_init(struct bpf_elf_ctx *ctx, const char *db_file)
|
||||
|
||||
fp = fopen(db_file, "r");
|
||||
if (!fp)
|
||||
return;
|
||||
return -errno;
|
||||
|
||||
while ((ret = bpf_read_pin_mapping(fp, &pinning, subpath))) {
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Database %s is corrupted at: %s\n",
|
||||
db_file, subpath);
|
||||
fclose(fp);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bpf_pinning_reserved(pinning)) {
|
||||
@ -2796,6 +2796,8 @@ static void bpf_hash_init(struct bpf_elf_ctx *ctx, const char *db_file)
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bpf_hash_destroy(struct bpf_elf_ctx *ctx)
|
||||
@ -2924,7 +2926,9 @@ static int bpf_elf_ctx_init(struct bpf_elf_ctx *ctx, const char *pathname,
|
||||
}
|
||||
|
||||
bpf_save_finfo(ctx);
|
||||
bpf_hash_init(ctx, CONFDIR "/bpf_pinning");
|
||||
bpf_hash_init(ctx, CONF_ETC_DIR "/bpf_pinning");
|
||||
if (ret == -ENOENT)
|
||||
ret = bpf_hash_init(ctx, CONF_USR_DIR "/bpf_pinning");
|
||||
|
||||
return 0;
|
||||
out_free:
|
||||
|
228
lib/rt_names.c
228
lib/rt_names.c
@ -12,8 +12,10 @@
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
@ -56,7 +58,7 @@ static int fread_id_name(FILE *fp, int *id, char *namebuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
|
||||
{
|
||||
struct rtnl_hash_entry *entry;
|
||||
@ -67,14 +69,14 @@ rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (!fp)
|
||||
return;
|
||||
return -errno;
|
||||
|
||||
while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Database %s is corrupted at %s\n",
|
||||
file, namebuf);
|
||||
fclose(fp);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (id < 0)
|
||||
@ -91,9 +93,11 @@ rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
|
||||
hash[id & (size - 1)] = entry;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtnl_tab_initialize(const char *file, char **tab, int size)
|
||||
static int rtnl_tab_initialize(const char *file, char **tab, int size)
|
||||
{
|
||||
FILE *fp;
|
||||
int id;
|
||||
@ -102,14 +106,14 @@ static void rtnl_tab_initialize(const char *file, char **tab, int size)
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (!fp)
|
||||
return;
|
||||
return -errno;
|
||||
|
||||
while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Database %s is corrupted at %s\n",
|
||||
file, namebuf);
|
||||
fclose(fp);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (id < 0 || id > size)
|
||||
continue;
|
||||
@ -117,6 +121,8 @@ static void rtnl_tab_initialize(const char *file, char **tab, int size)
|
||||
tab[id] = strdup(namebuf);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *rtnl_rtprot_tab[256] = {
|
||||
@ -144,25 +150,26 @@ static char *rtnl_rtprot_tab[256] = {
|
||||
[RTPROT_EIGRP] = "eigrp",
|
||||
};
|
||||
|
||||
struct tabhash {
|
||||
enum { TAB, HASH } type;
|
||||
union tab_or_hash {
|
||||
char **tab;
|
||||
struct rtnl_hash_entry **hash;
|
||||
} data;
|
||||
};
|
||||
|
||||
static int rtnl_rtprot_init;
|
||||
|
||||
static void rtnl_rtprot_initialize(void)
|
||||
static void
|
||||
rtnl_tabhash_readdir(const char *dirpath_base, const char *dirpath_overload,
|
||||
const struct tabhash tabhash, const int size)
|
||||
{
|
||||
struct dirent *de;
|
||||
DIR *d;
|
||||
|
||||
rtnl_rtprot_init = 1;
|
||||
rtnl_tab_initialize(CONFDIR "/rt_protos",
|
||||
rtnl_rtprot_tab, 256);
|
||||
|
||||
d = opendir(CONFDIR "/rt_protos.d");
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
d = opendir(dirpath_base);
|
||||
while (d && (de = readdir(d)) != NULL) {
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
struct stat sb;
|
||||
|
||||
if (*de->d_name == '.')
|
||||
continue;
|
||||
@ -174,11 +181,67 @@ static void rtnl_rtprot_initialize(void)
|
||||
if (strcmp(de->d_name + len - 5, ".conf"))
|
||||
continue;
|
||||
|
||||
snprintf(path, sizeof(path), CONFDIR "/rt_protos.d/%s",
|
||||
de->d_name);
|
||||
rtnl_tab_initialize(path, rtnl_rtprot_tab, 256);
|
||||
if (dirpath_overload) {
|
||||
/* only consider filenames not present in
|
||||
the overloading directory, e.g. /etc */
|
||||
snprintf(path, sizeof(path), "%s/%s", dirpath_overload, de->d_name);
|
||||
if (lstat(path, &sb) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* load the conf file in the base directory, e.g., /usr */
|
||||
snprintf(path, sizeof(path), "%s/%s", dirpath_base, de->d_name);
|
||||
if (tabhash.type == TAB)
|
||||
rtnl_tab_initialize(path, tabhash.data.tab, size);
|
||||
else
|
||||
rtnl_hash_initialize(path, tabhash.data.hash, size);
|
||||
}
|
||||
closedir(d);
|
||||
if (d)
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
static void
|
||||
rtnl_tabhash_initialize_dir(const char *ddir, const struct tabhash tabhash, const int size)
|
||||
{
|
||||
char dirpath_usr[PATH_MAX], dirpath_etc[PATH_MAX];
|
||||
|
||||
snprintf(dirpath_usr, sizeof(dirpath_usr), "%s/%s", CONF_USR_DIR, ddir);
|
||||
snprintf(dirpath_etc, sizeof(dirpath_etc), "%s/%s", CONF_ETC_DIR, ddir);
|
||||
|
||||
/* load /usr/lib/iproute2/foo.d/X conf files, unless /etc/iproute2/foo.d/X exists */
|
||||
rtnl_tabhash_readdir(dirpath_usr, dirpath_etc, tabhash, size);
|
||||
|
||||
/* load /etc/iproute2/foo.d/X conf files */
|
||||
rtnl_tabhash_readdir(dirpath_etc, NULL, tabhash, size);
|
||||
}
|
||||
|
||||
static void
|
||||
rtnl_tab_initialize_dir(const char *ddir, char **tab, const int size) {
|
||||
struct tabhash tab_data = {.type = TAB, .data.tab = tab};
|
||||
rtnl_tabhash_initialize_dir(ddir, tab_data, size);
|
||||
}
|
||||
|
||||
static void
|
||||
rtnl_hash_initialize_dir(const char *ddir, struct rtnl_hash_entry **hash,
|
||||
const int size) {
|
||||
struct tabhash hash_data = {.type = HASH, .data.hash = hash};
|
||||
rtnl_tabhash_initialize_dir(ddir, hash_data, size);
|
||||
}
|
||||
|
||||
static int rtnl_rtprot_init;
|
||||
|
||||
static void rtnl_rtprot_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_rtprot_init = 1;
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/rt_protos",
|
||||
rtnl_rtprot_tab, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_tab_initialize(CONF_USR_DIR "/rt_protos",
|
||||
rtnl_rtprot_tab, 256);
|
||||
|
||||
rtnl_tab_initialize_dir("rt_protos.d", rtnl_rtprot_tab, 256);
|
||||
}
|
||||
|
||||
const char *rtnl_rtprot_n2a(int id, char *buf, int len)
|
||||
@ -240,10 +303,17 @@ static bool rtnl_addrprot_tab_initialized;
|
||||
|
||||
static void rtnl_addrprot_initialize(void)
|
||||
{
|
||||
rtnl_tab_initialize(CONFDIR "/rt_addrprotos",
|
||||
rtnl_addrprot_tab,
|
||||
ARRAY_SIZE(rtnl_addrprot_tab));
|
||||
int ret;
|
||||
|
||||
rtnl_addrprot_tab_initialized = true;
|
||||
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/rt_addrprotos",
|
||||
rtnl_addrprot_tab,
|
||||
ARRAY_SIZE(rtnl_addrprot_tab));
|
||||
if (ret == -ENOENT)
|
||||
ret = rtnl_tab_initialize(CONF_USR_DIR "/rt_addrprotos",
|
||||
rtnl_addrprot_tab,
|
||||
ARRAY_SIZE(rtnl_addrprot_tab));
|
||||
}
|
||||
|
||||
const char *rtnl_addrprot_n2a(__u8 id, char *buf, int len)
|
||||
@ -296,9 +366,14 @@ static int rtnl_rtscope_init;
|
||||
|
||||
static void rtnl_rtscope_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_rtscope_init = 1;
|
||||
rtnl_tab_initialize(CONFDIR "/rt_scopes",
|
||||
rtnl_rtscope_tab, 256);
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/rt_scopes",
|
||||
rtnl_rtscope_tab, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_tab_initialize(CONF_USR_DIR "/rt_scopes",
|
||||
rtnl_rtscope_tab, 256);
|
||||
}
|
||||
|
||||
const char *rtnl_rtscope_n2a(int id, char *buf, int len)
|
||||
@ -361,9 +436,14 @@ static int rtnl_rtrealm_init;
|
||||
|
||||
static void rtnl_rtrealm_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_rtrealm_init = 1;
|
||||
rtnl_tab_initialize(CONFDIR "/rt_realms",
|
||||
rtnl_rtrealm_tab, 256);
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/rt_realms",
|
||||
rtnl_rtrealm_tab, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_tab_initialize(CONF_USR_DIR "/rt_realms",
|
||||
rtnl_rtrealm_tab, 256);
|
||||
}
|
||||
|
||||
const char *rtnl_rtrealm_n2a(int id, char *buf, int len)
|
||||
@ -430,41 +510,21 @@ static int rtnl_rttable_init;
|
||||
|
||||
static void rtnl_rttable_initialize(void)
|
||||
{
|
||||
struct dirent *de;
|
||||
DIR *d;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
rtnl_rttable_init = 1;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (rtnl_rttable_hash[i])
|
||||
rtnl_rttable_hash[i]->id = i;
|
||||
}
|
||||
rtnl_hash_initialize(CONFDIR "/rt_tables",
|
||||
rtnl_rttable_hash, 256);
|
||||
ret = rtnl_hash_initialize(CONF_ETC_DIR "/rt_tables",
|
||||
rtnl_rttable_hash, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_hash_initialize(CONF_USR_DIR "/rt_tables",
|
||||
rtnl_rttable_hash, 256);
|
||||
|
||||
d = opendir(CONFDIR "/rt_tables.d");
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
if (*de->d_name == '.')
|
||||
continue;
|
||||
|
||||
/* only consider filenames ending in '.conf' */
|
||||
len = strlen(de->d_name);
|
||||
if (len <= 5)
|
||||
continue;
|
||||
if (strcmp(de->d_name + len - 5, ".conf"))
|
||||
continue;
|
||||
|
||||
snprintf(path, sizeof(path),
|
||||
CONFDIR "/rt_tables.d/%s", de->d_name);
|
||||
rtnl_hash_initialize(path, rtnl_rttable_hash, 256);
|
||||
}
|
||||
closedir(d);
|
||||
rtnl_hash_initialize_dir("rt_tables.d", rtnl_rttable_hash, 256);
|
||||
}
|
||||
|
||||
const char *rtnl_rttable_n2a(__u32 id, char *buf, int len)
|
||||
@ -526,9 +586,14 @@ static int rtnl_rtdsfield_init;
|
||||
|
||||
static void rtnl_rtdsfield_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_rtdsfield_init = 1;
|
||||
rtnl_tab_initialize(CONFDIR "/rt_dsfield",
|
||||
rtnl_rtdsfield_tab, 256);
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/rt_dsfield",
|
||||
rtnl_rtdsfield_tab, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_tab_initialize(CONF_USR_DIR "/rt_dsfield",
|
||||
rtnl_rtdsfield_tab, 256);
|
||||
}
|
||||
|
||||
const char *rtnl_dsfield_n2a(int id, char *buf, int len)
|
||||
@ -605,9 +670,14 @@ static int rtnl_group_init;
|
||||
|
||||
static void rtnl_group_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_group_init = 1;
|
||||
rtnl_hash_initialize(CONFDIR "/group",
|
||||
rtnl_group_hash, 256);
|
||||
ret = rtnl_hash_initialize(CONF_ETC_DIR "/group",
|
||||
rtnl_group_hash, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_hash_initialize(CONF_USR_DIR "/group",
|
||||
rtnl_group_hash, 256);
|
||||
}
|
||||
|
||||
int rtnl_group_a2n(int *id, const char *arg)
|
||||
@ -695,9 +765,14 @@ static int nl_proto_init;
|
||||
|
||||
static void nl_proto_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nl_proto_init = 1;
|
||||
rtnl_tab_initialize(CONFDIR "/nl_protos",
|
||||
nl_proto_tab, 256);
|
||||
ret = rtnl_tab_initialize(CONF_ETC_DIR "/nl_protos",
|
||||
nl_proto_tab, 256);
|
||||
if (ret == -ENOENT)
|
||||
rtnl_tab_initialize(CONF_USR_DIR "/nl_protos",
|
||||
nl_proto_tab, 256);
|
||||
}
|
||||
|
||||
const char *nl_proto_n2a(int id, char *buf, int len)
|
||||
@ -757,35 +832,10 @@ static int protodown_reason_init;
|
||||
|
||||
static void protodown_reason_initialize(void)
|
||||
{
|
||||
struct dirent *de;
|
||||
DIR *d;
|
||||
|
||||
protodown_reason_init = 1;
|
||||
|
||||
d = opendir(CONFDIR "/protodown_reasons.d");
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
if (*de->d_name == '.')
|
||||
continue;
|
||||
|
||||
/* only consider filenames ending in '.conf' */
|
||||
len = strlen(de->d_name);
|
||||
if (len <= 5)
|
||||
continue;
|
||||
if (strcmp(de->d_name + len - 5, ".conf"))
|
||||
continue;
|
||||
|
||||
snprintf(path, sizeof(path), CONFDIR "/protodown_reasons.d/%s",
|
||||
de->d_name);
|
||||
rtnl_tab_initialize(path, protodown_reason_tab,
|
||||
PROTODOWN_REASON_NUM_BITS);
|
||||
}
|
||||
closedir(d);
|
||||
rtnl_tab_initialize_dir("protodown_reasons.d", protodown_reason_tab,
|
||||
PROTODOWN_REASON_NUM_BITS);
|
||||
}
|
||||
|
||||
int protodown_reason_n2a(int id, char *buf, int len)
|
||||
|
@ -9,7 +9,8 @@ all: $(TARGETS)
|
||||
sed \
|
||||
-e "s|@NETNS_ETC_DIR@|$(NETNS_ETC_DIR)|g" \
|
||||
-e "s|@NETNS_RUN_DIR@|$(NETNS_RUN_DIR)|g" \
|
||||
-e "s|@SYSCONFDIR@|$(CONFDIR)|g" \
|
||||
-e "s|@SYSCONF_ETC_DIR@|$(CONF_ETC_DIR)|g" \
|
||||
-e "s|@SYSCONF_USR_DIR@|$(CONF_USR_DIR)|g" \
|
||||
$< > $@
|
||||
|
||||
distclean: clean
|
||||
|
@ -208,8 +208,9 @@ The maximum allowed total length of label is 15 characters.
|
||||
.TP
|
||||
.BI scope " SCOPE_VALUE"
|
||||
the scope of the area where this address is valid.
|
||||
The available scopes are listed in file
|
||||
.BR "@SYSCONFDIR@/rt_scopes" .
|
||||
The available scopes are listed in
|
||||
.BR "@SYSCONF_USR_DIR@/rt_scopes" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_scopes" (has precedence if exists).
|
||||
Predefined scope values are:
|
||||
|
||||
.in +8
|
||||
|
@ -2250,8 +2250,9 @@ give the device a symbolic name for easy reference.
|
||||
.TP
|
||||
.BI group " GROUP"
|
||||
specify the group the device belongs to.
|
||||
The available groups are listed in file
|
||||
.BR "@SYSCONFDIR@/group" .
|
||||
The available groups are listed in
|
||||
.BR "@SYSCONF_USR_DIR@/group" or
|
||||
.BR "@SYSCONF_ETC_DIR@/group" (has precedence if exists).
|
||||
|
||||
.TP
|
||||
.BI vf " NUM"
|
||||
@ -2851,9 +2852,10 @@ specifies which help of link type to display.
|
||||
|
||||
.SS
|
||||
.I GROUP
|
||||
may be a number or a string from the file
|
||||
.B @SYSCONFDIR@/group
|
||||
which can be manually filled.
|
||||
may be a number or a string from
|
||||
.B @SYSCONF_USR_DIR@/group or
|
||||
.B @SYSCONF_ETC_DIR@/group
|
||||
which can be manually filled and has precedence if exists.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
|
@ -356,8 +356,9 @@ normal routing tables.
|
||||
.P
|
||||
.B Route tables:
|
||||
Linux-2.x can pack routes into several routing tables identified
|
||||
by a number in the range from 1 to 2^32-1 or by name from the file
|
||||
.B @SYSCONFDIR@/rt_tables
|
||||
by a number in the range from 1 to 2^32-1 or by name from
|
||||
.B @SYSCONF_USR_DIR@/rt_tables or
|
||||
.B @SYSCONF_ETC_DIR@/rt_tables (has precedence if exists).
|
||||
By default all normal routes are inserted into the
|
||||
.B main
|
||||
table (ID 254) and the kernel only uses this table when calculating routes.
|
||||
@ -420,7 +421,8 @@ may still match a route with a zero TOS.
|
||||
.I TOS
|
||||
is either an 8 bit hexadecimal number or an identifier
|
||||
from
|
||||
.BR "@SYSCONFDIR@/rt_dsfield" .
|
||||
.BR "@SYSCONF_USR_DIR@/rt_dsfield" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_dsfield" (has precedence if exists).
|
||||
|
||||
.TP
|
||||
.BI metric " NUMBER"
|
||||
@ -434,8 +436,9 @@ is an arbitrary 32bit number, where routes with lower values are preferred.
|
||||
.BI table " TABLEID"
|
||||
the table to add this route to.
|
||||
.I TABLEID
|
||||
may be a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_tables" .
|
||||
may be a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_tables" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_tables" (has precedence if exists).
|
||||
If this parameter is omitted,
|
||||
.B ip
|
||||
assumes the
|
||||
@ -475,8 +478,9 @@ covered by the route prefix.
|
||||
.BI realm " REALMID"
|
||||
the realm to which this route is assigned.
|
||||
.I REALMID
|
||||
may be a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_realms" .
|
||||
may be a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_realms" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_realms" (has precedence if exists).
|
||||
|
||||
.TP
|
||||
.BI mtu " MTU"
|
||||
@ -626,8 +630,9 @@ command.
|
||||
.BI scope " SCOPE_VAL"
|
||||
the scope of the destinations covered by the route prefix.
|
||||
.I SCOPE_VAL
|
||||
may be a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_scopes" .
|
||||
may be a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_scopes" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_scopes" (has precedence if exists).
|
||||
If this parameter is omitted,
|
||||
.B ip
|
||||
assumes scope
|
||||
@ -646,8 +651,9 @@ routes.
|
||||
.BI protocol " RTPROTO"
|
||||
the routing protocol identifier of this route.
|
||||
.I RTPROTO
|
||||
may be a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_protos" .
|
||||
may be a number or a string from
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_protos" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_protos" (has precedence if exists).
|
||||
If the routing protocol ID is not given,
|
||||
.B ip assumes protocol
|
||||
.B boot
|
||||
@ -879,8 +885,9 @@ matching packets are dropped.
|
||||
- Decapsulate the inner IPv6 packet and forward it according to the
|
||||
specified lookup table.
|
||||
.I TABLEID
|
||||
is either a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_tables" .
|
||||
is either a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_tables" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_tables" (has precedence if exists).
|
||||
If
|
||||
.B vrftable
|
||||
is used, the argument must be a VRF device associated with
|
||||
@ -895,8 +902,9 @@ and an inner IPv6 packet. Other matching packets are dropped.
|
||||
- Decapsulate the inner IPv4 packet and forward it according to the
|
||||
specified lookup table.
|
||||
.I TABLEID
|
||||
is either a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_tables" .
|
||||
is either a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_tables" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_tables" (has precedence if exists).
|
||||
The argument must be a VRF device associated with the table id.
|
||||
Moreover, the VRF table associated with the table id must be configured
|
||||
with the VRF strict mode turned on (net.vrf.strict_mode=1). This action
|
||||
@ -908,8 +916,9 @@ at all, and an inner IPv4 packet. Other matching packets are dropped.
|
||||
- Decapsulate the inner IPv4 or IPv6 packet and forward it according
|
||||
to the specified lookup table.
|
||||
.I TABLEID
|
||||
is either a number or a string from the file
|
||||
.BR "@SYSCONFDIR@/rt_tables" .
|
||||
is either a number or a string from
|
||||
.BR "@SYSCONF_USR_DIR@/rt_tables" or
|
||||
.BR "@SYSCONF_ETC_DIR@/rt_tables" (has precedence if exists).
|
||||
The argument must be a VRF device associated with the table id.
|
||||
Moreover, the VRF table associated with the table id must be configured
|
||||
with the VRF strict mode turned on (net.vrf.strict_mode=1). This action
|
||||
|
@ -21,7 +21,8 @@
|
||||
#include "tc_util.h"
|
||||
#include "m_ematch.h"
|
||||
|
||||
#define EMATCH_MAP "/etc/iproute2/ematch_map"
|
||||
#define EMATCH_MAP_USR CONF_USR_DIR "/ematch_map"
|
||||
#define EMATCH_MAP_ETC CONF_ETC_DIR "/ematch_map"
|
||||
|
||||
static struct ematch_util *ematch_list;
|
||||
|
||||
@ -39,11 +40,11 @@ static void bstr_print(FILE *fd, const struct bstr *b, int ascii);
|
||||
static inline void map_warning(int num, char *kind)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Error: Unable to find ematch \"%s\" in %s\n" \
|
||||
"Error: Unable to find ematch \"%s\" in %s or %s\n" \
|
||||
"Please assign a unique ID to the ematch kind the suggested " \
|
||||
"entry is:\n" \
|
||||
"\t%d\t%s\n",
|
||||
kind, EMATCH_MAP, num, kind);
|
||||
kind, EMATCH_MAP_ETC, EMATCH_MAP_USR, num, kind);
|
||||
}
|
||||
|
||||
static int lookup_map(__u16 num, char *dst, int len, const char *file)
|
||||
@ -160,8 +161,12 @@ static struct ematch_util *get_ematch_kind(char *kind)
|
||||
static struct ematch_util *get_ematch_kind_num(__u16 kind)
|
||||
{
|
||||
char name[513];
|
||||
int ret;
|
||||
|
||||
if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0)
|
||||
ret = lookup_map(kind, name, sizeof(name), EMATCH_MAP_ETC);
|
||||
if (ret == -ENOENT)
|
||||
ret = lookup_map(kind, name, sizeof(name), EMATCH_MAP_USR);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
return get_ematch_kind(name);
|
||||
@ -227,7 +232,9 @@ static int parse_tree(struct nlmsghdr *n, struct ematch *tree)
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = lookup_map_id(buf, &num, EMATCH_MAP);
|
||||
err = lookup_map_id(buf, &num, EMATCH_MAP_ETC);
|
||||
if (err == -ENOENT)
|
||||
err = lookup_map_id(buf, &num, EMATCH_MAP_USR);
|
||||
if (err < 0) {
|
||||
if (err == -ENOENT)
|
||||
map_warning(e->kind_num, buf);
|
||||
|
18
tc/tc_util.c
18
tc/tc_util.c
@ -28,7 +28,8 @@
|
||||
|
||||
static struct db_names *cls_names;
|
||||
|
||||
#define NAMES_DB "/etc/iproute2/tc_cls"
|
||||
#define NAMES_DB_USR CONF_USR_DIR "/tc_cls"
|
||||
#define NAMES_DB_ETC CONF_ETC_DIR "/tc_cls"
|
||||
|
||||
int cls_names_init(char *path)
|
||||
{
|
||||
@ -38,11 +39,18 @@ int cls_names_init(char *path)
|
||||
if (!cls_names)
|
||||
return -1;
|
||||
|
||||
ret = db_names_load(cls_names, path ?: NAMES_DB);
|
||||
if (ret == -ENOENT && path) {
|
||||
fprintf(stderr, "Can't open class names file: %s\n", path);
|
||||
return -1;
|
||||
if (path) {
|
||||
ret = db_names_load(cls_names, path);
|
||||
if (ret == -ENOENT) {
|
||||
fprintf(stderr, "Can't open class names file: %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = db_names_load(cls_names, NAMES_DB_ETC);
|
||||
if (ret == -ENOENT)
|
||||
ret = db_names_load(cls_names, NAMES_DB_USR);
|
||||
|
||||
if (ret) {
|
||||
db_names_free(cls_names);
|
||||
cls_names = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user