diff options
| author | Acee Lindem <acee@lindem.com> | 2024-04-17 20:14:56 +0000 | 
|---|---|---|
| committer | Acee Lindem <acee@lindem.com> | 2024-04-18 15:32:58 +0000 | 
| commit | 0ccad8a2b0b744d7ed64f53ab6e70a8d6aba69e6 (patch) | |
| tree | fce17b663806106750689e00ba161c42dd53b6fd /ospfd/ospf_interface.c | |
| parent | 84d1fb19e22a5f0d13d3bbb7c74e9948773e66f3 (diff) | |
ospfd: Add prefix-list filtering of OSPF neighbors on OSPF interface
This commit adds the capabiity to filter OSPF neighbors using a
prefix-list with rules matching the neighbor's IP source address.
Configuration, filtering, immediate neighbor pruning, topo-tests,
and documentation are included. The command is:
     ip ospf neighbor-filter <prefix-list> [A.B.C.D]
Signed-off-by: Acee Lindem <acee@lindem.com>
Diffstat (limited to 'ospfd/ospf_interface.c')
| -rw-r--r-- | ospfd/ospf_interface.c | 34 | 
1 files changed, 33 insertions, 1 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 319db1efe2..0b27501019 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 */ @@ -526,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(); @@ -544,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); @@ -579,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;  | 
