mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 00:41:20 +00:00
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>
This commit is contained in:
parent
308252d06d
commit
52b530fc64
@ -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;
|
||||
|
25
ldpd/l2vpn.c
25
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);
|
||||
}
|
||||
@ -140,6 +138,14 @@ l2vpn_if_find(struct l2vpn *l2vpn, const char *ifname)
|
||||
return (RB_FIND(l2vpn_if_head, &l2vpn->if_tree, &lif));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
}
|
||||
@ -219,6 +224,12 @@ l2vpn_pw_find_inactive(struct l2vpn *l2vpn, const char *ifname)
|
||||
return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s));
|
||||
}
|
||||
|
||||
void
|
||||
l2vpn_pw_update_info(struct l2vpn_pw *pw, struct kif *kif)
|
||||
{
|
||||
pw->ifindex = kif->ifindex;
|
||||
}
|
||||
|
||||
void
|
||||
l2vpn_pw_init(struct l2vpn_pw *pw)
|
||||
{
|
||||
|
34
ldpd/lde.c
34
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 +
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
11
ldpd/ldpd.c
11
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;
|
||||
}
|
||||
|
||||
|
13
ldpd/ldpe.c
13
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:
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user