From patchwork Mon Apr 16 20:41:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roopa Prabhu X-Patchwork-Id: 898930 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="WhJ19tbq"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40Q0fm1hl2z9s0R for ; Tue, 17 Apr 2018 06:41:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751857AbeDPUlt (ORCPT ); Mon, 16 Apr 2018 16:41:49 -0400 Received: from mail-pl0-f68.google.com ([209.85.160.68]:35559 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751210AbeDPUlq (ORCPT ); Mon, 16 Apr 2018 16:41:46 -0400 Received: by mail-pl0-f68.google.com with SMTP id 61-v6so10691764plb.2 for ; Mon, 16 Apr 2018 13:41:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QE9GVmoOeirJowFgkEYqoj60nLGcqtF+tL0lr7FPx7g=; b=WhJ19tbqc3E1cXmo2p1ymCNvWfzVxCt32kLMapeXf90RUCpc2RuoQeZiQrZvVkA3O5 giS9BGE9lPbGr3RXLWgHSMlCA03tWaHIVeF6T8/wUYUZ5ZONysHjnWTl0eGFvYcH+A1G 33nlCafriNuFIX6lcxIeHYMqtX1U051cL3/EQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QE9GVmoOeirJowFgkEYqoj60nLGcqtF+tL0lr7FPx7g=; b=AbmTWhSFcH+P7GhSHh4CB8DD0zpC9C8aZcjLsnpXpIXr6oLuRh33DUSQ8xqvoI5zk6 bcNv+p1+ZHlNnO6ENGX37bMQZCmzzBjPTgvynCi8K66drvRe/EwF/g91lXYXQgvxVITi w2MG5cIaOGoMNYLXJ5Vut4ec0HRObY9XcK77eQ1eaCeCdHPRU9WnS6M8W5FyMbjARn/I 2aLSVbCM4jpReawdBPfiAFMtM+G3do9jA94cyBv/DGh4EOBZkz7C7kocH+h9/0BftbaM JL5M9i8zpPbDdz/+iAbweaM+ufAlreKsHESn0+WqcY4zlY2eFqW47G3yOD3nUUi59Q+8 /GMQ== X-Gm-Message-State: ALQs6tAzav7WcI/QgudbSCwwm9VPgtIuQ5xOVSeWUSn9DDaBbpON0dDj ZDjf6FhcTJ4rpT6XXhEH1DCJEw== X-Google-Smtp-Source: AIpwx48aa06SW8vdmlLu+Jc56HKFYbxCGIpS4fsJ4FpeK1ak/19bv3mzZQHADE/gguLvKL2hD4UUnA== X-Received: by 2002:a17:902:6709:: with SMTP id f9-v6mr16599621plk.159.1523911306188; Mon, 16 Apr 2018 13:41:46 -0700 (PDT) Received: from monster-08.mvlab.cumulusnetworks.com. (fw.cumulusnetworks.com. [216.129.126.126]) by smtp.googlemail.com with ESMTPSA id v186sm24030774pfb.182.2018.04.16.13.41.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Apr 2018 13:41:45 -0700 (PDT) From: Roopa Prabhu X-Google-Original-From: Roopa Prabhu To: davem@davemloft.net Cc: netdev@vger.kernel.org, dsa@cumulusnetworks.com Subject: [PATCH net-next 3/5] ipv4: support sport, dport and ip protocol in RTM_GETROUTE Date: Mon, 16 Apr 2018 13:41:36 -0700 Message-Id: <1523911298-8965-4-git-send-email-roopa@cumulusnetworks.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1523911298-8965-1-git-send-email-roopa@cumulusnetworks.com> References: <1523911298-8965-1-git-send-email-roopa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Roopa Prabhu 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 --- 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)