[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1523911298-8965-4-git-send-email-roopa@cumulusnetworks.com>
Date: Mon, 16 Apr 2018 13:41:36 -0700
From: Roopa Prabhu <roopa@...ulusnetworks.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, dsa@...ulusnetworks.com
Subject: [PATCH net-next 3/5] ipv4: support sport, dport and ip protocol in RTM_GETROUTE
From: Roopa Prabhu <roopa@...ulusnetworks.com>
This is a followup to fib rules sport, dport and ip proto
match support. Having them supported in getroute
makes it easier to test fib rule lookups. Used by fib rule
self tests.
Signed-off-by: Roopa Prabhu <roopa@...ulusnetworks.com>
---
include/uapi/linux/rtnetlink.h | 3 ++
net/ipv4/route.c | 75 +++++++++++++++++++++++++++++++++---------
2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 9b15005..7947252 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -327,6 +327,9 @@ enum rtattr_type_t {
RTA_PAD,
RTA_UID,
RTA_TTL_PROPAGATE,
+ RTA_SPORT,
+ RTA_DPORT,
+ RTA_IP_PROTO,
__RTA_MAX
};
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ccb25d8..ae55711 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2663,6 +2663,18 @@ 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_u16(skb, RTA_SPORT, ntohs(fl4->fl4_sport)))
+ goto nla_put_failure;
+
+ if (fl4->fl4_dport &&
+ nla_put_u16(skb, RTA_DPORT, ntohs(fl4->fl4_dport)))
+ goto nla_put_failure;
+
+ if (fl4->flowi4_proto &&
+ nla_put_u8(skb, RTA_IP_PROTO, fl4->flowi4_proto))
+ goto nla_put_failure;
+
error = rt->dst.error;
if (rt_is_input_route(rt)) {
@@ -2695,35 +2707,48 @@ 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_u16(attr);
+
+ if (p <= 0 || p >= 0xffff)
+ return -EINVAL;
+
+ *port = htons(p);
+ return 0;
+}
+
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 = {};
struct rtable *rt = NULL;
+ struct sk_buff *skb;
+ struct rtmsg *rtm;
struct flowi4 fl4;
+ u8 ip_proto = 0;
__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
@@ -2740,6 +2765,20 @@ 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;
+ }
+
+ if (tb[RTA_DPORT]) {
+ err = nla_get_port(tb[RTA_DPORT], &dport);
+ if (err)
+ goto errout_free;
+ }
+
+ if (tb[RTA_IP_PROTO])
+ ip_proto = nla_get_u8(tb[RTA_IP_PROTO]);
/* Bugfix: need to give ip_route_input enough of an IP header to
* not gag.
@@ -2757,6 +2796,12 @@ 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;
+ if (ip_proto)
+ fl4.flowi4_proto = ip_proto;
rcu_read_lock();
@@ -2766,7 +2811,7 @@ 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);
@@ -2789,7 +2834,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;
@@ -2802,7 +2847,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
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,
@@ -2813,18 +2858,18 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
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;
+ return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
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
Powered by blists - more mailing lists