int                     dst_len;
        u8                      tos;
        u8                      type;
+       u8                      offload:1,
+                               trap:1,
+                               unused:6;
 };
 
 struct fib_entry_notifier_info {
 void fib_nh_common_release(struct fib_nh_common *nhc);
 
 /* Exported by fib_trie.c */
+void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri);
 void fib_trie_init(void);
 struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
 
 
 #define RTM_F_PREFIX           0x800   /* Prefix addresses             */
 #define RTM_F_LOOKUP_TABLE     0x1000  /* set rtm_table to FIB lookup result */
 #define RTM_F_FIB_MATCH                0x2000  /* return full fib lookup match */
+#define RTM_F_OFFLOAD          0x4000  /* route is offloaded */
+#define RTM_F_TRAP             0x8000  /* route is trapping packets */
 
 /* Reserved table identifiers */
 
 
        fri.dst_len = dst_len;
        fri.tos = fa->fa_tos;
        fri.type = fa->fa_type;
+       fri.offload = fa->offload;
+       fri.trap = fa->trap;
        err = fib_dump_info(skb, info->portid, seq, event, &fri, nlm_flags);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
                        goto nla_put_failure;
        }
 
+       if (fri->offload)
+               rtm->rtm_flags |= RTM_F_OFFLOAD;
+       if (fri->trap)
+               rtm->rtm_flags |= RTM_F_TRAP;
+
        nlmsg_end(skb, nlh);
        return 0;
 
 
        return NULL;
 }
 
+static struct fib_alias *
+fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri)
+{
+       u8 slen = KEYLENGTH - fri->dst_len;
+       struct key_vector *l, *tp;
+       struct fib_table *tb;
+       struct fib_alias *fa;
+       struct trie *t;
+
+       tb = fib_get_table(net, fri->tb_id);
+       if (!tb)
+               return NULL;
+
+       t = (struct trie *)tb->tb_data;
+       l = fib_find_node(t, &tp, be32_to_cpu(fri->dst));
+       if (!l)
+               return NULL;
+
+       hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) {
+               if (fa->fa_slen == slen && fa->tb_id == fri->tb_id &&
+                   fa->fa_tos == fri->tos && fa->fa_info == fri->fi &&
+                   fa->fa_type == fri->type)
+                       return fa;
+       }
+
+       return NULL;
+}
+
+void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
+{
+       struct fib_alias *fa_match;
+
+       rcu_read_lock();
+
+       fa_match = fib_find_matching_alias(net, fri);
+       if (!fa_match)
+               goto out;
+
+       fa_match->offload = fri->offload;
+       fa_match->trap = fri->trap;
+
+out:
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(fib_alias_hw_flags_set);
+
 static void trie_rebalance(struct trie *t, struct key_vector *tn)
 {
        while (!IS_TRIE(tn))
                        new_fa->fa_slen = fa->fa_slen;
                        new_fa->tb_id = tb->tb_id;
                        new_fa->fa_default = -1;
+                       new_fa->offload = 0;
+                       new_fa->trap = 0;
 
                        hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list);
 
        new_fa->fa_slen = slen;
        new_fa->tb_id = tb->tb_id;
        new_fa->fa_default = -1;
+       new_fa->offload = 0;
+       new_fa->trap = 0;
 
        /* Insert new entry to the list. */
        err = fib_insert_alias(t, tp, l, new_fa, fa, key);
                                fri.dst_len = KEYLENGTH - fa->fa_slen;
                                fri.tos = fa->fa_tos;
                                fri.type = fa->fa_type;
+                               fri.offload = fa->offload;
+                               fri.trap = fa->trap;
                                err = fib_dump_info(skb,
                                                    NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
 
                fri.dst_len = res.prefixlen;
                fri.tos = fl4.flowi4_tos;
                fri.type = rt->rt_type;
+               fri.offload = 0;
+               fri.trap = 0;
+               if (res.fa_head) {
+                       struct fib_alias *fa;
+
+                       hlist_for_each_entry_rcu(fa, res.fa_head, fa_list) {
+                               u8 slen = 32 - fri.dst_len;
+
+                               if (fa->fa_slen == slen &&
+                                   fa->tb_id == fri.tb_id &&
+                                   fa->fa_tos == fri.tos &&
+                                   fa->fa_info == res.fi &&
+                                   fa->fa_type == fri.type) {
+                                       fri.offload = fa->offload;
+                                       fri.trap = fa->trap;
+                                       break;
+                               }
+                       }
+               }
                err = fib_dump_info(skb, NETLINK_CB(in_skb).portid,
                                    nlh->nlmsg_seq, RTM_NEWROUTE, &fri, 0);
        } else {