diff options
author | David Ahern <dsahern@gmail.com> | 2018-10-15 21:56:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-16 03:14:07 -0400 |
commit | 196cfebf897266c3450519e916bab9daff74e52c (patch) | |
tree | 4efb78b202de30dbe119268bf8464fbbcd689822 /net/mpls | |
parent | effe6792662495ad9c175bf0d9c53459a51fdbbd (diff) |
net/mpls: Handle kernel side filtering of route dumps
Update the dump request parsing in MPLS for the non-INET case to
enable kernel side filtering. If INET is disabled the only filters
that make sense for MPLS are protocol and nexthop device.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls')
-rw-r--r-- | net/mpls/af_mpls.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 24381696932a..7d55d4c04088 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -2044,7 +2044,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh, | |||
2044 | struct netlink_callback *cb) | 2044 | struct netlink_callback *cb) |
2045 | { | 2045 | { |
2046 | struct netlink_ext_ack *extack = cb->extack; | 2046 | struct netlink_ext_ack *extack = cb->extack; |
2047 | struct nlattr *tb[RTA_MAX + 1]; | ||
2047 | struct rtmsg *rtm; | 2048 | struct rtmsg *rtm; |
2049 | int err, i; | ||
2048 | 2050 | ||
2049 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*rtm))) { | 2051 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*rtm))) { |
2050 | NL_SET_ERR_MSG_MOD(extack, "Invalid header for FIB dump request"); | 2052 | NL_SET_ERR_MSG_MOD(extack, "Invalid header for FIB dump request"); |
@@ -2053,15 +2055,36 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh, | |||
2053 | 2055 | ||
2054 | rtm = nlmsg_data(nlh); | 2056 | rtm = nlmsg_data(nlh); |
2055 | if (rtm->rtm_dst_len || rtm->rtm_src_len || rtm->rtm_tos || | 2057 | if (rtm->rtm_dst_len || rtm->rtm_src_len || rtm->rtm_tos || |
2056 | rtm->rtm_table || rtm->rtm_protocol || rtm->rtm_scope || | 2058 | rtm->rtm_table || rtm->rtm_scope || rtm->rtm_type || |
2057 | rtm->rtm_type || rtm->rtm_flags) { | 2059 | rtm->rtm_flags) { |
2058 | NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for FIB dump request"); | 2060 | NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for FIB dump request"); |
2059 | return -EINVAL; | 2061 | return -EINVAL; |
2060 | } | 2062 | } |
2061 | 2063 | ||
2062 | if (nlmsg_attrlen(nlh, sizeof(*rtm))) { | 2064 | if (rtm->rtm_protocol) { |
2063 | NL_SET_ERR_MSG_MOD(extack, "Invalid data after header in FIB dump request"); | 2065 | filter->protocol = rtm->rtm_protocol; |
2064 | return -EINVAL; | 2066 | filter->filter_set = 1; |
2067 | cb->answer_flags = NLM_F_DUMP_FILTERED; | ||
2068 | } | ||
2069 | |||
2070 | err = nlmsg_parse_strict(nlh, sizeof(*rtm), tb, RTA_MAX, | ||
2071 | rtm_mpls_policy, extack); | ||
2072 | if (err < 0) | ||
2073 | return err; | ||
2074 | |||
2075 | for (i = 0; i <= RTA_MAX; ++i) { | ||
2076 | int ifindex; | ||
2077 | |||
2078 | if (i == RTA_OIF) { | ||
2079 | ifindex = nla_get_u32(tb[i]); | ||
2080 | filter->dev = __dev_get_by_index(net, ifindex); | ||
2081 | if (!filter->dev) | ||
2082 | return -ENODEV; | ||
2083 | filter->filter_set = 1; | ||
2084 | } else if (tb[i]) { | ||
2085 | NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in dump request"); | ||
2086 | return -EINVAL; | ||
2087 | } | ||
2065 | } | 2088 | } |
2066 | 2089 | ||
2067 | return 0; | 2090 | return 0; |