diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index 8f255ecfb0..8f0c964c18 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -125,9 +125,12 @@ void zebra_pw_change(struct zebra_pw *pw, ifindex_t ifindex, int type, int af, pw->flags = flags; pw->data = *data; - if (zebra_pw_enabled(pw)) - zebra_register_rnh_pseudowire(pw->vrf_id, pw); - else { + if (zebra_pw_enabled(pw)) { + bool nht_exists; + zebra_register_rnh_pseudowire(pw->vrf_id, pw, &nht_exists); + if (nht_exists) + zebra_pw_update(pw); + } else { if (pw->protocol == ZEBRA_ROUTE_STATIC) zebra_deregister_rnh_pseudowire(pw->vrf_id, pw); zebra_pw_uninstall(pw); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index e94a445098..df6fabd1e1 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -343,25 +343,32 @@ static void addr2hostprefix(int af, const union g_addr *addr, } } -void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw) +void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw, + bool *nht_exists) { struct prefix nh; struct rnh *rnh; bool exists; struct zebra_vrf *zvrf; + *nht_exists = false; + zvrf = vrf_info_lookup(vrf_id); if (!zvrf) return; addr2hostprefix(pw->af, &pw->nexthop, &nh); rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE, &exists); - if (rnh && !listnode_lookup(rnh->zebra_pseudowire_list, pw)) { + if (!rnh) + return; + + if (!listnode_lookup(rnh->zebra_pseudowire_list, pw)) { listnode_add(rnh->zebra_pseudowire_list, pw); pw->rnh = rnh; zebra_evaluate_rnh(zvrf, family2afi(pw->af), 1, RNH_NEXTHOP_TYPE, &nh); - } + } else + *nht_exists = true; } void zebra_deregister_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw) diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index f07e5bc791..e744504920 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -50,7 +50,7 @@ extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, extern void zebra_free_rnh(struct rnh *rnh); extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, enum rnh_type type, vrf_id_t vrfid); -extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *); +extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *, bool *); extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *); extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, enum rnh_type type);