diff options
Diffstat (limited to 'ospf6d/ospf6_interface.c')
| -rw-r--r-- | ospf6d/ospf6_interface.c | 952 |
1 files changed, 514 insertions, 438 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index e7148d66ba..b9dace2fe8 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -35,6 +35,7 @@ #include "ospf6_proto.h" #include "lib/keychain.h" #include "ospf6_auth_trailer.h" +#include "ospf6d/ospf6_interface_clippy.c" DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface"); DEFINE_MTYPE(OSPF6D, OSPF6_AUTH_KEYCHAIN, "OSPF6 auth keychain"); @@ -48,8 +49,9 @@ DEFINE_HOOK(ospf6_interface_change, unsigned char conf_debug_ospf6_interface = 0; const char *const ospf6_interface_state_str[] = { - "None", "Down", "Loopback", "Waiting", "PointToPoint", - "DROther", "BDR", "DR", NULL}; + "None", "Down", "Loopback", "Waiting", "PointToPoint", + "PtMultipoint", "DROther", "BDR", "DR", NULL +}; int ospf6_interface_neighbor_count(struct ospf6_interface *oi) { @@ -82,8 +84,7 @@ struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex, } /* schedule routing table recalculation */ -static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa, - unsigned int reason) +static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa, unsigned int reason) { struct ospf6_interface *oi; @@ -130,6 +131,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi) uint32_t cost; uint32_t bw, refbw; struct ospf6 *ospf6; + /* interface speed and bw can be 0 in some platforms, * use ospf default bw. If bw is configured then it would * be used. @@ -151,6 +153,15 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi) cost = (uint32_t)((double)refbw / (double)bw + (double)0.5); if (cost < 1) cost = 1; + + /* If the interface type is point-to-multipoint or the interface + * is in the state Loopback, the global scope IPv6 addresses + * associated with the interface (if any) are copied into the + * intra-area-prefix-LSA with the PrefixOptions LA-bit set, the + * PrefixLength set to 128, and the metric set to 0. + */ + if (if_is_loopback(oi->interface)) + cost = 0; } return cost; @@ -202,6 +213,7 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp) oi->priority = OSPF6_INTERFACE_PRIORITY; oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; + oi->gr.hello_delay.interval = OSPF_HELLO_DELAY_DEFAULT; oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; oi->type = ospf6_default_iftype(ifp); @@ -215,9 +227,8 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp) iobuflen = ospf6_iobuf_size(ifp->mtu6); if (oi->ifmtu > iobuflen) { if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug( - "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); + zlog_debug("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", + ifp->name, iobuflen); oi->ifmtu = iobuflen; } @@ -230,8 +241,8 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp) oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove; oi->lsdb_self = ospf6_lsdb_create(oi); - oi->route_connected = - OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES); + oi->route_connected = OSPF6_ROUTE_TABLE_CREATE(INTERFACE, + CONNECTED_ROUTES); oi->route_connected->scope = oi; /* link both */ @@ -307,7 +318,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi) { SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE); - event_execute(master, interface_down, oi, 0); + event_execute(master, interface_down, oi, 0, NULL); ospf6_lsdb_remove_all(oi->lsdb); ospf6_lsdb_remove_all(oi->lsdb_self); @@ -324,17 +335,19 @@ void ospf6_interface_disable(struct ospf6_interface *oi) EVENT_OFF(oi->thread_intra_prefix_lsa); EVENT_OFF(oi->thread_as_extern_lsa); EVENT_OFF(oi->thread_wait_timer); + + oi->gr.hello_delay.elapsed_seconds = 0; + EVENT_OFF(oi->gr.hello_delay.t_grace_send); } static struct in6_addr * ospf6_interface_get_linklocal_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)) { + frr_each (if_connected, ifp->connected, c) { /* if family not AF_INET6, ignore */ if (c->address->family != AF_INET6) continue; @@ -365,26 +378,24 @@ void ospf6_interface_state_update(struct interface *ifp) iobuflen = ospf6_iobuf_size(ifp->mtu6); if (oi->ifmtu > iobuflen) { if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug( - "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); + zlog_debug("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", + ifp->name, iobuflen); oi->ifmtu = iobuflen; } } else if (oi->c_ifmtu > ifp->mtu6) { oi->ifmtu = ifp->mtu6; - zlog_warn( - "Configured mtu %u on %s overridden by kernel %u", - oi->c_ifmtu, ifp->name, ifp->mtu6); + zlog_warn("Configured mtu %u on %s overridden by kernel %u", + oi->c_ifmtu, ifp->name, ifp->mtu6); } else oi->ifmtu = oi->c_ifmtu; } - if (if_is_operative(ifp) - && (ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) - event_execute(master, interface_up, oi, 0); + if (if_is_operative(ifp) && + (ospf6_interface_get_linklocal_address(oi->interface) || + if_is_loopback(oi->interface))) + event_execute(master, interface_up, oi, 0, NULL); else - event_execute(master, interface_down, oi, 0); + event_execute(master, interface_down, oi, 0, NULL); return; } @@ -392,9 +403,7 @@ void ospf6_interface_state_update(struct interface *ifp) void ospf6_interface_connected_route_update(struct interface *ifp) { struct ospf6_interface *oi; - struct ospf6_route *route; struct connected *c; - struct listnode *node, *nnode; struct in6_addr nh_addr; oi = (struct ospf6_interface *)ifp->info; @@ -414,7 +423,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp) /* update "route to advertise" interface route table */ ospf6_route_remove_all(oi->route_connected); - for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) { + frr_each (if_connected, ifp->connected, c) { if (c->address->family != AF_INET6) continue; @@ -438,14 +447,43 @@ void ospf6_interface_connected_route_update(struct interface *ifp) ret = prefix_list_apply(plist, (void *)c->address); if (ret == PREFIX_DENY) { if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug( - "%pFX on %s filtered by prefix-list %s ", - c->address, oi->interface->name, - oi->plist_name); + zlog_debug("%pFX on %s filtered by prefix-list %s ", + c->address, + oi->interface->name, + oi->plist_name); continue; } } + if (oi->state == OSPF6_INTERFACE_LOOPBACK || + oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT || + oi->state == OSPF6_INTERFACE_POINTTOPOINT) { + struct ospf6_route *la_route; + + la_route = ospf6_route_create(oi->area->ospf6); + la_route->prefix = *c->address; + la_route->prefix.prefixlen = 128; + la_route->prefix_options |= OSPF6_PREFIX_OPTION_LA; + + la_route->type = OSPF6_DEST_TYPE_NETWORK; + la_route->path.area_id = oi->area->area_id; + la_route->path.type = OSPF6_PATH_TYPE_INTRA; + la_route->path.cost = 0; + inet_pton(AF_INET6, "::1", &nh_addr); + ospf6_route_add_nexthop(la_route, oi->interface->ifindex, + &nh_addr); + ospf6_route_add(la_route, oi->route_connected); + } + + if (oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT && + !oi->p2xp_connected_pfx_include) + continue; + if (oi->state == OSPF6_INTERFACE_POINTTOPOINT && + oi->p2xp_connected_pfx_exclude) + continue; + + struct ospf6_route *route; + route = ospf6_route_create(oi->area->ospf6); memcpy(&route->prefix, c->address, sizeof(struct prefix)); apply_mask(&route->prefix); @@ -454,8 +492,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp) route->path.type = OSPF6_PATH_TYPE_INTRA; route->path.cost = oi->cost; inet_pton(AF_INET6, "::1", &nh_addr); - ospf6_route_add_nexthop(route, oi->interface->ifindex, - &nh_addr); + ospf6_route_add_nexthop(route, oi->interface->ifindex, &nh_addr); ospf6_route_add(route, oi->route_connected); } @@ -491,17 +528,17 @@ static int ospf6_interface_state_change(uint8_t next_state, ospf6 = oi->area->ospf6; - if ((prev_state == OSPF6_INTERFACE_DR - || prev_state == OSPF6_INTERFACE_BDR) - && (next_state != OSPF6_INTERFACE_DR - && next_state != OSPF6_INTERFACE_BDR)) + if ((prev_state == OSPF6_INTERFACE_DR || + prev_state == OSPF6_INTERFACE_BDR) && + (next_state != OSPF6_INTERFACE_DR && + next_state != OSPF6_INTERFACE_BDR)) ospf6_sso(oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP, ospf6->fd); - if ((prev_state != OSPF6_INTERFACE_DR - && prev_state != OSPF6_INTERFACE_BDR) - && (next_state == OSPF6_INTERFACE_DR - || next_state == OSPF6_INTERFACE_BDR)) + if ((prev_state != OSPF6_INTERFACE_DR && + prev_state != OSPF6_INTERFACE_BDR) && + (next_state == OSPF6_INTERFACE_DR || + next_state == OSPF6_INTERFACE_BDR)) ospf6_sso(oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP, ospf6->fd); @@ -511,14 +548,17 @@ static int ospf6_interface_state_change(uint8_t next_state, OSPF6_NETWORK_LSA_EXECUTE(oi); OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); - OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); - } else if (prev_state == OSPF6_INTERFACE_DR - || next_state == OSPF6_INTERFACE_DR) { + } else if (prev_state == OSPF6_INTERFACE_DR || + next_state == OSPF6_INTERFACE_DR) { OSPF6_NETWORK_LSA_SCHEDULE(oi); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); } + if (next_state == OSPF6_INTERFACE_POINTTOPOINT || + next_state == OSPF6_INTERFACE_POINTTOMULTIPOINT) + ospf6_if_p2xp_up(oi); + hook_call(ospf6_interface_change, oi, next_state, prev_state); return 0; @@ -533,8 +573,8 @@ static int ospf6_interface_state_change(uint8_t next_state, static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a, struct ospf6_neighbor *b) { - if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) - && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)) + if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) && + (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)) return NULL; else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) return b; @@ -563,8 +603,8 @@ static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a, static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a, struct ospf6_neighbor *b) { - if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) - && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)) + if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) && + (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)) return NULL; else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) return b; @@ -627,10 +667,10 @@ uint8_t dr_election(struct ospf6_interface *oi) drouter = bdrouter; /* the router itself is newly/no longer DR/BDR (4) */ - if ((drouter == &myself && myself.drouter != myself.router_id) - || (drouter != &myself && myself.drouter == myself.router_id) - || (bdrouter == &myself && myself.bdrouter != myself.router_id) - || (bdrouter != &myself && myself.bdrouter == myself.router_id)) { + if ((drouter == &myself && myself.drouter != myself.router_id) || + (drouter != &myself && myself.drouter == myself.router_id) || + (bdrouter == &myself && myself.bdrouter != myself.router_id) || + (bdrouter != &myself && myself.bdrouter == myself.router_id)) { myself.drouter = (drouter ? drouter->router_id : htonl(0)); myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0)); @@ -704,8 +744,8 @@ static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr) continue; sdl = (struct sockaddr_dl *)ifma->ifma_name; sin6 = (struct sockaddr_in6 *)ifma->ifma_addr; - if (sdl->sdl_index == ifindex - && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) { + if (sdl->sdl_index == ifindex && + memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) { found = true; break; } @@ -745,11 +785,10 @@ void interface_up(struct event *thread) } /* check interface has a link-local address */ - if (!(ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) { - zlog_warn( - "Interface %s has no link local address, can't execute [InterfaceUp]", - oi->interface->name); + if (!(ospf6_interface_get_linklocal_address(oi->interface) || + if_is_loopback(oi->interface))) { + zlog_warn("Interface %s has no link local address, can't execute [InterfaceUp]", + oi->interface->name); return; } @@ -766,12 +805,22 @@ void interface_up(struct event *thread) /* If no area assigned, return */ if (oi->area == NULL) { - zlog_warn( - "%s: Not scheduling Hello for %s as there is no area assigned yet", - __func__, oi->interface->name); + zlog_warn("%s: Not scheduling Hello for %s as there is no area assigned yet", + __func__, oi->interface->name); return; } + /* + * RFC 3623 - Section 5 ("Unplanned Outages"): + * "The grace-LSAs are encapsulated in Link State Update Packets + * and sent out to all interfaces, even though the restarted + * router has no adjacencies and no knowledge of previous + * adjacencies". + */ + if (oi->area->ospf6->gr_info.restart_in_progress && + oi->area->ospf6->gr_info.reason == OSPF6_GR_UNKNOWN_RESTART) + ospf6_gr_unplanned_start_interface(oi); + #ifdef __FreeBSD__ /* * There's a delay in FreeBSD between issuing a command to leave a @@ -782,9 +831,8 @@ void interface_up(struct event *thread) * the interface actually left the group. */ if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) { - zlog_info( - "Interface %s is still in all routers group, rescheduling for SSO", - oi->interface->name); + zlog_info("Interface %s is still in all routers group, rescheduling for SSO", + oi->interface->name); event_add_timer(master, interface_up, oi, OSPF6_INTERFACE_SSO_RETRY_INT, &oi->thread_sso); return; @@ -795,12 +843,10 @@ void interface_up(struct event *thread) /* Join AllSPFRouters */ if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP, - ospf6->fd) - < 0) { + ospf6->fd) < 0) { if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) { - zlog_info( - "Scheduling %s for sso retry, trial count: %d", - oi->interface->name, oi->sso_try_cnt); + zlog_info("Scheduling %s for sso retry, trial count: %d", + oi->interface->name, oi->sso_try_cnt); event_add_timer(master, interface_up, oi, OSPF6_INTERFACE_SSO_RETRY_INT, &oi->thread_sso); @@ -813,8 +859,8 @@ void interface_up(struct event *thread) ospf6_interface_connected_route_update(oi->interface); /* Schedule Hello */ - if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE) - && !if_is_loopback(oi->interface)) { + if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE) && + !if_is_loopback(oi->interface)) { event_add_timer(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello); } @@ -824,6 +870,9 @@ void interface_up(struct event *thread) ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi); } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) { ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi); + } else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { + ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOMULTIPOINT, + oi); } else if (oi->priority == 0) ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi); else { @@ -874,9 +923,8 @@ void neighbor_change(struct event *thread) zlog_debug("Interface Event %s: [NeighborChange]", oi->interface->name); - if (oi->state == OSPF6_INTERFACE_DROTHER - || oi->state == OSPF6_INTERFACE_BDR - || oi->state == OSPF6_INTERFACE_DR) + if (oi->state == OSPF6_INTERFACE_DROTHER || + oi->state == OSPF6_INTERFACE_BDR || oi->state == OSPF6_INTERFACE_DR) ospf6_interface_state_change(dr_election(oi), oi); } @@ -952,6 +1000,8 @@ static const char *ospf6_iftype_str(uint8_t iftype) return "BROADCAST"; case OSPF_IFTYPE_POINTOPOINT: return "POINTOPOINT"; + case OSPF_IFTYPE_POINTOMULTIPOINT: + return "POINTOMULTIPOINT"; } return "UNKNOWN"; } @@ -963,7 +1013,6 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, struct ospf6_interface *oi; struct connected *c; struct prefix *p; - struct listnode *i; char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32]; uint8_t default_iftype; struct timeval res, now; @@ -1010,7 +1059,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, if (use_json) { json_arr = json_object_new_array(); - for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { + frr_each (if_connected, ifp->connected, c) { json_addr = json_object_new_object(); p = c->address; prefix2str(p, strbuf, sizeof(strbuf)); @@ -1042,7 +1091,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, } else { vty_out(vty, " Internet Address:\n"); - for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { + frr_each (if_connected, ifp->connected, c) { p = c->address; prefix2str(p, strbuf, sizeof(strbuf)); switch (p->family) { @@ -1061,12 +1110,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, if (use_json) { if (oi->area) { - json_object_boolean_true_add(json_obj, - "attachedToArea"); + json_object_boolean_true_add(json_obj, "attachedToArea"); json_object_int_add(json_obj, "instanceId", oi->instance_id); - json_object_int_add(json_obj, "interfaceMtu", - oi->ifmtu); + json_object_int_add(json_obj, "interfaceMtu", oi->ifmtu); json_object_int_add(json_obj, "autoDetect", ifp->mtu6); json_object_string_add(json_obj, "mtuMismatchDetection", oi->mtu_ignore ? "disabled" @@ -1106,9 +1153,9 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, oi->dead_interval); json_object_int_add(json_obj, "timerIntervalsConfigRetransmit", oi->rxmt_interval); - json_object_boolean_add( - json_obj, "timerPassiveIface", - !!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)); + json_object_boolean_add(json_obj, "timerPassiveIface", + !!CHECK_FLAG(oi->flag, + OSPF6_INTERFACE_PASSIVE)); } else { vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n", ospf6_interface_state_str[oi->state], oi->transdelay, @@ -1141,24 +1188,23 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, if (use_json) { timerclear(&res); if (event_is_scheduled(oi->thread_send_lsupdate)) - timersub(&oi->thread_send_lsupdate->u.sands, &now, - &res); + timersub(&oi->thread_send_lsupdate->u.sands, &now, &res); timerstring(&res, duration, sizeof(duration)); json_object_int_add(json_obj, "pendingLsaLsUpdateCount", oi->lsupdate_list->count); json_object_string_add(json_obj, "pendingLsaLsUpdateTime", duration); - json_object_string_add( - json_obj, "lsUpdateSendThread", - (event_is_scheduled(oi->thread_send_lsupdate) ? "on" - : "off")); + json_object_string_add(json_obj, "lsUpdateSendThread", + (event_is_scheduled( + oi->thread_send_lsupdate) + ? "on" + : "off")); json_arr = json_object_new_array(); for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) - json_object_array_add( - json_arr, json_object_new_string(lsa->name)); - json_object_object_add(json_obj, "pendingLsaLsUpdate", - json_arr); + json_object_array_add(json_arr, + json_object_new_string(lsa->name)); + json_object_object_add(json_obj, "pendingLsaLsUpdate", json_arr); timerclear(&res); if (event_is_scheduled(oi->thread_send_lsack)) @@ -1169,22 +1215,24 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, oi->lsack_list->count); json_object_string_add(json_obj, "pendingLsaLsAckTime", duration); - json_object_string_add( - json_obj, "lsAckSendThread", - (event_is_scheduled(oi->thread_send_lsack) ? "on" - : "off")); + json_object_string_add(json_obj, "lsAckSendThread", + (event_is_scheduled(oi->thread_send_lsack) + ? "on" + : "off")); json_arr = json_object_new_array(); for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) - json_object_array_add( - json_arr, json_object_new_string(lsa->name)); + json_object_array_add(json_arr, + json_object_new_string(lsa->name)); json_object_object_add(json_obj, "pendingLsaLsAck", json_arr); + if (oi->gr.hello_delay.interval != 0) + json_object_int_add(json_obj, "grHelloDelaySecs", + oi->gr.hello_delay.interval); } else { timerclear(&res); if (event_is_scheduled(oi->thread_send_lsupdate)) - timersub(&oi->thread_send_lsupdate->u.sands, &now, - &res); + timersub(&oi->thread_send_lsupdate->u.sands, &now, &res); timerstring(&res, duration, sizeof(duration)); vty_out(vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", @@ -1205,6 +1253,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, : "off")); for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); + + if (oi->gr.hello_delay.interval != 0) + vty_out(vty, " Graceful Restart hello delay: %us\n", + oi->gr.hello_delay.interval); } /* BFD specific. */ @@ -1212,9 +1264,8 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, if (use_json) { struct json_object *json_bfd = json_object_new_object(); - json_object_int_add( - json_bfd, "detectMultiplier", - oi->bfd_config.detection_multiplier); + json_object_int_add(json_bfd, "detectMultiplier", + oi->bfd_config.detection_multiplier); json_object_int_add(json_bfd, "rxMinInterval", oi->bfd_config.min_rx); json_object_int_add(json_bfd, "txMinInterval", @@ -1237,8 +1288,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, OSPF6_AUTH_TRAILER_KEYCHAIN)) { json_object_string_add(json_auth, "authType", "keychain"); - json_object_string_add(json_auth, - "keychainName", + json_object_string_add(json_auth, "keychainName", oi->at_data.keychain); } else if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY)) @@ -1278,11 +1328,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp, /* Find the global address to be used as a forwarding address in NSSA LSA.*/ struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp) { - struct listnode *n; struct connected *c; /* for each connected address */ - for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) { + frr_each (if_connected, ifp->connected, c) { /* if family not AF_INET6, ignore */ if (c->address->family != AF_INET6) continue; @@ -1300,7 +1349,6 @@ static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id, int idx_ifname, int intf_idx, int json_idx, bool uj) { - struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct interface *ifp; json_object *json; @@ -1430,18 +1478,15 @@ static int ospf6_interface_show_traffic(struct vty *vty, json_object_int_add(json_interface, "lsReqTx", oi->ls_req_out); json_object_int_add(json_interface, - "lsUpdateRx", - oi->ls_upd_in); - json_object_int_add(json_interface, - "lsUpdateTx", + "lsUpdateRx", oi->ls_upd_in); + json_object_int_add(json_interface, "lsUpdateTx", oi->ls_upd_out); json_object_int_add(json_interface, "lsAckRx", oi->ls_ack_in); json_object_int_add(json_interface, "lsAckTx", oi->ls_ack_out); - json_object_object_add(json, - oi->interface->name, + json_object_object_add(json, oi->interface->name, json_interface); } else vty_out(vty, @@ -1627,8 +1672,8 @@ DEFUN(show_ipv6_ospf6_interface_ifname_prefix, } oi = ifp->info; - if (oi == NULL - || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { + if (oi == NULL || + CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { vty_out(vty, "Interface %s not attached to area\n", argv[idx_ifname]->arg); @@ -1655,8 +1700,7 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd, |<X:X::X:X|X:X::X:X/M> [<match|detail>]\ >] [json]", SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR - "All VRFs\n" INTERFACE_STR - "Display connected prefixes to advertise\n" + "All VRFs\n" INTERFACE_STR "Display connected prefixes to advertise\n" "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR "Display details of the prefixes\n" JSON_STR) @@ -1681,9 +1725,9 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd, vrf = vrf_lookup_by_id(ospf6->vrf_id); FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; - if (oi == NULL - || CHECK_FLAG(oi->flag, - OSPF6_INTERFACE_DISABLE)) + if (oi == NULL || + CHECK_FLAG(oi->flag, + OSPF6_INTERFACE_DISABLE)) continue; ospf6_route_table_show(vty, idx_prefix, argc, @@ -1758,14 +1802,11 @@ void ospf6_interface_stop(struct ospf6_interface *oi) } /* interface variable set command */ -DEFUN (ipv6_ospf6_area, - ipv6_ospf6_area_cmd, - "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>", - IP6_STR - OSPF6_STR - "Specify the OSPF6 area ID\n" - "OSPF6 area ID in IPv4 address notation\n" - "OSPF6 area ID in decimal notation\n") +DEFUN(ipv6_ospf6_area, ipv6_ospf6_area_cmd, + "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>", + IP6_STR OSPF6_STR "Specify the OSPF6 area ID\n" + "OSPF6 area ID in IPv4 address notation\n" + "OSPF6 area ID in decimal notation\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1799,15 +1840,11 @@ DEFUN (ipv6_ospf6_area, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_area, - no_ipv6_ospf6_area_cmd, - "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]", - NO_STR - IP6_STR - OSPF6_STR - "Specify the OSPF6 area ID\n" - "OSPF6 area ID in IPv4 address notation\n" - "OSPF6 area ID in decimal notation\n") +DEFUN(no_ipv6_ospf6_area, no_ipv6_ospf6_area_cmd, + "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]", + NO_STR IP6_STR OSPF6_STR "Specify the OSPF6 area ID\n" + "OSPF6 area ID in IPv4 address notation\n" + "OSPF6 area ID in decimal notation\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1827,14 +1864,9 @@ DEFUN (no_ipv6_ospf6_area, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_ifmtu, - ipv6_ospf6_ifmtu_cmd, - "ipv6 ospf6 ifmtu (1-65535)", - IP6_STR - OSPF6_STR - "Interface MTU\n" - "OSPFv3 Interface MTU\n" - ) +DEFUN(ipv6_ospf6_ifmtu, ipv6_ospf6_ifmtu_cmd, "ipv6 ospf6 ifmtu (1-65535)", + IP6_STR OSPF6_STR "Interface MTU\n" + "OSPFv3 Interface MTU\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1883,15 +1915,10 @@ DEFUN (ipv6_ospf6_ifmtu, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_ifmtu, - no_ipv6_ospf6_ifmtu_cmd, - "no ipv6 ospf6 ifmtu [(1-65535)]", - NO_STR - IP6_STR - OSPF6_STR - "Interface MTU\n" - "OSPFv3 Interface MTU\n" - ) +DEFUN(no_ipv6_ospf6_ifmtu, no_ipv6_ospf6_ifmtu_cmd, + "no ipv6 ospf6 ifmtu [(1-65535)]", + NO_STR IP6_STR OSPF6_STR "Interface MTU\n" + "OSPFv3 Interface MTU\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1929,13 +1956,9 @@ DEFUN (no_ipv6_ospf6_ifmtu, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_cost, - ipv6_ospf6_cost_cmd, - "ipv6 ospf6 cost (1-65535)", - IP6_STR - OSPF6_STR - "Interface cost\n" - "Outgoing metric of this interface\n") +DEFUN(ipv6_ospf6_cost, ipv6_ospf6_cost_cmd, "ipv6 ospf6 cost (1-65535)", + IP6_STR OSPF6_STR "Interface cost\n" + "Outgoing metric of this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -1966,14 +1989,10 @@ DEFUN (ipv6_ospf6_cost, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_cost, - no_ipv6_ospf6_cost_cmd, - "no ipv6 ospf6 cost [(1-65535)]", - NO_STR - IP6_STR - OSPF6_STR - "Calculate interface cost from bandwidth\n" - "Outgoing metric of this interface\n") +DEFUN(no_ipv6_ospf6_cost, no_ipv6_ospf6_cost_cmd, + "no ipv6 ospf6 cost [(1-65535)]", + NO_STR IP6_STR OSPF6_STR "Calculate interface cost from bandwidth\n" + "Outgoing metric of this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -1991,12 +2010,11 @@ DEFUN (no_ipv6_ospf6_cost, return CMD_SUCCESS; } -DEFUN (auto_cost_reference_bandwidth, - auto_cost_reference_bandwidth_cmd, - "auto-cost reference-bandwidth (1-4294967)", - "Calculate OSPF interface cost according to bandwidth\n" - "Use reference bandwidth method to assign OSPF cost\n" - "The reference bandwidth in terms of Mbits per second\n") +DEFUN(auto_cost_reference_bandwidth, auto_cost_reference_bandwidth_cmd, + "auto-cost reference-bandwidth (1-4294967)", + "Calculate OSPF interface cost according to bandwidth\n" + "Use reference bandwidth method to assign OSPF cost\n" + "The reference bandwidth in terms of Mbits per second\n") { VTY_DECLVAR_CONTEXT(ospf6, o); int idx_number = 2; @@ -2023,13 +2041,11 @@ DEFUN (auto_cost_reference_bandwidth, return CMD_SUCCESS; } -DEFUN (no_auto_cost_reference_bandwidth, - no_auto_cost_reference_bandwidth_cmd, - "no auto-cost reference-bandwidth [(1-4294967)]", - NO_STR - "Calculate OSPF interface cost according to bandwidth\n" - "Use reference bandwidth method to assign OSPF cost\n" - "The reference bandwidth in terms of Mbits per second\n") +DEFUN(no_auto_cost_reference_bandwidth, no_auto_cost_reference_bandwidth_cmd, + "no auto-cost reference-bandwidth [(1-4294967)]", + NO_STR "Calculate OSPF interface cost according to bandwidth\n" + "Use reference bandwidth method to assign OSPF cost\n" + "The reference bandwidth in terms of Mbits per second\n") { VTY_DECLVAR_CONTEXT(ospf6, o); struct ospf6_area *oa; @@ -2048,11 +2064,10 @@ DEFUN (no_auto_cost_reference_bandwidth, } -DEFUN (ospf6_write_multiplier, - ospf6_write_multiplier_cmd, - "write-multiplier (1-100)", - "Write multiplier\n" - "Maximum number of interface serviced per write\n") +DEFUN(ospf6_write_multiplier, ospf6_write_multiplier_cmd, + "write-multiplier (1-100)", + "Write multiplier\n" + "Maximum number of interface serviced per write\n") { VTY_DECLVAR_CONTEXT(ospf6, o); uint32_t write_oi_count; @@ -2067,12 +2082,10 @@ DEFUN (ospf6_write_multiplier, return CMD_SUCCESS; } -DEFUN (no_ospf6_write_multiplier, - no_ospf6_write_multiplier_cmd, - "no write-multiplier (1-100)", - NO_STR - "Write multiplier\n" - "Maximum number of interface serviced per write\n") +DEFUN(no_ospf6_write_multiplier, no_ospf6_write_multiplier_cmd, + "no write-multiplier (1-100)", + NO_STR "Write multiplier\n" + "Maximum number of interface serviced per write\n") { VTY_DECLVAR_CONTEXT(ospf6, o); @@ -2080,13 +2093,9 @@ DEFUN (no_ospf6_write_multiplier, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_hellointerval, - ipv6_ospf6_hellointerval_cmd, - "ipv6 ospf6 hello-interval (1-65535)", - IP6_STR - OSPF6_STR - "Time between HELLO packets\n" - SECONDS_STR) +DEFUN(ipv6_ospf6_hellointerval, ipv6_ospf6_hellointerval_cmd, + "ipv6 ospf6 hello-interval (1-65535)", + IP6_STR OSPF6_STR "Time between HELLO packets\n" SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2114,23 +2123,15 @@ DEFUN (ipv6_ospf6_hellointerval, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_hellointerval, - no_ipv6_ospf6_hellointerval_cmd, - "no ipv6 ospf6 hello-interval [(1-65535)]", - NO_STR - IP6_STR - OSPF6_STR - "Time between HELLO packets\n" - SECONDS_STR) +ALIAS(ipv6_ospf6_hellointerval, no_ipv6_ospf6_hellointerval_cmd, + "no ipv6 ospf6 hello-interval [(1-65535)]", + NO_STR IP6_STR OSPF6_STR "Time between HELLO packets\n" SECONDS_STR) /* interface variable set command */ -DEFUN (ipv6_ospf6_deadinterval, - ipv6_ospf6_deadinterval_cmd, - "ipv6 ospf6 dead-interval (1-65535)", - IP6_STR - OSPF6_STR - "Interval time after which a neighbor is declared down\n" - SECONDS_STR) +DEFUN(ipv6_ospf6_deadinterval, ipv6_ospf6_deadinterval_cmd, + "ipv6 ospf6 dead-interval (1-65535)", + IP6_STR OSPF6_STR + "Interval time after which a neighbor is declared down\n" SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2148,23 +2149,54 @@ DEFUN (ipv6_ospf6_deadinterval, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_deadinterval, - no_ipv6_ospf6_deadinterval_cmd, - "no ipv6 ospf6 dead-interval [(1-65535)]", - NO_STR - IP6_STR - OSPF6_STR - "Interval time after which a neighbor is declared down\n" - SECONDS_STR) +ALIAS(ipv6_ospf6_deadinterval, no_ipv6_ospf6_deadinterval_cmd, + "no ipv6 ospf6 dead-interval [(1-65535)]", + NO_STR IP6_STR OSPF6_STR + "Interval time after which a neighbor is declared down\n" SECONDS_STR) + +DEFPY(ipv6_ospf6_gr_hdelay, ipv6_ospf6_gr_hdelay_cmd, + "ipv6 ospf6 graceful-restart hello-delay (1-1800)", + IP6_STR OSPF6_STR "Graceful Restart parameters\n" + "Delay the sending of the first hello packets.\n" + "Delay in seconds\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + + oi = ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + + /* Note: new or updated value won't affect ongoing graceful restart. */ + oi->gr.hello_delay.interval = hello_delay; + + return CMD_SUCCESS; +} + +DEFPY(no_ipv6_ospf6_gr_hdelay, no_ipv6_ospf6_gr_hdelay_cmd, + "no ipv6 ospf6 graceful-restart hello-delay [(1-1800)]", + NO_STR IP6_STR OSPF6_STR "Graceful Restart parameters\n" + "Delay the sending of the first hello packets.\n" + "Delay in seconds\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + + oi = ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + + oi->gr.hello_delay.interval = OSPF_HELLO_DELAY_DEFAULT; + oi->gr.hello_delay.elapsed_seconds = 0; + EVENT_OFF(oi->gr.hello_delay.t_grace_send); + + return CMD_SUCCESS; +} /* interface variable set command */ -DEFUN (ipv6_ospf6_transmitdelay, - ipv6_ospf6_transmitdelay_cmd, - "ipv6 ospf6 transmit-delay (1-3600)", - IP6_STR - OSPF6_STR - "Link state transmit delay\n" - SECONDS_STR) +DEFUN(ipv6_ospf6_transmitdelay, ipv6_ospf6_transmitdelay_cmd, + "ipv6 ospf6 transmit-delay (1-3600)", + IP6_STR OSPF6_STR "Link state transmit delay\n" SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2182,23 +2214,15 @@ DEFUN (ipv6_ospf6_transmitdelay, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_transmitdelay, - no_ipv6_ospf6_transmitdelay_cmd, - "no ipv6 ospf6 transmit-delay [(1-3600)]", - NO_STR - IP6_STR - OSPF6_STR - "Link state transmit delay\n" - SECONDS_STR) +ALIAS(ipv6_ospf6_transmitdelay, no_ipv6_ospf6_transmitdelay_cmd, + "no ipv6 ospf6 transmit-delay [(1-3600)]", + NO_STR IP6_STR OSPF6_STR "Link state transmit delay\n" SECONDS_STR) /* interface variable set command */ -DEFUN (ipv6_ospf6_retransmitinterval, - ipv6_ospf6_retransmitinterval_cmd, - "ipv6 ospf6 retransmit-interval (1-65535)", - IP6_STR - OSPF6_STR - "Time between retransmitting lost link state advertisements\n" - SECONDS_STR) +DEFUN(ipv6_ospf6_retransmitinterval, ipv6_ospf6_retransmitinterval_cmd, + "ipv6 ospf6 retransmit-interval (1-65535)", + IP6_STR OSPF6_STR + "Time between retransmitting lost link state advertisements\n" SECONDS_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2216,23 +2240,16 @@ DEFUN (ipv6_ospf6_retransmitinterval, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_retransmitinterval, - no_ipv6_ospf6_retransmitinterval_cmd, - "no ipv6 ospf6 retransmit-interval [(1-65535)]", - NO_STR - IP6_STR - OSPF6_STR - "Time between retransmitting lost link state advertisements\n" - SECONDS_STR) +ALIAS(ipv6_ospf6_retransmitinterval, no_ipv6_ospf6_retransmitinterval_cmd, + "no ipv6 ospf6 retransmit-interval [(1-65535)]", + NO_STR IP6_STR OSPF6_STR + "Time between retransmitting lost link state advertisements\n" SECONDS_STR) /* interface variable set command */ -DEFUN (ipv6_ospf6_priority, - ipv6_ospf6_priority_cmd, - "ipv6 ospf6 priority (0-255)", - IP6_STR - OSPF6_STR - "Router priority\n" - "Priority value\n") +DEFUN(ipv6_ospf6_priority, ipv6_ospf6_priority_cmd, + "ipv6 ospf6 priority (0-255)", + IP6_STR OSPF6_STR "Router priority\n" + "Priority value\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2248,10 +2265,9 @@ DEFUN (ipv6_ospf6_priority, ? OSPF6_INTERFACE_PRIORITY : strtoul(argv[idx_number]->arg, NULL, 10); - if (oi->area - && (oi->state == OSPF6_INTERFACE_DROTHER - || oi->state == OSPF6_INTERFACE_BDR - || oi->state == OSPF6_INTERFACE_DR)) { + if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER || + oi->state == OSPF6_INTERFACE_BDR || + oi->state == OSPF6_INTERFACE_DR)) { if (ospf6_interface_state_change(dr_election(oi), oi) == -1) OSPF6_LINK_LSA_SCHEDULE(oi); } @@ -2259,22 +2275,15 @@ DEFUN (ipv6_ospf6_priority, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_priority, - no_ipv6_ospf6_priority_cmd, - "no ipv6 ospf6 priority [(0-255)]", - NO_STR - IP6_STR - OSPF6_STR - "Router priority\n" - "Priority value\n") +ALIAS(ipv6_ospf6_priority, no_ipv6_ospf6_priority_cmd, + "no ipv6 ospf6 priority [(0-255)]", + NO_STR IP6_STR OSPF6_STR "Router priority\n" + "Priority value\n") -DEFUN (ipv6_ospf6_instance, - ipv6_ospf6_instance_cmd, - "ipv6 ospf6 instance-id (0-255)", - IP6_STR - OSPF6_STR - "Instance ID for this interface\n" - "Instance ID value\n") +DEFUN(ipv6_ospf6_instance, ipv6_ospf6_instance_cmd, + "ipv6 ospf6 instance-id (0-255)", + IP6_STR OSPF6_STR "Instance ID for this interface\n" + "Instance ID value\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; @@ -2292,22 +2301,14 @@ DEFUN (ipv6_ospf6_instance, return CMD_SUCCESS; } -ALIAS (ipv6_ospf6_instance, - no_ipv6_ospf6_instance_cmd, - "no ipv6 ospf6 instance-id [(0-255)]", - NO_STR - IP6_STR - OSPF6_STR - "Instance ID for this interface\n" - "Instance ID value\n") +ALIAS(ipv6_ospf6_instance, no_ipv6_ospf6_instance_cmd, + "no ipv6 ospf6 instance-id [(0-255)]", + NO_STR IP6_STR OSPF6_STR "Instance ID for this interface\n" + "Instance ID value\n") -DEFUN (ipv6_ospf6_passive, - ipv6_ospf6_passive_cmd, - "ipv6 ospf6 passive", - IP6_STR - OSPF6_STR - "Passive interface; no adjacency will be formed on this interface\n" - ) +DEFUN(ipv6_ospf6_passive, ipv6_ospf6_passive_cmd, "ipv6 ospf6 passive", + IP6_STR OSPF6_STR + "Passive interface; no adjacency will be formed on this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2333,14 +2334,9 @@ DEFUN (ipv6_ospf6_passive, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_passive, - no_ipv6_ospf6_passive_cmd, - "no ipv6 ospf6 passive", - NO_STR - IP6_STR - OSPF6_STR - "passive interface: No Adjacency will be formed on this I/F\n" - ) +DEFUN(no_ipv6_ospf6_passive, no_ipv6_ospf6_passive_cmd, "no ipv6 ospf6 passive", + NO_STR IP6_STR OSPF6_STR + "passive interface: No Adjacency will be formed on this I/F\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2363,13 +2359,8 @@ DEFUN (no_ipv6_ospf6_passive, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_mtu_ignore, - ipv6_ospf6_mtu_ignore_cmd, - "ipv6 ospf6 mtu-ignore", - IP6_STR - OSPF6_STR - "Disable MTU mismatch detection on this interface\n" - ) +DEFUN(ipv6_ospf6_mtu_ignore, ipv6_ospf6_mtu_ignore_cmd, "ipv6 ospf6 mtu-ignore", + IP6_STR OSPF6_STR "Disable MTU mismatch detection on this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2385,14 +2376,10 @@ DEFUN (ipv6_ospf6_mtu_ignore, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_mtu_ignore, - no_ipv6_ospf6_mtu_ignore_cmd, - "no ipv6 ospf6 mtu-ignore", - NO_STR - IP6_STR - OSPF6_STR - "Disable MTU mismatch detection on this interface\n" - ) +DEFUN(no_ipv6_ospf6_mtu_ignore, no_ipv6_ospf6_mtu_ignore_cmd, + "no ipv6 ospf6 mtu-ignore", + NO_STR IP6_STR OSPF6_STR + "Disable MTU mismatch detection on this interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2408,15 +2395,11 @@ DEFUN (no_ipv6_ospf6_mtu_ignore, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_advertise_prefix_list, - ipv6_ospf6_advertise_prefix_list_cmd, - "ipv6 ospf6 advertise prefix-list WORD", - IP6_STR - OSPF6_STR - "Advertising options\n" - "Filter prefix using prefix-list\n" - "Prefix list name\n" - ) +DEFUN(ipv6_ospf6_advertise_prefix_list, ipv6_ospf6_advertise_prefix_list_cmd, + "ipv6 ospf6 advertise prefix-list PREFIXLIST6_NAME", + IP6_STR OSPF6_STR "Advertising options\n" + "Filter prefix using prefix-list\n" + "Prefix list name\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_word = 4; @@ -2446,15 +2429,12 @@ DEFUN (ipv6_ospf6_advertise_prefix_list, return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_advertise_prefix_list, - no_ipv6_ospf6_advertise_prefix_list_cmd, - "no ipv6 ospf6 advertise prefix-list [WORD]", - NO_STR - IP6_STR - OSPF6_STR - "Advertising options\n" - "Filter prefix using prefix-list\n" - "Prefix list name\n") +DEFUN(no_ipv6_ospf6_advertise_prefix_list, + no_ipv6_ospf6_advertise_prefix_list_cmd, + "no ipv6 ospf6 advertise prefix-list [PREFIXLIST6_NAME]", + NO_STR IP6_STR OSPF6_STR "Advertising options\n" + "Filter prefix using prefix-list\n" + "Prefix list name\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2482,15 +2462,12 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list, return CMD_SUCCESS; } -DEFUN (ipv6_ospf6_network, - ipv6_ospf6_network_cmd, - "ipv6 ospf6 network <broadcast|point-to-point>", - IP6_STR - OSPF6_STR - "Network type\n" - "Specify OSPF6 broadcast network\n" - "Specify OSPF6 point-to-point network\n" - ) +DEFUN(ipv6_ospf6_network, ipv6_ospf6_network_cmd, + "ipv6 ospf6 network <broadcast|point-to-point|point-to-multipoint>", + IP6_STR OSPF6_STR "Network type\n" + "Specify OSPF6 broadcast network\n" + "Specify OSPF6 point-to-point network\n" + "Specify OSPF6 point-to-multipoint network\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_network = 3; @@ -2515,24 +2492,25 @@ DEFUN (ipv6_ospf6_network, return CMD_SUCCESS; } oi->type = OSPF_IFTYPE_POINTOPOINT; + } else if (strncmp(argv[idx_network]->arg, "point-to-m", 10) == 0) { + if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { + return CMD_SUCCESS; + } + oi->type = OSPF_IFTYPE_POINTOMULTIPOINT; } /* Reset the interface */ - event_execute(master, interface_down, oi, 0); - event_execute(master, interface_up, oi, 0); + event_execute(master, interface_down, oi, 0, NULL); + event_execute(master, interface_up, oi, 0, NULL); return CMD_SUCCESS; } -DEFUN (no_ipv6_ospf6_network, - no_ipv6_ospf6_network_cmd, - "no ipv6 ospf6 network [<broadcast|point-to-point>]", - NO_STR - IP6_STR - OSPF6_STR - "Set default network type\n" - "Specify OSPF6 broadcast network\n" - "Specify OSPF6 point-to-point network\n") +DEFUN(no_ipv6_ospf6_network, no_ipv6_ospf6_network_cmd, + "no ipv6 ospf6 network [<broadcast|point-to-point>]", + NO_STR IP6_STR OSPF6_STR "Set default network type\n" + "Specify OSPF6 broadcast network\n" + "Specify OSPF6 point-to-point network\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2541,9 +2519,8 @@ DEFUN (no_ipv6_ospf6_network, assert(ifp); oi = (struct ospf6_interface *)ifp->info; - if (oi == NULL) { + if (oi == NULL) return CMD_SUCCESS; - } oi->type_cfg = false; @@ -2554,12 +2531,101 @@ DEFUN (no_ipv6_ospf6_network, oi->type = type; /* Reset the interface */ - event_execute(master, interface_down, oi, 0); - event_execute(master, interface_up, oi, 0); + event_execute(master, interface_down, oi, 0, NULL); + event_execute(master, interface_up, oi, 0, NULL); + + return CMD_SUCCESS; +} + +DEFPY(ipv6_ospf6_p2xp_only_cfg_neigh, ipv6_ospf6_p2xp_only_cfg_neigh_cmd, + "[no] ipv6 ospf6 p2p-p2mp config-neighbors-only", + NO_STR IP6_STR OSPF6_STR + "Point-to-point and Point-to-Multipoint parameters\n" + "Only form adjacencies with explicitly configured neighbors\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi = ifp->info; + + if (no) { + if (!oi) + return CMD_SUCCESS; + + oi->p2xp_only_cfg_neigh = false; + return CMD_SUCCESS; + } + + if (!oi) + oi = ospf6_interface_create(ifp); + oi->p2xp_only_cfg_neigh = true; return CMD_SUCCESS; } +DEFPY(ipv6_ospf6_p2xp_no_multicast_hello, ipv6_ospf6_p2xp_no_multicast_hello_cmd, + "[no] ipv6 ospf6 p2p-p2mp disable-multicast-hello", + NO_STR IP6_STR OSPF6_STR + "Point-to-point and Point-to-Multipoint parameters\n" + "Do not send multicast hellos\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi = ifp->info; + + if (no) { + if (!oi) + return CMD_SUCCESS; + + oi->p2xp_no_multicast_hello = false; + return CMD_SUCCESS; + } + + if (!oi) + oi = ospf6_interface_create(ifp); + + oi->p2xp_no_multicast_hello = true; + return CMD_SUCCESS; +} + +DEFPY(ipv6_ospf6_p2xp_connected_pfx, ipv6_ospf6_p2xp_connected_pfx_cmd, + "[no] ipv6 ospf6 p2p-p2mp connected-prefixes <include$incl|exclude$excl>", + NO_STR IP6_STR OSPF6_STR + "Point-to-point and Point-to-Multipoint parameters\n" + "Adjust handling of directly connected prefixes\n" + "Advertise prefixes and own /128 (default for PtP)\n" + "Ignore, only advertise own /128 (default for PtMP)\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi = ifp->info; + bool old_incl, old_excl; + + if (no && !oi) + return CMD_SUCCESS; + + if (!oi) + oi = ospf6_interface_create(ifp); + + old_incl = oi->p2xp_connected_pfx_include; + old_excl = oi->p2xp_connected_pfx_exclude; + oi->p2xp_connected_pfx_include = false; + oi->p2xp_connected_pfx_exclude = false; + + if (incl && !no) + oi->p2xp_connected_pfx_include = true; + if (excl && !no) + oi->p2xp_connected_pfx_exclude = true; + + if (oi->p2xp_connected_pfx_include != old_incl || + oi->p2xp_connected_pfx_exclude != old_excl) + ospf6_interface_connected_route_update(ifp); + return CMD_SUCCESS; +} + +ALIAS(ipv6_ospf6_p2xp_connected_pfx, no_ipv6_ospf6_p2xp_connected_pfx_cmd, + "no ipv6 ospf6 p2p-p2mp connected-prefixes", + NO_STR IP6_STR OSPF6_STR + "Point-to-point and Point-to-Multipoint parameters\n" + "Adjust handling of directly connected prefixes\n") + + static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf) { struct ospf6_interface *oi; @@ -2619,11 +2685,34 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf) if (oi->mtu_ignore) vty_out(vty, " ipv6 ospf6 mtu-ignore\n"); - if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT) + if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + vty_out(vty, + " ipv6 ospf6 network point-to-multipoint\n"); + else 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"); + if (oi->gr.hello_delay.interval != OSPF_HELLO_DELAY_DEFAULT) + vty_out(vty, + " ipv6 ospf6 graceful-restart hello-delay %u\n", + oi->gr.hello_delay.interval); + if (oi->p2xp_only_cfg_neigh) + vty_out(vty, + " ipv6 ospf6 p2p-p2mp config-neighbors-only\n"); + + if (oi->p2xp_no_multicast_hello) + vty_out(vty, + " ipv6 ospf6 p2p-p2mp disable-multicast-hello\n"); + + if (oi->p2xp_connected_pfx_include) + vty_out(vty, + " ipv6 ospf6 p2p-p2mp connected-prefixes include\n"); + else if (oi->p2xp_connected_pfx_exclude) + vty_out(vty, + " ipv6 ospf6 p2p-p2mp connected-prefixes exclude\n"); + + config_write_ospf6_p2xp_neighbor(vty, oi); ospf6_bfd_write_config(vty, oi); ospf6_auth_write_config(vty, &oi->at_data); @@ -2661,10 +2750,10 @@ static int ospf6_ifp_create(struct interface *ifp) static int ospf6_ifp_up(struct interface *ifp) { if (IS_OSPF6_DEBUG_ZEBRA(RECV)) - zlog_debug( - "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d", - ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, - ifp->metric, ifp->mtu6, ifp->bandwidth); + zlog_debug("Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d", + ifp->name, ifp->ifindex, + (unsigned long long)ifp->flags, ifp->metric, + ifp->mtu6, ifp->bandwidth); ospf6_interface_state_update(ifp); @@ -2674,10 +2763,10 @@ static int ospf6_ifp_up(struct interface *ifp) static int ospf6_ifp_down(struct interface *ifp) { if (IS_OSPF6_DEBUG_ZEBRA(RECV)) - zlog_debug( - "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d", - ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, - ifp->metric, ifp->mtu6, ifp->bandwidth); + zlog_debug("Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d", + ifp->name, ifp->ifindex, + (unsigned long long)ifp->flags, ifp->metric, + ifp->mtu6, ifp->bandwidth); ospf6_interface_state_update(ifp); @@ -2704,13 +2793,14 @@ void ospf6_interface_init(void) { /* Install interface node. */ if_cmd_init(config_write_interface); - if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up, - ospf6_ifp_down, ospf6_ifp_destroy); + hook_register_prio(if_real, 0, ospf6_ifp_create); + hook_register_prio(if_up, 0, ospf6_ifp_up); + hook_register_prio(if_down, 0, ospf6_ifp_down); + hook_register_prio(if_unreal, 0, ospf6_ifp_destroy); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); - install_element(VIEW_NODE, - &show_ipv6_ospf6_interface_ifname_prefix_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd); @@ -2722,12 +2812,14 @@ void ospf6_interface_init(void) install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_gr_hdelay_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_gr_hdelay_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd); @@ -2746,6 +2838,11 @@ void ospf6_interface_init(void) install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd); install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_only_cfg_neigh_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_no_multicast_hello_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_connected_pfx_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_p2xp_connected_pfx_cmd); + /* reference bandwidth commands */ install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd); install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd); @@ -2771,21 +2868,14 @@ void ospf6_interface_clear(struct interface *ifp) zlog_debug("Interface %s: clear by reset", ifp->name); /* Reset the interface */ - event_execute(master, interface_down, oi, 0); - event_execute(master, interface_up, oi, 0); + event_execute(master, interface_down, oi, 0, NULL); + event_execute(master, interface_up, oi, 0, NULL); } /* Clear interface */ -DEFUN (clear_ipv6_ospf6_interface, - clear_ipv6_ospf6_interface_cmd, - "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]", - CLEAR_STR - IP6_STR - OSPF6_STR - VRF_CMD_HELP_STR - INTERFACE_STR - IFNAME_STR - ) +DEFUN(clear_ipv6_ospf6_interface, clear_ipv6_ospf6_interface_cmd, + "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]", + CLEAR_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR INTERFACE_STR IFNAME_STR) { struct vrf *vrf; int idx_vrf = 3; @@ -2826,26 +2916,16 @@ void install_element_ospf6_clear_interface(void) install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd); } -DEFUN (debug_ospf6_interface, - debug_ospf6_interface_cmd, - "debug ospf6 interface", - DEBUG_STR - OSPF6_STR - "Debug OSPFv3 Interface\n" - ) +DEFUN(debug_ospf6_interface, debug_ospf6_interface_cmd, "debug ospf6 interface", + DEBUG_STR OSPF6_STR "Debug OSPFv3 Interface\n") { OSPF6_DEBUG_INTERFACE_ON(); return CMD_SUCCESS; } -DEFUN (no_debug_ospf6_interface, - no_debug_ospf6_interface_cmd, - "no debug ospf6 interface", - NO_STR - DEBUG_STR - OSPF6_STR - "Debug OSPFv3 Interface\n" - ) +DEFUN(no_debug_ospf6_interface, no_debug_ospf6_interface_cmd, + "no debug ospf6 interface", + NO_STR DEBUG_STR OSPF6_STR "Debug OSPFv3 Interface\n") { OSPF6_DEBUG_INTERFACE_OFF(); return CMD_SUCCESS; @@ -2882,10 +2962,9 @@ void ospf6_auth_write_config(struct vty *vty, struct ospf6_auth_data *at_data) DEFUN(ipv6_ospf6_intf_auth_trailer_keychain, ipv6_ospf6_intf_auth_trailer_keychain_cmd, "ipv6 ospf6 authentication keychain KEYCHAIN_NAME", - IP6_STR OSPF6_STR - "Enable authentication on this interface\n" - "Keychain\n" - "Keychain name\n") + IP6_STR OSPF6_STR "Enable authentication on this interface\n" + "Keychain\n" + "Keychain name\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int keychain_idx = 4; @@ -2906,8 +2985,8 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_keychain, if (oi->at_data.keychain) XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain); - oi->at_data.keychain = - XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN, argv[keychain_idx]->arg); + oi->at_data.keychain = XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN, + argv[keychain_idx]->arg); return CMD_SUCCESS; } @@ -2915,10 +2994,9 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_keychain, DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain, no_ipv6_ospf6_intf_auth_trailer_keychain_cmd, "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]", - NO_STR IP6_STR OSPF6_STR - "Enable authentication on this interface\n" - "Keychain\n" - "Keychain name\n") + NO_STR IP6_STR OSPF6_STR "Enable authentication on this interface\n" + "Keychain\n" + "Keychain name\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; @@ -2944,18 +3022,17 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd, "ipv6 ospf6 authentication key-id (1-65535) hash-algo " "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> " "key WORD", - IP6_STR OSPF6_STR - "Authentication\n" - "Key ID\n" - "Key ID value\n" - "Cryptographic-algorithm\n" - "Use MD5 algorithm\n" - "Use HMAC-SHA-1 algorithm\n" - "Use HMAC-SHA-256 algorithm\n" - "Use HMAC-SHA-384 algorithm\n" - "Use HMAC-SHA-512 algorithm\n" - "Password\n" - "Password string (key)\n") + IP6_STR OSPF6_STR "Authentication\n" + "Key ID\n" + "Key ID value\n" + "Cryptographic-algorithm\n" + "Use MD5 algorithm\n" + "Use HMAC-SHA-1 algorithm\n" + "Use HMAC-SHA-256 algorithm\n" + "Use HMAC-SHA-384 algorithm\n" + "Use HMAC-SHA-512 algorithm\n" + "Password\n" + "Password string (key)\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int key_id_idx = 4; @@ -2989,8 +3066,8 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd, oi->at_data.key_id = (uint16_t)strtol(argv[key_id_idx]->arg, NULL, 10); if (oi->at_data.auth_key) XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key); - oi->at_data.auth_key = - XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY, argv[password_idx]->arg); + oi->at_data.auth_key = XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY, + argv[password_idx]->arg); return CMD_SUCCESS; } @@ -3000,18 +3077,17 @@ DEFUN(no_ipv6_ospf6_intf_auth_trailer_key, "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo " "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> " "key WORD]", - NO_STR IP6_STR OSPF6_STR - "Authentication\n" - "Key ID\n" - "Key ID value\n" - "Cryptographic-algorithm\n" - "Use MD5 algorithm\n" - "Use HMAC-SHA-1 algorithm\n" - "Use HMAC-SHA-256 algorithm\n" - "Use HMAC-SHA-384 algorithm\n" - "Use HMAC-SHA-512 algorithm\n" - "Password\n" - "Password string (key)\n") + NO_STR IP6_STR OSPF6_STR "Authentication\n" + "Key ID\n" + "Key ID value\n" + "Cryptographic-algorithm\n" + "Use MD5 algorithm\n" + "Use HMAC-SHA-1 algorithm\n" + "Use HMAC-SHA-256 algorithm\n" + "Use HMAC-SHA-384 algorithm\n" + "Use HMAC-SHA-512 algorithm\n" + "Password\n" + "Password string (key)\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct ospf6_interface *oi; |
