diff options
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_apiserver.c | 27 | ||||
-rw-r--r-- | ospfd/ospf_apiserver.h | 8 | ||||
-rw-r--r-- | ospfd/ospf_asbr.c | 3 | ||||
-rw-r--r-- | ospfd/ospf_ase.c | 2 | ||||
-rw-r--r-- | ospfd/ospf_flood.c | 5 | ||||
-rw-r--r-- | ospfd/ospf_interface.c | 97 | ||||
-rw-r--r-- | ospfd/ospf_interface.h | 18 | ||||
-rw-r--r-- | ospfd/ospf_ism.c | 2 | ||||
-rw-r--r-- | ospfd/ospf_ldp_sync.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_main.c | 28 | ||||
-rw-r--r-- | ospfd/ospf_neighbor.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_nsm.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_packet.c | 117 | ||||
-rw-r--r-- | ospfd/ospf_ri.c | 15 | ||||
-rw-r--r-- | ospfd/ospf_sr.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_te.c | 1 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 304 | ||||
-rw-r--r-- | ospfd/ospf_zebra.c | 14 | ||||
-rw-r--r-- | ospfd/ospfd.c | 7 |
19 files changed, 411 insertions, 253 deletions
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 419113e..fcc28c6 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -62,6 +62,11 @@ DEFINE_MTYPE_STATIC(OSPFD, APISERVER_MSGFILTER, "API Server Message Filter"); /* List of all active connections. */ struct list *apiserver_list; +/* Indicates that API the server socket local addresss has been + * specified. + */ +struct in_addr ospf_apiserver_addr; + /* ----------------------------------------------------------- * Functions to lookup interfaces * ----------------------------------------------------------- @@ -109,7 +114,21 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp) unsigned short ospf_apiserver_getport(void) { - struct servent *sp = getservbyname("ospfapi", "tcp"); + struct servent *sp = NULL; + char sbuf[16]; + + /* + * Allow the OSPF API server port to be specified per-instance by + * including the instance ID in the /etc/services name. Use the + * prior name if no per-instance service is specified. + */ + if (ospf_instance) { + snprintfrr(sbuf, sizeof(sbuf), "ospfapi-%d", ospf_instance); + sp = getservbyname(sbuf, "tcp"); + } + + if (!sp) + sp = getservbyname("ospfapi", "tcp"); return sp ? ntohs(sp->s_port) : OSPF_API_SYNC_PORT; } @@ -557,8 +576,10 @@ int ospf_apiserver_serv_sock_family(unsigned short port, int family) sockopt_reuseaddr(accept_sock); sockopt_reuseport(accept_sock); - /* Bind socket to address and given port. */ - rc = sockunion_bind(accept_sock, &su, port, NULL); + /* Bind socket to optional lcoal address and port. */ + if (ospf_apiserver_addr.s_addr) + sockunion2ip(&su) = ospf_apiserver_addr.s_addr; + rc = sockunion_bind(accept_sock, &su, port, &su); if (rc < 0) { close(accept_sock); /* Close socket */ return rc; diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h index 0aaf67c..4341a9d 100644 --- a/ospfd/ospf_apiserver.h +++ b/ospfd/ospf_apiserver.h @@ -67,6 +67,14 @@ enum ospf_apiserver_event { }; /* ----------------------------------------------------------- + * External definitions for OSPF API ospfd parameters. + * ----------------------------------------------------------- + */ + +extern int ospf_apiserver_enable; +extern struct in_addr ospf_apiserver_addr; + +/* ----------------------------------------------------------- * Following are functions to manage client connections. * ----------------------------------------------------------- */ diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 5baad17..9b62f36 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -110,7 +110,8 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance, new = rn->info; if ((new->ifindex == ifindex) && (new->nexthop.s_addr == nexthop.s_addr) - && (new->tag == tag)) { + && (new->tag == tag) + && (new->metric == metric)) { route_unlock_node(rn); return NULL; /* NULL => no LSA to refresh */ } diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 610b5fc..9e26a2a 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -480,7 +480,7 @@ static int ospf_ase_route_match_same(struct route_table *rt, assert(or); - if (or->path_type != newor->path_type) + if (or->changed || (or->path_type != newor->path_type)) return 0; switch (or->path_type) { diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 95a593a..e15871a 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -765,8 +765,9 @@ int ospf_flood_through_interface(struct ospf_interface *oi, packets must be sent, as unicasts, to each adjacent neighbor (i.e., those in state Exchange or greater). The destination IP addresses for these packets are the neighbors' IP - addresses. */ - if (oi->type == OSPF_IFTYPE_NBMA) { + addresses. This behavior is extended to P2MP networks which + don't support broadcast. */ + if (OSPF_IF_NON_BROADCAST(oi)) { struct ospf_neighbor *nbr; for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 173dafb..11ac7af 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -19,6 +19,7 @@ #include "zclient.h" #include "bfd.h" #include "ldp_sync.h" +#include "plist.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_bfd.h" @@ -67,6 +68,34 @@ int ospf_interface_neighbor_count(struct ospf_interface *oi) return count; } + +void ospf_intf_neighbor_filter_apply(struct ospf_interface *oi) +{ + struct route_node *rn; + struct ospf_neighbor *nbr = NULL; + struct prefix nbr_src_prefix = { AF_INET, IPV4_MAX_BITLEN, { 0 } }; + + if (!oi->nbr_filter) + return; + + /* + * Kill neighbors that don't match the neighbor filter prefix-list + * excluding the neighbor for the router itself and any neighbors + * that are already down. + */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + nbr = rn->info; + if (nbr && nbr != oi->nbr_self && nbr->state != NSM_Down) { + nbr_src_prefix.u.prefix4 = nbr->src; + if (prefix_list_apply(oi->nbr_filter, + (struct prefix *)&( + nbr_src_prefix)) != + PREFIX_PERMIT) + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); + } + } +} + int ospf_if_get_output_cost(struct ospf_interface *oi) { /* If all else fails, use default OSPF cost */ @@ -147,17 +176,11 @@ void ospf_if_reset(struct interface *ifp) } } -void ospf_if_reset_variables(struct ospf_interface *oi) +static void ospf_if_default_variables(struct ospf_interface *oi) { /* Set default values. */ - /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */ - if (oi->vl_data) - oi->type = OSPF_IFTYPE_VIRTUALLINK; - else - /* preserve network-type */ - if (oi->type != OSPF_IFTYPE_NBMA) - oi->type = OSPF_IFTYPE_BROADCAST; + oi->type = OSPF_IFTYPE_BROADCAST; oi->state = ISM_Down; @@ -254,7 +277,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, oi->ls_ack_direct.ls_ack = list_new(); /* Set default values. */ - ospf_if_reset_variables(oi); + ospf_if_default_variables(oi); /* Set pseudo neighbor to Null */ oi->nbr_self = NULL; @@ -532,6 +555,7 @@ static struct ospf_if_params *ospf_new_if_params(void) UNSET_IF_PARAM(oip, if_area); UNSET_IF_PARAM(oip, opaque_capable); UNSET_IF_PARAM(oip, keychain_name); + UNSET_IF_PARAM(oip, nbr_filter_name); oip->auth_crypt = list_new(); @@ -550,6 +574,7 @@ static void ospf_del_if_params(struct interface *ifp, { list_delete(&oip->auth_crypt); XFREE(MTYPE_OSPF_IF_PARAMS, oip->keychain_name); + XFREE(MTYPE_OSPF_IF_PARAMS, oip->nbr_filter_name); ospf_interface_disable_bfd(ifp, oip); ldp_sync_info_free(&(oip->ldp_sync_info)); XFREE(MTYPE_OSPF_IF_PARAMS, oip); @@ -585,7 +610,8 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) !OSPF_IF_PARAM_CONFIGURED(oip, if_area) && !OSPF_IF_PARAM_CONFIGURED(oip, opaque_capable) && !OSPF_IF_PARAM_CONFIGURED(oip, prefix_suppression) && - !OSPF_IF_PARAM_CONFIGURED(oip, keychain_name) && + !OSPF_IF_PARAM_CONFIGURED(oip, keychain_name) && + !OSPF_IF_PARAM_CONFIGURED(oip, nbr_filter_name) && listcount(oip->auth_crypt) == 0) { ospf_del_if_params(ifp, oip); rn->info = NULL; @@ -821,14 +847,41 @@ int ospf_if_up(struct ospf_interface *oi) return 1; } -int ospf_if_down(struct ospf_interface *oi) +/* This function will mark routes with next-hops matching the down + * OSPF interface as changed. It is used to assure routes that get + * removed from the zebra RIB when an interface goes down are + * reinstalled if the interface comes back up prior to an intervening + * SPF calculation. + */ +static void ospf_if_down_mark_routes_changed(struct route_table *table, + struct ospf_interface *oi) { - struct ospf *ospf; struct route_node *rn; struct ospf_route *or; struct listnode *nh; struct ospf_path *op; + for (rn = route_top(table); rn; rn = route_next(rn)) { + or = rn->info; + + if (or == NULL) + continue; + + for (nh = listhead(or->paths); nh; + nh = listnextnode_unchecked(nh)) { + op = listgetdata(nh); + if (op->ifindex == oi->ifp->ifindex) { + or->changed = true; + break; + } + } + } +} + +int ospf_if_down(struct ospf_interface *oi) +{ + struct ospf *ospf; + if (oi == NULL) return 0; @@ -864,23 +917,11 @@ int ospf_if_down(struct ospf_interface *oi) /* Shutdown packet reception and sending */ ospf_if_stream_unset(oi); - if (!ospf->new_table) - return 1; - for (rn = route_top(ospf->new_table); rn; rn = route_next(rn)) { - or = rn->info; - - if (!or) - continue; + if (ospf->new_table) + ospf_if_down_mark_routes_changed(ospf->new_table, oi); - for (nh = listhead(or->paths); nh; - nh = listnextnode_unchecked(nh)) { - op = listgetdata(nh); - if (op->ifindex == oi->ifp->ifindex) { - or->changed = true; - break; - } - } - } + if (ospf->new_external_route) + ospf_if_down_mark_routes_changed(ospf->new_external_route, oi); return 1; } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 39dc951..45d0b79 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -120,8 +120,14 @@ struct ospf_if_params { /* point-to-multipoint delayed reflooding configuration */ bool p2mp_delay_reflood; + /* point-to-multipoint doesn't support broadcast */ + bool p2mp_non_broadcast; + /* Opaque LSA capability at interface level (see RFC5250) */ DECLARE_IF_PARAM(bool, opaque_capable); + + /* Name of prefix-list name for packet source address filtering. */ + DECLARE_IF_PARAM(char *, nbr_filter_name); }; enum { MEMBER_ALLROUTERS = 0, @@ -186,6 +192,10 @@ struct ospf_interface { /* OSPF Network Type. */ uint8_t type; +#define OSPF_IF_NON_BROADCAST(O) \ + (((O)->type == OSPF_IFTYPE_NBMA) || \ + ((((O)->type == OSPF_IFTYPE_POINTOMULTIPOINT) && \ + (O)->p2mp_non_broadcast))) /* point-to-point DMVPN configuration */ uint8_t ptp_dmvpn; @@ -193,6 +203,9 @@ struct ospf_interface { /* point-to-multipoint delayed reflooding */ bool p2mp_delay_reflood; + /* point-to-multipoint doesn't support broadcast */ + bool p2mp_non_broadcast; + /* State of Interface State Machine. */ uint8_t state; @@ -233,6 +246,9 @@ struct ospf_interface { /* List of configured NBMA neighbor. */ struct list *nbr_nbma; + /* Configured prefix-list for filtering neighbors. */ + struct prefix_list *nbr_filter; + /* Graceful-Restart data. */ struct { struct { @@ -327,7 +343,6 @@ extern void ospf_if_update_params(struct interface *ifp, struct in_addr addr); extern int ospf_if_new_hook(struct interface *ifp); extern void ospf_if_init(void); extern void ospf_if_stream_unset(struct ospf_interface *oi); -extern void ospf_if_reset_variables(struct ospf_interface *oi); extern int ospf_if_is_enable(struct ospf_interface *oi); extern int ospf_if_get_output_cost(struct ospf_interface *oi); extern void ospf_if_recalculate_output_cost(struct interface *ifp); @@ -359,6 +374,7 @@ extern void ospf_crypt_key_add(struct list *list, struct crypt_key *key); extern int ospf_crypt_key_delete(struct list *list, uint8_t key_id); extern uint8_t ospf_default_iftype(struct interface *ifp); extern int ospf_interface_neighbor_count(struct ospf_interface *oi); +extern void ospf_intf_neighbor_filter_apply(struct ospf_interface *oi); /* Set all multicast memberships appropriately based on the type and state of the interface. */ diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 2516fa7..878ab72 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -367,7 +367,7 @@ static int ism_interface_up(struct ospf_interface *oi) /* Otherwise, the state transitions to Waiting. */ next_state = ISM_Waiting; - if (oi->type == OSPF_IFTYPE_NBMA) + if (OSPF_IF_NON_BROADCAST(oi)) ospf_nbr_nbma_if_update(oi->ospf, oi); /* ospf_ism_event (t); */ diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index 4aab880..496ae5b 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -774,7 +774,7 @@ DEFPY (no_ospf_mpls_ldp_sync, "Disable MPLS LDP-IGP Sync\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - ospf_ldp_sync_gbl_exit(ospf, false); + ospf_ldp_sync_gbl_exit(ospf, true); return CMD_SUCCESS; } @@ -901,7 +901,7 @@ DEFPY (no_mpls_ldp_sync, * stop holddown timer if running * restore ospf cost */ - SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); + UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; EVENT_OFF(ldp_sync_info->t_holddown); diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 6a4a9a1..fdb4e5c 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -28,6 +28,7 @@ #include "libfrr.h" #include "routemap.h" #include "keychain.h" +#include "libagentx.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -44,6 +45,7 @@ #include "ospfd/ospf_errors.h" #include "ospfd/ospf_ldp_sync.h" #include "ospfd/ospf_routemap_nb.h" +#include "ospfd/ospf_apiserver.h" #define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir #define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i @@ -75,6 +77,7 @@ struct zebra_privs_t ospfd_privs = { const struct option longopts[] = { {"instance", required_argument, NULL, 'n'}, {"apiserver", no_argument, NULL, 'a'}, + {"apiserver_addr", required_argument, NULL, 'l'}, {0} }; @@ -83,10 +86,6 @@ const struct option longopts[] = { /* Master of threads. */ struct event_loop *master; -#ifdef SUPPORT_OSPF_API -extern int ospf_apiserver_enable; -#endif /* SUPPORT_OSPF_API */ - /* SIGHUP handler. */ static void sighup(void) { @@ -134,6 +133,8 @@ static const struct frr_yang_module_info *const ospfd_yang_modules[] = { &frr_route_map_info, &frr_vrf_info, &frr_ospf_route_map_info, + &ietf_key_chain_info, + &ietf_key_chain_deviation_info, }; /* actual paths filled in main() */ @@ -191,15 +192,11 @@ static void ospf_config_end(void) /* OSPFd main routine. */ int main(int argc, char **argv) { -#ifdef SUPPORT_OSPF_API - /* OSPF apiserver is disabled by default. */ - ospf_apiserver_enable = 0; -#endif /* SUPPORT_OSPF_API */ - frr_preinit(&ospfd_di, argc, argv); - frr_opt_add("n:a", longopts, + frr_opt_add("n:al:", longopts, " -n, --instance Set the instance id\n" - " -a, --apiserver Enable OSPF apiserver\n"); + " -a, --apiserver Enable OSPF apiserver\n" + " -l, --apiserver_addr Set OSPF apiserver bind address\n"); while (1) { int opt; @@ -221,6 +218,14 @@ int main(int argc, char **argv) case 'a': ospf_apiserver_enable = 1; break; + case 'l': + if (inet_pton(AF_INET, optarg, &ospf_apiserver_addr) <= + 0) { + zlog_err("OSPF: Invalid API Server IPv4 address %s specified", + optarg); + exit(0); + } + break; #endif /* SUPPORT_OSPF_API */ default: frr_help_exit(1); @@ -252,6 +257,7 @@ int main(int argc, char **argv) master = om->master; /* Library inits. */ + libagentx_init(); ospf_debug_init(); ospf_vrf_init(); diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index c238f05..d47d581 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -431,7 +431,7 @@ static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi, memcpy(&nbr->address, p, sizeof(struct prefix)); nbr->nbr_nbma = NULL; - if (oi->type == OSPF_IFTYPE_NBMA) { + if (OSPF_IF_NON_BROADCAST(oi)) { struct ospf_nbr_nbma *nbr_nbma; struct listnode *node; @@ -485,7 +485,7 @@ struct ospf_neighbor *ospf_nbr_get(struct ospf_interface *oi, route_unlock_node(rn); nbr = rn->info; - if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) { + if (OSPF_IF_NON_BROADCAST(nbr->oi) && nbr->state == NSM_Attempt) { nbr->src = iph->ip_src; memcpy(&nbr->address, p, sizeof(struct prefix)); } diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 08aa103..c466ddc 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -166,7 +166,7 @@ static int nsm_hello_received(struct ospf_neighbor *nbr) OSPF_NSM_TIMER_ON(nbr->t_inactivity, ospf_inactivity_timer, nbr->v_inactivity); - if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma) + if (OSPF_IF_NON_BROADCAST(nbr->oi) && nbr->nbr_nbma != NULL) EVENT_OFF(nbr->nbr_nbma->t_poll); /* Send proactive ARP requests */ @@ -377,7 +377,7 @@ static int nsm_kill_nbr(struct ospf_neighbor *nbr) return 0; } - if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma != NULL) { + if (OSPF_IF_NON_BROADCAST(nbr->oi) && nbr->nbr_nbma != NULL) { struct ospf_nbr_nbma *nbr_nbma = nbr->nbr_nbma; nbr_nbma->nbr = NULL; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 4bf4ae9..87aacca 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -23,6 +23,7 @@ #endif #include "vrf.h" #include "lib_errors.h" +#include "plist.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_network.h" @@ -1486,12 +1487,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* Packet overflows MTU size, send immediately. */ if (length + ntohs(find->data->length) > ospf_packet_max(oi)) { - if (oi->type == OSPF_IFTYPE_NBMA) - ospf_ls_upd_send(nbr, ls_upd, - OSPF_SEND_PACKET_DIRECT, 0); - else - ospf_ls_upd_send(nbr, ls_upd, - OSPF_SEND_PACKET_INDIRECT, 0); + ospf_ls_upd_send(nbr, ls_upd, + OSPF_SEND_PACKET_DIRECT, 0); /* Only remove list contents. Keep ls_upd. */ list_delete_all_node(ls_upd); @@ -1508,12 +1505,7 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* Send rest of Link State Update. */ if (listcount(ls_upd) > 0) { - if (oi->type == OSPF_IFTYPE_NBMA) - ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT, - 0); - else - ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT, - 0); + ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT, 0); list_delete(&ls_upd); } else @@ -2756,6 +2748,20 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) oi = ospf_if_lookup_recv_if(ospf, iph->ip_src, ifp); /* + * If a neighbor filter prefix-list is configured, apply it to the IP + * source address and ignore the packet if it doesn't match. + */ + if (oi && oi->nbr_filter) { + struct prefix ip_src_prefix = { AF_INET, IPV4_MAX_BITLEN, { 0 } }; + + ip_src_prefix.u.prefix4 = iph->ip_src; + if (prefix_list_apply(oi->nbr_filter, + (struct prefix *)&(ip_src_prefix)) != + PREFIX_PERMIT) + return OSPF_READ_CONTINUE; + } + + /* * ospf_verify_header() relies on a valid "oi" and thus can be called * only after the passive/backbone/other checks below are passed. * These checks in turn access the fields of unverified "ospfh" @@ -3404,17 +3410,19 @@ static void ospf_poll_send(struct ospf_nbr_nbma *nbr_nbma) if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE) return; - if (oi->type != OSPF_IFTYPE_NBMA) - return; - if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down) return; - if (PRIORITY(oi) == 0) - return; + if (oi->type == OSPF_IFTYPE_NBMA) { + if (PRIORITY(oi) == 0) + return; + + if (nbr_nbma->priority == 0 && oi->state != ISM_DR && + oi->state != ISM_Backup) + return; - if (nbr_nbma->priority == 0 && oi->state != ISM_DR - && oi->state != ISM_Backup) + } else if (oi->type != OSPF_IFTYPE_POINTOMULTIPOINT || + !oi->p2mp_non_broadcast) return; ospf_hello_send_sub(oi, nbr_nbma->addr.s_addr); @@ -3460,7 +3468,7 @@ void ospf_hello_send(struct ospf_interface *oi) if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE) return; - if (oi->type == OSPF_IFTYPE_NBMA) { + if (OSPF_IF_NON_BROADCAST(oi)) { struct ospf_neighbor *nbr; struct route_node *rn; @@ -3476,31 +3484,44 @@ void ospf_hello_send(struct ospf_interface *oi) continue; /* - * RFC 2328 Section 9.5.1 - * If the router is not eligible to become Designated - * Router, it must periodically send Hello Packets to - * both the Designated Router and the Backup - * Designated Router (if they exist). + * Always send to all neighbors on Point-to-Multipoint + * non-braodcast networks. */ - if (PRIORITY(oi) == 0 && - IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) && - IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4)) - continue; + if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + ospf_hello_send_sub(oi, nbr->address.u.prefix4 + .s_addr); + else { + /* + * RFC 2328 Section 9.5.1 + * If the router is not eligible to become Designated + * Router, it must periodically send Hello Packets to + * both the Designated Router and the Backup + * Designated Router (if they exist). + */ + if (PRIORITY(oi) == 0 && + IPV4_ADDR_CMP(&DR(oi), + &nbr->address.u.prefix4) && + IPV4_ADDR_CMP(&BDR(oi), + &nbr->address.u.prefix4)) + continue; - /* - * If the router is eligible to become Designated - * Router, it must periodically send Hello Packets to - * all neighbors that are also eligible. In addition, - * if the router is itself the Designated Router or - * Backup Designated Router, it must also send periodic - * Hello Packets to all other neighbors. - */ - if (nbr->priority == 0 && oi->state == ISM_DROther) - continue; + /* + * If the router is eligible to become Designated + * Router, it must periodically send Hello Packets to + * all neighbors that are also eligible. In addition, + * if the router is itself the Designated Router or + * Backup Designated Router, it must also send periodic + * Hello Packets to all other neighbors. + */ + if (nbr->priority == 0 && + oi->state == ISM_DROther) + continue; - /* if oi->state == Waiting, send - * hello to all neighbors */ - ospf_hello_send_sub(oi, nbr->address.u.prefix4.s_addr); + /* if oi->state == Waiting, send + * hello to all neighbors */ + ospf_hello_send_sub(oi, nbr->address.u.prefix4 + .s_addr); + } } } else { /* Decide destination address. */ @@ -3857,11 +3878,10 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag, else p.prefix.s_addr = htonl(OSPF_ALLDROUTERS); - if (oi->type == OSPF_IFTYPE_NBMA) { + if (OSPF_IF_NON_BROADCAST(oi)) { if (flag == OSPF_SEND_PACKET_INDIRECT) - flog_warn( - EC_OSPF_PACKET, - "* LS-Update is directly sent on NBMA network."); + flog_warn(EC_OSPF_PACKET, + "* LS-Update is directly sent on non-broadcast network."); if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix)) flog_warn(EC_OSPF_PACKET, "* LS-Update is sent to myself."); @@ -3919,7 +3939,8 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, /* Decide destination address. */ if (oi->type == OSPF_IFTYPE_POINTOPOINT || - oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && + !oi->p2mp_non_broadcast)) op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); else op->dst.s_addr = dst.s_addr; @@ -3971,7 +3992,7 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi) networks, delayed Link State Acknowledgment packets must be unicast separately over each adjacency (i.e., neighbor whose state is >= Exchange). */ - if (oi->type == OSPF_IFTYPE_NBMA) { + if (OSPF_IF_NON_BROADCAST(oi)) { struct ospf_neighbor *nbr; struct route_node *rn; diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 99326b4..dbe44f7 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -1784,11 +1784,10 @@ static void ospf_router_info_schedule(enum lsa_opcode opcode) DEFUN (router_info, router_info_area_cmd, - "router-info <as|area [A.B.C.D]>", + "router-info <as|area>", OSPF_RI_STR "Enable the Router Information functionality with AS flooding scope\n" - "Enable the Router Information functionality with Area flooding scope\n" - "OSPF area ID in IP format (deprecated)\n") + "Enable the Router Information functionality with Area flooding scope\n") { int idx_mode = 1; uint8_t scope; @@ -1844,6 +1843,15 @@ DEFUN (router_info, return CMD_SUCCESS; } +#if CONFDATE > 20240809 +CPP_NOTICE("Drop deprecated router_info_area_id_cmd") +#endif +ALIAS_HIDDEN (router_info, + router_info_area_id_cmd, + "router-info area A.B.C.D", + OSPF_RI_STR + "Enable the Router Information functionality with Area flooding scope\n" + "OSPF area ID in IP format (deprecated)\n") DEFUN (no_router_info, no_router_info_cmd, @@ -2239,6 +2247,7 @@ static void ospf_router_info_register_vty(void) install_element(VIEW_NODE, &show_ip_ospf_router_info_pce_cmd); install_element(OSPF_NODE, &router_info_area_cmd); + install_element(OSPF_NODE, &router_info_area_id_cmd); install_element(OSPF_NODE, &no_router_info_cmd); install_element(OSPF_NODE, &pce_address_cmd); install_element(OSPF_NODE, &no_pce_address_cmd); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index e26fe6f..198309c 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -2740,9 +2740,9 @@ static void show_sr_node(struct vty *vty, struct json_object *json, if (srn->algo[i] == SR_ALGORITHM_UNSET) continue; json_obj = json_object_new_object(); - char tmp[2]; + char tmp[12]; - snprintf(tmp, sizeof(tmp), "%u", i); + snprintf(tmp, sizeof(tmp), "%d", i); json_object_string_add(json_obj, tmp, srn->algo[i] == SR_ALGORITHM_SPF ? "SPF" diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index b1563b5..d57990e 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -4016,7 +4016,6 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json, json_object *jobj = NULL; sum = 0; - sub = 0; total = lsa->size - OSPF_LSA_HEADER_SIZE; for (tlvh = TLV_HDR_TOP(lsah); sum < total && tlvh; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4f30d52..7cb5197 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2406,130 +2406,30 @@ DEFUN (no_ospf_timers_lsa_min_arrival, return CMD_SUCCESS; } -DEFUN (ospf_neighbor, - ospf_neighbor_cmd, - "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]", - NEIGHBOR_STR - "Neighbor IP address\n" - "Neighbor Priority\n" - "Priority\n" - "Dead Neighbor Polling interval\n" - "Seconds\n") -{ - VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - int idx_ipv4 = 1; - int idx_pri = 3; - int idx_poll = 5; - struct in_addr nbr_addr; - unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; - - if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) { - vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > 2) - priority = strtoul(argv[idx_pri]->arg, NULL, 10); - - if (argc > 4) - interval = strtoul(argv[idx_poll]->arg, NULL, 10); - - ospf_nbr_nbma_set(ospf, nbr_addr); - - if (argc > 2) - ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority); - - if (argc > 4) - ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval); - - return CMD_SUCCESS; -} - -DEFUN (ospf_neighbor_poll_interval, - ospf_neighbor_poll_interval_cmd, - "neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]", - NEIGHBOR_STR - "Neighbor IP address\n" - "Dead Neighbor Polling interval\n" - "Seconds\n" - "OSPF priority of non-broadcast neighbor\n" - "Priority\n") -{ - VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - int idx_ipv4 = 1; - int idx_poll = 3; - int idx_pri = 5; - struct in_addr nbr_addr; - unsigned int priority; - unsigned int interval; - - if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) { - vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - interval = strtoul(argv[idx_poll]->arg, NULL, 10); - - priority = argc > 4 ? strtoul(argv[idx_pri]->arg, NULL, 10) - : OSPF_NEIGHBOR_PRIORITY_DEFAULT; - - ospf_nbr_nbma_set(ospf, nbr_addr); - ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval); - - if (argc > 4) - ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority); - - return CMD_SUCCESS; -} - -DEFUN (no_ospf_neighbor, - no_ospf_neighbor_cmd, - "no neighbor A.B.C.D [priority (0-255) [poll-interval (1-65525)]]", - NO_STR - NEIGHBOR_STR - "Neighbor IP address\n" - "Neighbor Priority\n" - "Priority\n" - "Dead Neighbor Polling interval\n" - "Seconds\n") +DEFPY(ospf_neighbor, ospf_neighbor_cmd, + "[no] neighbor A.B.C.D$nbr_address [{priority (0-255)$priority | poll-interval (1-65535)$interval}]", + NO_STR + NEIGHBOR_STR + "Neighbor IP address\n" + "Neighbor Priority\n" + "Priority\n" + "Dead Neighbor Polling interval\n" + "Seconds\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct in_addr nbr_addr; - - if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) { - vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - (void)ospf_nbr_nbma_unset(ospf, nbr_addr); - return CMD_SUCCESS; -} - -DEFUN (no_ospf_neighbor_poll, - no_ospf_neighbor_poll_cmd, - "no neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]", - NO_STR - NEIGHBOR_STR - "Neighbor IP address\n" - "Dead Neighbor Polling interval\n" - "Seconds\n" - "Neighbor Priority\n" - "Priority\n") -{ - VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct in_addr nbr_addr; + if (no) + ospf_nbr_nbma_unset(ospf, nbr_address); + else { + ospf_nbr_nbma_set(ospf, nbr_address); + if (priority_str) + ospf_nbr_nbma_priority_set(ospf, nbr_address, priority); - if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) { - vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + if (interval_str) + ospf_nbr_nbma_poll_interval_set(ospf, nbr_address, + interval); } - (void)ospf_nbr_nbma_unset(ospf, nbr_addr); - return CMD_SUCCESS; } @@ -2680,7 +2580,7 @@ DEFUN (no_ospf_write_multiplier, } ALIAS(no_ospf_write_multiplier, no_write_multiplier_cmd, - "no write-multiplier (1-100)", NO_STR + "no write-multiplier [(1-100)]", NO_STR "Write multiplier\n" "Maximum number of interface serviced per write\n") @@ -2754,9 +2654,10 @@ DEFUN (ospf_max_multipath, DEFUN (no_ospf_max_multipath, no_ospf_max_multipath_cmd, - "no maximum-paths", + "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]", NO_STR - "Max no of multiple paths for ECMP support\n") + "Max no of multiple paths for ECMP support\n" + "Number of paths\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); uint16_t maxpaths = MULTIPATH_NUM; @@ -4148,6 +4049,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); ospf_interface_auth_show(vty, oi, json_oi, use_json); + + /* Point-to-Multipoint Interface options. */ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { if (use_json) { json_object_boolean_add(json_interface_sub, @@ -4162,6 +4065,19 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, " %sDelay reflooding LSAs received on P2MP interface\n", oi->p2mp_delay_reflood ? "" : "Don't "); } + if (use_json) { + json_object_boolean_add(json_interface_sub, + "p2mpNonBroadcast", + oi->p2mp_non_broadcast); + + json_object_boolean_add(json_oi, + "p2mpNonBroadcast", + oi->p2mp_non_broadcast); + } else { + vty_out(vty, + " P2MP interface does %ssupport broadcast\n", + oi->p2mp_non_broadcast ? "not " : ""); + } } /* Add ospf_interface object to main json blob using SIP as key @@ -4169,6 +4085,31 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (use_json) json_object_object_addf(json_ois, json_oi, "%pI4", &oi->address->u.prefix4); + + if (oi->nbr_filter) { + if (use_json) { + json_object_string_add(json_interface_sub, + "nbrFilterPrefixList", + prefix_list_name( + oi->nbr_filter)); + json_object_string_add(json_oi, + "nbrFilterPrefixList", + prefix_list_name( + oi->nbr_filter)); + } else + vty_out(vty, + " Neighbor filter prefix-list: %s\n", + prefix_list_name(oi->nbr_filter)); + } else { + if (use_json) { + json_object_string_add(json_interface_sub, + "nbrFilterPrefixList", + "N/A"); + json_object_string_add(json_oi, + "nbrFilterPrefixList", + "N/A"); + } + } } } @@ -5970,7 +5911,7 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty, prev_nbr = nbr; } - if (oi->type != OSPF_IFTYPE_NBMA) + if (!OSPF_IF_NON_BROADCAST(oi)) continue; struct listnode *nd; @@ -8550,7 +8491,7 @@ DEFUN_HIDDEN (no_ospf_hello_interval, DEFUN(ip_ospf_network, ip_ospf_network_cmd, "ip ospf network <broadcast|" "non-broadcast|" - "point-to-multipoint [delay-reflood]|" + "point-to-multipoint [delay-reflood|non-broadcast]|" "point-to-point [dmvpn]>", "IP Information\n" "OSPF interface commands\n" @@ -8559,6 +8500,7 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, "Specify OSPF NBMA network\n" "Specify OSPF point-to-multipoint network\n" "Specify OSPF delayed reflooding of LSAs received on P2MP interface\n" + "Specify OSPF point-to-multipoint network doesn't support broadcast\n" "Specify OSPF point-to-point network\n" "Specify OSPF point-to-point DMVPN network\n") { @@ -8567,6 +8509,7 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, int old_type = IF_DEF_PARAMS(ifp)->type; uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn; uint8_t old_p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood; + uint8_t old_p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast; struct route_node *rn; if (old_type == OSPF_IFTYPE_LOOPBACK) { @@ -8578,16 +8521,19 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0; IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT; + IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT; if (argv_find(argv, argc, "broadcast", &idx)) IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST; - else if (argv_find(argv, argc, "non-broadcast", &idx)) - IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA; else if (argv_find(argv, argc, "point-to-multipoint", &idx)) { IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT; if (argv_find(argv, argc, "delay-reflood", &idx)) IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = true; - } else if (argv_find(argv, argc, "point-to-point", &idx)) { + if (argv_find(argv, argc, "non-broadcast", &idx)) + IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = true; + } else if (argv_find(argv, argc, "non-broadcast", &idx)) + IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA; + else if (argv_find(argv, argc, "point-to-point", &idx)) { IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT; if (argv_find(argv, argc, "dmvpn", &idx)) IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1; @@ -8597,7 +8543,8 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, if (IF_DEF_PARAMS(ifp)->type == old_type && IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn && - IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood) + IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood && + IF_DEF_PARAMS(ifp)->p2mp_non_broadcast == old_p2mp_non_broadcast) return CMD_SUCCESS; SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); @@ -8611,13 +8558,16 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd, oi->type = IF_DEF_PARAMS(ifp)->type; oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn; oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood; + oi->p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast; /* * The OSPF interface only needs to be flapped if the network * type or DMVPN parameter changes. */ if (IF_DEF_PARAMS(ifp)->type != old_type || - IF_DEF_PARAMS(ifp)->ptp_dmvpn != old_ptp_dmvpn) { + IF_DEF_PARAMS(ifp)->ptp_dmvpn != old_ptp_dmvpn || + IF_DEF_PARAMS(ifp)->p2mp_non_broadcast != + old_p2mp_non_broadcast) { if (oi->state > ISM_Down) { OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp); @@ -8662,6 +8612,7 @@ DEFUN (no_ip_ospf_network, IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0; IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT; + IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT; if (IF_DEF_PARAMS(ifp)->type == old_type) return CMD_SUCCESS; @@ -10016,6 +9967,58 @@ DEFPY(ip_ospf_prefix_suppression, ip_ospf_prefix_suppression_addr_cmd, return CMD_SUCCESS; } +DEFPY(ip_ospf_neighbor_filter, ip_ospf_neighbor_filter_addr_cmd, + "[no] ip ospf neighbor-filter ![PREFIXLIST4_NAME]$prefix_list [A.B.C.D]$ip_addr", NO_STR + "IP Information\n" + "OSPF interface commands\n" + "Filter OSPF neighbor packets\n" + "Prefix-List used for filtering\n" + "Address of interface\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; + struct prefix_list *nbr_filter = NULL; + struct route_node *rn; + + params = IF_DEF_PARAMS(ifp); + + if (ip_addr.s_addr != INADDR_ANY) { + params = ospf_get_if_params(ifp, ip_addr); + ospf_if_update_params(ifp, ip_addr); + } + + if (params->nbr_filter_name) + XFREE(MTYPE_OSPF_IF_PARAMS, params->nbr_filter_name); + + if (no) { + UNSET_IF_PARAM(params, nbr_filter_name); + params->nbr_filter_name = NULL; + } else { + SET_IF_PARAM(params, nbr_filter_name); + params->nbr_filter_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS, + prefix_list); + nbr_filter = prefix_list_lookup(AFI_IP, params->nbr_filter_name); + } + + /* + * Determine if there is a change in neighbor filter prefix-list for the + * interface. + */ + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (oi && + (ip_addr.s_addr == INADDR_ANY || + IPV4_ADDR_SAME(&oi->address->u.prefix4, &ip_addr)) && + oi->nbr_filter != nbr_filter) { + oi->nbr_filter = nbr_filter; + if (oi->nbr_filter) + ospf_intf_neighbor_filter_apply(oi); + } + } + return CMD_SUCCESS; +} + DEFUN (ospf_max_metric_router_lsa_admin, ospf_max_metric_router_lsa_admin_cmd, "max-metric router-lsa administrative", @@ -10526,15 +10529,6 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, json_object_string_add(json_vrf, "strictLsaCheck", (ospf->strict_lsa_check) ? "Enabled" : "Disabled"); -#if CONFDATE > 20240401 - CPP_NOTICE("Remove deprecated json key: restartSupoort") -#endif - json_object_string_add( - json_vrf, "restartSupoort", - (ospf->only_planned_restart) - ? "Planned Restart only" - : "Planned and Unplanned Restarts"); - json_object_string_add( json_vrf, "restartSupport", (ospf->only_planned_restart) @@ -10761,10 +10755,11 @@ DEFUN (ospf_route_aggregation_timer, DEFPY (show_ip_ospf_gr_helper, show_ip_ospf_gr_helper_cmd, - "show ip ospf [vrf <NAME|all>] graceful-restart helper [detail] [json]", + "show ip ospf [{(1-65535)$instance|vrf <NAME|all>}] graceful-restart helper [detail] [json]", SHOW_STR IP_STR "OSPF information\n" + "Instance ID\n" VRF_CMD_HELP_STR "All VRFs\n" "OSPF Graceful Restart\n" @@ -10785,8 +10780,20 @@ DEFPY (show_ip_ospf_gr_helper, int inst = 0; bool detail = false; + if (instance && instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + if (instance && vrf_name) { + vty_out(vty, "%% VRF is not supported in instance mode\n"); + return CMD_WARNING; + } + if (argv_find(argv, argc, "detail", &idx)) detail = true; @@ -12228,6 +12235,10 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) OSPF_IFTYPE_POINTOMULTIPOINT && params->p2mp_delay_reflood) vty_out(vty, " delay-reflood"); + if (params->type == + OSPF_IFTYPE_POINTOMULTIPOINT && + params->p2mp_non_broadcast) + vty_out(vty, " non-broadcast"); if (params != IF_DEF_PARAMS(ifp) && rn) vty_out(vty, " %pI4", &rn->p.u.prefix4); vty_out(vty, "\n"); @@ -12440,6 +12451,15 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, "\n"); } + /* neighbor-filter print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, nbr_filter_name)) { + vty_out(vty, " ip ospf neighbor-filter %s", + params->nbr_filter_name); + if (params != IF_DEF_PARAMS(ifp) && rn) + vty_out(vty, " %pI4", &rn->p.u.prefix4); + vty_out(vty, "\n"); + } + while (1) { if (rn == NULL) rn = route_top(IF_OIFS_PARAMS(ifp)); @@ -13256,6 +13276,9 @@ static void ospf_vty_if_init(void) /* "ip ospf prefix-suppression" commands. */ install_element(INTERFACE_NODE, &ip_ospf_prefix_suppression_addr_cmd); + /* "ip ospf neighbor-filter" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_neighbor_filter_addr_cmd); + /* These commands are compatibitliy for previous version. */ install_element(INTERFACE_NODE, &ospf_authentication_key_cmd); install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd); @@ -13754,11 +13777,8 @@ void ospf_vty_init(void) install_element(OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd); install_element(OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd); - /* "neighbor" commands. */ + /* "neighbor" command. */ install_element(OSPF_NODE, &ospf_neighbor_cmd); - install_element(OSPF_NODE, &ospf_neighbor_poll_interval_cmd); - install_element(OSPF_NODE, &no_ospf_neighbor_cmd); - install_element(OSPF_NODE, &no_ospf_neighbor_poll_cmd); /* write multiplier commands */ install_element(OSPF_NODE, &ospf_write_multiplier_cmd); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index bb6cc3a..2c518f2 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -1769,6 +1769,7 @@ static void ospf_prefix_list_update(struct prefix_list *plist) int type; int abr_inv = 0; struct ospf_area *area; + struct ospf_interface *oi; struct listnode *node, *n1; /* If OSPF instatnce does not exist, return right now. */ @@ -1824,6 +1825,19 @@ static void ospf_prefix_list_update(struct prefix_list *plist) } } + /* Update interface neighbor-filter lists. */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if (OSPF_IF_PARAM(oi, nbr_filter_name) && + strcmp(OSPF_IF_PARAM(oi, nbr_filter_name), + prefix_list_name(plist)) == 0) { + oi->nbr_filter = prefix_list_lookup( + AFI_IP, + OSPF_IF_PARAM(oi, nbr_filter_name)); + if (oi->nbr_filter) + ospf_intf_neighbor_filter_apply(oi); + } + } + /* Schedule ABR task. */ if (IS_OSPF_ABR(ospf) && abr_inv) ospf_schedule_abr_task(ospf); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 4c4666d..1d013b2 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1096,6 +1096,7 @@ struct ospf_interface *add_ospf_interface(struct connected *co, oi->type = IF_DEF_PARAMS(co->ifp)->type; oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn; oi->p2mp_delay_reflood = IF_DEF_PARAMS(co->ifp)->p2mp_delay_reflood; + oi->p2mp_non_broadcast = IF_DEF_PARAMS(co->ifp)->p2mp_non_broadcast; /* Add pseudo neighbor. */ ospf_nbr_self_reset(oi, oi->ospf->router_id); @@ -1989,7 +1990,7 @@ static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma, struct route_node *rn; struct prefix p; - if (oi->type != OSPF_IFTYPE_NBMA) + if (!OSPF_IF_NON_BROADCAST(oi)) return; if (nbr_nbma->nbr != NULL) @@ -2036,7 +2037,7 @@ void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi) struct route_node *rn; struct prefix_ipv4 p; - if (oi->type != OSPF_IFTYPE_NBMA) + if (!OSPF_IF_NON_BROADCAST(oi)) return; for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) @@ -2095,7 +2096,7 @@ int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr) rn->info = nbr_nbma; for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { - if (oi->type == OSPF_IFTYPE_NBMA) + if (OSPF_IF_NON_BROADCAST(oi)) if (prefix_match(oi->address, (struct prefix *)&p)) { ospf_nbr_nbma_add(nbr_nbma, oi); break; |