mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-06 09:09:03 +00:00

ip vrf exec requires root or CAP_NET_ADMIN, CAP_SYS_ADMIN and CAP_DAC_OVERRIDE. It is not possible to run unprivileged commands like ping as non-root or non-cap-enabled due to this requirement. To allow users and administrators to safely add the required capabilities to the binary, drop all capabilities on start if not invoked with "vrf exec". Update the manpage with the requirements. Signed-off-by: Luca Boccassi <bluca@debian.org> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
433 lines
8.1 KiB
Bash
Executable File
433 lines
8.1 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# This is not an autoconf generated configure
|
|
#
|
|
INCLUDE=${1:-"$PWD/include"}
|
|
|
|
# Output file which is input to Makefile
|
|
CONFIG=config.mk
|
|
|
|
# Make a temp directory in build tree.
|
|
TMPDIR=$(mktemp -d config.XXXXXX)
|
|
trap 'status=$?; rm -rf $TMPDIR; exit $status' EXIT HUP INT QUIT TERM
|
|
|
|
check_prog()
|
|
{
|
|
echo -n "$2"
|
|
command -v $1 >/dev/null 2>&1 && (echo "$3:=y" >> $CONFIG; echo "yes") || (echo "no"; return 1)
|
|
}
|
|
|
|
check_toolchain()
|
|
{
|
|
: ${PKG_CONFIG:=pkg-config}
|
|
: ${AR=ar}
|
|
: ${CC=gcc}
|
|
echo "PKG_CONFIG:=${PKG_CONFIG}" >>$CONFIG
|
|
echo "AR:=${AR}" >>$CONFIG
|
|
echo "CC:=${CC}" >>$CONFIG
|
|
}
|
|
|
|
check_atm()
|
|
{
|
|
cat >$TMPDIR/atmtest.c <<EOF
|
|
#include <atm.h>
|
|
int main(int argc, char **argv) {
|
|
struct atm_qos qos;
|
|
(void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0);
|
|
return 0;
|
|
}
|
|
EOF
|
|
|
|
$CC -I$INCLUDE -o $TMPDIR/atmtest $TMPDIR/atmtest.c -latm >/dev/null 2>&1
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "TC_CONFIG_ATM:=y" >>$CONFIG
|
|
echo yes
|
|
else
|
|
echo no
|
|
fi
|
|
rm -f $TMPDIR/atmtest.c $TMPDIR/atmtest
|
|
}
|
|
|
|
check_xtables()
|
|
{
|
|
if ! ${PKG_CONFIG} xtables --exists
|
|
then
|
|
echo "TC_CONFIG_NO_XT:=y" >>$CONFIG
|
|
fi
|
|
}
|
|
|
|
check_xt()
|
|
{
|
|
#check if we have xtables from iptables >= 1.4.5.
|
|
cat >$TMPDIR/ipttest.c <<EOF
|
|
#include <xtables.h>
|
|
#include <linux/netfilter.h>
|
|
static struct xtables_globals test_globals = {
|
|
.option_offset = 0,
|
|
.program_name = "tc-ipt",
|
|
.program_version = XTABLES_VERSION,
|
|
.orig_opts = NULL,
|
|
.opts = NULL,
|
|
.exit_err = NULL,
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
xtables_init_all(&test_globals, NFPROTO_IPV4);
|
|
return 0;
|
|
}
|
|
EOF
|
|
|
|
if $CC -I$INCLUDE $IPTC -o $TMPDIR/ipttest $TMPDIR/ipttest.c $IPTL \
|
|
$(${PKG_CONFIG} xtables --cflags --libs) -ldl >/dev/null 2>&1
|
|
then
|
|
echo "TC_CONFIG_XT:=y" >>$CONFIG
|
|
echo "using xtables"
|
|
fi
|
|
rm -f $TMPDIR/ipttest.c $TMPDIR/ipttest
|
|
}
|
|
|
|
check_xt_old()
|
|
{
|
|
# bail if previous XT checks has already succeded.
|
|
if grep -q TC_CONFIG_XT $CONFIG
|
|
then
|
|
return
|
|
fi
|
|
|
|
#check if we dont need our internal header ..
|
|
cat >$TMPDIR/ipttest.c <<EOF
|
|
#include <xtables.h>
|
|
char *lib_dir;
|
|
unsigned int global_option_offset = 0;
|
|
const char *program_version = XTABLES_VERSION;
|
|
const char *program_name = "tc-ipt";
|
|
struct afinfo afinfo = {
|
|
.libprefix = "libxt_",
|
|
};
|
|
|
|
void exit_error(enum exittype status, const char *msg, ...)
|
|
{
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
return 0;
|
|
}
|
|
|
|
EOF
|
|
|
|
$CC -I$INCLUDE $IPTC -o $TMPDIR/ipttest $TMPDIR/ipttest.c $IPTL -ldl >/dev/null 2>&1
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "TC_CONFIG_XT_OLD:=y" >>$CONFIG
|
|
echo "using old xtables (no need for xt-internal.h)"
|
|
fi
|
|
rm -f $TMPDIR/ipttest.c $TMPDIR/ipttest
|
|
}
|
|
|
|
check_xt_old_internal_h()
|
|
{
|
|
# bail if previous XT checks has already succeded.
|
|
if grep -q TC_CONFIG_XT $CONFIG
|
|
then
|
|
return
|
|
fi
|
|
|
|
#check if we need our own internal.h
|
|
cat >$TMPDIR/ipttest.c <<EOF
|
|
#include <xtables.h>
|
|
#include "xt-internal.h"
|
|
char *lib_dir;
|
|
unsigned int global_option_offset = 0;
|
|
const char *program_version = XTABLES_VERSION;
|
|
const char *program_name = "tc-ipt";
|
|
struct afinfo afinfo = {
|
|
.libprefix = "libxt_",
|
|
};
|
|
|
|
void exit_error(enum exittype status, const char *msg, ...)
|
|
{
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
return 0;
|
|
}
|
|
|
|
EOF
|
|
$CC -I$INCLUDE $IPTC -o $TMPDIR/ipttest $TMPDIR/ipttest.c $IPTL -ldl >/dev/null 2>&1
|
|
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "using old xtables with xt-internal.h"
|
|
echo "TC_CONFIG_XT_OLD_H:=y" >>$CONFIG
|
|
fi
|
|
rm -f $TMPDIR/ipttest.c $TMPDIR/ipttest
|
|
}
|
|
|
|
check_ipt()
|
|
{
|
|
if ! grep TC_CONFIG_XT $CONFIG > /dev/null
|
|
then
|
|
echo "using iptables"
|
|
fi
|
|
}
|
|
|
|
check_ipt_lib_dir()
|
|
{
|
|
IPT_LIB_DIR=$(${PKG_CONFIG} --variable=xtlibdir xtables)
|
|
if [ -n "$IPT_LIB_DIR" ]; then
|
|
echo $IPT_LIB_DIR
|
|
echo "IPT_LIB_DIR:=$IPT_LIB_DIR" >> $CONFIG
|
|
return
|
|
fi
|
|
|
|
for dir in /lib /usr/lib /usr/local/lib
|
|
do
|
|
for file in $dir/{xtables,iptables}/lib*t_*so ; do
|
|
if [ -f $file ]; then
|
|
echo ${file%/*}
|
|
echo "IPT_LIB_DIR:=${file%/*}" >> $CONFIG
|
|
return
|
|
fi
|
|
done
|
|
done
|
|
echo "not found!"
|
|
}
|
|
|
|
check_setns()
|
|
{
|
|
cat >$TMPDIR/setnstest.c <<EOF
|
|
#include <sched.h>
|
|
int main(int argc, char **argv)
|
|
{
|
|
(void)setns(0,0);
|
|
return 0;
|
|
}
|
|
EOF
|
|
$CC -I$INCLUDE -o $TMPDIR/setnstest $TMPDIR/setnstest.c >/dev/null 2>&1
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "IP_CONFIG_SETNS:=y" >>$CONFIG
|
|
echo "yes"
|
|
echo "CFLAGS += -DHAVE_SETNS" >>$CONFIG
|
|
else
|
|
echo "no"
|
|
fi
|
|
rm -f $TMPDIR/setnstest.c $TMPDIR/setnstest
|
|
}
|
|
|
|
check_ipset()
|
|
{
|
|
cat >$TMPDIR/ipsettest.c <<EOF
|
|
#include <linux/netfilter/ipset/ip_set.h>
|
|
#ifndef IP_SET_INVALID
|
|
#define IPSET_DIM_MAX 3
|
|
typedef unsigned short ip_set_id_t;
|
|
#endif
|
|
#include <linux/netfilter/xt_set.h>
|
|
|
|
struct xt_set_info info;
|
|
#if IPSET_PROTOCOL == 6
|
|
int main(void)
|
|
{
|
|
return IPSET_MAXNAMELEN;
|
|
}
|
|
#else
|
|
#error unknown ipset version
|
|
#endif
|
|
EOF
|
|
|
|
if $CC -I$INCLUDE -o $TMPDIR/ipsettest $TMPDIR/ipsettest.c >/dev/null 2>&1
|
|
then
|
|
echo "TC_CONFIG_IPSET:=y" >>$CONFIG
|
|
echo "yes"
|
|
else
|
|
echo "no"
|
|
fi
|
|
rm -f $TMPDIR/ipsettest.c $TMPDIR/ipsettest
|
|
}
|
|
|
|
check_elf()
|
|
{
|
|
if ${PKG_CONFIG} libelf --exists
|
|
then
|
|
echo "HAVE_ELF:=y" >>$CONFIG
|
|
echo "yes"
|
|
|
|
echo 'CFLAGS += -DHAVE_ELF' `${PKG_CONFIG} libelf --cflags` >> $CONFIG
|
|
echo 'LDLIBS += ' `${PKG_CONFIG} libelf --libs` >>$CONFIG
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
check_selinux()
|
|
# SELinux is a compile time option in the ss utility
|
|
{
|
|
if ${PKG_CONFIG} libselinux --exists
|
|
then
|
|
echo "HAVE_SELINUX:=y" >>$CONFIG
|
|
echo "yes"
|
|
|
|
echo 'LDLIBS +=' `${PKG_CONFIG} --libs libselinux` >>$CONFIG
|
|
echo 'CFLAGS += -DHAVE_SELINUX' `${PKG_CONFIG} --cflags libselinux` >>$CONFIG
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
check_mnl()
|
|
{
|
|
if ${PKG_CONFIG} libmnl --exists
|
|
then
|
|
echo "HAVE_MNL:=y" >>$CONFIG
|
|
echo "yes"
|
|
|
|
echo 'CFLAGS += -DHAVE_LIBMNL' `${PKG_CONFIG} libmnl --cflags` >>$CONFIG
|
|
echo 'LDLIBS +=' `${PKG_CONFIG} libmnl --libs` >> $CONFIG
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
check_berkeley_db()
|
|
{
|
|
cat >$TMPDIR/dbtest.c <<EOF
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <db_185.h>
|
|
int main(int argc, char **argv) {
|
|
dbopen("/tmp/xxx_test_db.db", O_CREAT|O_RDWR, 0644, DB_HASH, NULL);
|
|
return 0;
|
|
}
|
|
EOF
|
|
$CC -I$INCLUDE -o $TMPDIR/dbtest $TMPDIR/dbtest.c -ldb >/dev/null 2>&1
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "HAVE_BERKELEY_DB:=y" >>$CONFIG
|
|
echo "yes"
|
|
else
|
|
echo "no"
|
|
fi
|
|
rm -f $TMPDIR/dbtest.c $TMPDIR/dbtest
|
|
}
|
|
|
|
check_strlcpy()
|
|
{
|
|
cat >$TMPDIR/strtest.c <<EOF
|
|
#include <string.h>
|
|
int main(int argc, char **argv) {
|
|
char dst[10];
|
|
strlcpy(dst, "test", sizeof(dst));
|
|
return 0;
|
|
}
|
|
EOF
|
|
$CC -I$INCLUDE -o $TMPDIR/strtest $TMPDIR/strtest.c >/dev/null 2>&1
|
|
if [ $? -eq 0 ]
|
|
then
|
|
echo "no"
|
|
else
|
|
echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
|
|
echo "yes"
|
|
fi
|
|
rm -f $TMPDIR/strtest.c $TMPDIR/strtest
|
|
}
|
|
|
|
check_cap()
|
|
{
|
|
if ${PKG_CONFIG} libcap --exists
|
|
then
|
|
echo "HAVE_CAP:=y" >>$CONFIG
|
|
echo "yes"
|
|
|
|
echo 'CFLAGS += -DHAVE_LIBCAP' `${PKG_CONFIG} libcap --cflags` >>$CONFIG
|
|
echo 'LDLIBS +=' `${PKG_CONFIG} libcap --libs` >> $CONFIG
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
quiet_config()
|
|
{
|
|
cat <<EOF
|
|
# user can control verbosity similar to kernel builds (e.g., V=1)
|
|
ifeq ("\$(origin V)", "command line")
|
|
VERBOSE = \$(V)
|
|
endif
|
|
ifndef VERBOSE
|
|
VERBOSE = 0
|
|
endif
|
|
ifeq (\$(VERBOSE),1)
|
|
Q =
|
|
else
|
|
Q = @
|
|
endif
|
|
|
|
ifeq (\$(VERBOSE), 0)
|
|
QUIET_CC = @echo ' CC '\$@;
|
|
QUIET_AR = @echo ' AR '\$@;
|
|
QUIET_LINK = @echo ' LINK '\$@;
|
|
QUIET_YACC = @echo ' YACC '\$@;
|
|
QUIET_LEX = @echo ' LEX '\$@;
|
|
endif
|
|
EOF
|
|
}
|
|
|
|
echo "# Generated config based on" $INCLUDE >$CONFIG
|
|
quiet_config >> $CONFIG
|
|
|
|
check_toolchain
|
|
|
|
echo "TC schedulers"
|
|
|
|
echo -n " ATM "
|
|
check_atm
|
|
|
|
check_xtables
|
|
if ! grep -q TC_CONFIG_NO_XT $CONFIG
|
|
then
|
|
echo -n " IPT "
|
|
check_xt
|
|
check_xt_old
|
|
check_xt_old_internal_h
|
|
check_ipt
|
|
|
|
echo -n " IPSET "
|
|
check_ipset
|
|
fi
|
|
|
|
echo
|
|
if ! grep -q TC_CONFIG_NO_XT $CONFIG
|
|
then
|
|
echo -n "iptables modules directory: "
|
|
check_ipt_lib_dir
|
|
fi
|
|
|
|
echo -n "libc has setns: "
|
|
check_setns
|
|
|
|
echo -n "SELinux support: "
|
|
check_selinux
|
|
|
|
echo -n "ELF support: "
|
|
check_elf
|
|
|
|
echo -n "libmnl support: "
|
|
check_mnl
|
|
|
|
echo -n "Berkeley DB: "
|
|
check_berkeley_db
|
|
|
|
echo -n "need for strlcpy: "
|
|
check_strlcpy
|
|
|
|
echo -n "libcap support: "
|
|
check_cap
|
|
|
|
echo >> $CONFIG
|
|
echo "%.o: %.c" >> $CONFIG
|
|
echo ' $(QUIET_CC)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<' >> $CONFIG
|