diff options
Diffstat (limited to 'ldpd/lde.c')
| -rw-r--r-- | ldpd/lde.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/ldpd/lde.c b/ldpd/lde.c index 6ac0f07daf..3041c44bdc 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -259,16 +259,10 @@ lde_dispatch_imsg(struct thread *thread) lde_check_request(&map, ln); break; case IMSG_LABEL_RELEASE: - if (map.type == MAP_TYPE_WILDCARD) - lde_check_release_wcard(&map, ln); - else - lde_check_release(&map, ln); + lde_check_release(&map, ln); break; case IMSG_LABEL_WITHDRAW: - if (map.type == MAP_TYPE_WILDCARD) - lde_check_withdraw_wcard(&map, ln); - else - lde_check_withdraw(&map, ln); + lde_check_withdraw(&map, ln); break; case IMSG_LABEL_ABORT: /* not necessary */ @@ -929,8 +923,8 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single) } void -lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label, - struct status_tlv *st) +lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, + struct map *wcard, struct status_tlv *st) { struct lde_wdraw *lw; struct map map; @@ -959,11 +953,8 @@ lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label, break; } map.label = fn->local_label; - } else { - memset(&map, 0, sizeof(map)); - map.type = MAP_TYPE_WILDCARD; - map.label = label; - } + } else + memcpy(&map, wcard, sizeof(map)); if (st) { map.st.status_code = st->status_code; @@ -984,8 +975,13 @@ lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label, lw = lde_wdraw_add(ln, fn); lw->label = map.label; } else { + struct lde_map *me; + RB_FOREACH(f, fec_tree, &ft) { fn = (struct fec_node *)f; + me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec); + if (lde_wildcard_apply(wcard, &fn->fec, me) == 0) + continue; lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec); @@ -997,16 +993,34 @@ lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label, } void -lde_send_labelwithdraw_all(struct fec_node *fn, uint32_t label) +lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label) { - struct lde_nbr *ln; + struct map wcard; - RB_FOREACH(ln, nbr_tree, &lde_nbrs) - lde_send_labelwithdraw(ln, fn, label, NULL); + memset(&wcard, 0, sizeof(wcard)); + wcard.type = MAP_TYPE_WILDCARD; + wcard.label = label; + lde_send_labelwithdraw(ln, NULL, &wcard, NULL); } void -lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn, uint32_t label) +lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type, + uint32_t group_id) +{ + struct map wcard; + + memset(&wcard, 0, sizeof(wcard)); + wcard.type = MAP_TYPE_PWID; + wcard.fec.pwid.type = pw_type; + wcard.fec.pwid.group_id = group_id; + /* we can not append a Label TLV when using PWid group wildcards. */ + wcard.label = NO_LABEL; + lde_send_labelwithdraw(ln, NULL, &wcard, NULL); +} + +void +lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn, + struct map *wcard, uint32_t label) { struct map map; struct l2vpn_pw *pw; @@ -1032,10 +1046,8 @@ lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn, uint32_t label) map.flags |= F_MAP_PW_CWORD; break; } - } else { - memset(&map, 0, sizeof(map)); - map.type = MAP_TYPE_WILDCARD; - } + } else + memcpy(&map, wcard, sizeof(map)); map.label = label; lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0, @@ -1352,13 +1364,11 @@ lde_change_egress_label(int af) /* explicitly withdraw all null labels */ RB_FOREACH(ln, nbr_tree, &lde_nbrs) { - lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL, NULL); + lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL); if (ln->v4_enabled) - lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV4NULL, - NULL); + lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL); if (ln->v6_enabled) - lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV6NULL, - NULL); + lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL); } /* update label of connected routes */ |
