From 84eb735560da869f527706b866d4d16ad3ee5549 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Sep 2019 16:15:32 +0200 Subject: [PATCH 1/3] ospf6d: interface state needs update even w/o area We can't skip reading interface state if there's no area yet, we'll be missing information later when the interface is configured. Signed-off-by: David Lamparter --- ospf6d/ospf6_interface.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 692c84ad08..8fd2755500 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -355,8 +355,6 @@ void ospf6_interface_state_update(struct interface *ifp) oi = (struct ospf6_interface *)ifp->info; if (oi == NULL) return; - if (oi->area == NULL) - return; if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) return; From e59733536272459193b5a149f160db92d9d0570f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Sep 2019 16:18:26 +0200 Subject: [PATCH 2/3] ospf6d: fix mistaken if_is_* instead of oi->type If the user configured an interface to be in a particular mode, we need to be consistent about that. No looking at if_is_pointopoint() or if_is_broadcast(). Signed-off-by: David Lamparter --- ospf6d/ospf6_interface.c | 3 +-- ospf6d/ospf6_neighbor.c | 2 +- ospf6d/ospf6_snmp.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 8fd2755500..d47b22a8c4 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -772,8 +772,7 @@ int interface_up(struct thread *thread) } /* decide next interface state */ - if ((if_is_pointopoint(oi->interface)) - || (oi->type == OSPF_IFTYPE_POINTOPOINT)) { + if (oi->type == OSPF_IFTYPE_POINTOPOINT) { ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi); } else if (oi->priority == 0) ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi); diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 46dc621ae7..dccf15aee2 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -618,7 +618,7 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on) snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s); /* Neighbor State */ - if (if_is_pointopoint(on->ospf6_if->interface)) + if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) snprintf(nstate, sizeof(nstate), "PointToPoint"); else { if (on->router_id == on->drouter) diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index fc7c6177d7..1ba89f3bd6 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -1130,9 +1130,9 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, return SNMP_INTEGER(ntohl(oi->area->area_id)); break; case OSPFv3IFTYPE: - if (if_is_broadcast(oi->interface)) + if (oi->type == OSPF_IFTYPE_BROADCAST) return SNMP_INTEGER(1); - else if (if_is_pointopoint(oi->interface)) + else if (oi->type == OSPF_IFTYPE_POINTOPOINT) return SNMP_INTEGER(3); else break; /* Unknown, don't put anything */ From 5aeb4f3c60789b09b5194da5ea63d036d6c80f6c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Sep 2019 16:19:45 +0200 Subject: [PATCH 3/3] ospf6d: track explicit interface type config If the interface doesn't exist in system, we'll default to broadcast and then later not change that when the interface comes up. Explicitly track whether the user configured the type and properly auto-set it if they didn't. Fixes: #3930 Fixes: #4873 Signed-off-by: David Lamparter --- ospf6d/ospf6_interface.c | 50 +++++++++++++++++++++++++--------------- ospf6d/ospf6_interface.h | 1 + 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index d47b22a8c4..4d7c75a330 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -681,6 +681,9 @@ int interface_up(struct thread *thread) oi = (struct ospf6_interface *)THREAD_ARG(thread); assert(oi && oi->interface); + if (!oi->type_cfg) + oi->type = ospf6_default_iftype(oi->interface); + /* * Remove old pointer. If this thread wasn't a timer this * operation won't make a difference, because it is already NULL. @@ -877,6 +880,19 @@ int interface_down(struct thread *thread) } +static const char *ospf6_iftype_str(uint8_t iftype) +{ + switch (iftype) { + case OSPF_IFTYPE_LOOPBACK: + return "LOOPBACK"; + case OSPF_IFTYPE_BROADCAST: + return "BROADCAST"; + case OSPF_IFTYPE_POINTOPOINT: + return "POINTOPOINT"; + } + return "UNKNOWN"; +} + /* show specified interface structure */ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) { @@ -885,23 +901,16 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) struct prefix *p; struct listnode *i; char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32]; - const char *type; + uint8_t default_iftype; struct timeval res, now; char duration[32]; struct ospf6_lsa *lsa; - /* check physical interface type */ - if (if_is_loopback(ifp)) - type = "LOOPBACK"; - else if (if_is_broadcast(ifp)) - type = "BROADCAST"; - else if (if_is_pointopoint(ifp)) - type = "POINTOPOINT"; - else - type = "UNKNOWN"; + default_iftype = ospf6_default_iftype(ifp); vty_out(vty, "%s is %s, type %s\n", ifp->name, - (if_is_operative(ifp) ? "up" : "down"), type); + (if_is_operative(ifp) ? "up" : "down"), + ospf6_iftype_str(default_iftype)); vty_out(vty, " Interface ID: %d\n", ifp->ifindex); if (ifp->info == NULL) { @@ -910,6 +919,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) } else oi = (struct ospf6_interface *)ifp->info; + if (if_is_operative(ifp) && oi->type != default_iftype) + vty_out(vty, " Operating as type %s\n", + ospf6_iftype_str(oi->type)); + vty_out(vty, " Internet Address:\n"); for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { @@ -1806,6 +1819,8 @@ DEFUN (ipv6_ospf6_network, } assert(oi); + oi->type_cfg = true; + if (strncmp(argv[idx_network]->arg, "b", 1) == 0) { if (oi->type == OSPF_IFTYPE_BROADCAST) return CMD_SUCCESS; @@ -1846,6 +1861,8 @@ DEFUN (no_ipv6_ospf6_network, return CMD_SUCCESS; } + oi->type_cfg = false; + type = ospf6_default_iftype(ifp); if (oi->type == type) { return CMD_SUCCESS; @@ -1913,13 +1930,10 @@ static int config_write_ospf6_interface(struct vty *vty) if (oi->mtu_ignore) vty_out(vty, " ipv6 ospf6 mtu-ignore\n"); - if (oi->type != ospf6_default_iftype(ifp)) { - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - vty_out(vty, - " ipv6 ospf6 network point-to-point\n"); - else if (oi->type == OSPF_IFTYPE_BROADCAST) - vty_out(vty, " ipv6 ospf6 network broadcast\n"); - } + if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT) + vty_out(vty, " ipv6 ospf6 network point-to-point\n"); + else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST) + vty_out(vty, " ipv6 ospf6 network broadcast\n"); ospf6_bfd_write_config(vty, oi); diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index e0c39a29b4..53a8910f4d 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -55,6 +55,7 @@ struct ospf6_interface { /* Network Type */ uint8_t type; + bool type_cfg; /* Router Priority */ uint8_t priority;