@@ -2067,12 +2067,35 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
2067
2067
}
2068
2068
#endif
2069
2069
2070
+ static bool mpls_rt_uses_dev (struct mpls_route * rt ,
2071
+ const struct net_device * dev )
2072
+ {
2073
+ struct net_device * nh_dev ;
2074
+
2075
+ if (rt -> rt_nhn == 1 ) {
2076
+ struct mpls_nh * nh = rt -> rt_nh ;
2077
+
2078
+ nh_dev = rtnl_dereference (nh -> nh_dev );
2079
+ if (dev == nh_dev )
2080
+ return true;
2081
+ } else {
2082
+ for_nexthops (rt ) {
2083
+ nh_dev = rtnl_dereference (nh -> nh_dev );
2084
+ if (nh_dev == dev )
2085
+ return true;
2086
+ } endfor_nexthops (rt );
2087
+ }
2088
+
2089
+ return false;
2090
+ }
2091
+
2070
2092
static int mpls_dump_routes (struct sk_buff * skb , struct netlink_callback * cb )
2071
2093
{
2072
2094
const struct nlmsghdr * nlh = cb -> nlh ;
2073
2095
struct net * net = sock_net (skb -> sk );
2074
2096
struct mpls_route __rcu * * platform_label ;
2075
2097
struct fib_dump_filter filter = {};
2098
+ unsigned int flags = NLM_F_MULTI ;
2076
2099
size_t platform_labels ;
2077
2100
unsigned int index ;
2078
2101
@@ -2084,6 +2107,14 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
2084
2107
err = mpls_valid_fib_dump_req (net , nlh , & filter , cb -> extack );
2085
2108
if (err < 0 )
2086
2109
return err ;
2110
+
2111
+ /* for MPLS, there is only 1 table with fixed type and flags.
2112
+ * If either are set in the filter then return nothing.
2113
+ */
2114
+ if ((filter .table_id && filter .table_id != RT_TABLE_MAIN ) ||
2115
+ (filter .rt_type && filter .rt_type != RTN_UNICAST ) ||
2116
+ filter .flags )
2117
+ return skb -> len ;
2087
2118
}
2088
2119
2089
2120
index = cb -> args [0 ];
@@ -2092,15 +2123,24 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
2092
2123
2093
2124
platform_label = rtnl_dereference (net -> mpls .platform_label );
2094
2125
platform_labels = net -> mpls .platform_labels ;
2126
+
2127
+ if (filter .filter_set )
2128
+ flags |= NLM_F_DUMP_FILTERED ;
2129
+
2095
2130
for (; index < platform_labels ; index ++ ) {
2096
2131
struct mpls_route * rt ;
2132
+
2097
2133
rt = rtnl_dereference (platform_label [index ]);
2098
2134
if (!rt )
2099
2135
continue ;
2100
2136
2137
+ if ((filter .dev && !mpls_rt_uses_dev (rt , filter .dev )) ||
2138
+ (filter .protocol && rt -> rt_protocol != filter .protocol ))
2139
+ continue ;
2140
+
2101
2141
if (mpls_dump_route (skb , NETLINK_CB (cb -> skb ).portid ,
2102
2142
cb -> nlh -> nlmsg_seq , RTM_NEWROUTE ,
2103
- index , rt , NLM_F_MULTI ) < 0 )
2143
+ index , rt , flags ) < 0 )
2104
2144
break ;
2105
2145
}
2106
2146
cb -> args [0 ] = index ;
0 commit comments