summaryrefslogtreecommitdiff
path: root/ldpd/lde.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-03-03 17:50:22 -0300
committerRenato Westphal <renato@opensourcerouting.org>2017-03-03 17:50:22 -0300
commit0bcc2916a08dfb762d8a5775e6b01a4885c8936a (patch)
tree09d352749f431edd8c51ba9ade3dd2b64ac4b2dc /ldpd/lde.c
parentbe8e0d318815395a49632f8c6546be1f96c17557 (diff)
ldpd: implement support for PWid group wildcards
This was missing from our original RFC 4447 VPLS implementation. Now ldpd understands group wildcards as mandated by the RFC, but we still don't send them ourselves. I can't see any case in which sending a group wildcard would be useful, but nonetheless this patch provides a function called lde_send_labelwithdraw_pwid_wcard() which is ready to be used in the future anytime we feel like it might be useful. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ldpd/lde.c')
-rw-r--r--ldpd/lde.c68
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 */