static void fec_free(void *);
static struct fec_node *fec_add(struct fec *fec);
static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
- ifindex_t, uint8_t);
+ ifindex_t, uint8_t, unsigned short);
static void fec_nh_del(struct fec_nh *);
RB_GENERATE(fec_tree, fec, entry, fec_compare)
{
struct fec *f;
- while ((f = RB_ROOT(fec_tree, fh)) != NULL) {
+ while (!RB_EMPTY(fec_tree, fh)) {
+ f = RB_ROOT(fec_tree, fh);
+
fec_remove(fh, f);
free_cb(f);
}
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);
+ 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));
struct fec_nh *
fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- ifindex_t ifindex, uint8_t priority)
+ ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{
struct fec_nh *fnh;
if (fnh->af == af &&
ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
fnh->ifindex == ifindex &&
- fnh->priority == priority)
+ fnh->route_type == route_type &&
+ fnh->route_instance == route_instance)
return (fnh);
return (NULL);
static struct fec_nh *
fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- ifindex_t ifindex, uint8_t priority)
+ ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{
struct fec_nh *fnh;
fnh->nexthop = *nexthop;
fnh->ifindex = ifindex;
fnh->remote_label = NO_LABEL;
- fnh->priority = priority;
+ fnh->route_type = route_type;
+ fnh->route_instance = route_instance;
LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
return (fnh);
void
lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
- ifindex_t ifindex, uint8_t priority, int connected, void *data)
+ ifindex_t ifindex, uint8_t route_type, unsigned short route_instance,
+ int connected, void *data)
{
struct fec_node *fn;
struct fec_nh *fnh;
if (data)
fn->data = data;
- fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, route_type, route_instance);
if (fnh == NULL)
- fnh = fec_nh_add(fn, af, nexthop, ifindex, priority);
+ fnh = fec_nh_add(fn, af, nexthop, ifindex, route_type,
+ route_instance);
fnh->flags |= F_FEC_NH_NEW;
if (connected)
fnh->flags |= F_FEC_NH_CONNECTED;
void
lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
- ifindex_t ifindex, uint8_t priority)
+ ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{
struct fec_node *fn;
struct fec_nh *fnh;
if (fn == NULL)
/* route lost */
return;
- fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, route_type, route_instance);
if (fnh == NULL)
/* route lost */
return;
lde_gc_start_timer();
} else {
fn->local_label = lde_update_label(fn);
- if (fn->local_label != NO_LABEL &&
- RB_EMPTY(lde_map_head, &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);
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);
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;
!RB_EMPTY(lde_map_head, &fn->upstream))
continue;
+ if (fn->local_label != NO_LABEL)
+ lde_free_label(fn->local_label);
+
fec_remove(&ft, &fn->fec);
free(fn);
count++;