Skip to content

Commit 18a8021

Browse files
dsaherndavem330
authored andcommitted
net/ipv4: Plumb support for filtering route dumps
Implement kernel side filtering of routes by table id, egress device index, protocol and route type. If the table id is given in the filter, lookup the table and call fib_table_dump directly for it. Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4724676 commit 18a8021

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

include/net/ip_fib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ int fib_table_insert(struct net *, struct fib_table *, struct fib_config *,
239239
int fib_table_delete(struct net *, struct fib_table *, struct fib_config *,
240240
struct netlink_ext_ack *extack);
241241
int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
242-
struct netlink_callback *cb);
242+
struct netlink_callback *cb, struct fib_dump_filter *filter);
243243
int fib_table_flush(struct net *net, struct fib_table *table);
244244
struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
245245
void fib_table_flush_external(struct fib_table *table);

net/ipv4/fib_frontend.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,17 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
855855
((struct rtmsg *)nlmsg_data(nlh))->rtm_flags & RTM_F_CLONED)
856856
return skb->len;
857857

858+
if (filter.table_id) {
859+
tb = fib_get_table(net, filter.table_id);
860+
if (!tb) {
861+
NL_SET_ERR_MSG(cb->extack, "ipv4: FIB table does not exist");
862+
return -ENOENT;
863+
}
864+
865+
err = fib_table_dump(tb, skb, cb, &filter);
866+
return skb->len ? : err;
867+
}
868+
858869
s_h = cb->args[0];
859870
s_e = cb->args[1];
860871

@@ -869,7 +880,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
869880
if (dumped)
870881
memset(&cb->args[2], 0, sizeof(cb->args) -
871882
2 * sizeof(cb->args[0]));
872-
err = fib_table_dump(tb, skb, cb);
883+
err = fib_table_dump(tb, skb, cb, &filter);
873884
if (err < 0) {
874885
if (likely(skb->len))
875886
goto out;

net/ipv4/fib_trie.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,38 +2003,53 @@ void fib_free_table(struct fib_table *tb)
20032003
}
20042004

20052005
static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
2006-
struct sk_buff *skb, struct netlink_callback *cb)
2006+
struct sk_buff *skb, struct netlink_callback *cb,
2007+
struct fib_dump_filter *filter)
20072008
{
2009+
unsigned int flags = NLM_F_MULTI;
20082010
__be32 xkey = htonl(l->key);
20092011
struct fib_alias *fa;
20102012
int i, s_i;
20112013

2014+
if (filter->filter_set)
2015+
flags |= NLM_F_DUMP_FILTERED;
2016+
20122017
s_i = cb->args[4];
20132018
i = 0;
20142019

20152020
/* rcu_read_lock is hold by caller */
20162021
hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) {
20172022
int err;
20182023

2019-
if (i < s_i) {
2020-
i++;
2021-
continue;
2022-
}
2024+
if (i < s_i)
2025+
goto next;
20232026

2024-
if (tb->tb_id != fa->tb_id) {
2025-
i++;
2026-
continue;
2027+
if (tb->tb_id != fa->tb_id)
2028+
goto next;
2029+
2030+
if (filter->filter_set) {
2031+
if (filter->rt_type && fa->fa_type != filter->rt_type)
2032+
goto next;
2033+
2034+
if ((filter->protocol &&
2035+
fa->fa_info->fib_protocol != filter->protocol))
2036+
goto next;
2037+
2038+
if (filter->dev &&
2039+
!fib_info_nh_uses_dev(fa->fa_info, filter->dev))
2040+
goto next;
20272041
}
20282042

20292043
err = fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
20302044
cb->nlh->nlmsg_seq, RTM_NEWROUTE,
20312045
tb->tb_id, fa->fa_type,
20322046
xkey, KEYLENGTH - fa->fa_slen,
2033-
fa->fa_tos, fa->fa_info, NLM_F_MULTI);
2047+
fa->fa_tos, fa->fa_info, flags);
20342048
if (err < 0) {
20352049
cb->args[4] = i;
20362050
return err;
20372051
}
2052+
next:
20382053
i++;
20392054
}
20402055

@@ -2044,7 +2059,7 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
20442059

20452060
/* rcu_read_lock needs to be hold by caller from readside */
20462061
int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
2047-
struct netlink_callback *cb)
2062+
struct netlink_callback *cb, struct fib_dump_filter *filter)
20482063
{
20492064
struct trie *t = (struct trie *)tb->tb_data;
20502065
struct key_vector *l, *tp = t->kv;
@@ -2057,7 +2072,7 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
20572072
while ((l = leaf_walk_rcu(&tp, key)) != NULL) {
20582073
int err;
20592074

2060-
err = fn_trie_dump_leaf(l, tb, skb, cb);
2075+
err = fn_trie_dump_leaf(l, tb, skb, cb, filter);
20612076
if (err < 0) {
20622077
cb->args[3] = key;
20632078
cb->args[2] = count;

0 commit comments

Comments
 (0)