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_flood.c | 5 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 49 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 19 | ||||
| -rw-r--r-- | ospfd/ospf_ism.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_main.c | 24 | ||||
| -rw-r--r-- | ospfd/ospf_neighbor.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_nsm.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 102 | ||||
| -rw-r--r-- | ospfd/ospf_snmp.c | 26 | ||||
| -rw-r--r-- | ospfd/ospf_sr.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 326 | ||||
| -rw-r--r-- | ospfd/ospf_zebra.c | 14 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 7 |
15 files changed, 374 insertions, 247 deletions
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 419113e6d7..fcc28c6f9f 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 0aaf67c1f3..4341a9d380 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_flood.c b/ospfd/ospf_flood.c index 95a593ad4d..e15871ac81 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 17426d2615..11ac7af7c9 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; @@ -1388,7 +1414,8 @@ static int ospf_ifp_create(struct interface *ifp) (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type) || if_is_loopback(ifp))) { SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); - IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); + if (!IF_DEF_PARAMS(ifp)->type_cfg) + IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); } ospf = ifp->vrf->info; diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 08a2b11273..45d0b7943a 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -57,6 +57,7 @@ struct ospf_if_params { DECLARE_IF_PARAM(struct in_addr, if_area); uint32_t if_area_id_fmt; + bool type_cfg; DECLARE_IF_PARAM(uint8_t, type); /* type of interface */ #define OSPF_IF_ACTIVE 0 #define OSPF_IF_PASSIVE 1 @@ -119,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, @@ -185,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; @@ -192,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; @@ -232,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 { @@ -326,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); @@ -358,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 2516fa75db..878ab725bd 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_main.c b/ospfd/ospf_main.c index abad6c5b90..9e97abba1c 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -44,6 +44,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 +76,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 +85,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) { @@ -193,15 +191,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; @@ -223,6 +217,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); diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index c238f051df..d47d581605 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 08aa103686..c466ddcc6f 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 861b4e022a..87aaccad92 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" @@ -2747,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" @@ -3395,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); @@ -3451,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; @@ -3467,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. */ @@ -3848,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."); @@ -3910,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; @@ -3962,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_snmp.c b/ospfd/ospf_snmp.c index fc0c143c28..4e1f15361e 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -906,7 +906,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, area = ospf_area_lookup_by_area_id(ospf, *area_id); if (!area) return NULL; - offset++; + offset += IN_ADDR_SIZE; /* Type. */ *type = *offset; @@ -914,7 +914,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, /* LS ID. */ oid2in_addr(offset, IN_ADDR_SIZE, ls_id); - offset++; + offset += IN_ADDR_SIZE; /* Router ID. */ oid2in_addr(offset, IN_ADDR_SIZE, router_id); @@ -971,7 +971,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, } /* Router ID. */ - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; len = offsetlen; @@ -996,11 +996,11 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, /* Fill in value. */ offset = name + v->namelen; oid_copy_in_addr(offset, area_id); - offset++; + offset += IN_ADDR_SIZE; *offset = lsa->data->type; offset++; oid_copy_in_addr(offset, &lsa->data->id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, &lsa->data->adv_router); @@ -1106,7 +1106,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, if (!area) return NULL; - offset++; + offset += IN_ADDR_SIZE; /* Lookup area range. */ oid2in_addr(offset, IN_ADDR_SIZE, range_net); @@ -1135,7 +1135,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, return NULL; do { - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; len = offsetlen; @@ -1157,7 +1157,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, /* Fill in value. */ offset = name + v->namelen; oid_copy_in_addr(offset, area_id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, range_net); return range; @@ -1559,7 +1559,7 @@ static struct ospf_interface *ospfIfLookup(struct variable *v, oid *name, *length = v->namelen + IN_ADDR_SIZE + 1; offset = name + v->namelen; oid_copy_in_addr(offset, ifaddr); - offset++; + offset += IN_ADDR_SIZE; *offset = *ifindex; return oi; } @@ -1703,7 +1703,7 @@ static struct ospf_interface *ospfIfMetricLookup(struct variable *v, oid *name, *length = v->namelen + IN_ADDR_SIZE + 1 + 1; offset = name + v->namelen; oid_copy_in_addr(offset, ifaddr); - offset++; + offset += IN_ADDR_SIZE; *offset = *ifindex; offset++; *offset = OSPF_SNMP_METRIC_VALUE; @@ -2241,7 +2241,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, /* LS ID. */ oid2in_addr(offset, IN_ADDR_SIZE, ls_id); - offset++; + offset += IN_ADDR_SIZE; /* Router ID. */ oid2in_addr(offset, IN_ADDR_SIZE, router_id); @@ -2269,7 +2269,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, oid2in_addr(offset, len, ls_id); - offset++; + offset += IN_ADDR_SIZE; offsetlen -= IN_ADDR_SIZE; /* Router ID. */ @@ -2292,7 +2292,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, *offset = OSPF_AS_EXTERNAL_LSA; offset++; oid_copy_in_addr(offset, &lsa->data->id); - offset++; + offset += IN_ADDR_SIZE; oid_copy_in_addr(offset, &lsa->data->adv_router); return lsa; diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index e26fe6f53a..198309c1ef 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_vty.c b/ospfd/ospf_vty.c index 93dd12ce49..3f8731f369 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; @@ -8548,7 +8489,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" @@ -8557,6 +8498,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") { @@ -8565,6 +8507,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) { @@ -8576,24 +8519,30 @@ 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; } + IF_DEF_PARAMS(ifp)->type_cfg = true; + 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); @@ -8607,13 +8556,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); @@ -8654,9 +8606,11 @@ DEFUN (no_ip_ospf_network, struct route_node *rn; IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); + IF_DEF_PARAMS(ifp)->type_cfg = false; 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; @@ -10011,6 +9965,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", @@ -10521,15 +10527,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) @@ -12211,25 +12208,25 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) do { /* Interface Network print. */ - if (OSPF_IF_PARAM_CONFIGURED(params, type) - && params->type != OSPF_IFTYPE_LOOPBACK) { - if (params->type != ospf_default_iftype(ifp)) { - vty_out(vty, " ip ospf network %s", - ospf_int_type_str - [params->type]); - if (params->type - == OSPF_IFTYPE_POINTOPOINT - && params->ptp_dmvpn) - vty_out(vty, " dmvpn"); - if (params->type == - OSPF_IFTYPE_POINTOMULTIPOINT && - params->p2mp_delay_reflood) - vty_out(vty, " delay-reflood"); - if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %pI4", - &rn->p.u.prefix4); - vty_out(vty, "\n"); - } + if (OSPF_IF_PARAM_CONFIGURED(params, type) && + params->type != OSPF_IFTYPE_LOOPBACK && + params->type_cfg) { + vty_out(vty, " ip ospf network %s", + ospf_int_type_str[params->type]); + if (params->type == OSPF_IFTYPE_POINTOPOINT && + params->ptp_dmvpn) + vty_out(vty, " dmvpn"); + if (params->type == + 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"); } /* OSPF interface authentication print */ @@ -12439,6 +12436,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)); @@ -13255,6 +13261,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); @@ -13753,11 +13762,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 bb6cc3a89c..2c518f2c9e 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 4c4666db52..1d013b260e 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; |
