diff options
-rw-r--r-- | ldpd/l2vpn.c | 12 | ||||
-rw-r--r-- | ldpd/lde.c | 2 | ||||
-rw-r--r-- | ldpd/lde.h | 5 | ||||
-rw-r--r-- | ldpd/lde_lib.c | 17 |
4 files changed, 30 insertions, 6 deletions
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index 0d479e77b..2c68f3edb 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -294,6 +294,16 @@ l2vpn_pw_reset(struct l2vpn_pw *pw) pw->flags |= F_PW_STATUSTLV; else pw->flags &= ~F_PW_STATUSTLV; + + if (pw->flags & F_PW_STATUSTLV_CONF) { + struct fec_node *fn; + struct fec fec; + l2vpn_pw_fec(pw, &fec); + fn = (struct fec_node *)fec_find(&ft, &fec); + if (fn) + pw->remote_status = fn->pw_remote_status; + } + } int @@ -433,6 +443,8 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm) /* unknown fec */ return; + fn->pw_remote_status = nm->pw_status; + pw = (struct l2vpn_pw *) fn->data; if (pw == NULL) return; diff --git a/ldpd/lde.c b/ldpd/lde.c index 4fca4b096..734c1ea23 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -296,7 +296,7 @@ lde_dispatch_imsg(struct thread *thread) switch (imsg.hdr.type) { case IMSG_LABEL_MAPPING: - lde_check_mapping(map, ln); + lde_check_mapping(map, ln, 1); break; case IMSG_LABEL_REQUEST: lde_check_request(map, ln); diff --git a/ldpd/lde.h b/ldpd/lde.h index 2895e00ae..9e6db3a90 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -125,6 +125,9 @@ struct fec_node { struct lde_map_head upstream; /* sent mappings */ uint32_t local_label; + + uint32_t pw_remote_status; + void *data; /* fec specific data */ }; @@ -209,7 +212,7 @@ void lde_kernel_insert(struct fec *, int, union ldpd_addr *, void lde_kernel_remove(struct fec *, int, union ldpd_addr *, ifindex_t, uint8_t, unsigned short); void lde_kernel_update(struct fec *); -void lde_check_mapping(struct map *, struct lde_nbr *); +void lde_check_mapping(struct map *, struct lde_nbr *, int); void lde_check_request(struct map *, struct lde_nbr *); void lde_check_request_wcard(struct map *, struct lde_nbr *); void lde_check_release(struct map *, struct lde_nbr *); diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 8f524e0aa..71fb0c7bf 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -267,6 +267,9 @@ fec_add(struct fec *fec) RB_INIT(lde_map_head, &fn->downstream); LIST_INIT(&fn->nexthops); + if (fec->type == FEC_TYPE_PWID) + fn->pw_remote_status = PW_FORWARDING; + if (fec_insert(&ft, &fn->fec)) log_warnx("failed to add %s to ft tree", log_fec(&fn->fec)); @@ -455,13 +458,13 @@ lde_kernel_update(struct fec *fec) me = (struct lde_map *)fec_find(&ln->recv_map, &fn->fec); if (me) /* FEC.5 */ - lde_check_mapping(&me->map, ln); + lde_check_mapping(&me->map, ln, 0); } } } void -lde_check_mapping(struct map *map, struct lde_nbr *ln) +lde_check_mapping(struct map *map, struct lde_nbr *ln, int rcvd_label_mapping) { struct fec fec; struct fec_node *fn; @@ -507,8 +510,12 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln) lde_req_del(ln, lre, 1); /* RFC 4447 control word and status tlv negotiation */ - if (map->type == MAP_TYPE_PWID && l2vpn_pw_negotiate(ln, fn, map)) + if (map->type == MAP_TYPE_PWID && l2vpn_pw_negotiate(ln, fn, map)) { + if (rcvd_label_mapping && map->flags & F_MAP_PW_STATUS) + fn->pw_remote_status = map->pw_status; + return; + } /* * LMp.3 - LMp.8: loop detection - unnecessary for frame-mode @@ -570,8 +577,10 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln) pw->remote_group = map->fec.pwid.group_id; if (map->flags & F_MAP_PW_IFMTU) pw->remote_mtu = map->fec.pwid.ifmtu; - if (map->flags & F_MAP_PW_STATUS) + if (rcvd_label_mapping && map->flags & F_MAP_PW_STATUS) { pw->remote_status = map->pw_status; + fn->pw_remote_status = map->pw_status; + } else pw->remote_status = PW_FORWARDING; fnh->remote_label = map->label; |