After a lot of preparation diffs this does the actuall change of moving
the nexthop form struct rde_aspath to struct prefix. Also the nexthop
flags are moved into their own flag variable (reducing the flag masking
that happened before).
I tested this with most nexthop combos I can think of and all seems to
work. More testing welcome.
--
:wq Claudio
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.400
diff -u -p -r1.400 rde.c
--- rde.c 24 Jul 2018 10:10:58 -0000 1.400
+++ rde.c 24 Jul 2018 10:13:16 -0000
@@ -990,7 +990,7 @@ rde_update_dispatch(struct imsg *imsg)
imsg->hdr.len - IMSG_HEADER_SIZE - 4 - withdrawn_len - attrpath_len;
bzero(&mpa, sizeof(mpa));
- rde_filterstate_prep(&state, NULL, NULL);
+ rde_filterstate_prep(&state, NULL, NULL, 0);
if (attrpath_len != 0) { /* 0 = no NLRI information in this message */
/* parse path attributes */
while (len > 0) {
@@ -1305,7 +1305,8 @@ rde_update_update(struct rde_peer *peer,
for (i = RIB_LOC_START; i < rib_size; i++) {
if (*ribs[i].name == '\0')
break;
- rde_filterstate_prep(&state, &in->aspath, in->nexthop);
+ rde_filterstate_prep(&state, &in->aspath, in->nexthop,
+ in->nhflags);
/* input filter */
action = rde_filter(ribs[i].in_rules, peer, p, &state);
@@ -2100,7 +2101,8 @@ rde_dump_filterout(struct rde_peer *peer
if (up_test_update(peer, p) != 1)
return;
- rde_filterstate_prep(&state, prefix_aspath(p), prefix_nexthop(p));
+ rde_filterstate_prep(&state, prefix_aspath(p), prefix_nexthop(p),
+ prefix_nhflags(p));
a = rde_filter(out_rules, peer, p, &state);
if (a == ACTION_ALLOW)
@@ -2421,9 +2423,9 @@ rde_send_kroute(struct rib *rib, struct
bzero(&kr, sizeof(kr));
memcpy(&kr.prefix, &addr, sizeof(kr.prefix));
kr.prefixlen = p->re->prefix->prefixlen;
- if (asp->flags & F_NEXTHOP_REJECT)
+ if (prefix_nhflags(p) == NEXTHOP_REJECT)
kr.flags |= F_REJECT;
- if (asp->flags & F_NEXTHOP_BLACKHOLE)
+ if (prefix_nhflags(p) == NEXTHOP_BLACKHOLE)
kr.flags |= F_BLACKHOLE;
if (type == IMSG_KROUTE_CHANGE)
memcpy(&kr.nexthop, &prefix_nexthop(p)->true_nexthop,
@@ -2856,7 +2858,8 @@ rde_softreconfig_in(struct rib_entry *re
asp = prefix_aspath(p);
peer = asp->peer;
- rde_filterstate_prep(&state, asp, prefix_nexthop(p));
+ rde_filterstate_prep(&state, asp, prefix_nexthop(p),
+ prefix_nhflags(p));
action = rde_filter(rib->in_rules, peer, p, &state);
if (action == ACTION_ALLOW) {
@@ -2894,8 +2897,10 @@ rde_softreconfig_out(struct rib_entry *r
if (up_test_update(peer, p) != 1)
return;
- rde_filterstate_prep(&ostate, prefix_aspath(p), prefix_nexthop(p));
- rde_filterstate_prep(&nstate, prefix_aspath(p), prefix_nexthop(p));
+ rde_filterstate_prep(&ostate, prefix_aspath(p), prefix_nexthop(p),
+ prefix_nhflags(p));
+ rde_filterstate_prep(&nstate, prefix_aspath(p), prefix_nexthop(p),
+ prefix_nhflags(p));
oa = rde_filter(out_rules_tmp, peer, p, &ostate);
na = rde_filter(out_rules, peer, p, &nstate);
@@ -2909,17 +2914,10 @@ rde_softreconfig_out(struct rib_entry *r
/* send withdraw */
up_generate(peer, NULL, &addr, pt->prefixlen);
} else if (oa == ACTION_ALLOW && na == ACTION_ALLOW) {
- /* XXX update nexthop for now, ugly but will go away */
- nexthop_put(nstate.aspath.nexthop);
- nstate.aspath.nexthop = nexthop_ref(nstate.nexthop);
- nstate.aspath.flags = (nstate.aspath.flags & ~F_NEXTHOP_MASK) |
- (nstate.nhflags & F_NEXTHOP_MASK);
- nexthop_put(ostate.aspath.nexthop);
- ostate.aspath.nexthop = nexthop_ref(ostate.nexthop);
- ostate.aspath.flags = (ostate.aspath.flags & ~F_NEXTHOP_MASK) |
- (ostate.nhflags & F_NEXTHOP_MASK);
- /* send update if path attributes changed */
- if (path_compare(&nstate.aspath, &ostate.aspath) != 0)
+ /* send update if anything changed */
+ if (nstate.nhflags != ostate.nhflags ||
+ nexthop_compare(nstate.nexthop, ostate.nexthop) != 0 ||
+ path_compare(&nstate.aspath, &ostate.aspath) != 0)
up_generate(peer, &nstate, &addr, pt->prefixlen);
}
@@ -2943,7 +2941,8 @@ rde_softreconfig_unload_peer(struct rib_
if (up_test_update(peer, p) != 1)
return;
- rde_filterstate_prep(&ostate, prefix_aspath(p), prefix_nexthop(p));
+ rde_filterstate_prep(&ostate, prefix_aspath(p), prefix_nexthop(p),
+ prefix_nhflags(p));
if (rde_filter(out_rules_tmp, peer, p, &ostate) != ACTION_DENY) {
/* send withdraw */
up_generate(peer, NULL, &addr, pt->prefixlen);
@@ -3418,7 +3417,7 @@ network_add(struct network_config *nc, i
}
if (!flagstatic)
asp->flags |= F_ANN_DYNAMIC;
- rde_filterstate_prep(&state, asp, NULL); /* nexthop is not set */
+ rde_filterstate_prep(&state, asp, NULL, 0); /* nexthop is not set */
rde_apply_set(&nc->attrset, &state, nc->prefix.aid, peerself, peerself);
if (vpnset)
rde_apply_set(vpnset, &state, nc->prefix.aid, peerself,
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.181
diff -u -p -r1.181 rde.h
--- rde.h 22 Jul 2018 16:59:08 -0000 1.181
+++ rde.h 24 Jul 2018 07:45:21 -0000
@@ -166,11 +166,6 @@ struct mpattr {
#define F_ATTR_LOOP 0x00200 /* path would cause a route
loop */
#define F_PREFIX_ANNOUNCED 0x00400
#define F_ANN_DYNAMIC 0x00800
-#define F_NEXTHOP_SELF 0x01000
-#define F_NEXTHOP_REJECT 0x02000
-#define F_NEXTHOP_BLACKHOLE 0x04000
-#define F_NEXTHOP_NOMODIFY 0x08000
-#define F_NEXTHOP_MASK 0x0f000
#define F_ATTR_PARSE_ERR 0x10000 /* parse error, not eligable */
#define F_ATTR_LINKED 0x20000 /* if set path is on various
lists */
#define F_ATTR_UPDATE 0x20000 /* if set linked on update_l */
@@ -183,13 +178,12 @@ struct mpattr {
#define DEFAULT_LPREF 100
struct rde_aspath {
- LIST_ENTRY(rde_aspath) path_l, nexthop_l;
+ LIST_ENTRY(rde_aspath) path_l;
TAILQ_ENTRY(rde_aspath) peer_l, update_l;
struct prefix_queue prefixes, updates;
struct attr **others;
struct rde_peer *peer;
struct aspath *aspath;
- struct nexthop *nexthop; /* may be NULL */
u_int64_t hash;
u_int32_t flags; /* internally used */
u_int32_t med; /* multi exit disc */
@@ -209,7 +203,7 @@ enum nexthop_state {
struct nexthop {
LIST_ENTRY(nexthop) nexthop_l;
- struct aspath_head path_h;
+ struct prefix_list prefix_h;
struct bgpd_addr exit_nexthop;
struct bgpd_addr true_nexthop;
struct bgpd_addr nexthop_net;
@@ -303,21 +297,28 @@ struct rib_desc {
#define RIB_LOC_START 2
struct prefix {
- LIST_ENTRY(prefix) rib_l;
+ LIST_ENTRY(prefix) rib_l, nexthop_l;
TAILQ_ENTRY(prefix) path_l;
struct rib_entry *re;
struct rde_aspath *aspath;
struct rde_peer *peer;
+ struct nexthop *nexthop; /* may be NULL */
time_t lastchange;
- int flags;
+ u_int8_t flags;
+ u_int8_t nhflags;
};
#define F_PREFIX_USE_UPDATES 0x01 /* linked onto the updates list */
+#define NEXTHOP_SELF 0x01
+#define NEXTHOP_REJECT 0x02
+#define NEXTHOP_BLACKHOLE 0x04
+#define NEXTHOP_NOMODIFY 0x08
+
struct filterstate {
- struct rde_aspath aspath;
+ struct rde_aspath aspath;
struct nexthop *nexthop;
- unsigned int nhflags;
+ u_int8_t nhflags;
};
extern struct rde_memstats rdemem;
@@ -401,7 +402,8 @@ u_char *community_ext_delete_non_trans(
void prefix_evaluate(struct prefix *, struct rib_entry *);
/* rde_filter.c */
-void rde_filterstate_prep(struct filterstate *, struct rde_aspath
*, struct nexthop *);
+void rde_filterstate_prep(struct filterstate *, struct rde_aspath *,
+ struct nexthop *, u_int8_t);
void rde_filterstate_clean(struct filterstate *);
enum filter_actions rde_filter(struct filter_head *, struct rde_peer *,
struct prefix *, struct filterstate *);
@@ -490,12 +492,18 @@ int prefix_write(u_char *, int, struct
int prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t);
struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *,
u_int32_t);
-void prefix_updateall(struct rde_aspath *, enum nexthop_state,
+void prefix_updateall(struct prefix *, enum nexthop_state,
enum nexthop_state);
void prefix_destroy(struct prefix *);
void prefix_network_clean(struct rde_peer *, time_t, u_int32_t);
void prefix_relink(struct prefix *, struct rde_aspath *, int);
+static inline struct rde_peer *
+prefix_peer(struct prefix *p)
+{
+ return (p->peer);
+}
+
static inline struct rde_aspath *
prefix_aspath(struct prefix *p)
{
@@ -505,21 +513,21 @@ prefix_aspath(struct prefix *p)
static inline struct nexthop *
prefix_nexthop(struct prefix *p)
{
- return (p->aspath->nexthop);
+ return (p->nexthop);
}
-static inline struct rde_peer *
-prefix_peer(struct prefix *p)
+static inline u_int8_t
+prefix_nhflags(struct prefix *p)
{
- return (p->peer);
+ return (p->nhflags);
}
void nexthop_init(u_int32_t);
void nexthop_shutdown(void);
void nexthop_modify(struct nexthop *, enum action_types, u_int8_t,
- struct nexthop **, u_int32_t *);
-void nexthop_link(struct rde_aspath *);
-void nexthop_unlink(struct rde_aspath *);
+ struct nexthop **, u_int8_t *);
+void nexthop_link(struct prefix *);
+void nexthop_unlink(struct prefix *);
void nexthop_update(struct kroute_nexthop *);
struct nexthop *nexthop_get(struct bgpd_addr *);
struct nexthop *nexthop_ref(struct nexthop *);
Index: rde_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.97
diff -u -p -r1.97 rde_filter.c
--- rde_filter.c 22 Jul 2018 16:59:08 -0000 1.97
+++ rde_filter.c 24 Jul 2018 07:43:05 -0000
@@ -640,7 +640,7 @@ rde_filter_equal(struct filter_head *a,
void
rde_filterstate_prep(struct filterstate *state, struct rde_aspath *asp,
- struct nexthop *nh)
+ struct nexthop *nh, u_int8_t nhflags)
{
memset(state, 0, sizeof(*state));
@@ -648,9 +648,7 @@ rde_filterstate_prep(struct filterstate
if (asp)
path_copy(&state->aspath, asp);
state->nexthop = nexthop_ref(nh);
- /* XXX the flag handling needs improvement */
- if (asp)
- state->nhflags |= asp->flags & F_NEXTHOP_MASK;
+ state->nhflags = nhflags;
}
void
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.172
diff -u -p -r1.172 rde_rib.c
--- rde_rib.c 22 Jul 2018 16:59:08 -0000 1.172
+++ rde_rib.c 24 Jul 2018 10:52:06 -0000
@@ -48,9 +48,11 @@ struct rib_entry *rib_restart(struct rib
RB_PROTOTYPE(rib_tree, rib_entry, rib_e, rib_compare);
RB_GENERATE(rib_tree, rib_entry, rib_e, rib_compare);
-int prefix_add(struct rib *, struct rde_aspath *,
- struct bgpd_addr *, int, int);
-void prefix_move(struct rde_aspath *, struct prefix *, int);
+int prefix_add(struct bgpd_addr *, int, struct rib *,
+ struct rde_peer *, struct rde_aspath *,
+ struct filterstate *, int);
+int prefix_move(struct prefix *, struct rde_peer *,
+ struct rde_aspath *, struct filterstate *, int);
static inline void
re_lock(struct rib_entry *re)
@@ -423,11 +425,6 @@ path_update(struct rib *rib, struct rde_
struct prefix *p;
int pflag = 0;
- nexthop_put(nasp->nexthop);
- nasp->nexthop = nexthop_ref(state->nexthop);
- nasp->flags = (nasp->flags & ~F_NEXTHOP_MASK) |
- (state->nhflags & F_NEXTHOP_MASK);
-
if (nasp->pftableid) {
rde_send_pftable(nasp->pftableid, prefix, prefixlen, 0);
rde_send_pftable_commit();
@@ -457,10 +454,10 @@ path_update(struct rib *rib, struct rde_
/* If the prefix was found move it else add it to the aspath. */
if (p != NULL)
- prefix_move(asp, p, pflag);
+ return (prefix_move(p, peer, asp, state, pflag));
else
- return (prefix_add(rib, asp, prefix, prefixlen, pflag));
- return (0);
+ return (prefix_add(prefix, prefixlen, rib, peer, asp,
+ state, pflag));
}
int
@@ -506,8 +503,6 @@ path_compare(struct rde_aspath *a, struc
return (-1);
r = aspath_compare(a->aspath, b->aspath);
- if (r == 0)
- r = nexthop_compare(a->nexthop, b->nexthop);
if (r > 0)
return (1);
if (r < 0)
@@ -658,7 +653,6 @@ path_destroy(struct rde_aspath *asp)
if (!TAILQ_EMPTY(&asp->prefixes) || !TAILQ_EMPTY(&asp->updates))
log_warnx("path_destroy: still has prefixes, leaking");
- nexthop_unlink(asp);
LIST_REMOVE(asp, path_l);
TAILQ_REMOVE(&asp->peer->path_h, asp, peer_l);
asp->peer = NULL;
@@ -692,7 +686,6 @@ path_link(struct rde_aspath *asp, struct
LIST_INSERT_HEAD(head, asp, path_l);
TAILQ_INSERT_HEAD(&peer->path_h, asp, peer_l);
- nexthop_link(asp);
asp->flags |= F_ATTR_LINKED;
}
@@ -708,7 +701,6 @@ path_copy(struct rde_aspath *dst, const
dst->aspath->refcnt++;
rdemem.aspath_refs++;
}
- dst->nexthop = nexthop_ref(src->nexthop);
dst->hash = 0;
dst->med = src->med;
dst->lpref = src->lpref;
@@ -759,7 +751,6 @@ path_clean(struct rde_aspath *asp)
rtlabel_unref(asp->rtlabelid);
pftable_unref(asp->pftableid);
aspath_put(asp->aspath);
- nexthop_put(asp->nexthop);
attr_freeall(asp);
}
@@ -781,7 +772,8 @@ path_put(struct rde_aspath *asp)
static struct prefix *prefix_alloc(void);
static void prefix_free(struct prefix *);
static void prefix_link(struct prefix *, struct rib_entry *,
- struct rde_aspath *, int);
+ struct rde_peer *, struct rde_aspath *,
+ struct filterstate *, int);
static void prefix_unlink(struct prefix *);
/*
@@ -803,9 +795,9 @@ prefix_get(struct rib *rib, struct rde_p
* Adds or updates a prefix.
*/
int
-prefix_add(struct rib *rib, struct rde_aspath *asp, struct bgpd_addr *prefix,
- int prefixlen, int flag)
-
+prefix_add(struct bgpd_addr *prefix, int prefixlen, struct rib *rib,
+ struct rde_peer *peer, struct rde_aspath *asp, struct filterstate *state,
+ int flag)
{
struct prefix *p;
struct rib_entry *re;
@@ -817,14 +809,16 @@ prefix_add(struct rib *rib, struct rde_a
p = prefix_bypeer(re, asp->peer, asp->flags);
if (p == NULL) {
p = prefix_alloc();
- prefix_link(p, re, asp, flag);
+ prefix_link(p, re, peer, asp, state, flag);
return (1);
} else {
- if (prefix_aspath(p) != asp) {
- /* prefix belongs to a different aspath so move */
- prefix_move(asp, p, flag);
- } else
- p->lastchange = time(NULL);
+ if (prefix_aspath(p) != asp ||
+ prefix_nexthop(p) != state->nexthop ||
+ prefix_nhflags(p) != state->nhflags) {
+ /* prefix metadata changed therefor move */
+ return (prefix_move(p, peer, asp, state, flag));
+ }
+ p->lastchange = time(NULL);
return (0);
}
}
@@ -832,22 +826,25 @@ prefix_add(struct rib *rib, struct rde_a
/*
* Move the prefix to the specified as path, removes the old asp if needed.
*/
-void
-prefix_move(struct rde_aspath *asp, struct prefix *p, int flag)
+int
+prefix_move(struct prefix *p, struct rde_peer *peer,
+ struct rde_aspath *asp, struct filterstate *state, int flag)
{
struct prefix *np;
struct rde_aspath *oasp;
- if (asp->peer != prefix_peer(p))
+ if (peer != prefix_peer(p))
fatalx("prefix_move: cross peer move");
- /* create new prefix node */
np = prefix_alloc();
np->aspath = asp;
- np->peer = asp->peer;
+ np->nexthop = nexthop_ref(state->nexthop);
+ nexthop_link(np);
+ np->peer = peer;
np->re = p->re;
np->lastchange = time(NULL);
np->flags = flag;
+ np->nhflags = state->nhflags;
/* add to new as path */
if (np->flags & F_PREFIX_USE_UPDATES)
@@ -882,11 +879,16 @@ prefix_move(struct rde_aspath *asp, stru
p->aspath = NULL;
p->peer = NULL;
p->re = NULL;
+ nexthop_unlink(p);
+ nexthop_put(p->nexthop);
+ p->nexthop = NULL;
prefix_free(p);
/* destroy old path if empty */
if (path_empty(oasp))
path_destroy(oasp);
+
+ return (0);
}
/*
@@ -1020,47 +1022,43 @@ prefix_bypeer(struct rib_entry *re, stru
}
void
-prefix_updateall(struct rde_aspath *asp, enum nexthop_state state,
+prefix_updateall(struct prefix *p, enum nexthop_state state,
enum nexthop_state oldstate)
{
- struct prefix *p;
-
- TAILQ_FOREACH(p, &asp->prefixes, path_l) {
- /*
- * Skip non local-RIBs or RIBs that are flagged as noeval.
- * There is no need to run over updates since that is only
- * used on the Adj-RIB-Out.
- */
- if (re_rib(p->re)->flags & F_RIB_NOEVALUATE)
- continue;
-
- if (oldstate == state && state == NEXTHOP_REACH) {
- /*
- * The state of the nexthop did not change. The only
- * thing that may have changed is the true_nexthop
- * or other internal infos. This will not change
- * the routing decision so shortcut here.
- */
- if ((re_rib(p->re)->flags & F_RIB_NOFIB) == 0 &&
- p == p->re->active)
- rde_send_kroute(re_rib(p->re), p, NULL);
- continue;
- }
+ /*
+ * Skip non local-RIBs or RIBs that are flagged as noeval.
+ * There is no need to run over updates since that is only
+ * used on the Adj-RIB-Out.
+ */
+ if (re_rib(p->re)->flags & F_RIB_NOEVALUATE)
+ return;
- /* redo the route decision */
- LIST_REMOVE(p, rib_l);
+ if (oldstate == state && state == NEXTHOP_REACH) {
/*
- * If the prefix is the active one remove it first,
- * this has to be done because we can not detect when
- * the active prefix changes its state. In this case
- * we know that this is a withdrawal and so the second
- * prefix_evaluate() will generate no update because
- * the nexthop is unreachable or ineligible.
+ * The state of the nexthop did not change. The only
+ * thing that may have changed is the true_nexthop
+ * or other internal infos. This will not change
+ * the routing decision so shortcut here.
*/
- if (p == p->re->active)
- prefix_evaluate(NULL, p->re);
- prefix_evaluate(p, p->re);
+ if ((re_rib(p->re)->flags & F_RIB_NOFIB) == 0 &&
+ p == p->re->active)
+ rde_send_kroute(re_rib(p->re), p, NULL);
+ return;
}
+
+ /* redo the route decision */
+ LIST_REMOVE(p, rib_l);
+ /*
+ * If the prefix is the active one remove it first,
+ * this has to be done because we can not detect when
+ * the active prefix changes its state. In this case
+ * we know that this is a withdrawal and so the second
+ * prefix_evaluate() will generate no update because
+ * the nexthop is unreachable or ineligible.
+ */
+ if (p == p->re->active)
+ prefix_evaluate(NULL, p->re);
+ prefix_evaluate(p, p->re);
}
/* kill a prefix. */
@@ -1107,8 +1105,8 @@ prefix_network_clean(struct rde_peer *pe
* Link a prefix into the different parent objects.
*/
static void
-prefix_link(struct prefix *pref, struct rib_entry *re, struct rde_aspath *asp,
- int flag)
+prefix_link(struct prefix *pref, struct rib_entry *re, struct rde_peer *peer,
+ struct rde_aspath *asp, struct filterstate *state, int flag)
{
if (flag & F_PREFIX_USE_UPDATES)
TAILQ_INSERT_HEAD(&asp->updates, pref, path_l);
@@ -1116,10 +1114,13 @@ prefix_link(struct prefix *pref, struct
TAILQ_INSERT_HEAD(&asp->prefixes, pref, path_l);
pref->aspath = asp;
- pref->peer = asp->peer;
+ pref->peer = peer;
+ pref->nexthop = nexthop_ref(state->nexthop);
+ nexthop_link(pref);
pref->re = re;
pref->lastchange = time(NULL);
pref->flags = flag;
+ pref->nhflags = state->nhflags;
/* make route decision */
prefix_evaluate(pref, re);
@@ -1148,6 +1149,9 @@ prefix_unlink(struct prefix *pref)
rib_remove(re);
/* destroy all references to other objects */
+ nexthop_unlink(pref);
+ nexthop_put(pref->nexthop);
+ pref->nexthop = NULL;
pref->aspath = NULL;
pref->peer = NULL;
pref->re = NULL;
@@ -1248,7 +1252,7 @@ void
nexthop_update(struct kroute_nexthop *msg)
{
struct nexthop *nh;
- struct rde_aspath *asp;
+ struct prefix *p;
enum nexthop_state oldstate;
nh = nexthop_lookup(&msg->nexthop);
@@ -1289,28 +1293,27 @@ nexthop_update(struct kroute_nexthop *ms
*/
return;
- LIST_FOREACH(asp, &nh->path_h, nexthop_l) {
- prefix_updateall(asp, nh->state, oldstate);
+ LIST_FOREACH(p, &nh->prefix_h, nexthop_l) {
+ prefix_updateall(p, nh->state, oldstate);
}
}
void
nexthop_modify(struct nexthop *setnh, enum action_types type, u_int8_t aid,
- struct nexthop **nexthop, u_int32_t *flags)
+ struct nexthop **nexthop, u_int8_t *flags)
{
- *flags &= ~F_NEXTHOP_MASK;
switch (type) {
case ACTION_SET_NEXTHOP_REJECT:
- *flags |= F_NEXTHOP_REJECT;
+ *flags = NEXTHOP_REJECT;
break;
case ACTION_SET_NEXTHOP_BLACKHOLE:
- *flags |= F_NEXTHOP_BLACKHOLE;
+ *flags = NEXTHOP_BLACKHOLE;
break;
case ACTION_SET_NEXTHOP_NOMODIFY:
- *flags |= F_NEXTHOP_NOMODIFY;
+ *flags = NEXTHOP_NOMODIFY;
break;
case ACTION_SET_NEXTHOP_SELF:
- *flags |= F_NEXTHOP_SELF;
+ *flags = NEXTHOP_SELF;
break;
case ACTION_SET_NEXTHOP:
/*
@@ -1321,6 +1324,7 @@ nexthop_modify(struct nexthop *setnh, en
break;
nexthop_put(*nexthop);
*nexthop = nexthop_ref(setnh);
+ *flags = 0;
break;
default:
break;
@@ -1328,29 +1332,21 @@ nexthop_modify(struct nexthop *setnh, en
}
void
-nexthop_link(struct rde_aspath *asp)
+nexthop_link(struct prefix *p)
{
- if (asp->nexthop == NULL)
+ if (p->nexthop == NULL)
return;
- LIST_INSERT_HEAD(&asp->nexthop->path_h, asp, nexthop_l);
+ LIST_INSERT_HEAD(&p->nexthop->prefix_h, p, nexthop_l);
}
void
-nexthop_unlink(struct rde_aspath *asp)
+nexthop_unlink(struct prefix *p)
{
- struct nexthop *nh;
-
- if (asp->nexthop == NULL)
+ if (p->nexthop == NULL)
return;
- LIST_REMOVE(asp, nexthop_l);
-
- /* remove reference to nexthop */
- nh = asp->nexthop;
- asp->nexthop = NULL;
-
- (void)nexthop_put(nh);
+ LIST_REMOVE(p, nexthop_l);
}
struct nexthop *
@@ -1365,7 +1361,7 @@ nexthop_get(struct bgpd_addr *nexthop)
fatal("nexthop_alloc");
rdemem.nexthop_cnt++;
- LIST_INIT(&nh->path_h);
+ LIST_INIT(&nh->prefix_h);
nh->state = NEXTHOP_LOOKUP;
nexthop_ref(nh); /* take reference for lookup */
nh->exit_nexthop = *nexthop;
@@ -1396,7 +1392,7 @@ nexthop_put(struct nexthop *nh)
return (0);
/* sanity check */
- if (!LIST_EMPTY(&nh->path_h) || nh->state == NEXTHOP_LOOKUP)
+ if (!LIST_EMPTY(&nh->prefix_h) || nh->state == NEXTHOP_LOOKUP)
fatalx("nexthop_put: refcnt error");
LIST_REMOVE(nh, nexthop_l);
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.95
diff -u -p -r1.95 rde_update.c
--- rde_update.c 22 Jul 2018 16:59:08 -0000 1.95
+++ rde_update.c 24 Jul 2018 07:44:38 -0000
@@ -426,7 +426,7 @@ withdraw:
}
rde_filterstate_prep(&state, prefix_aspath(new),
- prefix_nexthop(new));
+ prefix_nexthop(new), prefix_nhflags(new));
if (rde_filter(rules, peer, new, &state) == ACTION_DENY) {
rde_filterstate_clean(&state);
goto withdraw;
@@ -485,7 +485,7 @@ up_generate_default(struct filter_head *
p.flags = 0;
/* filter as usual */
- rde_filterstate_prep(&state, asp, NULL);
+ rde_filterstate_prep(&state, asp, NULL, 0);
if (rde_filter(rules, peer, &p, &state) == ACTION_DENY) {
rde_filterstate_clean(&state);
return;
@@ -547,13 +547,13 @@ up_get_nexthop(struct rde_peer *peer, st
in_addr_t mask;
/* nexthop, already network byte order */
- if (state->nhflags & F_NEXTHOP_NOMODIFY) {
+ if (state->nhflags & NEXTHOP_NOMODIFY) {
/* no modify flag set */
if (state->nexthop == NULL)
return (peer->local_v4_addr.v4.s_addr);
else
return (state->nexthop->exit_nexthop.v4.s_addr);
- } else if (state->nhflags & F_NEXTHOP_SELF)
+ } else if (state->nhflags & NEXTHOP_SELF)
return (peer->local_v4_addr.v4.s_addr);
else if (!peer->conf.ebgp) {
/*
@@ -616,7 +616,7 @@ up_generate_mp_reach(struct rde_peer *pe
upa->mpattr[20] = 0; /* Reserved must be 0 */
/* nexthop dance see also up_get_nexthop() */
- if (state->nhflags & F_NEXTHOP_NOMODIFY) {
+ if (state->nhflags & NEXTHOP_NOMODIFY) {
/* no modify flag set */
if (state->nexthop == NULL)
memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
@@ -625,7 +625,7 @@ up_generate_mp_reach(struct rde_peer *pe
memcpy(&upa->mpattr[4],
&state->nexthop->exit_nexthop.v6,
sizeof(struct in6_addr));
- } else if (state->nhflags & F_NEXTHOP_SELF)
+ } else if (state->nhflags & NEXTHOP_SELF)
memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
sizeof(struct in6_addr));
else if (!peer->conf.ebgp) {
@@ -675,7 +675,7 @@ up_generate_mp_reach(struct rde_peer *pe
upa->mpattr[3] = sizeof(u_int64_t) + sizeof(struct in_addr);
/* nexthop dance see also up_get_nexthop() */
- if (state->nhflags & F_NEXTHOP_NOMODIFY) {
+ if (state->nhflags & NEXTHOP_NOMODIFY) {
/* no modify flag set */
if (state->nexthop == NULL)
memcpy(&upa->mpattr[12],
@@ -686,7 +686,7 @@ up_generate_mp_reach(struct rde_peer *pe
memcpy(&upa->mpattr[12],
&state->nexthop->exit_nexthop.v4,
sizeof(struct in_addr));
- } else if (state->nhflags & F_NEXTHOP_SELF)
+ } else if (state->nhflags & NEXTHOP_SELF)
memcpy(&upa->mpattr[12], &peer->local_v4_addr.v4,
sizeof(struct in_addr));
else if (!peer->conf.ebgp) {