summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-03-31 02:58:47 +0200
committerRenato Westphal <renato@opensourcerouting.org>2017-03-31 17:57:37 +0200
commit52b530fc64355933d428e2b88591cbf926b85bc8 (patch)
tree3aa1c68bb61da7fbd462b86aa0cada9ade2054c6
parentldpd: remove the interface vty node (diff)
downloadfrr-52b530fc64355933d428e2b88591cbf926b85bc8.tar.xz
frr-52b530fc64355933d428e2b88591cbf926b85bc8.zip
ldpd: fix configuration of non-existing VPLS interfaces and pseudowires
If we don't know the ifindex, flags, etc of an interface at the time it's configured, we should make sure that once this information is available the appropriate structures are updated. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--ldpd/interface.c7
-rw-r--r--ldpd/l2vpn.c25
-rw-r--r--ldpd/lde.c34
-rw-r--r--ldpd/lde.h6
-rw-r--r--ldpd/ldp_vty_conf.c75
-rw-r--r--ldpd/ldp_zebra.c6
-rw-r--r--ldpd/ldpd.c11
-rw-r--r--ldpd/ldpe.c13
-rw-r--r--ldpd/ldpe.h2
9 files changed, 80 insertions, 99 deletions
diff --git a/ldpd/interface.c b/ldpd/interface.c
index 17b3237b3..11bce12b0 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -49,17 +49,14 @@ iface_compare(struct iface *a, struct iface *b)
}
struct iface *
-if_new(struct kif *kif)
+if_new(const char *name)
{
struct iface *iface;
if ((iface = calloc(1, sizeof(*iface))) == NULL)
fatal("if_new: calloc");
- strlcpy(iface->name, kif->ifname, sizeof(iface->name));
- LIST_INIT(&iface->addr_list);
- if (kif->ifindex)
- if_update_info(iface, kif);
+ strlcpy(iface->name, name, sizeof(iface->name));
/* ipv4 */
iface->ipv4.af = AF_INET;
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
index bdfcd420e..92d865210 100644
--- a/ldpd/l2vpn.c
+++ b/ldpd/l2vpn.c
@@ -117,7 +117,7 @@ l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b)
}
struct l2vpn_if *
-l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
+l2vpn_if_new(struct l2vpn *l2vpn, const char *ifname)
{
struct l2vpn_if *lif;
@@ -125,9 +125,7 @@ l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
fatal("l2vpn_if_new: calloc");
lif->l2vpn = l2vpn;
- strlcpy(lif->ifname, kif->ifname, sizeof(lif->ifname));
- lif->ifindex = kif->ifindex;
- lif->flags = kif->flags;
+ strlcpy(lif->ifname, ifname, sizeof(lif->ifname));
return (lif);
}
@@ -141,6 +139,14 @@ l2vpn_if_find(struct l2vpn *l2vpn, const char *ifname)
}
void
+l2vpn_if_update_info(struct l2vpn_if *lif, struct kif *kif)
+{
+ lif->ifindex = kif->ifindex;
+ lif->flags = kif->flags;
+ memcpy(lif->mac, kif->mac, sizeof(lif->mac));
+}
+
+void
l2vpn_if_update(struct l2vpn_if *lif)
{
struct l2vpn *l2vpn = lif->l2vpn;
@@ -174,7 +180,7 @@ l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b)
}
struct l2vpn_pw *
-l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
+l2vpn_pw_new(struct l2vpn *l2vpn, const char *ifname)
{
struct l2vpn_pw *pw;
@@ -182,8 +188,7 @@ l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
fatal("l2vpn_pw_new: calloc");
pw->l2vpn = l2vpn;
- strlcpy(pw->ifname, kif->ifname, sizeof(pw->ifname));
- pw->ifindex = kif->ifindex;
+ strlcpy(pw->ifname, ifname, sizeof(pw->ifname));
return (pw);
}
@@ -220,6 +225,12 @@ l2vpn_pw_find_inactive(struct l2vpn *l2vpn, const char *ifname)
}
void
+l2vpn_pw_update_info(struct l2vpn_pw *pw, struct kif *kif)
+{
+ pw->ifindex = kif->ifindex;
+}
+
+void
l2vpn_pw_init(struct l2vpn_pw *pw)
{
struct fec fec;
diff --git a/ldpd/lde.c b/ldpd/lde.c
index bc808e684..607a9f7b1 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -439,13 +439,14 @@ static int
lde_dispatch_parent(struct thread *thread)
{
static struct ldpd_conf *nconf;
- struct iface *niface;
+ struct iface *iface, *niface;
struct tnbr *ntnbr;
struct nbr_params *nnbrp;
- static struct l2vpn *nl2vpn;
- struct l2vpn_if *nlif;
- struct l2vpn_pw *npw;
+ static struct l2vpn *l2vpn, *nl2vpn;
+ struct l2vpn_if *lif, *nlif;
+ struct l2vpn_pw *pw, *npw;
struct imsg imsg;
+ struct kif *kif;
struct kroute *kr;
int fd = THREAD_FD(thread);
struct imsgev *iev = THREAD_ARG(thread);
@@ -468,6 +469,31 @@ lde_dispatch_parent(struct thread *thread)
break;
switch (imsg.hdr.type) {
+ case IMSG_IFSTATUS:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct kif))
+ fatalx("IFSTATUS imsg with wrong len");
+ kif = imsg.data;
+
+ iface = if_lookup_name(ldeconf, kif->ifname);
+ if (iface) {
+ if_update_info(iface, kif);
+ break;
+ }
+
+ RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
+ lif = l2vpn_if_find(l2vpn, kif->ifname);
+ if (lif) {
+ l2vpn_if_update_info(lif, kif);
+ break;
+ }
+ pw = l2vpn_pw_find(l2vpn, kif->ifname);
+ if (pw) {
+ l2vpn_pw_update_info(pw, kif);
+ break;
+ }
+ }
+ break;
case IMSG_NETWORK_ADD:
case IMSG_NETWORK_UPDATE:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
diff --git a/ldpd/lde.h b/ldpd/lde.h
index 8ee62b02d..57791cd1b 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -212,13 +212,15 @@ struct l2vpn *l2vpn_find(struct ldpd_conf *, const char *);
void l2vpn_del(struct l2vpn *);
void l2vpn_init(struct l2vpn *);
void l2vpn_exit(struct l2vpn *);
-struct l2vpn_if *l2vpn_if_new(struct l2vpn *, struct kif *);
+struct l2vpn_if *l2vpn_if_new(struct l2vpn *, const char *);
struct l2vpn_if *l2vpn_if_find(struct l2vpn *, const char *);
+void l2vpn_if_update_info(struct l2vpn_if *, struct kif *);
void l2vpn_if_update(struct l2vpn_if *);
-struct l2vpn_pw *l2vpn_pw_new(struct l2vpn *, struct kif *);
+struct l2vpn_pw *l2vpn_pw_new(struct l2vpn *, const char *);
struct l2vpn_pw *l2vpn_pw_find(struct l2vpn *, const char *);
struct l2vpn_pw *l2vpn_pw_find_active(struct l2vpn *, const char *);
struct l2vpn_pw *l2vpn_pw_find_inactive(struct l2vpn *, const char *);
+void l2vpn_pw_update_info(struct l2vpn_pw *, struct kif *);
void l2vpn_pw_init(struct l2vpn_pw *);
void l2vpn_pw_exit(struct l2vpn_pw *);
void l2vpn_pw_reset(struct l2vpn_pw *);
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index dcf5f5243..4c6cfcd4a 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -907,8 +907,6 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
int af;
struct iface *iface;
struct iface_af *ia;
- struct interface *ifp;
- struct kif kif;
const char *ifname;
int disable;
@@ -940,23 +938,12 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS);
}
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
- iface = if_new(&kif);
-
+ iface = if_new(ifname);
ia = iface_af_get(iface, af);
ia->enabled = 1;
RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
ldp_reload(vty_conf);
} else {
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
-
ia = iface_af_get(iface, af);
if (!ia->enabled) {
ia->enabled = 1;
@@ -1505,8 +1492,6 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
{
struct l2vpn *l2vpn;
struct l2vpn_if *lif;
- struct interface *ifp;
- struct kif kif;
const char *ifname;
int disable;
@@ -1535,15 +1520,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS);
}
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
-
- lif = l2vpn_if_new(l2vpn, &kif);
+ lif = l2vpn_if_new(l2vpn, ifname);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
ldp_reload(vty_conf);
@@ -1556,8 +1533,6 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
{
struct l2vpn *l2vpn;
struct l2vpn_pw *pw;
- struct interface *ifp;
- struct kif kif;
const char *ifname;
int disable;
@@ -1588,15 +1563,7 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS);
}
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
-
- pw = l2vpn_pw_new(l2vpn, &kif);
+ pw = l2vpn_pw_new(l2vpn, ifname);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
@@ -1771,21 +1738,11 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
{
const char *ifname = name;
struct iface *iface;
- struct interface *ifp;
- struct kif kif;
if (ldp_iface_is_configured(conf, ifname))
return NULL;
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
-
- iface = if_new(&kif);
+ iface = if_new(name);
RB_INSERT(iface_head, &conf->iface_tree, iface);
return (iface);
}
@@ -1882,21 +1839,11 @@ l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
const char *ifname)
{
struct l2vpn_if *lif;
- struct interface *ifp;
- struct kif kif;
if (ldp_iface_is_configured(conf, ifname))
return (NULL);
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
-
- lif = l2vpn_if_new(l2vpn, &kif);
+ lif = l2vpn_if_new(l2vpn, ifname);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
return (lif);
}
@@ -1913,21 +1860,11 @@ l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
const char *ifname)
{
struct l2vpn_pw *pw;
- struct interface *ifp;
- struct kif kif;
if (ldp_iface_is_configured(conf, ifname))
return (NULL);
- memset(&kif, 0, sizeof(kif));
- strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
- ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
- if (ifp) {
- kif.ifindex = ifp->ifindex;
- kif.flags = ifp->flags;
- }
-
- pw = l2vpn_pw_new(l2vpn, &kif);
+ pw = l2vpn_pw_new(l2vpn, ifname);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
return (pw);
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index c41a0dbd9..702b5c5ea 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -180,7 +180,7 @@ kif_redistribute(const char *ifname)
continue;
ifp2kif(ifp, &kif);
- main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
+ main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
ifc2kaddr(ifp, ifc, &ka);
@@ -222,7 +222,7 @@ ldp_interface_add(int command, struct zclient *zclient, zebra_size_t length,
ifp->ifindex, ifp->mtu);
ifp2kif(ifp, &kif);
- main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
+ main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
return (0);
}
@@ -270,7 +270,7 @@ ldp_interface_status_change(int command, struct zclient *zclient,
debug_zebra_in("interface %s state update", ifp->name);
ifp2kif(ifp, &kif);
- main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
+ main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
link_new = (ifp->flags & IFF_UP) && (ifp->flags & IFF_RUNNING);
if (link_new) {
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index 3b3a07c28..6c888c534 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -1660,8 +1660,10 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf);
xf->l2vpn = l2vpn;
- if (ldpd_process == PROC_MAIN)
- QOBJ_REG (xf, l2vpn_if);
+ if (ldpd_process == PROC_MAIN) {
+ QOBJ_REG(xf, l2vpn_if);
+ kif_redistribute(xf->ifname);
+ }
continue;
}
@@ -1705,6 +1707,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
break;
case PROC_MAIN:
QOBJ_REG (xp, l2vpn_pw);
+ kif_redistribute(xp->ifname);
break;
}
continue;
@@ -1792,8 +1795,10 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp);
xp->l2vpn = l2vpn;
- if (ldpd_process == PROC_MAIN)
+ if (ldpd_process == PROC_MAIN) {
QOBJ_REG (xp, l2vpn_pw);
+ kif_redistribute(xp->ifname);
+ }
continue;
}
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 96a7052ec..f8e9abab0 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -256,8 +256,8 @@ ldpe_dispatch_main(struct thread *thread)
struct tnbr *ntnbr;
struct nbr_params *nnbrp;
static struct l2vpn *l2vpn, *nl2vpn;
- struct l2vpn_if *lif = NULL, *nlif;
- struct l2vpn_pw *npw;
+ struct l2vpn_if *lif, *nlif;
+ struct l2vpn_pw *pw, *npw;
struct imsg imsg;
int fd = THREAD_FD(thread);
struct imsgev *iev = THREAD_ARG(thread);
@@ -305,12 +305,15 @@ ldpe_dispatch_main(struct thread *thread)
RB_FOREACH(l2vpn, l2vpn_head, &leconf->l2vpn_tree) {
lif = l2vpn_if_find(l2vpn, kif->ifname);
if (lif) {
- lif->flags = kif->flags;
- memcpy(lif->mac, kif->mac,
- sizeof(lif->mac));
+ l2vpn_if_update_info(lif, kif);
l2vpn_if_update(lif);
break;
}
+ pw = l2vpn_pw_find(l2vpn, kif->ifname);
+ if (pw) {
+ l2vpn_pw_update_info(pw, kif);
+ break;
+ }
}
break;
case IMSG_NEWADDR:
diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h
index 8215d0840..e4b8394aa 100644
--- a/ldpd/ldpe.h
+++ b/ldpd/ldpe.h
@@ -214,7 +214,7 @@ void mapping_list_add(struct mapping_head *, struct map *);
void mapping_list_clr(struct mapping_head *);
/* interface.c */
-struct iface *if_new(struct kif *);
+struct iface *if_new(const char *);
void if_exit(struct iface *);
struct iface *if_lookup(struct ldpd_conf *, unsigned short);
struct iface *if_lookup_name(struct ldpd_conf *, const char *);