All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/3] fib rule selftest
@ 2018-05-07  0:59 Roopa Prabhu
  2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Roopa Prabhu @ 2018-05-07  0:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, dsa, nikolay, idosch

From: Roopa Prabhu <roopa@cumulusnetworks.com>

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.


Roopa Prabhu (3):
  ipv4: support sport and dport in RTM_GETROUTE
  ipv6: support sport and dport in RTM_GETROUTE
  selftests: net: initial fib rule tests

 include/uapi/linux/rtnetlink.h                |   2 +
 net/ipv4/route.c                              | 152 ++++++++++++-----
 net/ipv6/route.c                              |  25 +++
 tools/testing/selftests/net/Makefile          |   2 +-
 tools/testing/selftests/net/fib_rule_tests.sh | 224 ++++++++++++++++++++++++++
 5 files changed, 366 insertions(+), 39 deletions(-)
 create mode 100644 tools/testing/selftests/net/fib_rule_tests.sh

-- 
2.1.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 [PATCH net-next v2 0/3] fib rule selftest Roopa Prabhu
@ 2018-05-07  0:59 ` Roopa Prabhu
  2018-05-07  1:46   ` David Ahern
  2018-05-07  5:49   ` kbuild test robot
  2018-05-07  0:59 ` [PATCH net-next v2 2/3] ipv6: " Roopa Prabhu
  2018-05-07  0:59 ` [PATCH net-next v2 3/3] selftests: net: initial fib rule tests Roopa Prabhu
  2 siblings, 2 replies; 9+ messages in thread
From: Roopa Prabhu @ 2018-05-07  0:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, dsa, nikolay, idosch

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This is a followup to fib rules sport, dport match support.
Having them supported in getroute makes it easier to test
fib rule lookups. Used by fib rule self tests. Before this patch
getroute used same skb to pass through the route lookup and
for the netlink getroute reply msg. This patch allocates separate
skb's to keep flow dissector happy.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 include/uapi/linux/rtnetlink.h |   2 +
 net/ipv4/route.c               | 151 ++++++++++++++++++++++++++++++-----------
 2 files changed, 115 insertions(+), 38 deletions(-)

diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 9b15005..630ecf4 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -327,6 +327,8 @@ enum rtattr_type_t {
 	RTA_PAD,
 	RTA_UID,
 	RTA_TTL_PROPAGATE,
+	RTA_SPORT,
+	RTA_DPORT,
 	__RTA_MAX
 };
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1412a7b..e91ed62 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2568,11 +2568,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;
@@ -2651,6 +2650,14 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
 			from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
 		goto nla_put_failure;
 
+	if (fl4->fl4_sport &&
+	    nla_put_be16(skb, RTA_SPORT, fl4->fl4_sport))
+		goto nla_put_failure;
+
+	if (fl4->fl4_dport &&
+	    nla_put_be16(skb, RTA_DPORT, fl4->fl4_dport))
+		goto nla_put_failure;
+
 	error = rt->dst.error;
 
 	if (rt_is_input_route(rt)) {
@@ -2668,7 +2675,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;
 	}
 
@@ -2683,35 +2690,86 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
 	return -EMSGSIZE;
 }
 
+static int nla_get_port(struct nlattr *attr, __be16 *port)
+{
+	int p = nla_get_be16(attr);
+
+	if (p <= 0 || p >= 0xffff)
+		return -EINVAL;
+
+	*port = p;
+	return 0;
+}
+
+static int inet_rtm_getroute_reply(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+				   __be32 dst, __be32 src, struct flowi4 *fl4,
+				   struct rtable *rt, struct fib_result *res)
+{
+	struct net *net = sock_net(in_skb->sk);
+	struct rtmsg *rtm = nlmsg_data(nlh);
+	u32 table_id = RT_TABLE_MAIN;
+	struct sk_buff *skb;
+	int err = 0;
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!skb) {
+		err = -ENOMEM;
+		return err;
+	}
+
+	if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
+		table_id = res->table ? res->table->tb_id : 0;
+
+	if (rtm->rtm_flags & RTM_F_FIB_MATCH)
+		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, rt, table_id,
+				   fl4, skb, NETLINK_CB(in_skb).portid,
+				   nlh->nlmsg_seq);
+	if (err < 0)
+		goto errout;
+
+	return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
+
+errout:
+	kfree_skb(skb);
+	return err;
+}
+
 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];
+	__be16 sport = 0, dport = 0;
 	struct fib_result res = {};
 	struct rtable *rt = NULL;
+	struct sk_buff *skb;
+	struct rtmsg *rtm;
 	struct flowi4 fl4;
+	struct iphdr *iph;
+	struct udphdr *udph;
 	__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;
+		return err;
 	}
 
 	/* Reserve room for dummy headers, this skb can pass
@@ -2728,15 +2786,36 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		uid = make_kuid(current_user_ns(), nla_get_u32(tb[RTA_UID]));
 	else
 		uid = (iif ? INVALID_UID : current_uid());
+	if (tb[RTA_SPORT]) {
+		err = nla_get_port(tb[RTA_SPORT], &sport);
+		if (err)
+			goto errout_free;
+	}
 
-	/* 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_DPORT]) {
+		err = nla_get_port(tb[RTA_DPORT], &dport);
+		if (err)
+			goto errout_free;
+	}
 
-	skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
+	skb->protocol = htons(ETH_P_IP);
+	iph = skb_put(skb, sizeof(struct iphdr));
+	iph->protocol = IPPROTO_UDP;
+	iph->saddr = src;
+	iph->daddr = dst;
+	iph->version = 0x4;
+	iph->frag_off = 0;
+
+	if (sport || dport) {
+		iph->ihl = 0x5;
+		skb_set_transport_header(skb, skb->len);
+
+		udph = skb_put(skb, sizeof(struct udphdr));
+		udph->dest = dport;
+		udph->source = sport;
+		udph->len = sizeof(struct udphdr);
+		udph->check = 0;
+	}
 
 	memset(&fl4, 0, sizeof(fl4));
 	fl4.daddr = dst;
@@ -2745,6 +2824,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 = IPPROTO_UDP;
 
 	rcu_read_lock();
 
@@ -2754,9 +2838,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;
 		}
 
+		fl4.flowi4_iif = iif; /* for rt_fill_info */
 		skb->protocol	= htons(ETH_P_IP);
 		skb->dev	= dev;
 		skb->mark	= mark;
@@ -2777,42 +2862,32 @@ 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;
 
-	if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
-		table_id = res.table ? res.table->tb_id : 0;
-
 	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,
-				   NETLINK_CB(in_skb).portid, nlh->nlmsg_seq);
 	}
+
+	err = inet_rtm_getroute_reply(in_skb, nlh, dst, src, &fl4, rt, &res);
 	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:
-	rcu_read_unlock();
 	kfree_skb(skb);
-	goto errout;
+	return err;
+errout_rcu:
+	rcu_read_unlock();
+	goto errout_free;
 }
 
 void ip_rt_multicast_event(struct in_device *in_dev)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v2 2/3] ipv6: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 [PATCH net-next v2 0/3] fib rule selftest Roopa Prabhu
  2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
@ 2018-05-07  0:59 ` Roopa Prabhu
  2018-05-07  1:46   ` David Ahern
  2018-05-07  6:23   ` kbuild test robot
  2018-05-07  0:59 ` [PATCH net-next v2 3/3] selftests: net: initial fib rule tests Roopa Prabhu
  2 siblings, 2 replies; 9+ messages in thread
From: Roopa Prabhu @ 2018-05-07  0:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, dsa, nikolay, idosch

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This is a followup to fib6 rules sport and dport
match support. Having them supported in getroute
makes it easier to test fib6 rule lookups. Used by fib6 rule
self tests.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 net/ipv6/route.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8ed1b51..bcdc056 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4071,6 +4071,8 @@ 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_SPORT]		= { .type = NLA_U16 },
+	[RTA_DPORT]		= { .type = NLA_U16 },
 };
 
 static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -4728,6 +4730,17 @@ int rt6_dump_route(struct fib6_info *rt, void *p_arg)
 			     arg->cb->nlh->nlmsg_seq, NLM_F_MULTI);
 }
 
+static int nla_get_port(struct nlattr *attr, __be16 *port)
+{
+	int p = nla_get_be16(attr);
+
+	if (p <= 0 || p >= 0xffff)
+		return -EINVAL;
+
+	*port = p;
+	return 0;
+}
+
 static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 			      struct netlink_ext_ack *extack)
 {
@@ -4782,6 +4795,18 @@ 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]) {
+		err = nla_get_port(tb[RTA_SPORT], &fl6.fl6_sport);
+		if (err)
+			goto errout;
+	}
+
+	if (tb[RTA_DPORT]) {
+		err = nla_get_port(tb[RTA_DPORT], &fl6.fl6_dport);
+		if (err)
+			goto errout;
+	}
+
 	if (iif) {
 		struct net_device *dev;
 		int flags = 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next v2 3/3] selftests: net: initial fib rule tests
  2018-05-07  0:59 [PATCH net-next v2 0/3] fib rule selftest Roopa Prabhu
  2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
  2018-05-07  0:59 ` [PATCH net-next v2 2/3] ipv6: " Roopa Prabhu
@ 2018-05-07  0:59 ` Roopa Prabhu
  2 siblings, 0 replies; 9+ messages in thread
From: Roopa Prabhu @ 2018-05-07  0:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, dsa, nikolay, idosch

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This adds a first set of tests for fib rule match/action for
ipv4 and ipv6. Initial tests only cover action lookup table.
can be extended to cover other actions in the future.
Uses ip route get to validate the rule lookup.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 tools/testing/selftests/net/Makefile          |   2 +-
 tools/testing/selftests/net/fib_rule_tests.sh | 224 ++++++++++++++++++++++++++
 2 files changed, 225 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/net/fib_rule_tests.sh

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 902820d..9a8f9b0 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -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 in_netns.sh pmtu.sh udpgso.sh
-TEST_PROGS += udpgso_bench.sh
+TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh
 TEST_GEN_PROGS_EXTENDED := in_netns.sh
 TEST_GEN_FILES =  socket
 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
diff --git a/tools/testing/selftests/net/fib_rule_tests.sh b/tools/testing/selftests/net/fib_rule_tests.sh
new file mode 100644
index 0000000..01a250f
--- /dev/null
+++ b/tools/testing/selftests/net/fib_rule_tests.sh
@@ -0,0 +1,224 @@
+#!/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_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
+}
+
+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
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
@ 2018-05-07  1:46   ` David Ahern
  2018-05-07 14:42     ` Roopa Prabhu
  2018-05-07  5:49   ` kbuild test robot
  1 sibling, 1 reply; 9+ messages in thread
From: David Ahern @ 2018-05-07  1:46 UTC (permalink / raw)
  To: Roopa Prabhu, davem; +Cc: netdev, nikolay, idosch

On 5/6/18 6:59 PM, Roopa Prabhu wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
> 
> This is a followup to fib rules sport, dport match support.
> Having them supported in getroute makes it easier to test
> fib rule lookups. Used by fib rule self tests. Before this patch
> getroute used same skb to pass through the route lookup and
> for the netlink getroute reply msg. This patch allocates separate
> skb's to keep flow dissector happy.
> 
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
> ---
>  include/uapi/linux/rtnetlink.h |   2 +
>  net/ipv4/route.c               | 151 ++++++++++++++++++++++++++++++-----------
>  2 files changed, 115 insertions(+), 38 deletions(-)
> 
> diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
> index 9b15005..630ecf4 100644
> --- a/include/uapi/linux/rtnetlink.h
> +++ b/include/uapi/linux/rtnetlink.h
> @@ -327,6 +327,8 @@ enum rtattr_type_t {
>  	RTA_PAD,
>  	RTA_UID,
>  	RTA_TTL_PROPAGATE,
> +	RTA_SPORT,
> +	RTA_DPORT,

If you are going to add sport and dport because of the potential for FIB
rules, you need to add ip-proto as well. I realize existing code assumed
UDP, but the FIB rules cover any IP proto. Yes, I know this makes the
change much larger to generate tcp, udp as well as iphdr options; the
joys of new features. ;-)

I also suggest a comment that these new RTA attributes are used for
GETROUTE only.

And you need to add the new entries to rtm_ipv4_policy.


>  	__RTA_MAX
>  };
>  
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 1412a7b..e91ed62 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2568,11 +2568,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;
> @@ -2651,6 +2650,14 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
>  			from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
>  		goto nla_put_failure;
>  
> +	if (fl4->fl4_sport &&
> +	    nla_put_be16(skb, RTA_SPORT, fl4->fl4_sport))
> +		goto nla_put_failure;
> +
> +	if (fl4->fl4_dport &&
> +	    nla_put_be16(skb, RTA_DPORT, fl4->fl4_dport))
> +		goto nla_put_failure;

Why return the attributes to the user? I can't see any value in that.
UID option is not returned either so there is precedence.


> +
>  	error = rt->dst.error;
>  
>  	if (rt_is_input_route(rt)) {
> @@ -2668,7 +2675,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;
>  	}
>  
> @@ -2683,35 +2690,86 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
>  	return -EMSGSIZE;
>  }
>  
> +static int nla_get_port(struct nlattr *attr, __be16 *port)
> +{
> +	int p = nla_get_be16(attr);

__be16 p;

> +
> +	if (p <= 0 || p >= 0xffff)
> +		return -EINVAL;

This check is not needed by definition of be16.

> +
> +	*port = p;
> +	return 0;
> +}
> +
> +static int inet_rtm_getroute_reply(struct sk_buff *in_skb, struct nlmsghdr *nlh,
> +				   __be32 dst, __be32 src, struct flowi4 *fl4,
> +				   struct rtable *rt, struct fib_result *res)
> +{
> +	struct net *net = sock_net(in_skb->sk);
> +	struct rtmsg *rtm = nlmsg_data(nlh);
> +	u32 table_id = RT_TABLE_MAIN;
> +	struct sk_buff *skb;
> +	int err = 0;
> +
> +	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
> +	if (!skb) {
> +		err = -ENOMEM;
> +		return err;
> +	}

just 'return -ENOMEM' and without the {}.


> +
> +	if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
> +		table_id = res->table ? res->table->tb_id : 0;
> +
> +	if (rtm->rtm_flags & RTM_F_FIB_MATCH)
> +		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, rt, table_id,
> +				   fl4, skb, NETLINK_CB(in_skb).portid,
> +				   nlh->nlmsg_seq);
> +	if (err < 0)
> +		goto errout;
> +
> +	return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
> +
> +errout:
> +	kfree_skb(skb);
> +	return err;
> +}
> +
>  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];
> +	__be16 sport = 0, dport = 0;
>  	struct fib_result res = {};
>  	struct rtable *rt = NULL;
> +	struct sk_buff *skb;
> +	struct rtmsg *rtm;
>  	struct flowi4 fl4;
> +	struct iphdr *iph;
> +	struct udphdr *udph;
>  	__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;
> +		return err;

just return -ENOBUFS


>  	}
>  
>  	/* Reserve room for dummy headers, this skb can pass

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v2 2/3] ipv6: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 ` [PATCH net-next v2 2/3] ipv6: " Roopa Prabhu
@ 2018-05-07  1:46   ` David Ahern
  2018-05-07  6:23   ` kbuild test robot
  1 sibling, 0 replies; 9+ messages in thread
From: David Ahern @ 2018-05-07  1:46 UTC (permalink / raw)
  To: Roopa Prabhu, davem; +Cc: netdev, nikolay, idosch

On 5/6/18 6:59 PM, Roopa Prabhu wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
> 
> This is a followup to fib6 rules sport and dport
> match support. Having them supported in getroute
> makes it easier to test fib6 rule lookups. Used by fib6 rule
> self tests.
> 
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
> ---
>  net/ipv6/route.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)

similar comments as IPv4 patch.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
  2018-05-07  1:46   ` David Ahern
@ 2018-05-07  5:49   ` kbuild test robot
  1 sibling, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2018-05-07  5:49 UTC (permalink / raw)
  To: Roopa Prabhu; +Cc: kbuild-all, davem, netdev, dsa, nikolay, idosch

Hi Roopa,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Roopa-Prabhu/fib-rule-selftest/20180507-094538
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   net/ipv4/route.c:1271:31: sparse: expression using sizeof(void)
   net/ipv4/route.c:1271:31: sparse: expression using sizeof(void)
   net/ipv4/route.c:1274:16: sparse: expression using sizeof(void)
   net/ipv4/route.c:1274:16: sparse: expression using sizeof(void)
   net/ipv4/route.c:1295:15: sparse: expression using sizeof(void)
   net/ipv4/route.c:688:38: sparse: expression using sizeof(void)
   net/ipv4/route.c:712:38: sparse: expression using sizeof(void)
   net/ipv4/route.c:782:46: sparse: incorrect type in argument 2 (different base types) @@    expected unsigned int [unsigned] [usertype] key @@    got ed int [unsigned] [usertype] key @@
   net/ipv4/route.c:782:46:    expected unsigned int [unsigned] [usertype] key
   net/ipv4/route.c:782:46:    got restricted __be32 [usertype] new_gw
>> net/ipv4/route.c:2695:29: sparse: incorrect type in initializer (different base types) @@    expected int [signed] p @@    got restint [signed] p @@
   net/ipv4/route.c:2695:29:    expected int [signed] p
   net/ipv4/route.c:2695:29:    got restricted __be16
>> net/ipv4/route.c:2700:15: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] <noident> @@    got 6 [usertype] <noident> @@
   net/ipv4/route.c:2700:15:    expected restricted __be16 [usertype] <noident>
   net/ipv4/route.c:2700:15:    got int [signed] p
>> net/ipv4/route.c:2816:27: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] len @@    got 6 [usertype] len @@
   net/ipv4/route.c:2816:27:    expected restricted __be16 [usertype] len
   net/ipv4/route.c:2816:27:    got unsigned long

vim +2695 net/ipv4/route.c

  2692	
  2693	static int nla_get_port(struct nlattr *attr, __be16 *port)
  2694	{
> 2695		int p = nla_get_be16(attr);
  2696	
  2697		if (p <= 0 || p >= 0xffff)
  2698			return -EINVAL;
  2699	
> 2700		*port = p;
  2701		return 0;
  2702	}
  2703	
  2704	static int inet_rtm_getroute_reply(struct sk_buff *in_skb, struct nlmsghdr *nlh,
  2705					   __be32 dst, __be32 src, struct flowi4 *fl4,
  2706					   struct rtable *rt, struct fib_result *res)
  2707	{
  2708		struct net *net = sock_net(in_skb->sk);
  2709		struct rtmsg *rtm = nlmsg_data(nlh);
  2710		u32 table_id = RT_TABLE_MAIN;
  2711		struct sk_buff *skb;
  2712		int err = 0;
  2713	
  2714		skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  2715		if (!skb) {
  2716			err = -ENOMEM;
  2717			return err;
  2718		}
  2719	
  2720		if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
  2721			table_id = res->table ? res->table->tb_id : 0;
  2722	
  2723		if (rtm->rtm_flags & RTM_F_FIB_MATCH)
  2724			err = fib_dump_info(skb, NETLINK_CB(in_skb).portid,
  2725					    nlh->nlmsg_seq, RTM_NEWROUTE, table_id,
  2726					    rt->rt_type, res->prefix, res->prefixlen,
  2727					    fl4->flowi4_tos, res->fi, 0);
  2728		else
  2729			err = rt_fill_info(net, dst, src, rt, table_id,
  2730					   fl4, skb, NETLINK_CB(in_skb).portid,
  2731					   nlh->nlmsg_seq);
  2732		if (err < 0)
  2733			goto errout;
  2734	
  2735		return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
  2736	
  2737	errout:
  2738		kfree_skb(skb);
  2739		return err;
  2740	}
  2741	
  2742	static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
  2743				     struct netlink_ext_ack *extack)
  2744	{
  2745		struct net *net = sock_net(in_skb->sk);
  2746		struct nlattr *tb[RTA_MAX+1];
  2747		__be16 sport = 0, dport = 0;
  2748		struct fib_result res = {};
  2749		struct rtable *rt = NULL;
  2750		struct sk_buff *skb;
  2751		struct rtmsg *rtm;
  2752		struct flowi4 fl4;
  2753		struct iphdr *iph;
  2754		struct udphdr *udph;
  2755		__be32 dst = 0;
  2756		__be32 src = 0;
  2757		kuid_t uid;
  2758		u32 iif;
  2759		int err;
  2760		int mark;
  2761	
  2762		err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy,
  2763				  extack);
  2764		if (err < 0)
  2765			return err;
  2766	
  2767		rtm = nlmsg_data(nlh);
  2768	
  2769		skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  2770		if (!skb) {
  2771			err = -ENOBUFS;
  2772			return err;
  2773		}
  2774	
  2775		/* Reserve room for dummy headers, this skb can pass
  2776		   through good chunk of routing engine.
  2777		 */
  2778		skb_reset_mac_header(skb);
  2779		skb_reset_network_header(skb);
  2780	
  2781		src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0;
  2782		dst = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
  2783		iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
  2784		mark = tb[RTA_MARK] ? nla_get_u32(tb[RTA_MARK]) : 0;
  2785		if (tb[RTA_UID])
  2786			uid = make_kuid(current_user_ns(), nla_get_u32(tb[RTA_UID]));
  2787		else
  2788			uid = (iif ? INVALID_UID : current_uid());
  2789		if (tb[RTA_SPORT]) {
  2790			err = nla_get_port(tb[RTA_SPORT], &sport);
  2791			if (err)
  2792				goto errout_free;
  2793		}
  2794	
  2795		if (tb[RTA_DPORT]) {
  2796			err = nla_get_port(tb[RTA_DPORT], &dport);
  2797			if (err)
  2798				goto errout_free;
  2799		}
  2800	
  2801		skb->protocol = htons(ETH_P_IP);
  2802		iph = skb_put(skb, sizeof(struct iphdr));
  2803		iph->protocol = IPPROTO_UDP;
  2804		iph->saddr = src;
  2805		iph->daddr = dst;
  2806		iph->version = 0x4;
  2807		iph->frag_off = 0;
  2808	
  2809		if (sport || dport) {
  2810			iph->ihl = 0x5;
  2811			skb_set_transport_header(skb, skb->len);
  2812	
  2813			udph = skb_put(skb, sizeof(struct udphdr));
  2814			udph->dest = dport;
  2815			udph->source = sport;
> 2816			udph->len = sizeof(struct udphdr);
  2817			udph->check = 0;
  2818		}
  2819	
  2820		memset(&fl4, 0, sizeof(fl4));
  2821		fl4.daddr = dst;
  2822		fl4.saddr = src;
  2823		fl4.flowi4_tos = rtm->rtm_tos;
  2824		fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
  2825		fl4.flowi4_mark = mark;
  2826		fl4.flowi4_uid = uid;
  2827		if (sport)
  2828			fl4.fl4_sport = sport;
  2829		if (dport)
  2830			fl4.fl4_dport = dport;
  2831		fl4.flowi4_proto = IPPROTO_UDP;
  2832	
  2833		rcu_read_lock();
  2834	
  2835		if (iif) {
  2836			struct net_device *dev;
  2837	
  2838			dev = dev_get_by_index_rcu(net, iif);
  2839			if (!dev) {
  2840				err = -ENODEV;
  2841				goto errout_rcu;
  2842			}
  2843	
  2844			fl4.flowi4_iif = iif; /* for rt_fill_info */
  2845			skb->protocol	= htons(ETH_P_IP);
  2846			skb->dev	= dev;
  2847			skb->mark	= mark;
  2848			err = ip_route_input_rcu(skb, dst, src, rtm->rtm_tos,
  2849						 dev, &res);
  2850	
  2851			rt = skb_rtable(skb);
  2852			if (err == 0 && rt->dst.error)
  2853				err = -rt->dst.error;
  2854		} else {
  2855			fl4.flowi4_iif = LOOPBACK_IFINDEX;
  2856			rt = ip_route_output_key_hash_rcu(net, &fl4, &res, skb);
  2857			err = 0;
  2858			if (IS_ERR(rt))
  2859				err = PTR_ERR(rt);
  2860			else
  2861				skb_dst_set(skb, &rt->dst);
  2862		}
  2863	
  2864		if (err)
  2865			goto errout_rcu;
  2866	
  2867		if (rtm->rtm_flags & RTM_F_NOTIFY)
  2868			rt->rt_flags |= RTCF_NOTIFY;
  2869	
  2870		if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
  2871			if (!res.fi) {
  2872				err = fib_props[res.type].error;
  2873				if (!err)
  2874					err = -EHOSTUNREACH;
  2875				goto errout_rcu;
  2876			}
  2877		}
  2878	
  2879		err = inet_rtm_getroute_reply(in_skb, nlh, dst, src, &fl4, rt, &res);
  2880		if (err < 0)
  2881			goto errout_rcu;
  2882	
  2883		rcu_read_unlock();
  2884	
  2885	errout_free:
  2886		kfree_skb(skb);
  2887		return err;
  2888	errout_rcu:
  2889		rcu_read_unlock();
  2890		goto errout_free;
  2891	}
  2892	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v2 2/3] ipv6: support sport and dport in RTM_GETROUTE
  2018-05-07  0:59 ` [PATCH net-next v2 2/3] ipv6: " Roopa Prabhu
  2018-05-07  1:46   ` David Ahern
@ 2018-05-07  6:23   ` kbuild test robot
  1 sibling, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2018-05-07  6:23 UTC (permalink / raw)
  To: Roopa Prabhu; +Cc: kbuild-all, davem, netdev, dsa, nikolay, idosch

Hi Roopa,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Roopa-Prabhu/fib-rule-selftest/20180507-094538
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   net/ipv6/route.c:2591:15: sparse: expression using sizeof(void)
   net/ipv6/route.c:1391:15: sparse: expression using sizeof(void)
   net/ipv6/route.c:1590:36: sparse: incorrect type in initializer (different address spaces) @@    expected struct fib6_info *from @@    got struct fib6_info struct fib6_info *from @@
   net/ipv6/route.c:1590:36:    expected struct fib6_info *from
   net/ipv6/route.c:1590:36:    got struct fib6_info [noderef] <asn:4>*from
   net/ipv6/route.c:1968:39: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [unsigned] [usertype] flow_label @@    got gned] [usertype] flow_label @@
   net/ipv6/route.c:1968:39:    expected unsigned int [unsigned] [usertype] flow_label
   net/ipv6/route.c:1968:39:    got restricted __be32
   net/ipv6/route.c:2311:15: sparse: expression using sizeof(void)
>> net/ipv6/route.c:4735:29: sparse: incorrect type in initializer (different base types) @@    expected int [signed] p @@    got restint [signed] p @@
   net/ipv6/route.c:4735:29:    expected int [signed] p
   net/ipv6/route.c:4735:29:    got restricted __be16
>> net/ipv6/route.c:4740:15: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] <noident> @@    got 6 [usertype] <noident> @@
   net/ipv6/route.c:4740:15:    expected restricted __be16 [usertype] <noident>
   net/ipv6/route.c:4740:15:    got int [signed] p
   net/ipv6/route.c:3196:12: sparse: context imbalance in 'ip6_route_del' - wrong count at exit

vim +4735 net/ipv6/route.c

  4732	
  4733	static int nla_get_port(struct nlattr *attr, __be16 *port)
  4734	{
> 4735		int p = nla_get_be16(attr);
  4736	
  4737		if (p <= 0 || p >= 0xffff)
  4738			return -EINVAL;
  4739	
> 4740		*port = p;
  4741		return 0;
  4742	}
  4743	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE
  2018-05-07  1:46   ` David Ahern
@ 2018-05-07 14:42     ` Roopa Prabhu
  0 siblings, 0 replies; 9+ messages in thread
From: Roopa Prabhu @ 2018-05-07 14:42 UTC (permalink / raw)
  To: David Ahern; +Cc: David Miller, netdev, Nikolay Aleksandrov, Ido Schimmel

On Sun, May 6, 2018 at 6:46 PM, David Ahern <dsa@cumulusnetworks.com> wrote:
> On 5/6/18 6:59 PM, Roopa Prabhu wrote:
>> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>
>> This is a followup to fib rules sport, dport match support.
>> Having them supported in getroute makes it easier to test
>> fib rule lookups. Used by fib rule self tests. Before this patch
>> getroute used same skb to pass through the route lookup and
>> for the netlink getroute reply msg. This patch allocates separate
>> skb's to keep flow dissector happy.
>>
>> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>> ---
>>  include/uapi/linux/rtnetlink.h |   2 +
>>  net/ipv4/route.c               | 151 ++++++++++++++++++++++++++++++-----------
>>  2 files changed, 115 insertions(+), 38 deletions(-)
>>
>> diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
>> index 9b15005..630ecf4 100644
>> --- a/include/uapi/linux/rtnetlink.h
>> +++ b/include/uapi/linux/rtnetlink.h
>> @@ -327,6 +327,8 @@ enum rtattr_type_t {
>>       RTA_PAD,
>>       RTA_UID,
>>       RTA_TTL_PROPAGATE,
>> +     RTA_SPORT,
>> +     RTA_DPORT,
>
> If you are going to add sport and dport because of the potential for FIB
> rules, you need to add ip-proto as well. I realize existing code assumed
> UDP, but the FIB rules cover any IP proto. Yes, I know this makes the
> change much larger to generate tcp, udp as well as iphdr options; the
> joys of new features. ;-)


:) sure..like i mentioned in the cover letter..., i was thinking of
submitting follow up patches for more ip_proto.
since i will be spinning v3, let me see if i can include that too.



>
> I also suggest a comment that these new RTA attributes are used for
> GETROUTE only.


sure

>
> And you need to add the new entries to rtm_ipv4_policy.
>
>
>>       __RTA_MAX
>>  };

ack,

>>
>> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
>> index 1412a7b..e91ed62 100644
>> --- a/net/ipv4/route.c
>> +++ b/net/ipv4/route.c
>> @@ -2568,11 +2568,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;
>> @@ -2651,6 +2650,14 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
>>                       from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
>>               goto nla_put_failure;
>>
>> +     if (fl4->fl4_sport &&
>> +         nla_put_be16(skb, RTA_SPORT, fl4->fl4_sport))
>> +             goto nla_put_failure;
>> +
>> +     if (fl4->fl4_dport &&
>> +         nla_put_be16(skb, RTA_DPORT, fl4->fl4_dport))
>> +             goto nla_put_failure;
>
> Why return the attributes to the user? I can't see any value in that.
> UID option is not returned either so there is precedence.

hmm..i do see UID returned just 2 lines above. :)

In the least i think it will confirm that the kernel did see your attributes :).


>
>
>> +
>>       error = rt->dst.error;
>>
>>       if (rt_is_input_route(rt)) {
>> @@ -2668,7 +2675,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;
>>       }
>>
>> @@ -2683,35 +2690,86 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
>>       return -EMSGSIZE;
>>  }
>>
>> +static int nla_get_port(struct nlattr *attr, __be16 *port)
>> +{
>> +     int p = nla_get_be16(attr);
>
> __be16 p;
>
>> +
>> +     if (p <= 0 || p >= 0xffff)
>> +             return -EINVAL;
>
> This check is not needed by definition of be16.

ack, will fix the kbuild sparse warning also for both v4 and v6.


>
>> +
>> +     *port = p;
>> +     return 0;
>> +}
>> +
>> +static int inet_rtm_getroute_reply(struct sk_buff *in_skb, struct nlmsghdr *nlh,
>> +                                __be32 dst, __be32 src, struct flowi4 *fl4,
>> +                                struct rtable *rt, struct fib_result *res)
>> +{
>> +     struct net *net = sock_net(in_skb->sk);
>> +     struct rtmsg *rtm = nlmsg_data(nlh);
>> +     u32 table_id = RT_TABLE_MAIN;
>> +     struct sk_buff *skb;
>> +     int err = 0;
>> +
>> +     skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
>> +     if (!skb) {
>> +             err = -ENOMEM;
>> +             return err;
>> +     }
>
> just 'return -ENOMEM' and without the {}.

yep

>
>
>> +
>> +     if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
>> +             table_id = res->table ? res->table->tb_id : 0;
>> +
>> +     if (rtm->rtm_flags & RTM_F_FIB_MATCH)
>> +             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, rt, table_id,
>> +                                fl4, skb, NETLINK_CB(in_skb).portid,
>> +                                nlh->nlmsg_seq);
>> +     if (err < 0)
>> +             goto errout;
>> +
>> +     return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
>> +
>> +errout:
>> +     kfree_skb(skb);
>> +     return err;
>> +}
>> +
>>  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];
>> +     __be16 sport = 0, dport = 0;
>>       struct fib_result res = {};
>>       struct rtable *rt = NULL;
>> +     struct sk_buff *skb;
>> +     struct rtmsg *rtm;
>>       struct flowi4 fl4;
>> +     struct iphdr *iph;
>> +     struct udphdr *udph;
>>       __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;
>> +             return err;
>
> just return -ENOBUFS
>

yes

>
>>       }
>>
>>       /* Reserve room for dummy headers, this skb can pass
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-05-07 14:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-07  0:59 [PATCH net-next v2 0/3] fib rule selftest Roopa Prabhu
2018-05-07  0:59 ` [PATCH net-next v2 1/3] ipv4: support sport and dport in RTM_GETROUTE Roopa Prabhu
2018-05-07  1:46   ` David Ahern
2018-05-07 14:42     ` Roopa Prabhu
2018-05-07  5:49   ` kbuild test robot
2018-05-07  0:59 ` [PATCH net-next v2 2/3] ipv6: " Roopa Prabhu
2018-05-07  1:46   ` David Ahern
2018-05-07  6:23   ` kbuild test robot
2018-05-07  0:59 ` [PATCH net-next v2 3/3] selftests: net: initial fib rule tests Roopa Prabhu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.