diff options
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_interface.c | 3 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.c | 72 | ||||
| -rw-r--r-- | ospfd/ospf_route.c | 6 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 83 | 
5 files changed, 146 insertions, 21 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 72de198116..bdab672b47 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -600,6 +600,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr)  	    !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) &&  	    !OSPF_IF_PARAM_CONFIGURED(oip, if_area) &&  	    !OSPF_IF_PARAM_CONFIGURED(oip, opaque_capable) && +	    !OSPF_IF_PARAM_CONFIGURED(oip, prefix_suppression) &&  	    listcount(oip->auth_crypt) == 0) {  		ospf_del_if_params(ifp, oip);  		rn->info = NULL; @@ -709,6 +710,8 @@ int ospf_if_new_hook(struct interface *ifp)  	SET_IF_PARAM(IF_DEF_PARAMS(ifp), opaque_capable);  	IF_DEF_PARAMS(ifp)->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT; +	IF_DEF_PARAMS(ifp)->prefix_suppression = OSPF_PREFIX_SUPPRESSION_DEFAULT; +  	rc = ospf_opaque_new_if(ifp);  	return rc;  } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 38ec45c757..47b70f8039 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -81,6 +81,9 @@ struct ospf_if_params {  	/* Fast-Hellos */  	DECLARE_IF_PARAM(uint8_t, fast_hello); +	/* Prefix-Suppression */ +	DECLARE_IF_PARAM(bool, prefix_suppression); +  	/* Authentication data. */  	uint8_t auth_simple[OSPF_AUTH_SIMPLE_SIZE + 1]; /* Simple password. */  	uint8_t auth_simple__config : 1; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 27e7e02759..7ef9834274 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -539,16 +539,23 @@ static int lsa_link_ptop_set(struct stream **s, struct ospf_interface *oi)  		}  	/* no need for a stub link for unnumbered interfaces */ -	if (oi->ptp_dmvpn -	    || !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { -		/* Regardless of the state of the neighboring router, we must -		   add a Type 3 link (stub network). -		   N.B. Options 1 & 2 share basically the same logic. */ -		masklen2ip(oi->address->prefixlen, &mask); -		id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr -			    & mask.s_addr; -		links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, -				       oi->output_cost); +	if (OSPF_IF_PARAM(oi, prefix_suppression)) { +		if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) +			zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", +				   oi->ifp->name); +	} else { +		if (oi->ptp_dmvpn || +		    !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { +			/* Regardless of the state of the neighboring router, we must +			   add a Type 3 link (stub network). +			   N.B. Options 1 & 2 share basically the same logic. */ +			masklen2ip(oi->address->prefixlen, &mask); +			id.s_addr = +				CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & +				mask.s_addr; +			links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, +					       0, oi->output_cost); +		}  	}  	return links; @@ -563,10 +570,15 @@ static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi)  	/* Describe Type 3 Link. */  	if (oi->state == ISM_Waiting) { +		if (OSPF_IF_PARAM(oi, prefix_suppression)) { +			if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) +				zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", +					   oi->ifp->name); +			return 0; +		}  		if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) -			zlog_debug( -				"LSA[Type1]: Interface %s is in state Waiting. Adding stub interface", -				oi->ifp->name); +			zlog_debug("LSA[Type1]: Interface %s is in state Waiting. Adding stub interface", +				   oi->ifp->name);  		masklen2ip(oi->address->prefixlen, &mask);  		id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;  		return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, @@ -587,10 +599,15 @@ static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi)  	}  	/* Describe type 3 link. */  	else { +		if (OSPF_IF_PARAM(oi, prefix_suppression)) { +			if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) +				zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", +					   oi->ifp->name); +			return 0; +		}  		if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) -			zlog_debug( -				"LSA[Type1]: Interface %s has no DR. Adding stub interface", -				oi->ifp->name); +			zlog_debug("LSA[Type1]: Interface %s has no DR. Adding stub interface", +				   oi->ifp->name);  		masklen2ip(oi->address->prefixlen, &mask);  		id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;  		return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, @@ -603,7 +620,7 @@ static int lsa_link_loopback_set(struct stream **s, struct ospf_interface *oi)  	struct in_addr id, mask;  	/* Describe Type 3 Link. */ -	if (oi->state != ISM_Loopback) +	if ((oi->state != ISM_Loopback) || OSPF_IF_PARAM(oi, prefix_suppression))  		return 0;  	mask.s_addr = 0xffffffff; @@ -645,9 +662,15 @@ static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi)  	struct in_addr id, mask;  	uint16_t cost = ospf_link_cost(oi); -	mask.s_addr = 0xffffffff; -	id.s_addr = oi->address->u.prefix4.s_addr; -	links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); +	if (OSPF_IF_PARAM(oi, prefix_suppression)) { +		if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) +			zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", +				   oi->ifp->name); +	} else { +		mask.s_addr = 0xffffffff; +		id.s_addr = oi->address->u.prefix4.s_addr; +		links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); +	}  	if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))  		zlog_debug("PointToMultipoint: running ptomultip_set"); @@ -1006,7 +1029,14 @@ static void ospf_network_lsa_body_set(struct stream *s,  	struct route_node *rn;  	struct ospf_neighbor *nbr; -	masklen2ip(oi->address->prefixlen, &mask); +	if (OSPF_IF_PARAM(oi, prefix_suppression)) { +		mask.s_addr = 0xffffffff; +		if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) +			zlog_debug("LSA[Type2]: Interface %s network mask set to host mask due prefix-suppression", +				   oi->ifp->name); +	} else { +		masklen2ip(oi->address->prefixlen, &mask); +	}  	stream_put_ipv4(s, mask.s_addr);  	/* The network-LSA lists those routers that are fully adjacent to diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index cdb1eb0095..85da212d22 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -462,6 +462,12 @@ void ospf_intra_add_transit(struct route_table *rt, struct vertex *v,  	   the IP network number, which can be obtained by masking the  	   Vertex ID (Link State ID) with its associated subnet mask (found  	   in the body of the associated network-LSA). */ +	if (lsa->mask.s_addr == 0xffffffff) { +		if (IS_DEBUG_OSPF_EVENT) +			zlog_debug("Suppress installing LSA[Type2,%pI4] route due to host mask", +				   &(lsa->header.id)); +		return; +	}  	p.family = AF_INET;  	p.prefix = v->id;  	p.prefixlen = ip_masklen(lsa->mask); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 54fd60af23..267898afcc 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4076,6 +4076,20 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,  		ospf_interface_bfd_show(vty, ifp, json_interface_sub); +		if (use_json) { +			json_object_boolean_add(json_interface_sub, +						"prefixSuppression", +						OSPF_IF_PARAM(oi, +							      prefix_suppression)); +			json_object_boolean_add(json_oi, "prefixSuppression", +						OSPF_IF_PARAM(oi, +							      prefix_suppression)); +		} else { +			if (OSPF_IF_PARAM(oi, prefix_suppression)) +				vty_out(vty, +					"  Suppress advertisement of interface IP prefix\n"); +		} +  		/* OSPF Authentication information */  		ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); @@ -9865,6 +9879,56 @@ DEFPY(ip_ospf_capability_opaque, ip_ospf_capability_opaque_addr_cmd,  } +DEFPY(ip_ospf_prefix_suppression, ip_ospf_prefix_suppression_addr_cmd, +      "[no] ip ospf prefix-suppression [A.B.C.D]$ip_addr", NO_STR +      "IP Information\n" +      "OSPF interface commands\n" +      "Supress OSPF prefix advertisement on this interface\n" +      "Address of interface\n") +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct route_node *rn; +	bool prefix_suppression_change; +	struct ospf_if_params *params; + +	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); +	} + +	prefix_suppression_change = (params->prefix_suppression == (bool)no); +	params->prefix_suppression = (no) ? false : true; +	if (params->prefix_suppression != OSPF_PREFIX_SUPPRESSION_DEFAULT) +		SET_IF_PARAM(params, prefix_suppression); +	else { +		UNSET_IF_PARAM(params, prefix_suppression); +		if (params != IF_DEF_PARAMS(ifp)) { +			ospf_free_if_params(ifp, ip_addr); +			ospf_if_update_params(ifp, ip_addr); +		} +	} + +	/* +	 * If there is a change to the prefix suppression, update the Router-LSA. +	 */ +	if (prefix_suppression_change) { +		for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { +			struct ospf_interface *oi = rn->info; + +			if (oi && (oi->state > ISM_Down) && +			    (ip_addr.s_addr == INADDR_ANY || +			     IPV4_ADDR_SAME(&oi->address->u.prefix4, &ip_addr))) { +				(void)ospf_router_lsa_update_area(oi->area); +				if (oi->state == ISM_DR) +					ospf_network_lsa_update(oi); +			} +		} +	} +	return CMD_SUCCESS; +} +  DEFUN (ospf_max_metric_router_lsa_admin,         ospf_max_metric_router_lsa_admin_cmd,         "max-metric router-lsa administrative", @@ -12243,6 +12307,22 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)  				vty_out(vty, "\n");  			} +			/* prefix-suppression print. */ +			if (OSPF_IF_PARAM_CONFIGURED(params, +						     prefix_suppression) && +			    params->prefix_suppression != +				    OSPF_PREFIX_SUPPRESSION_DEFAULT) { +				if (params->prefix_suppression == false) +					vty_out(vty, +						" no ip ospf prefix-suppression"); +				else +					vty_out(vty, +						" ip ospf prefix-suppression"); +				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)); @@ -13055,6 +13135,9 @@ static void ospf_vty_if_init(void)  	/* "ip ospf capability opaque" commands. */  	install_element(INTERFACE_NODE, &ip_ospf_capability_opaque_addr_cmd); +	/* "ip ospf prefix-suppression" commands. */ +	install_element(INTERFACE_NODE, &ip_ospf_prefix_suppression_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);  | 
