diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index bd07484ab9dd..d15e5638b937 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -69,8 +69,6 @@ struct fib_rules_ops {
 	int			(*action)(struct fib_rule *,
 					  struct flowi *, int,
 					  struct fib_lookup_arg *);
-	bool			(*suppress)(struct fib_rule *, int,
-					    struct fib_lookup_arg *);
 	int			(*match)(struct fib_rule *,
 					 struct flowi *, int);
 	int			(*configure)(struct fib_rule *,
@@ -216,11 +214,4 @@ INDIRECT_CALLABLE_DECLARE(int fib6_rule_action(struct fib_rule *rule,
 INDIRECT_CALLABLE_DECLARE(int fib4_rule_action(struct fib_rule *rule,
 			    struct flowi *flp, int flags,
 			    struct fib_lookup_arg *arg));
-
-INDIRECT_CALLABLE_DECLARE(bool fib6_rule_suppress(struct fib_rule *rule,
-						int flags,
-						struct fib_lookup_arg *arg));
-INDIRECT_CALLABLE_DECLARE(bool fib4_rule_suppress(struct fib_rule *rule,
-						int flags,
-						struct fib_lookup_arg *arg));
 #endif
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 1bb567a3b329..52e67f8aa0c5 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -11,9 +11,11 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <net/net_namespace.h>
+#include <net/nexthop.h>
 #include <net/sock.h>
 #include <net/fib_rules.h>
 #include <net/ip_tunnels.h>
+#include <net/ip6_route.h>
 #include <linux/indirect_call_wrapper.h>
 
 #if defined(CONFIG_IPV6) && defined(CONFIG_IPV6_MULTIPLE_TABLES)
@@ -289,6 +291,87 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
 	return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
 }
 
+static bool fib4_rule_suppress(struct fib_rule *rule,
+			       int flags,
+			       struct fib_lookup_arg *arg)
+{
+	struct fib_result *result = (struct fib_result *)arg->result;
+	struct net_device *dev = NULL;
+
+	if (result->fi) {
+		struct fib_nh_common *nhc = fib_info_nhc(result->fi, 0);
+
+		dev = nhc->nhc_dev;
+	}
+
+	/* do not accept result if the route does
+	 * not meet the required prefix length
+	 */
+	if (result->prefixlen <= rule->suppress_prefixlen)
+		goto suppress_route;
+
+	/* do not accept result if the route uses a device
+	 * belonging to a forbidden interface group
+	 */
+	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
+		goto suppress_route;
+
+	return false;
+
+suppress_route:
+	if (!(arg->flags & FIB_LOOKUP_NOREF))
+		fib_info_put(result->fi);
+	return true;
+}
+
+static bool fib6_rule_suppress(struct fib_rule *rule,
+			       int flags,
+			       struct fib_lookup_arg *arg)
+{
+	struct fib6_result *res = arg->result;
+	struct rt6_info *rt = res->rt6;
+	struct net_device *dev = NULL;
+
+	if (!rt)
+		return false;
+
+	if (rt->rt6i_idev)
+		dev = rt->rt6i_idev->dev;
+
+	/* do not accept result if the route does
+	 * not meet the required prefix length
+	 */
+	if (rt->rt6i_dst.plen <= rule->suppress_prefixlen)
+		goto suppress_route;
+
+	/* do not accept result if the route uses a device
+	 * belonging to a forbidden interface group
+	 */
+	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
+		goto suppress_route;
+
+	return false;
+
+suppress_route:
+	ip6_rt_put_flags(rt, flags);
+	return true;
+}
+
+static bool fib_rule_suppress(int family,
+			      struct fib_rule *rule,
+			      int flags,
+			      struct fib_lookup_arg *arg)
+{
+	switch (family) {
+	case AF_INET:
+		return fib4_rule_suppress(rule, flags, arg);
+	case AF_INET6:
+		return fib6_rule_suppress(rule, flags, arg);
+	}
+
+	return false;
+}
+
 int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
 		     int flags, struct fib_lookup_arg *arg)
 {
@@ -320,10 +403,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
 					       fib4_rule_action,
 					       rule, fl, flags, arg);
 
-		if (!err && ops->suppress && INDIRECT_CALL_MT(ops->suppress,
-							      fib6_rule_suppress,
-							      fib4_rule_suppress,
-							      rule, flags, arg))
+		if (!err && fib_rule_suppress(ops->family, rule, flags, arg))
 			continue;
 
 		if (err != -EAGAIN) {
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index d279cb8ac158..560702a9bed4 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -140,39 +140,6 @@ INDIRECT_CALLABLE_SCOPE int fib4_rule_action(struct fib_rule *rule,
 	return err;
 }
 
-INDIRECT_CALLABLE_SCOPE bool fib4_rule_suppress(struct fib_rule *rule,
-						int flags,
-						struct fib_lookup_arg *arg)
-{
-	struct fib_result *result = (struct fib_result *) arg->result;
-	struct net_device *dev = NULL;
-
-	if (result->fi) {
-		struct fib_nh_common *nhc = fib_info_nhc(result->fi, 0);
-
-		dev = nhc->nhc_dev;
-	}
-
-	/* do not accept result if the route does
-	 * not meet the required prefix length
-	 */
-	if (result->prefixlen <= rule->suppress_prefixlen)
-		goto suppress_route;
-
-	/* do not accept result if the route uses a device
-	 * belonging to a forbidden interface group
-	 */
-	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
-		goto suppress_route;
-
-	return false;
-
-suppress_route:
-	if (!(arg->flags & FIB_LOOKUP_NOREF))
-		fib_info_put(result->fi);
-	return true;
-}
-
 INDIRECT_CALLABLE_SCOPE int fib4_rule_match(struct fib_rule *rule,
 					    struct flowi *fl, int flags)
 {
@@ -377,7 +344,6 @@ static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = {
 	.rule_size	= sizeof(struct fib4_rule),
 	.addr_size	= sizeof(u32),
 	.action		= fib4_rule_action,
-	.suppress	= fib4_rule_suppress,
 	.match		= fib4_rule_match,
 	.configure	= fib4_rule_configure,
 	.delete		= fib4_rule_delete,
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index dcedfe29d9d9..6b6718844fee 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -266,39 +266,6 @@ INDIRECT_CALLABLE_SCOPE int fib6_rule_action(struct fib_rule *rule,
 	return __fib6_rule_action(rule, flp, flags, arg);
 }
 
-INDIRECT_CALLABLE_SCOPE bool fib6_rule_suppress(struct fib_rule *rule,
-						int flags,
-						struct fib_lookup_arg *arg)
-{
-	struct fib6_result *res = arg->result;
-	struct rt6_info *rt = res->rt6;
-	struct net_device *dev = NULL;
-
-	if (!rt)
-		return false;
-
-	if (rt->rt6i_idev)
-		dev = rt->rt6i_idev->dev;
-
-	/* do not accept result if the route does
-	 * not meet the required prefix length
-	 */
-	if (rt->rt6i_dst.plen <= rule->suppress_prefixlen)
-		goto suppress_route;
-
-	/* do not accept result if the route uses a device
-	 * belonging to a forbidden interface group
-	 */
-	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
-		goto suppress_route;
-
-	return false;
-
-suppress_route:
-	ip6_rt_put_flags(rt, flags);
-	return true;
-}
-
 INDIRECT_CALLABLE_SCOPE int fib6_rule_match(struct fib_rule *rule,
 					    struct flowi *fl, int flags)
 {
@@ -452,7 +419,6 @@ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
 	.addr_size		= sizeof(struct in6_addr),
 	.action			= fib6_rule_action,
 	.match			= fib6_rule_match,
-	.suppress		= fib6_rule_suppress,
 	.configure		= fib6_rule_configure,
 	.delete			= fib6_rule_delete,
 	.compare		= fib6_rule_compare,
