diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index 3335be08a8..f638d6a65b 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -295,17 +295,26 @@ int l2vpn_pw_ok(struct l2vpn_pw *pw, struct fec_nh *fnh) { /* check for a remote label */ - if (fnh->remote_label == NO_LABEL) + if (fnh->remote_label == NO_LABEL) { + log_warnx("%s: pseudowire %s: no remote label", __func__, + pw->ifname); return (0); + } /* MTUs must match */ - if (pw->l2vpn->mtu != pw->remote_mtu) + if (pw->l2vpn->mtu != pw->remote_mtu) { + log_warnx("%s: pseudowire %s: MTU mismatch detected", __func__, + pw->ifname); return (0); + } /* check pw status if applicable */ if ((pw->flags & F_PW_STATUSTLV) && - pw->remote_status != PW_FORWARDING) + pw->remote_status != PW_FORWARDING) { + log_warnx("%s: pseudowire %s: remote end is down", __func__, + pw->ifname); return (0); + } return (1); } @@ -550,7 +559,8 @@ l2vpn_pw_ctl(pid_t pid) sizeof(pwctl.ifname)); pwctl.pwid = pw->pwid; pwctl.lsr_id = pw->lsr_id; - if (pw->local_status == PW_FORWARDING && + if (pw->enabled && + pw->local_status == PW_FORWARDING && pw->remote_status == PW_FORWARDING) pwctl.status = 1; diff --git a/ldpd/lde.c b/ldpd/lde.c index b597d967d7..63e1e39946 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -767,11 +767,12 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh) sizeof(kr)); break; case FEC_TYPE_PWID: - if (fn->local_label == NO_LABEL || + pw = (struct l2vpn_pw *) fn->data; + if (!pw || fn->local_label == NO_LABEL || fnh->remote_label == NO_LABEL) return; - pw = (struct l2vpn_pw *) fn->data; + pw->enabled = true; pw2zpw(pw, &zpw); zpw.local_label = fn->local_label; zpw.remote_label = fnh->remote_label; @@ -818,6 +819,10 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh) break; case FEC_TYPE_PWID: pw = (struct l2vpn_pw *) fn->data; + if (!pw) + return; + + pw->enabled = false; pw2zpw(pw, &zpw); zpw.local_label = fn->local_label; zpw.remote_label = fnh->remote_label; diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index e703a9ff61..a12a4b913e 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -450,18 +450,38 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, /* loop through all the nexthops */ for (i = 0; i < api.nexthop_num; i++) { api_nh = &api.nexthops[i]; - - switch (kr.af) { - case AF_INET: + switch (api_nh->type) { + case NEXTHOP_TYPE_IPV4: + if (kr.af != AF_INET) + continue; kr.nexthop.v4 = api_nh->gate.ipv4; + kr.ifindex = 0; break; - case AF_INET6: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (kr.af != AF_INET) + continue; + kr.nexthop.v4 = api_nh->gate.ipv4; + kr.ifindex = api_nh->ifindex; + break; + case NEXTHOP_TYPE_IPV6: + if (kr.af != AF_INET6) + continue; kr.nexthop.v6 = api_nh->gate.ipv6; + kr.ifindex = 0; + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (kr.af != AF_INET6) + continue; + kr.nexthop.v6 = api_nh->gate.ipv6; + kr.ifindex = api_nh->ifindex; + break; + case NEXTHOP_TYPE_IFINDEX: + if (!(kr.flags & F_CONNECTED)) + continue; break; default: - break; + continue; } - kr.ifindex = api_nh->ifindex;; debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)", (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix), diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index 5580ea5d67..4824f1720b 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -409,6 +409,7 @@ struct l2vpn_pw { uint32_t pwid; char ifname[IF_NAMESIZE]; unsigned int ifindex; + bool enabled; uint32_t remote_group; uint16_t remote_mtu; uint32_t local_status; diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index d3492fb41c..bbd01a759e 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -73,7 +73,7 @@ struct zebra_pw *zebra_pw_add(struct zebra_vrf *zvrf, const char *ifname, pw->protocol = protocol; pw->vrf_id = zvrf_id(zvrf); pw->client = client; - pw->status = PW_STATUS_UP; + pw->status = PW_STATUS_DOWN; pw->local_label = MPLS_NO_LABEL; pw->remote_label = MPLS_NO_LABEL; pw->flags = F_PSEUDOWIRE_CWORD;