mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-04 19:56:49 +02:00
Adding route blackhole
Change-Id: I70212b0ab91e628e8528bca896c3aecc499e31b1
This commit is contained in:
parent
07f15f2cad
commit
d980c6db30
@ -16,6 +16,8 @@
|
||||
package org.onosproject.segmentrouting;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.onlab.packet.IpPrefix;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.PortNumber;
|
||||
@ -62,6 +64,9 @@ public class AppConfigHandler {
|
||||
SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
|
||||
deviceService.getAvailableDevices().forEach(device -> {
|
||||
populateVRouter(device.id(), getMacAddresses(config));
|
||||
config.blackholeIPs().forEach(ipPrefix -> {
|
||||
srManager.routingRulePopulator.populateDefaultRouteBlackhole(device.id(), ipPrefix);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -86,6 +91,14 @@ public class AppConfigHandler {
|
||||
|
||||
revokeVRouter(device.id(), prevMacAddresses);
|
||||
populateVRouter(device.id(), macAddresses);
|
||||
Set<IpPrefix> toRemove = Sets.difference(prevConfig.blackholeIPs(), config.blackholeIPs());
|
||||
toRemove.forEach(ipPrefix -> {
|
||||
srManager.routingRulePopulator.removeDefaultRouteBlackhole(device.id(), ipPrefix);
|
||||
});
|
||||
Set<IpPrefix> toAdd = Sets.difference(config.blackholeIPs(), prevConfig.blackholeIPs());
|
||||
toAdd.forEach(ipPrefix -> {
|
||||
srManager.routingRulePopulator.populateDefaultRouteBlackhole(device.id(), ipPrefix);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
@ -100,11 +113,14 @@ public class AppConfigHandler {
|
||||
SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
|
||||
deviceService.getAvailableDevices().forEach(device -> {
|
||||
revokeVRouter(device.id(), getMacAddresses(prevConfig));
|
||||
prevConfig.blackholeIPs().forEach(ipPrefix -> {
|
||||
srManager.routingRulePopulator.removeDefaultRouteBlackhole(device.id(), ipPrefix);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates initial vRouter rules.
|
||||
* Populates initial vRouter and blackhole rules.
|
||||
*
|
||||
* @param deviceId device ID
|
||||
*/
|
||||
@ -112,6 +128,9 @@ public class AppConfigHandler {
|
||||
SegmentRoutingAppConfig config =
|
||||
srManager.cfgService.getConfig(srManager.appId, SegmentRoutingAppConfig.class);
|
||||
populateVRouter(deviceId, getMacAddresses(config));
|
||||
config.blackholeIPs().forEach(ipPrefix -> {
|
||||
srManager.routingRulePopulator.populateDefaultRouteBlackhole(deviceId, ipPrefix);
|
||||
});
|
||||
}
|
||||
|
||||
private void populateVRouter(DeviceId deviceId, Set<MacAddress> pendingAdd) {
|
||||
@ -166,7 +185,9 @@ public class AppConfigHandler {
|
||||
if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) {
|
||||
return true;
|
||||
}
|
||||
} catch (DeviceConfigNotFoundException e) { }
|
||||
} catch (DeviceConfigNotFoundException e) {
|
||||
log.warn("Device configuration for {} is not present.", deviceId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1373,6 +1373,75 @@ public class RoutingRulePopulator {
|
||||
return fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a forwarding objective to send packets that miss other high
|
||||
* priority Bridging Table entries to a group that contains all ports of
|
||||
* its subnet.
|
||||
*
|
||||
* @param address the address to block
|
||||
* @param deviceId switch ID to set the rules
|
||||
*/
|
||||
void populateDefaultRouteBlackhole(DeviceId deviceId, IpPrefix address) {
|
||||
updateDefaultRouteBlackhole(deviceId, address, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a forwarding objective to send packets that miss other high
|
||||
* priority Bridging Table entries to a group that contains all ports of
|
||||
* its subnet.
|
||||
*
|
||||
* @param address the address to block
|
||||
* @param deviceId switch ID to set the rules
|
||||
*/
|
||||
void removeDefaultRouteBlackhole(DeviceId deviceId, IpPrefix address) {
|
||||
updateDefaultRouteBlackhole(deviceId, address, false);
|
||||
}
|
||||
|
||||
private void updateDefaultRouteBlackhole(DeviceId deviceId, IpPrefix address, boolean install) {
|
||||
try {
|
||||
if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) {
|
||||
|
||||
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
|
||||
if (address.isIp4()) {
|
||||
sbuilder.matchIPDst(address);
|
||||
sbuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
|
||||
} else {
|
||||
sbuilder.matchIPv6Dst(address);
|
||||
sbuilder.matchEthType(EthType.EtherType.IPV6.ethType().toShort());
|
||||
}
|
||||
|
||||
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
|
||||
|
||||
tBuilder.transition(60);
|
||||
tBuilder.wipeDeferred();
|
||||
|
||||
ForwardingObjective.Builder fob = DefaultForwardingObjective.builder();
|
||||
fob.withFlag(Flag.SPECIFIC)
|
||||
.withSelector(sbuilder.build())
|
||||
.withTreatment(tBuilder.build())
|
||||
.withPriority(getPriorityFromPrefix(address))
|
||||
.fromApp(srManager.appId)
|
||||
.makePermanent();
|
||||
|
||||
log.debug("{} blackhole forwarding objectives for dev: {}",
|
||||
install ? "Installing" : "Removing", deviceId);
|
||||
ObjectiveContext context = new DefaultObjectiveContext(
|
||||
(objective) -> log.debug("Forward for {} {}", deviceId,
|
||||
install ? "installed" : "removed"),
|
||||
(objective, error) -> log.warn("Failed to {} forward for {}: {}",
|
||||
install ? "install" : "remove", deviceId, error));
|
||||
if (install) {
|
||||
srManager.flowObjectiveService.forward(deviceId, fob.add(context));
|
||||
} else {
|
||||
srManager.flowObjectiveService.forward(deviceId, fob.remove(context));
|
||||
}
|
||||
}
|
||||
} catch (DeviceConfigNotFoundException e) {
|
||||
log.info("Not populating blackhole for un-configured device {}", deviceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a forwarding objective to send packets that miss other high
|
||||
* priority Bridging Table entries to a group that contains all ports of
|
||||
|
||||
@ -19,6 +19,7 @@ package org.onosproject.segmentrouting.config;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.onlab.packet.IpPrefix;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
@ -38,14 +39,68 @@ public class SegmentRoutingAppConfig extends Config<ApplicationId> {
|
||||
// TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
|
||||
private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
|
||||
private static final String MPLS_ECMP = "MPLS-ECMP";
|
||||
private static final String BLACKHOLE_IPS = "blackholeIps";
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return hasOnlyFields(VROUTER_MACS, SUPPRESS_SUBNET,
|
||||
SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP) &&
|
||||
SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP, BLACKHOLE_IPS) &&
|
||||
vRouterMacs() != null &&
|
||||
suppressSubnet() != null && suppressHostByPort() != null &&
|
||||
suppressHostByProvider() != null;
|
||||
suppressHostByProvider() != null &&
|
||||
blackholeIPs() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ips to blackhole from the config.
|
||||
*
|
||||
* @return Set of ips to blackhole, empty is not specified,
|
||||
* or null if not valid
|
||||
*/
|
||||
public Set<IpPrefix> blackholeIPs() {
|
||||
if (!object.has(BLACKHOLE_IPS)) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
ImmutableSet.Builder<IpPrefix> builder = ImmutableSet.builder();
|
||||
ArrayNode arrayNode = (ArrayNode) object.path(BLACKHOLE_IPS);
|
||||
for (JsonNode jsonNode : arrayNode) {
|
||||
IpPrefix address;
|
||||
|
||||
String addrStr = jsonNode.asText(null);
|
||||
if (addrStr == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
address = IpPrefix.valueOf(addrStr);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
builder.add(address);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ips to blackhole to the config.
|
||||
*
|
||||
* @param blackholeIps a set of ips to blackhole
|
||||
* @return this {@link SegmentRoutingAppConfig}
|
||||
*/
|
||||
public SegmentRoutingAppConfig setBalckholeIps(Set<IpPrefix> blackholeIps) {
|
||||
if (blackholeIps == null) {
|
||||
object.remove(BLACKHOLE_IPS);
|
||||
} else {
|
||||
ArrayNode arrayNode = mapper.createArrayNode();
|
||||
|
||||
blackholeIps.forEach(ip -> {
|
||||
arrayNode.add(ip.toString());
|
||||
});
|
||||
|
||||
object.set(BLACKHOLE_IPS, arrayNode);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -262,6 +317,7 @@ public class SegmentRoutingAppConfig extends Config<ApplicationId> {
|
||||
.add("suppressHostByPort", suppressHostByPort())
|
||||
.add("suppressHostByProvider", suppressHostByProvider())
|
||||
.add("mplsEcmp", mplsEcmp())
|
||||
.add("blackholeIps", blackholeIPs())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onlab.packet.IpPrefix;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.TestApplicationId;
|
||||
@ -55,6 +56,8 @@ public class SegmentRoutingAppConfigTest {
|
||||
private static final String PROVIDER_1 = "org.onosproject.provider.host";
|
||||
private static final String PROVIDER_2 = "org.onosproject.netcfghost";
|
||||
private static final String PROVIDER_3 = "org.onosproject.anotherprovider";
|
||||
private static final IpPrefix BLACKHOLE_IP = IpPrefix.valueOf("10.0.0.0/8");
|
||||
private static final IpPrefix BLACKHOLE_IP_2 = IpPrefix.valueOf("20.0.0.0/8");
|
||||
|
||||
/**
|
||||
* Initialize test related variables.
|
||||
@ -263,6 +266,34 @@ public class SegmentRoutingAppConfigTest {
|
||||
assertTrue(supprsuppressHostByProvider.contains(PROVIDER_3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BlackHoleIps getter.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testBlackHoleIps() throws Exception {
|
||||
Set<IpPrefix> blackHoleIps = config.blackholeIPs();
|
||||
assertNotNull("BlackHoleIps should not be null", blackHoleIps);
|
||||
assertThat(blackHoleIps.size(), is(1));
|
||||
assertTrue(blackHoleIps.contains(BLACKHOLE_IP));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BlackHoleIps setter.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testSetBlackHoleIps() throws Exception {
|
||||
|
||||
config.setBalckholeIps(ImmutableSet.of(BLACKHOLE_IP_2));
|
||||
|
||||
Set<IpPrefix> blackHoleIps = config.blackholeIPs();
|
||||
assertThat(blackHoleIps.size(), is(1));
|
||||
assertTrue(blackHoleIps.contains(BLACKHOLE_IP_2));
|
||||
}
|
||||
|
||||
private class MockDelegate implements ConfigApplyDelegate {
|
||||
@Override
|
||||
public void onApply(Config config) {
|
||||
|
||||
@ -14,5 +14,8 @@
|
||||
"suppressHostByProvider" : [
|
||||
"org.onosproject.provider.host",
|
||||
"org.onosproject.netcfghost"
|
||||
],
|
||||
"blackholeIps": [
|
||||
"10.0.0.0/8"
|
||||
]
|
||||
}
|
||||
|
||||
@ -284,6 +284,15 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this driver supports installing a clearDeferred action on table 30.
|
||||
*
|
||||
* @return true if required
|
||||
*/
|
||||
protected boolean supportsUnicastBlackHole() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Flow Objectives
|
||||
//////////////////////////////////////
|
||||
@ -1462,6 +1471,15 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline
|
||||
tb.transition(ACL_TABLE);
|
||||
}
|
||||
|
||||
if (fwd.treatment() != null && fwd.treatment().clearedDeferred()) {
|
||||
if (supportsUnicastBlackHole()) {
|
||||
tb.wipeDeferred();
|
||||
} else {
|
||||
log.warn("Clear Deferred is not supported Unicast Routing Table on device {}", deviceId);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
|
||||
.fromApp(fwd.appId())
|
||||
.withPriority(fwd.priority())
|
||||
|
||||
@ -65,7 +65,10 @@ import java.util.List;
|
||||
|
||||
import static org.onlab.packet.MacAddress.NONE;
|
||||
import static org.onosproject.driver.extensions.Ofdpa3MplsType.VPWS;
|
||||
import static org.onosproject.net.flow.criteria.Criterion.Type.*;
|
||||
import static org.onosproject.net.flow.criteria.Criterion.Type.INNER_VLAN_VID;
|
||||
import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
|
||||
import static org.onosproject.net.flow.criteria.Criterion.Type.TUNNEL_ID;
|
||||
import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
|
||||
import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
|
||||
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
@ -99,6 +102,11 @@ public class Ofdpa3Pipeline extends Ofdpa2Pipeline {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnicastBlackHole() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processFilter(FilteringObjective filteringObjective,
|
||||
boolean install,
|
||||
|
||||
@ -50,4 +50,9 @@ public class OvsOfdpa2Pipeline extends CpqdOfdpa2Pipeline {
|
||||
protected boolean supportPuntGroup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnicastBlackHole() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user