diff options
Diffstat (limited to 'ldpd/lde_lib.c')
| -rw-r--r-- | ldpd/lde_lib.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 8f524e0aa9..11d85b7449 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; @@ -847,6 +856,9 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln) if (me && (map->label == NO_LABEL || map->label == me->map.label)) /* LWd.4: remove record of previously received lbl mapping */ lde_map_del(ln, me, 0); + else + /* LWd.13 done */ + return; /* Ordered Control: additional withdraw steps */ if (ldeconf->flags & F_LDPD_ORDERED_CONTROL) { @@ -858,15 +870,17 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln) /* LWd.9: check if previously sent a label mapping */ me = (struct lde_map *)fec_find(&lnbr->sent_map, &fn->fec); + /* * LWd.10: does label sent to peer "map" to withdraw * label */ - if (me) + if (me && lde_nbr_is_nexthop(fn, lnbr)) /* LWd.11: send label withdraw */ lde_send_labelwithdraw(lnbr, fn, NULL, NULL); } } + } void @@ -924,24 +938,33 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln) * label mapping */ lde_map_del(ln, me, 0); + else + /* LWd.13 done */ + continue; /* Ordered Control: additional withdraw steps */ if (ldeconf->flags & F_LDPD_ORDERED_CONTROL) { - /* LWd.8: for each neighbor other that src of withdraw msg */ + /* + * LWd.8: for each neighbor other that src of + * withdraw msg + */ RB_FOREACH(lnbr, nbr_tree, &lde_nbrs) { if (ln->peerid == lnbr->peerid) continue; - /* LWd.9: check if previously sent a label mapping */ - me = (struct lde_map *)fec_find(&lnbr->sent_map, - &fn->fec); + /* LWd.9: check if previously sent a label + * mapping + */ + me = (struct lde_map *)fec_find( + &lnbr->sent_map, &fn->fec); /* - * LWd.10: does label sent to peer "map" to withdraw - * label + * LWd.10: does label sent to peer "map" to + * withdraw label */ - if (me) + if (me && lde_nbr_is_nexthop(fn, lnbr)) /* LWd.11: send label withdraw */ - lde_send_labelwithdraw(lnbr, fn, NULL, NULL); + lde_send_labelwithdraw(lnbr, fn, NULL, + NULL); } } } |
