summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldpd/l2vpn.c12
-rw-r--r--ldpd/lde.c2
-rw-r--r--ldpd/lde.h5
-rw-r--r--ldpd/lde_lib.c17
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;