u32                     pref;
        u32                     flags;
        u32                     table;
+       u8                      table_prefixlen_min;
        u8                      action;
        u32                     target;
        struct fib_rule __rcu   *ctarget;
        int                     (*action)(struct fib_rule *,
                                          struct flowi *, int,
                                          struct fib_lookup_arg *);
+       bool                    (*suppress)(struct fib_rule *,
+                                           struct fib_lookup_arg *);
        int                     (*match)(struct fib_rule *,
                                         struct flowi *, int);
        int                     (*configure)(struct fib_rule *,
        [FRA_FWMARK]    = { .type = NLA_U32 }, \
        [FRA_FWMASK]    = { .type = NLA_U32 }, \
        [FRA_TABLE]     = { .type = NLA_U32 }, \
+       [FRA_TABLE_PREFIXLEN_MIN] = { .type = NLA_U8 }, \
        [FRA_GOTO]      = { .type = NLA_U32 }
 
 static inline void fib_rule_get(struct fib_rule *rule)
 
        FRA_FLOW,       /* flow/class id */
        FRA_UNUSED6,
        FRA_UNUSED7,
-       FRA_UNUSED8,
+       FRA_TABLE_PREFIXLEN_MIN,
        FRA_TABLE,      /* Extended table id */
        FRA_FWMASK,     /* mask for netfilter mark */
        FRA_OIFNAME,
 
                else
                        err = ops->action(rule, fl, flags, arg);
 
+               if (!err && ops->suppress && ops->suppress(rule, arg))
+                       continue;
+
                if (err != -EAGAIN) {
                        if ((arg->flags & FIB_LOOKUP_NOREF) ||
                            likely(atomic_inc_not_zero(&rule->refcnt))) {
        rule->action = frh->action;
        rule->flags = frh->flags;
        rule->table = frh_get_table(frh, tb);
+       if (tb[FRA_TABLE_PREFIXLEN_MIN])
+               rule->table_prefixlen_min = nla_get_u8(tb[FRA_TABLE_PREFIXLEN_MIN]);
 
        if (!tb[FRA_PRIORITY] && ops->default_pref)
                rule->pref = ops->default_pref(ops);
                         + nla_total_size(IFNAMSIZ) /* FRA_OIFNAME */
                         + nla_total_size(4) /* FRA_PRIORITY */
                         + nla_total_size(4) /* FRA_TABLE */
+                        + nla_total_size(1) /* FRA_TABLE_PREFIXLEN_MIN */
                         + nla_total_size(4) /* FRA_FWMARK */
                         + nla_total_size(4); /* FRA_FWMASK */
 
        frh->table = rule->table;
        if (nla_put_u32(skb, FRA_TABLE, rule->table))
                goto nla_put_failure;
+       if (nla_put_u8(skb, FRA_TABLE_PREFIXLEN_MIN, rule->table_prefixlen_min))
+               goto nla_put_failure;
        frh->res1 = 0;
        frh->res2 = 0;
        frh->action = rule->action;
 
        return err;
 }
 
+static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
+{
+       /* do not accept result if the route does
+        * not meet the required prefix length
+        */
+       struct fib_result *result = (struct fib_result *) arg->result;
+       if (result->prefixlen < rule->table_prefixlen_min) {
+               if (!(arg->flags & FIB_LOOKUP_NOREF))
+                       fib_info_put(result->fi);
+               return true;
+       }
+       return false;
+}
 
 static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
        .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,
 
        return rt == NULL ? -EAGAIN : 0;
 }
 
+static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
+{
+       struct rt6_info *rt = (struct rt6_info *) arg->result;
+       /* do not accept result if the route does
+        * not meet the required prefix length
+        */
+       if (rt->rt6i_dst.plen < rule->table_prefixlen_min) {
+               ip6_rt_put(rt);
+               return true;
+       }
+       return false;
+}
 
 static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
        .addr_size              = sizeof(struct in6_addr),
        .action                 = fib6_rule_action,
        .match                  = fib6_rule_match,
+       .suppress               = fib6_rule_suppress,
        .configure              = fib6_rule_configure,
        .compare                = fib6_rule_compare,
        .fill                   = fib6_rule_fill,