mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-16 22:36:11 +07:00
Merge branch 'fib-rule-selftest'
Roopa Prabhu says: ==================== fib rule selftest This series adds a new test to test fib rules. ip route get is used to test fib rule matches. This series also extends ip route get to match on sport and dport to test recent support of sport and dport fib rule match. v2 - address ido's commemt to make sport dport ip route get to work correctly for input route get. I don't support ip route get on ip-proto match yet. ip route get creates a udp packet and i have left it at that. We could extend ip route get to support a few ip proto matches in followup patches. v3 - Support ip_proto (only tcp and udp) match in getroute. dropped printing of new match attrs in ip route get, because ipv6 does not print it. And ipv6 currrently shares the dump api with ipv6 notify and its better to not add them to the notify api. dropped it to keep the api consistent between ipv4 and ipv6 (though uid is already printed in the ipv4 case). If we need it, both ipv4 and ipv6 can be enhanced to provide a separate get api. Moved skb creation for ipv4 to a separate func. v4 - drop separate skb for netlink and fix concerns around rcu and netlink reply (as pointed out by DaveM). I now try to reset the skb after the route lookup and before the netlink send (testing shows this is ok. More eyes and any feedback here will be helpful) v5 - dropped RTA_TABLE ipv4_rtm_policy update from this series and posted it separately for net (feedback from Eric) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8fcb0972b1
@ -664,4 +664,7 @@ extern int sysctl_icmp_msgs_burst;
|
||||
int ip_misc_proc_init(void);
|
||||
#endif
|
||||
|
||||
int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto,
|
||||
struct netlink_ext_ack *extack);
|
||||
|
||||
#endif /* _IP_H */
|
||||
|
@ -327,6 +327,9 @@ enum rtattr_type_t {
|
||||
RTA_PAD,
|
||||
RTA_UID,
|
||||
RTA_TTL_PROPAGATE,
|
||||
RTA_IP_PROTO,
|
||||
RTA_SPORT,
|
||||
RTA_DPORT,
|
||||
__RTA_MAX
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@ obj-y := route.o inetpeer.o protocol.o \
|
||||
udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
|
||||
fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
|
||||
inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
|
||||
metrics.o
|
||||
metrics.o netlink.o
|
||||
|
||||
obj-$(CONFIG_BPFILTER) += bpfilter/
|
||||
|
||||
|
@ -649,6 +649,9 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
|
||||
[RTA_ENCAP] = { .type = NLA_NESTED },
|
||||
[RTA_UID] = { .type = NLA_U32 },
|
||||
[RTA_MARK] = { .type = NLA_U32 },
|
||||
[RTA_IP_PROTO] = { .type = NLA_U8 },
|
||||
[RTA_SPORT] = { .type = NLA_U16 },
|
||||
[RTA_DPORT] = { .type = NLA_U16 },
|
||||
};
|
||||
|
||||
static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
|
||||
|
23
net/ipv4/netlink.c
Normal file
23
net/ipv4/netlink.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
*ip_proto = nla_get_u8(attr);
|
||||
|
||||
switch (*ip_proto) {
|
||||
case IPPROTO_TCP:
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_ICMP:
|
||||
return 0;
|
||||
default:
|
||||
NL_SET_ERR_MSG(extack, "Unsupported ip proto");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtm_getroute_parse_ip_proto);
|
146
net/ipv4/route.c
146
net/ipv4/route.c
@ -2574,11 +2574,10 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
|
||||
EXPORT_SYMBOL_GPL(ip_route_output_flow);
|
||||
|
||||
/* called with rcu_read_lock held */
|
||||
static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id,
|
||||
struct flowi4 *fl4, struct sk_buff *skb, u32 portid,
|
||||
u32 seq)
|
||||
static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
|
||||
struct rtable *rt, u32 table_id, struct flowi4 *fl4,
|
||||
struct sk_buff *skb, u32 portid, u32 seq)
|
||||
{
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
struct rtmsg *r;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned long expires = 0;
|
||||
@ -2674,7 +2673,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id,
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex))
|
||||
if (nla_put_u32(skb, RTA_IIF, fl4->flowi4_iif))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
@ -2689,43 +2688,93 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id,
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static struct sk_buff *inet_rtm_getroute_build_skb(__be32 src, __be32 dst,
|
||||
u8 ip_proto, __be16 sport,
|
||||
__be16 dport)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct iphdr *iph;
|
||||
|
||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
/* Reserve room for dummy headers, this skb can pass
|
||||
* through good chunk of routing engine.
|
||||
*/
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
iph = skb_put(skb, sizeof(struct iphdr));
|
||||
iph->protocol = ip_proto;
|
||||
iph->saddr = src;
|
||||
iph->daddr = dst;
|
||||
iph->version = 0x4;
|
||||
iph->frag_off = 0;
|
||||
iph->ihl = 0x5;
|
||||
skb_set_transport_header(skb, skb->len);
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_UDP: {
|
||||
struct udphdr *udph;
|
||||
|
||||
udph = skb_put_zero(skb, sizeof(struct udphdr));
|
||||
udph->source = sport;
|
||||
udph->dest = dport;
|
||||
udph->len = sizeof(struct udphdr);
|
||||
udph->check = 0;
|
||||
break;
|
||||
}
|
||||
case IPPROTO_TCP: {
|
||||
struct tcphdr *tcph;
|
||||
|
||||
tcph = skb_put_zero(skb, sizeof(struct tcphdr));
|
||||
tcph->source = sport;
|
||||
tcph->dest = dport;
|
||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||
tcph->rst = 1;
|
||||
tcph->check = ~tcp_v4_check(sizeof(struct tcphdr),
|
||||
src, dst, 0);
|
||||
break;
|
||||
}
|
||||
case IPPROTO_ICMP: {
|
||||
struct icmphdr *icmph;
|
||||
|
||||
icmph = skb_put_zero(skb, sizeof(struct icmphdr));
|
||||
icmph->type = ICMP_ECHO;
|
||||
icmph->code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net *net = sock_net(in_skb->sk);
|
||||
struct rtmsg *rtm;
|
||||
struct nlattr *tb[RTA_MAX+1];
|
||||
u32 table_id = RT_TABLE_MAIN;
|
||||
__be16 sport = 0, dport = 0;
|
||||
struct fib_result res = {};
|
||||
u8 ip_proto = IPPROTO_UDP;
|
||||
struct rtable *rt = NULL;
|
||||
struct sk_buff *skb;
|
||||
struct rtmsg *rtm;
|
||||
struct flowi4 fl4;
|
||||
__be32 dst = 0;
|
||||
__be32 src = 0;
|
||||
kuid_t uid;
|
||||
u32 iif;
|
||||
int err;
|
||||
int mark;
|
||||
struct sk_buff *skb;
|
||||
u32 table_id = RT_TABLE_MAIN;
|
||||
kuid_t uid;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy,
|
||||
extack);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
return err;
|
||||
|
||||
rtm = nlmsg_data(nlh);
|
||||
|
||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
err = -ENOBUFS;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Reserve room for dummy headers, this skb can pass
|
||||
through good chunk of routing engine.
|
||||
*/
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0;
|
||||
dst = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
|
||||
iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
|
||||
@ -2735,14 +2784,22 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
else
|
||||
uid = (iif ? INVALID_UID : current_uid());
|
||||
|
||||
/* Bugfix: need to give ip_route_input enough of an IP header to
|
||||
* not gag.
|
||||
*/
|
||||
ip_hdr(skb)->protocol = IPPROTO_UDP;
|
||||
ip_hdr(skb)->saddr = src;
|
||||
ip_hdr(skb)->daddr = dst;
|
||||
if (tb[RTA_IP_PROTO]) {
|
||||
err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO],
|
||||
&ip_proto, extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
|
||||
if (tb[RTA_SPORT])
|
||||
sport = nla_get_be16(tb[RTA_SPORT]);
|
||||
|
||||
if (tb[RTA_DPORT])
|
||||
dport = nla_get_be16(tb[RTA_DPORT]);
|
||||
|
||||
skb = inet_rtm_getroute_build_skb(src, dst, ip_proto, sport, dport);
|
||||
if (!skb)
|
||||
return -ENOBUFS;
|
||||
|
||||
memset(&fl4, 0, sizeof(fl4));
|
||||
fl4.daddr = dst;
|
||||
@ -2751,6 +2808,11 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
|
||||
fl4.flowi4_mark = mark;
|
||||
fl4.flowi4_uid = uid;
|
||||
if (sport)
|
||||
fl4.fl4_sport = sport;
|
||||
if (dport)
|
||||
fl4.fl4_dport = dport;
|
||||
fl4.flowi4_proto = ip_proto;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
@ -2760,10 +2822,10 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
dev = dev_get_by_index_rcu(net, iif);
|
||||
if (!dev) {
|
||||
err = -ENODEV;
|
||||
goto errout_free;
|
||||
goto errout_rcu;
|
||||
}
|
||||
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
fl4.flowi4_iif = iif; /* for rt_fill_info */
|
||||
skb->dev = dev;
|
||||
skb->mark = mark;
|
||||
err = ip_route_input_rcu(skb, dst, src, rtm->rtm_tos,
|
||||
@ -2783,7 +2845,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto errout_free;
|
||||
goto errout_rcu;
|
||||
|
||||
if (rtm->rtm_flags & RTM_F_NOTIFY)
|
||||
rt->rt_flags |= RTCF_NOTIFY;
|
||||
@ -2791,34 +2853,40 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
|
||||
table_id = res.table ? res.table->tb_id : 0;
|
||||
|
||||
/* reset skb for netlink reply msg */
|
||||
skb_trim(skb, 0);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
|
||||
if (!res.fi) {
|
||||
err = fib_props[res.type].error;
|
||||
if (!err)
|
||||
err = -EHOSTUNREACH;
|
||||
goto errout_free;
|
||||
goto errout_rcu;
|
||||
}
|
||||
err = fib_dump_info(skb, NETLINK_CB(in_skb).portid,
|
||||
nlh->nlmsg_seq, RTM_NEWROUTE, table_id,
|
||||
rt->rt_type, res.prefix, res.prefixlen,
|
||||
fl4.flowi4_tos, res.fi, 0);
|
||||
} else {
|
||||
err = rt_fill_info(net, dst, src, table_id, &fl4, skb,
|
||||
err = rt_fill_info(net, dst, src, rt, table_id, &fl4, skb,
|
||||
NETLINK_CB(in_skb).portid, nlh->nlmsg_seq);
|
||||
}
|
||||
if (err < 0)
|
||||
goto errout_free;
|
||||
goto errout_rcu;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
|
||||
errout:
|
||||
return err;
|
||||
|
||||
errout_free:
|
||||
return err;
|
||||
errout_rcu:
|
||||
rcu_read_unlock();
|
||||
kfree_skb(skb);
|
||||
goto errout;
|
||||
goto errout_free;
|
||||
}
|
||||
|
||||
void ip_rt_multicast_event(struct in_device *in_dev)
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <net/lwtunnel.h>
|
||||
#include <net/ip_tunnels.h>
|
||||
#include <net/l3mdev.h>
|
||||
#include <net/ip.h>
|
||||
#include <trace/events/fib6.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
@ -4083,6 +4084,9 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
|
||||
[RTA_UID] = { .type = NLA_U32 },
|
||||
[RTA_MARK] = { .type = NLA_U32 },
|
||||
[RTA_TABLE] = { .type = NLA_U32 },
|
||||
[RTA_IP_PROTO] = { .type = NLA_U8 },
|
||||
[RTA_SPORT] = { .type = NLA_U16 },
|
||||
[RTA_DPORT] = { .type = NLA_U16 },
|
||||
};
|
||||
|
||||
static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
@ -4795,6 +4799,19 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
else
|
||||
fl6.flowi6_uid = iif ? INVALID_UID : current_uid();
|
||||
|
||||
if (tb[RTA_SPORT])
|
||||
fl6.fl6_sport = nla_get_be16(tb[RTA_SPORT]);
|
||||
|
||||
if (tb[RTA_DPORT])
|
||||
fl6.fl6_dport = nla_get_be16(tb[RTA_DPORT]);
|
||||
|
||||
if (tb[RTA_IP_PROTO]) {
|
||||
err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO],
|
||||
&fl6.flowi6_proto, extack);
|
||||
if (err)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (iif) {
|
||||
struct net_device *dev;
|
||||
int flags = 0;
|
||||
|
@ -6,7 +6,7 @@ CFLAGS += -I../../../../usr/include/
|
||||
|
||||
TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh
|
||||
TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh udpgso.sh
|
||||
TEST_PROGS += udpgso_bench.sh
|
||||
TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh
|
||||
TEST_PROGS_EXTENDED := in_netns.sh
|
||||
TEST_GEN_FILES = socket
|
||||
TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
|
||||
|
248
tools/testing/selftests/net/fib_rule_tests.sh
Executable file
248
tools/testing/selftests/net/fib_rule_tests.sh
Executable file
@ -0,0 +1,248 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# This test is for checking IPv4 and IPv6 FIB rules API
|
||||
|
||||
ret=0
|
||||
|
||||
PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
|
||||
IP="ip -netns testns"
|
||||
|
||||
RTABLE=100
|
||||
GW_IP4=192.51.100.2
|
||||
SRC_IP=192.51.100.3
|
||||
GW_IP6=2001:db8:1::2
|
||||
SRC_IP6=2001:db8:1::3
|
||||
|
||||
DEV_ADDR=192.51.100.1
|
||||
DEV=dummy0
|
||||
|
||||
log_test()
|
||||
{
|
||||
local rc=$1
|
||||
local expected=$2
|
||||
local msg="$3"
|
||||
|
||||
if [ ${rc} -eq ${expected} ]; then
|
||||
nsuccess=$((nsuccess+1))
|
||||
printf "\n TEST: %-50s [ OK ]\n" "${msg}"
|
||||
else
|
||||
nfail=$((nfail+1))
|
||||
printf "\n TEST: %-50s [FAIL]\n" "${msg}"
|
||||
if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
|
||||
echo
|
||||
echo "hit enter to continue, 'q' to quit"
|
||||
read a
|
||||
[ "$a" = "q" ] && exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
log_section()
|
||||
{
|
||||
echo
|
||||
echo "######################################################################"
|
||||
echo "TEST SECTION: $*"
|
||||
echo "######################################################################"
|
||||
}
|
||||
|
||||
setup()
|
||||
{
|
||||
set -e
|
||||
ip netns add testns
|
||||
$IP link set dev lo up
|
||||
|
||||
$IP link add dummy0 type dummy
|
||||
$IP link set dev dummy0 up
|
||||
$IP address add 198.51.100.1/24 dev dummy0
|
||||
$IP -6 address add 2001:db8:1::1/64 dev dummy0
|
||||
|
||||
set +e
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
$IP link del dev dummy0 &> /dev/null
|
||||
ip netns del testns
|
||||
}
|
||||
|
||||
fib_check_iproute_support()
|
||||
{
|
||||
ip rule help 2>&1 | grep -q $1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: iproute2 iprule too old, missing $1 match"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ip route get help 2>&1 | grep -q $2
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: iproute2 get route too old, missing $2 match"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
fib_rule6_del()
|
||||
{
|
||||
$IP -6 rule del $1
|
||||
log_test $? 0 "rule6 del $1"
|
||||
}
|
||||
|
||||
fib_rule6_del_by_pref()
|
||||
{
|
||||
pref=$($IP -6 rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1)
|
||||
$IP -6 rule del pref $pref
|
||||
}
|
||||
|
||||
fib_rule6_test_match_n_redirect()
|
||||
{
|
||||
local match="$1"
|
||||
local getmatch="$2"
|
||||
|
||||
$IP -6 rule add $match table $RTABLE
|
||||
$IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"
|
||||
log_test $? 0 "rule6 check: $1"
|
||||
|
||||
fib_rule6_del_by_pref "$match"
|
||||
log_test $? 0 "rule6 del by pref: $match"
|
||||
}
|
||||
|
||||
fib_rule6_test()
|
||||
{
|
||||
# setup the fib rule redirect route
|
||||
$IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
|
||||
|
||||
match="oif $DEV"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "oif redirect to table"
|
||||
|
||||
match="from $SRC_IP6 iif $DEV"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "iif redirect to table"
|
||||
|
||||
match="tos 0x10"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "tos redirect to table"
|
||||
|
||||
match="fwmark 0x64"
|
||||
getmatch="mark 0x64"
|
||||
fib_rule6_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
|
||||
|
||||
fib_check_iproute_support "uidrange" "uid"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="uidrange 100-100"
|
||||
getmatch="uid 100"
|
||||
fib_rule6_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "sport" "sport"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="sport 666 dport 777"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "ipproto" "ipproto"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="ipproto tcp"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "ipproto match"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "ipproto" "ipproto"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="ipproto icmp"
|
||||
fib_rule6_test_match_n_redirect "$match" "$match" "ipproto icmp match"
|
||||
fi
|
||||
}
|
||||
|
||||
fib_rule4_del()
|
||||
{
|
||||
$IP rule del $1
|
||||
log_test $? 0 "del $1"
|
||||
}
|
||||
|
||||
fib_rule4_del_by_pref()
|
||||
{
|
||||
pref=$($IP rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1)
|
||||
$IP rule del pref $pref
|
||||
}
|
||||
|
||||
fib_rule4_test_match_n_redirect()
|
||||
{
|
||||
local match="$1"
|
||||
local getmatch="$2"
|
||||
|
||||
$IP rule add $match table $RTABLE
|
||||
$IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"
|
||||
log_test $? 0 "rule4 check: $1"
|
||||
|
||||
fib_rule4_del_by_pref "$match"
|
||||
log_test $? 0 "rule4 del by pref: $match"
|
||||
}
|
||||
|
||||
fib_rule4_test()
|
||||
{
|
||||
# setup the fib rule redirect route
|
||||
$IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
|
||||
|
||||
match="oif $DEV"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "oif redirect to table"
|
||||
|
||||
match="from $SRC_IP iif $DEV"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "iif redirect to table"
|
||||
|
||||
match="tos 0x10"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "tos redirect to table"
|
||||
|
||||
match="fwmark 0x64"
|
||||
getmatch="mark 0x64"
|
||||
fib_rule4_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
|
||||
|
||||
fib_check_iproute_support "uidrange" "uid"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="uidrange 100-100"
|
||||
getmatch="uid 100"
|
||||
fib_rule4_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "sport" "sport"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="sport 666 dport 777"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "ipproto" "ipproto"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="ipproto tcp"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "ipproto tcp match"
|
||||
fi
|
||||
|
||||
fib_check_iproute_support "ipproto" "ipproto"
|
||||
if [ $? -eq 0 ]; then
|
||||
match="ipproto icmp"
|
||||
fib_rule4_test_match_n_redirect "$match" "$match" "ipproto icmp match"
|
||||
fi
|
||||
}
|
||||
|
||||
run_fibrule_tests()
|
||||
{
|
||||
log_section "IPv4 fib rule"
|
||||
fib_rule4_test
|
||||
log_section "IPv6 fib rule"
|
||||
fib_rule6_test
|
||||
}
|
||||
|
||||
if [ "$(id -u)" -ne 0 ];then
|
||||
echo "SKIP: Need root privileges"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -x "$(command -v ip)" ]; then
|
||||
echo "SKIP: Could not run test without ip tool"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# start clean
|
||||
cleanup &> /dev/null
|
||||
setup
|
||||
run_fibrule_tests
|
||||
cleanup
|
||||
|
||||
exit $ret
|
Loading…
Reference in New Issue
Block a user