Introduce 'rde rib Loc-RIB include filtered' a feature that includes
authorclaudio <claudio@openbsd.org>
Wed, 14 Aug 2024 19:09:51 +0000 (19:09 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 14 Aug 2024 19:09:51 +0000 (19:09 +0000)
filtered prefixes in the Loc-RIB

This includes filtered prefixes into the Loc-RIB but they are marked
ineligible so nothing will select them but it is possible to show them
in bgpctl. So 'bppctl show rib filtered' will return all prefixes filtered
out by the input filters.

OK tb@

usr.sbin/bgpd/bgpd.conf.5
usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/config.c
usr.sbin/bgpd/parse.y
usr.sbin/bgpd/printconf.c
usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde.h
usr.sbin/bgpd/rde_decide.c
usr.sbin/bgpd/rde_rib.c

index e01abf8..d4b3fb7 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.241 2024/08/12 09:04:23 claudio Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.242 2024/08/14 19:09:51 claudio Exp $
 .\"
 .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
 .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,7 +16,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 12 2024 $
+.Dd $Mdocdate: August 14 2024 $
 .Dt BGPD.CONF 5
 .Os
 .Sh NAME
@@ -325,6 +325,13 @@ and
 .Ic Loc-RIB ,
 which are created automatically and used by default.
 .Pp
+.It Ic rde rib Loc-RIB include filtered
+Include filtered prefixes in the
+.Ic Loc-RIB .
+Filtered prefixes are not eligible by the decision process but can be
+displayed by
+.Xr bgpctl 8 .
+.Pp
 .It Xo
 .Ic rde
 .Ic route-age
index a4d2a10..78e245b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.494 2024/08/12 09:04:23 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.495 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
 #define        F_CTL_AVS_VALID         0x1000000
 #define        F_CTL_AVS_INVALID       0x2000000
 #define        F_CTL_AVS_UNKNOWN       0x4000000
+#define        F_CTL_FILTERED          0x8000000       /* only set on requests */
 #define        F_CTL_SSV               0x80000000      /* only used by bgpctl */
 
 #define CTASSERT(x)    extern char  _ctassert[(x) ? 1 : -1 ] \
@@ -317,6 +318,7 @@ struct bgpd_config {
        uint16_t                                 min_holdtime;
        uint16_t                                 connectretry;
        uint8_t                                  fib_priority;
+       uint8_t                                  filtered_in_locrib;
 };
 
 extern int cmd_opts;
@@ -888,6 +890,7 @@ struct ctl_neighbor {
 #define        F_PREF_OTC_LEAK 0x080
 #define        F_PREF_ECMP     0x100
 #define        F_PREF_AS_WIDE  0x200
+#define        F_PREF_FILTERED 0x400
 
 struct ctl_show_rib {
        struct bgpd_addr        true_nexthop;
index 7894319..bf93a52 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.109 2024/05/22 08:41:14 claudio Exp $ */
+/*     $OpenBSD: config.c,v 1.110 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -87,6 +87,7 @@ copy_config(struct bgpd_config *to, struct bgpd_config *from)
        to->min_holdtime = from->min_holdtime;
        to->connectretry = from->connectretry;
        to->fib_priority = from->fib_priority;
+       to->filtered_in_locrib = from->filtered_in_locrib;
 }
 
 void
index bffd409..1621c8a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.464 2024/08/12 09:04:23 claudio Exp $ */
+/*     $OpenBSD: parse.y,v 1.465 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -250,7 +250,7 @@ typedef struct {
 %token SEND RECV PLUS POLICY ROLE
 %token DEMOTE ENFORCE NEIGHBORAS ASOVERRIDE REFLECTOR DEPEND DOWN
 %token DUMP IN OUT SOCKET RESTRICTED
-%token LOG TRANSPARENT
+%token LOG TRANSPARENT FILTERED
 %token TCP MD5SIG PASSWORD KEY TTLSECURITY
 %token ALLOW DENY MATCH
 %token QUICK
@@ -941,6 +941,14 @@ conf_main  : AS as4number          {
                        }
                        free($3);
                }
+               | RDE RIB STRING INCLUDE FILTERED {
+                       if (strcmp($3, "Loc-RIB") != 0) {
+                               yyerror("include filtered only supported in "
+                                   "Loc-RIB");
+                               YYERROR;
+                       }
+                       conf->filtered_in_locrib = 1;
+               }
                | NEXTHOP QUALIFY VIA STRING    {
                        if (!strcmp($4, "bgp"))
                                conf->flags |= BGPD_FLAG_NEXTHOP_BGP;
@@ -3551,6 +3559,7 @@ lookup(char *s)
                { "ext-community",      EXTCOMMUNITY},
                { "fib-priority",       FIBPRIORITY},
                { "fib-update",         FIBUPDATE},
+               { "filtered",           FILTERED},
                { "flags",              FLAGS},
                { "flowspec",           FLOWSPEC},
                { "fragment",           FRAGMENT},
index 13a7320..8aeeeee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: printconf.c,v 1.173 2024/05/22 08:41:14 claudio Exp $ */
+/*     $OpenBSD: printconf.c,v 1.174 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1276,6 +1276,8 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l)
        SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry)
                print_l3vpn(vpn);
        printf("\n");
+       if (conf->filtered_in_locrib)
+               printf("rde rib Loc-RIB include filtered\n");
        SIMPLEQ_FOREACH(rr, rib_l, entry) {
                if (rr->flags & F_RIB_NOEVALUATE)
                        printf("rde rib %s no evaluate\n", rr->name);
index 558d851..c4c286e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.625 2024/05/22 08:41:14 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.626 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1854,7 +1854,7 @@ rde_update_update(struct rde_peer *peer, uint32_t path_id,
        path_id_tx = pathid_assign(peer, path_id, prefix, prefixlen);
        /* add original path to the Adj-RIB-In */
        if (prefix_update(rib_byid(RIB_ADJ_IN), peer, path_id, path_id_tx,
-           in, prefix, prefixlen) == 1)
+           in, 0, prefix, prefixlen) == 1)
                peer->stats.prefix_cnt++;
 
        /* max prefix checker */
@@ -1883,11 +1883,16 @@ rde_update_update(struct rde_peer *peer, uint32_t path_id,
                            &state.nexthop->exit_nexthop, prefix,
                            prefixlen);
                        prefix_update(rib, peer, path_id, path_id_tx, &state,
-                           prefix, prefixlen);
-               } else if (prefix_withdraw(rib, peer, path_id, prefix,
-                   prefixlen)) {
-                       rde_update_log(wmsg, i, peer,
-                           NULL, prefix, prefixlen);
+                           0, prefix, prefixlen);
+               } else if (conf->filtered_in_locrib && i == RIB_LOC_START) {
+                       rde_update_log(wmsg, i, peer, NULL, prefix, prefixlen);
+                       prefix_update(rib, peer, path_id, path_id_tx, &state,
+                           1, prefix, prefixlen);
+               } else {
+                       if (prefix_withdraw(rib, peer, path_id, prefix,
+                           prefixlen))
+                               rde_update_log(wmsg, i, peer,
+                                   NULL, prefix, prefixlen);
                }
 
                rde_filterstate_clean(&state);
@@ -2738,7 +2743,7 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags,
        rib.aspa_validation_state = prefix_aspa_vstate(p);
        rib.dmetric = p->dmetric;
        rib.flags = 0;
-       if (!adjout) {
+       if (!adjout && prefix_eligible(p)) {
                re = prefix_re(p);
                TAILQ_FOREACH(xp, &re->prefix_h, entry.list.rib) {
                        switch (xp->dmetric) {
@@ -2768,6 +2773,8 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags,
                rib.flags |= F_PREF_ANNOUNCE;
        if (prefix_eligible(p))
                rib.flags |= F_PREF_ELIGIBLE;
+       if (prefix_filtered(p))
+               rib.flags |= F_PREF_FILTERED;
        /* otc loop includes parse err so skip the latter if the first is set */
        if (asp->flags & F_ATTR_OTC_LEAK)
                rib.flags |= F_PREF_OTC_LEAK;
@@ -2854,6 +2861,8 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req, int adjout)
        if ((req->flags & F_CTL_INVALID) &&
            (asp->flags & F_ATTR_PARSE_ERR) == 0)
                return;
+       if ((req->flags & F_CTL_FILTERED) && !prefix_filtered(p))
+               return;
        if ((req->flags & F_CTL_INELIGIBLE) && prefix_eligible(p))
                return;
        if ((req->flags & F_CTL_LEAKED) &&
@@ -3557,7 +3566,7 @@ rde_reload_done(void)
        struct rde_prefixset_head originsets_old;
        struct as_set_head       as_sets_old;
        uint16_t                 rid;
-       int                      reload = 0;
+       int                      reload = 0, force_locrib = 0;
 
        softreconfig = 0;
 
@@ -3568,6 +3577,12 @@ rde_reload_done(void)
        SIMPLEQ_CONCAT(&originsets_old, &conf->rde_originsets);
        SIMPLEQ_CONCAT(&as_sets_old, &conf->as_sets);
 
+       /* run softreconfig in if filter mode changed */
+       if (conf->filtered_in_locrib != nconf->filtered_in_locrib) {
+               log_debug("filter mode changed, reloading Loc-Rib");
+               force_locrib = 1;
+       }
+
        /* merge the main config */
        copy_config(conf, nconf);
 
@@ -3688,7 +3703,7 @@ rde_reload_done(void)
        }
 
        /* bring ribs in sync */
-       for (rid = 0; rid < rib_size; rid++) {
+       for (rid = RIB_LOC_START; rid < rib_size; rid++) {
                struct rib *rib = rib_byid(rid);
                if (rib == NULL)
                        continue;
@@ -3734,10 +3749,11 @@ rde_reload_done(void)
                        rib->state = RECONF_KEEP;
                        /* FALLTHROUGH */
                case RECONF_KEEP:
-                       if (rde_filter_equal(rib->in_rules, rib->in_rules_tmp))
+                       if (!(force_locrib && rid == RIB_LOC_START) &&
+                           rde_filter_equal(rib->in_rules, rib->in_rules_tmp))
                                /* rib is in sync */
                                break;
-                       log_debug("in filter change: reloading RIB %s",
+                       log_debug("filter change: reloading RIB %s",
                            rib->name);
                        rib->state = RECONF_RELOAD;
                        reload++;
@@ -3935,9 +3951,14 @@ rde_softreconfig_in(struct rib_entry *re, void *bula)
                        if (action == ACTION_ALLOW) {
                                /* update Local-RIB */
                                prefix_update(rib, peer, p->path_id,
-                                   p->path_id_tx, &state,
+                                   p->path_id_tx, &state, 0,
                                    &prefix, pt->prefixlen);
-                       } else if (action == ACTION_DENY) {
+                       } else if (conf->filtered_in_locrib &&
+                           i == RIB_LOC_START) {
+                               prefix_update(rib, peer, p->path_id,
+                                   p->path_id_tx, &state, 1,
+                                   &prefix, pt->prefixlen);
+                       } else {
                                /* remove from Local-RIB */
                                prefix_withdraw(rib, peer, p->path_id, &prefix,
                                    pt->prefixlen);
@@ -4084,9 +4105,14 @@ rde_rpki_softreload(struct rib_entry *re, void *bula)
                        if (action == ACTION_ALLOW) {
                                /* update Local-RIB */
                                prefix_update(rib, peer, p->path_id,
-                                   p->path_id_tx, &state,
+                                   p->path_id_tx, &state, 0,
+                                   &prefix, pt->prefixlen);
+                       } else if (conf->filtered_in_locrib &&
+                           i == RIB_LOC_START) {
+                               prefix_update(rib, peer, p->path_id,
+                                   p->path_id_tx, &state, 1,
                                    &prefix, pt->prefixlen);
-                       } else if (action == ACTION_DENY) {
+                       } else {
                                /* remove from Local-RIB */
                                prefix_withdraw(rib, peer, p->path_id, &prefix,
                                    pt->prefixlen);
@@ -4365,7 +4391,7 @@ network_add(struct network_config *nc, struct filterstate *state)
 
        path_id_tx = pathid_assign(peerself, 0, &nc->prefix, nc->prefixlen);
        if (prefix_update(rib_byid(RIB_ADJ_IN), peerself, 0, path_id_tx,
-           state, &nc->prefix, nc->prefixlen) == 1)
+           state, 0, &nc->prefix, nc->prefixlen) == 1)
                peerself->stats.prefix_cnt++;
        for (i = RIB_LOC_START; i < rib_size; i++) {
                struct rib *rib = rib_byid(i);
@@ -4374,8 +4400,8 @@ network_add(struct network_config *nc, struct filterstate *state)
                rde_update_log("announce", i, peerself,
                    state->nexthop ? &state->nexthop->exit_nexthop : NULL,
                    &nc->prefix, nc->prefixlen);
-               prefix_update(rib, peerself, 0, path_id_tx, state, &nc->prefix,
-                   nc->prefixlen);
+               prefix_update(rib, peerself, 0, path_id_tx, state, 0,
+                   &nc->prefix, nc->prefixlen);
        }
        filterset_free(&nc->attrset);
 }
index 5be48fd..899833d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.h,v 1.303 2024/05/29 10:36:32 claudio Exp $ */
+/*     $OpenBSD: rde.h,v 1.304 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -281,19 +281,21 @@ struct prefix {
        time_t                           lastchange;
        uint32_t                         path_id;
        uint32_t                         path_id_tx;
+       uint16_t                         flags;
        uint8_t                          validation_state;
        uint8_t                          nhflags;
        int8_t                           dmetric;       /* decision metric */
-       uint8_t                          flags;
-#define        PREFIX_FLAG_WITHDRAW    0x01    /* enqueued on withdraw queue */
-#define        PREFIX_FLAG_UPDATE      0x02    /* enqueued on update queue */
-#define        PREFIX_FLAG_DEAD        0x04    /* locked but removed */
-#define        PREFIX_FLAG_STALE       0x08    /* stale entry (graceful reload) */
-#define        PREFIX_FLAG_MASK        0x0f    /* mask for the prefix types */
-#define        PREFIX_FLAG_ADJOUT      0x10    /* prefix is in the adj-out rib */
-#define        PREFIX_FLAG_EOR         0x20    /* prefix is EoR */
-#define        PREFIX_NEXTHOP_LINKED   0x40    /* prefix is linked onto nexthop list */
-#define        PREFIX_FLAG_LOCKED      0x80    /* locked by rib walker */
+};
+#define        PREFIX_FLAG_WITHDRAW    0x0001  /* enqueued on withdraw queue */
+#define        PREFIX_FLAG_UPDATE      0x0002  /* enqueued on update queue */
+#define        PREFIX_FLAG_DEAD        0x0004  /* locked but removed */
+#define        PREFIX_FLAG_STALE       0x0008  /* stale entry (graceful reload) */
+#define        PREFIX_FLAG_MASK        0x000f  /* mask for the prefix types */
+#define        PREFIX_FLAG_ADJOUT      0x0010  /* prefix is in the adj-out rib */
+#define        PREFIX_FLAG_EOR         0x0020  /* prefix is EoR */
+#define        PREFIX_NEXTHOP_LINKED   0x0040  /* prefix is linked onto nexthop list */
+#define        PREFIX_FLAG_LOCKED      0x0080  /* locked by rib walker */
+#define        PREFIX_FLAG_FILTERED    0x0100  /* prefix is filtered (ineligible) */
 
 #define        PREFIX_DMETRIC_NONE     0
 #define        PREFIX_DMETRIC_INVALID  1
@@ -301,7 +303,6 @@ struct prefix {
 #define        PREFIX_DMETRIC_AS_WIDE  3
 #define        PREFIX_DMETRIC_ECMP     4
 #define        PREFIX_DMETRIC_BEST     5
-};
 
 /* possible states for nhflags */
 #define        NEXTHOP_SELF            0x01
@@ -579,7 +580,8 @@ struct prefix       *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *,
                    int);
 struct prefix  *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *);
 int             prefix_update(struct rib *, struct rde_peer *, uint32_t,
-                   uint32_t, struct filterstate *, struct bgpd_addr *, int);
+                   uint32_t, struct filterstate *, int, struct bgpd_addr *,
+                   int);
 int             prefix_withdraw(struct rib *, struct rde_peer *, uint32_t,
                    struct bgpd_addr *, int);
 int             prefix_flowspec_update(struct rde_peer *, struct filterstate *,
@@ -669,6 +671,12 @@ prefix_re(struct prefix *p)
        return (p->entry.list.re);
 }
 
+static inline int
+prefix_filtered(struct prefix *p)
+{
+       return ((p->flags & PREFIX_FLAG_FILTERED) != 0);
+}
+
 void            nexthop_shutdown(void);
 int             nexthop_pending(void);
 void            nexthop_runner(void);
index 5ebe405..2697f06 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_decide.c,v 1.102 2023/10/12 14:22:08 claudio Exp $ */
+/*     $OpenBSD: rde_decide.c,v 1.103 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -486,6 +486,10 @@ prefix_eligible(struct prefix *p)
 {
        struct rde_aspath *asp = prefix_aspath(p);
 
+       /* prefix itself is marked ineligible */
+       if (prefix_filtered(p))
+               return 0;
+
        /* The aspath needs to be loop and error free */
        if (asp == NULL ||
            asp->flags & (F_ATTR_LOOP|F_ATTR_OTC_LEAK|F_ATTR_PARSE_ERR))
index 3caaa3e..d595a0e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_rib.c,v 1.262 2024/05/29 10:34:56 claudio Exp $ */
+/*     $OpenBSD: rde_rib.c,v 1.263 2024/08/14 19:09:51 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -801,10 +801,10 @@ path_put(struct rde_aspath *asp)
 static int     prefix_add(struct bgpd_addr *, int, struct rib *,
                    struct rde_peer *, uint32_t, uint32_t, struct rde_aspath *,
                    struct rde_community *, struct nexthop *,
-                   uint8_t, uint8_t);
+                   uint8_t, uint8_t, int);
 static int     prefix_move(struct prefix *, struct rde_peer *,
                    struct rde_aspath *, struct rde_community *,
-                   struct nexthop *, uint8_t, uint8_t);
+                   struct nexthop *, uint8_t, uint8_t, int);
 
 static void    prefix_link(struct prefix *, struct rib_entry *,
                    struct pt_entry *, struct rde_peer *, uint32_t, uint32_t,
@@ -967,8 +967,8 @@ prefix_adjout_match(struct rde_peer *peer, struct bgpd_addr *addr)
  */
 int
 prefix_update(struct rib *rib, struct rde_peer *peer, uint32_t path_id,
-    uint32_t path_id_tx, struct filterstate *state, struct bgpd_addr *prefix,
-    int prefixlen)
+    uint32_t path_id_tx, struct filterstate *state, int filtered,
+    struct bgpd_addr *prefix, int prefixlen)
 {
        struct rde_aspath       *asp, *nasp = &state->aspath;
        struct rde_community    *comm, *ncomm = &state->communities;
@@ -987,6 +987,10 @@ prefix_update(struct rib *rib, struct rde_peer *peer, uint32_t path_id,
                        /* no change, update last change */
                        p->lastchange = getmonotime();
                        p->validation_state = state->vstate;
+                       if (filtered)
+                               p->flags |= PREFIX_FLAG_FILTERED;
+                       else
+                               p->flags &= ~PREFIX_FLAG_FILTERED;
                        return (0);
                }
        }
@@ -1010,11 +1014,11 @@ prefix_update(struct rib *rib, struct rde_peer *peer, uint32_t path_id,
        /* If the prefix was found move it else add it to the RIB. */
        if (p != NULL)
                return (prefix_move(p, peer, asp, comm, state->nexthop,
-                   state->nhflags, state->vstate));
+                   state->nhflags, state->vstate, filtered));
        else
                return (prefix_add(prefix, prefixlen, rib, peer, path_id,
                    path_id_tx, asp, comm, state->nexthop, state->nhflags,
-                   state->vstate));
+                   state->vstate, filtered));
 }
 
 /*
@@ -1024,7 +1028,7 @@ static int
 prefix_add(struct bgpd_addr *prefix, int prefixlen, struct rib *rib,
     struct rde_peer *peer, uint32_t path_id, uint32_t path_id_tx,
     struct rde_aspath *asp, struct rde_community *comm,
-    struct nexthop *nexthop, uint8_t nhflags, uint8_t vstate)
+    struct nexthop *nexthop, uint8_t nhflags, uint8_t vstate, int filtered)
 {
        struct pt_entry *pte;
        struct prefix           *p;
@@ -1041,6 +1045,9 @@ prefix_add(struct bgpd_addr *prefix, int prefixlen, struct rib *rib,
        prefix_link(p, re, re->prefix, peer, path_id, path_id_tx, asp, comm,
            nexthop, nhflags, vstate);
 
+       if (filtered)
+               p->flags |= PREFIX_FLAG_FILTERED;
+
        /* add possible pftable reference form aspath */
        if (asp && asp->pftableid)
                rde_pftable_add(asp->pftableid, p);
@@ -1055,7 +1062,7 @@ prefix_add(struct bgpd_addr *prefix, int prefixlen, struct rib *rib,
 static int
 prefix_move(struct prefix *p, struct rde_peer *peer,
     struct rde_aspath *asp, struct rde_community *comm,
-    struct nexthop *nexthop, uint8_t nhflags, uint8_t vstate)
+    struct nexthop *nexthop, uint8_t nhflags, uint8_t vstate, int filtered)
 {
        struct prefix           *np;
 
@@ -1070,6 +1077,9 @@ prefix_move(struct prefix *p, struct rde_peer *peer,
        prefix_link(np, prefix_re(p), p->pt, peer, p->path_id, p->path_id_tx,
            asp, comm, nexthop, nhflags, vstate);
 
+       if (filtered)
+               np->flags |= PREFIX_FLAG_FILTERED;
+
        /* add possible pftable reference from new aspath */
        if (asp && asp->pftableid)
                rde_pftable_add(asp->pftableid, np);