#include "mpls.h"
-static __inline int fec_compare(struct fec *, struct fec *);
+static __inline int fec_compare(const struct fec *, const struct fec *);
static int lde_nbr_is_nexthop(struct fec_node *,
struct lde_nbr *);
static void fec_free(void *);
void
fec_init(struct fec_tree *fh)
{
- RB_INIT(fh);
+ RB_INIT(fec_tree, fh);
}
static __inline int
-fec_compare(struct fec *a, struct fec *b)
+fec_compare(const struct fec *a, const struct fec *b)
{
if (a->type < b->type)
return (-1);
{
struct fec *f;
- while ((f = RB_ROOT(fh)) != NULL) {
+ while (!RB_EMPTY(fec_tree, fh)) {
+ f = RB_ROOT(fec_tree, fh);
+
fec_remove(fh, f);
free_cb(f);
}
RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
- RB_EMPTY(&fn->downstream))
+ RB_EMPTY(lde_map_head, &fn->downstream))
continue;
memset(&rtctl, 0, sizeof(rtctl));
}
rtctl.local_label = fn->local_label;
- if (RB_EMPTY(&fn->downstream)) {
+ if (RB_EMPTY(lde_map_head, &fn->downstream)) {
rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL;
struct fec_node *fn = arg;
struct fec_nh *fnh;
- while ((fnh = LIST_FIRST(&fn->nexthops)))
+ while ((fnh = LIST_FIRST(&fn->nexthops))) {
fec_nh_del(fnh);
- if (!RB_EMPTY(&fn->downstream))
+ assert(fnh != LIST_FIRST(&fn->nexthops));
+ }
+ if (!RB_EMPTY(lde_map_head, &fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec));
- if (!RB_EMPTY(&fn->upstream))
+ if (!RB_EMPTY(lde_map_head, &fn->upstream))
log_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec));
fn->fec = *fec;
fn->local_label = NO_LABEL;
- RB_INIT(&fn->upstream);
- RB_INIT(&fn->downstream);
+ RB_INIT(lde_map_head, &fn->upstream);
+ RB_INIT(lde_map_head, &fn->downstream);
LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec))
lde_gc_start_timer();
} else {
fn->local_label = lde_update_label(fn);
- if (fn->local_label != NO_LABEL && RB_EMPTY(&fn->upstream))
+ if (fn->local_label != NO_LABEL)
/* FEC.1: perform lsr label distribution procedure */
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_send_labelmapping(ln, fn, 1);
struct lde_req *lre;
struct lde_map *me;
struct l2vpn_pw *pw;
- int msgsource = 0;
lde_map2fec(map, ln->id, &fec);
pw->remote_mtu = map->fec.pwid.ifmtu;
if (map->flags & F_MAP_PW_STATUS)
pw->remote_status = map->pw_status;
+ else
+ pw->remote_status = PW_FORWARDING;
fnh->remote_label = map->label;
if (l2vpn_pw_ok(pw, fnh))
lde_send_change_klabel(fn, fnh);
default:
break;
}
-
- msgsource = 1;
}
/* LMp.13 & LMp.16: Record the mapping from this peer */
if (me == NULL)
me = lde_map_add(ln, fn, 0);
me->map = *map;
- if (msgsource == 0)
- /* LMp.13: just return since we use liberal lbl retention */
- return;
-
/*
* LMp.17 - LMp.27 are unnecessary since we don't need to implement
* loop detection. LMp.28 - LMp.30 are unnecessary because we are
pw = (struct l2vpn_pw *) fn->data;
if (pw == NULL)
continue;
+ pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
struct fec_node *fn;
struct fec_nh *fnh;
struct lde_map *me;
+ struct l2vpn_pw *pw;
/* LWd.2: send label release */
lde_send_labelrelease(ln, NULL, map, map->label);
case FEC_TYPE_PWID:
if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
continue;
+ pw = (struct l2vpn_pw *) fn->data;
+ if (pw)
+ pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) ||
- !RB_EMPTY(&fn->downstream) ||
- !RB_EMPTY(&fn->upstream))
+ !RB_EMPTY(lde_map_head, &fn->downstream) ||
+ !RB_EMPTY(lde_map_head, &fn->upstream))
continue;
fec_remove(&ft, &fn->fec);