diff options
Diffstat (limited to 'ospf6d/ospf6_interface.c')
| -rw-r--r-- | ospf6d/ospf6_interface.c | 126 |
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; |
