summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_interface.c')
-rw-r--r--ospf6d/ospf6_interface.c126
1 files changed, 71 insertions, 55 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index e0067d6d84..faa92c0dc1 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -44,9 +44,10 @@
#include "ospf6d.h"
#include "ospf6_bfd.h"
#include "ospf6_zebra.h"
+#include "ospf6_gr.h"
#include "lib/json.h"
-DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
+DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names");
DEFINE_QOBJ_TYPE(ospf6_interface);
DEFINE_HOOK(ospf6_interface_change,
@@ -59,6 +60,22 @@ const char *const ospf6_interface_state_str[] = {
"None", "Down", "Loopback", "Waiting", "PointToPoint",
"DROther", "BDR", "DR", NULL};
+int ospf6_interface_neighbor_count(struct ospf6_interface *oi)
+{
+ int count = 0;
+ struct ospf6_neighbor *nbr = NULL;
+ struct listnode *node;
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, nbr)) {
+ /* Down state is not shown. */
+ if (nbr->state == OSPF6_NEIGHBOR_DOWN)
+ continue;
+ count++;
+ }
+
+ return count;
+}
+
struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
vrf_id_t vrf_id)
{
@@ -110,7 +127,7 @@ static uint8_t ospf6_default_iftype(struct interface *ifp)
{
if (if_is_pointopoint(ifp))
return OSPF_IFTYPE_POINTOPOINT;
- else if (if_is_loopback_or_vrf(ifp))
+ else if (if_is_loopback(ifp))
return OSPF_IFTYPE_LOOPBACK;
else
return OSPF_IFTYPE_BROADCAST;
@@ -133,7 +150,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
: OSPF6_INTERFACE_BANDWIDTH;
}
- ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
+ ospf6 = oi->interface->vrf->info;
refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
/* A specifed ip ospf cost overrides a calculated one. */
@@ -370,7 +387,7 @@ void ospf6_interface_state_update(struct interface *ifp)
if (if_is_operative(ifp)
&& (ospf6_interface_get_linklocal_address(oi->interface)
- || if_is_loopback_or_vrf(oi->interface)))
+ || if_is_loopback(oi->interface)))
thread_execute(master, interface_up, oi, 0);
else
thread_execute(master, interface_down, oi, 0);
@@ -579,7 +596,7 @@ static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
return a;
}
-static uint8_t dr_election(struct ospf6_interface *oi)
+uint8_t dr_election(struct ospf6_interface *oi)
{
struct listnode *node, *nnode;
struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
@@ -658,7 +675,8 @@ static uint8_t dr_election(struct ospf6_interface *oi)
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
/* Schedule AdjOK. */
- thread_add_event(master, adj_ok, on, 0, NULL);
+ thread_add_event(master, adj_ok, on, 0,
+ &on->thread_adj_ok);
}
}
@@ -732,7 +750,7 @@ int interface_up(struct thread *thread)
/* check interface has a link-local address */
if (!(ospf6_interface_get_linklocal_address(oi->interface)
- || if_is_loopback_or_vrf(oi->interface))) {
+ || if_is_loopback(oi->interface))) {
zlog_warn(
"Interface %s has no link local address, can't execute [InterfaceUp]",
oi->interface->name);
@@ -801,8 +819,7 @@ int interface_up(struct thread *thread)
/* Schedule Hello */
if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
- && !if_is_loopback_or_vrf(oi->interface)) {
- oi->thread_send_hello = NULL;
+ && !if_is_loopback(oi->interface)) {
thread_add_event(master, ospf6_hello_send, oi, 0,
&oi->thread_send_hello);
}
@@ -896,6 +913,17 @@ int interface_down(struct thread *thread)
/* Stop trying to set socket options. */
THREAD_OFF(oi->thread_sso);
+ /* Cease the HELPER role for all the neighbours
+ * of this interface.
+ */
+ if (ospf6_interface_neighbor_count(oi)) {
+ struct listnode *ln;
+ struct ospf6_neighbor *nbr = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, ln, nbr))
+ ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_TOPO_CHG);
+ }
+
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
ospf6_neighbor_delete(on);
@@ -1218,7 +1246,6 @@ struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
{
struct listnode *n;
struct connected *c;
- struct in6_addr *l = (struct in6_addr *)NULL;
/* for each connected address */
for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
@@ -1227,9 +1254,10 @@ struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
continue;
if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
- l = &c->address->u.prefix6;
+ return &c->address->u.prefix6;
}
- return l;
+
+ return NULL;
}
@@ -1253,10 +1281,7 @@ static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
if (ifp == NULL) {
json_object_string_add(json, "noSuchInterface",
argv[idx_ifname]->arg);
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ vty_json(vty, json);
json_object_free(json_int);
return CMD_WARNING;
}
@@ -1270,10 +1295,7 @@ static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
json_int);
}
}
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ vty_json(vty, json);
} else {
if (argc == intf_idx) {
ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
@@ -1306,7 +1328,6 @@ DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (idx_vrf > 0) {
idx_ifname += 2;
@@ -1338,11 +1359,6 @@ static int ospf6_interface_show_traffic(struct vty *vty,
struct ospf6_interface *oi = NULL;
json_object *json_interface;
- if (intf_ifp)
- vrf = vrf_lookup_by_id(intf_ifp->vrf_id);
- else
- vrf = vrf_lookup_by_id(vrf_id);
-
if (!display_once && !use_json) {
vty_out(vty, "\n");
vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
@@ -1356,6 +1372,7 @@ static int ospf6_interface_show_traffic(struct vty *vty,
}
if (intf_ifp == NULL) {
+ vrf = vrf_lookup_by_id(vrf_id);
FOR_ALL_INTERFACES (vrf, ifp) {
if (ifp->info)
oi = (struct ospf6_interface *)ifp->info;
@@ -1465,10 +1482,7 @@ static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
"No Such Interface");
json_object_string_add(json, "interface",
intf_name);
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ vty_json(vty, json);
return CMD_WARNING;
}
if (ifp->info == NULL) {
@@ -1477,10 +1491,7 @@ static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
"OSPF not enabled on this interface");
json_object_string_add(json, "interface",
intf_name);
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ vty_json(vty, json);
return 0;
}
} else {
@@ -1500,12 +1511,8 @@ static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
ospf6_interface_show_traffic(vty, ifp, display_once, json, uj, vrf_id);
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (uj)
+ vty_json(vty, json);
return CMD_SUCCESS;
}
@@ -1523,7 +1530,6 @@ DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
@@ -1566,7 +1572,6 @@ DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (idx_vrf > 0) {
idx_ifname += 2;
@@ -1627,7 +1632,6 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (idx_vrf > 0)
idx_prefix += 2;
@@ -1665,7 +1669,7 @@ void ospf6_interface_start(struct ospf6_interface *oi)
if (oi->area)
return;
- ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
+ ospf6 = oi->interface->vrf->info;
if (!ospf6)
return;
@@ -2295,7 +2299,7 @@ DEFUN (no_ipv6_ospf6_passive,
THREAD_OFF(oi->thread_sso);
/* don't send hellos over loopback interface */
- if (!if_is_loopback_or_vrf(oi->interface))
+ if (!if_is_loopback(oi->interface))
thread_add_event(master, ospf6_hello_send, oi, 0,
&oi->thread_send_hello);
@@ -2569,7 +2573,7 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
ospf6_bfd_write_config(vty, oi);
- vty_endframe(vty, "!\n");
+ vty_endframe(vty, "exit\n!\n");
}
return 0;
}
@@ -2720,27 +2724,39 @@ void ospf6_interface_clear(struct interface *ifp)
/* Clear interface */
DEFUN (clear_ipv6_ospf6_interface,
clear_ipv6_ospf6_interface_cmd,
- "clear ipv6 ospf6 interface [IFNAME]",
+ "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
CLEAR_STR
IP6_STR
OSPF6_STR
+ VRF_CMD_HELP_STR
INTERFACE_STR
IFNAME_STR
)
{
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ struct vrf *vrf;
+ int idx_vrf = 3;
int idx_ifname = 4;
struct interface *ifp;
+ const char *vrf_name;
+
+ if (argv_find(argv, argc, "vrf", &idx_vrf))
+ vrf_name = argv[idx_vrf + 1]->arg;
+ else
+ vrf_name = VRF_DEFAULT_NAME;
+ vrf = vrf_lookup_by_name(vrf_name);
+ if (!vrf) {
+ vty_out(vty, "%% VRF %s not found\n", vrf_name);
+ return CMD_WARNING;
+ }
- if (argc == 4) /* Clear all the ospfv3 interfaces. */
- {
+ if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
+ /* Clear all the ospfv3 interfaces. */
FOR_ALL_INTERFACES (vrf, ifp)
ospf6_interface_clear(ifp);
- } else /* Interface name is specified. */
- {
- if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- VRF_DEFAULT))
- == NULL) {
+ } else {
+ /* Interface name is specified. */
+ ifp = if_lookup_by_name_vrf(argv[idx_ifname]->arg, vrf);
+ if (!ifp) {
vty_out(vty, "No such Interface: %s\n",
argv[idx_ifname]->arg);
return CMD_WARNING;