Skip to content

Commit

Permalink
Add INT watchlist config
Browse files Browse the repository at this point in the history
- add "watchSubnets" to the netcfg of INT app

Change-Id: I271d9c27692c8969999ece32f8aa08b4392216e0
(cherry picked from commit 906febe)
  • Loading branch information
Yi Tseng committed Apr 5, 2021
1 parent 2b4de87 commit 83a640a
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.onosproject.inbandtelemetry.api;

import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import org.onosproject.net.behaviour.inbandtelemetry.IntMetadataType;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
Expand Down Expand Up @@ -175,6 +176,27 @@ public static Builder builder() {
return new Builder();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
IntIntent intIntent = (IntIntent) o;
return Objects.equal(selector, intIntent.selector) &&
Objects.equal(metadataTypes, intIntent.metadataTypes) &&
headerType == intIntent.headerType &&
Objects.equal(reportTypes, intIntent.reportTypes) &&
telemetryMode == intIntent.telemetryMode;
}

@Override
public int hashCode() {
return Objects.hashCode(selector, metadataTypes, headerType, reportTypes, telemetryMode);
}

/**
* An IntIntent builder.
*/
Expand Down Expand Up @@ -246,7 +268,6 @@ public IntIntent.Builder withTelemetryMode(TelemetryMode telemetryMode) {
* @return an IntIntent
*/
public IntIntent build() {
checkArgument(!selector.criteria().isEmpty(), "Empty selector cannot match any flow.");
checkNotNull(headerType, "Header type cannot be null.");
checkArgument(!reportTypes.isEmpty(), "Report types cannot be empty.");
checkNotNull(telemetryMode, "Telemetry mode cannot be null.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
Expand Down Expand Up @@ -591,6 +593,32 @@ public void event(NetworkConfigEvent event) {
.enabled(true)
.build();
setConfig(intDeviceConfig);

// For each watched subnet, we install two INT rules.
// One match on the source, another match on the destination.
intentMap.clear();
config.watchSubnets().forEach(subnet -> {
IntIntent.Builder intIntentBuilder = IntIntent.builder()
.withReportType(IntIntent.IntReportType.TRACKED_FLOW)
.withReportType(IntIntent.IntReportType.DROPPED_PACKET)
.withReportType(IntIntent.IntReportType.CONGESTED_QUEUE)
.withTelemetryMode(IntIntent.TelemetryMode.POSTCARD);
if (subnet.prefixLength() == 0) {
// Special case, match any packet
installIntIntent(intIntentBuilder
.withSelector(DefaultTrafficSelector.emptySelector())
.build());
} else {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchIPSrc(subnet)
.build();
installIntIntent(intIntentBuilder.withSelector(selector).build());
selector = DefaultTrafficSelector.builder()
.matchIPDst(subnet)
.build();
installIntIntent(intIntentBuilder.withSelector(selector).build());
}
});
});
break;
// TODO: Support removing INT config.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TpPort;
Expand All @@ -35,6 +36,7 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.inbandtelemetry.api.IntIntent;
import org.onosproject.inbandtelemetry.api.IntIntentId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
Expand All @@ -58,13 +60,15 @@
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.host.HostService;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TestStorageService;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
Expand All @@ -90,12 +94,14 @@ public class SimpleIntManagerTest {
private static final int MIN_FLOW_HOP_LATENCY_CHANGE_NS = 32;
private static final String INT_REPORT_CONFIG_KEY = "report";
private static final DeviceId DEVICE_ID = DeviceId.deviceId("device:leaf1");
private static final String WATCHED_SUBNET_1 = "192.168.10.0/24";
private static final String WATCHED_SUBNET_2 = "192.168.20.0/24";
private static final TrafficSelector FLOW_SELECTOR1 = DefaultTrafficSelector.builder()
.matchIPDst(IpPrefix.valueOf("192.168.10.0/24"))
.matchIPDst(IpPrefix.valueOf(WATCHED_SUBNET_1))
.matchVlanId(VlanId.vlanId((short) 10))
.build();
private static final TrafficSelector FLOW_SELECTOR2 = DefaultTrafficSelector.builder()
.matchIPDst(IpPrefix.valueOf("192.168.20.0/24"))
.matchIPDst(IpPrefix.valueOf(WATCHED_SUBNET_2))
.matchVlanId(VlanId.vlanId((short) 20))
.build();
private static final Device DEFAULT_DEVICE =
Expand Down Expand Up @@ -182,6 +188,49 @@ public void testPushIntAppConfig() throws IOException {
IntDeviceConfig expectedConfig = createIntDeviceConfig();
IntDeviceConfig actualConfig = manager.getConfig();
assertEquals(expectedConfig, actualConfig);

// Install watch subnets via netcfg
// In the report-config.json, there are 3 subnets we want to watch
// For subnet 0.0.0.0/0, the IntManager will create only one IntIntent with an empty selector.
Set<IntIntent> expectedIntIntents = Sets.newHashSet();
ConsistentMap<IntIntentId, IntIntent> intentMap = TestUtils.getField(manager, "intentMap");
IntIntent.Builder baseIntentBuilder = IntIntent.builder()
.withReportType(IntIntent.IntReportType.TRACKED_FLOW)
.withReportType(IntIntent.IntReportType.DROPPED_PACKET)
.withReportType(IntIntent.IntReportType.CONGESTED_QUEUE)
.withTelemetryMode(IntIntent.TelemetryMode.POSTCARD);

// Watch IP Src == subnet 1
TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
.matchIPSrc(IpPrefix.valueOf(WATCHED_SUBNET_1))
.build();
expectedIntIntents.add(baseIntentBuilder.withSelector(expectedSelector).build());
// Watch IP Dst == subnet 1
expectedSelector = DefaultTrafficSelector.builder()
.matchIPDst(IpPrefix.valueOf(WATCHED_SUBNET_1))
.build();
expectedIntIntents.add(baseIntentBuilder.withSelector(expectedSelector).build());
// Watch IP Src == subnet 2
expectedSelector = DefaultTrafficSelector.builder()
.matchIPSrc(IpPrefix.valueOf(WATCHED_SUBNET_2))
.build();
expectedIntIntents.add(baseIntentBuilder.withSelector(expectedSelector).build());
// Watch IP Dst == subnet 2
expectedSelector = DefaultTrafficSelector.builder()
.matchIPDst(IpPrefix.valueOf(WATCHED_SUBNET_2))
.build();
expectedIntIntents.add(baseIntentBuilder.withSelector(expectedSelector).build());
// Any packets
expectedSelector = DefaultTrafficSelector.emptySelector();
expectedIntIntents.add(baseIntentBuilder.withSelector(expectedSelector).build());

// The INT intent installation order can be random, so we need to collect
// all expected INT intents and check if actual intent exists.
assertEquals(5, intentMap.size());
intentMap.entrySet().forEach(entry -> {
IntIntent actualIntIntent = entry.getValue().value();
assertTrue(expectedIntIntents.contains(actualIntIntent));
});
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"collectorIp": "10.0.0.1",
"collectorPort": 32766,
"minFlowHopLatencyChangeNs": 32
"minFlowHopLatencyChangeNs": 32,
"watchSubnets": [
"0.0.0.0/0",
"192.168.10.0/24",
"192.168.20.0/24"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import java.util.HashSet;
import java.util.Set;

import static com.google.common.base.Preconditions.checkArgument;

/**
* Represents a device-level objective to collect INT metadata for packets
* identified by a traffic selector.
Expand Down Expand Up @@ -129,8 +127,6 @@ public IntObjective.Builder withMetadataTypes(Set<IntMetadataType> metadataTypes
* @return an IntObjective
*/
public IntObjective build() {
checkArgument(!selector.criteria().isEmpty(), "Empty selector cannot match any flow.");

return new IntObjective(selector, metadataTypes);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@
*/
package org.onosproject.net.behaviour.inbandtelemetry;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.annotations.Beta;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config;
import org.onosproject.ui.JsonUtils;

import java.util.Collections;
import java.util.Set;

/**
* Application level configuration of the INT process.
* Config example:
Expand All @@ -32,7 +38,11 @@
* "report": {
* "collectorIp": "192.168.0.1",
* "collectorPort": 5500,
* "minFlowHopLatencyChangeNs": 300
* "minFlowHopLatencyChangeNs": 300,
* "watchSubnets": [
* "192.168.0.0/24",
* "10.140.0.0/16"
* ]
* }
* }
* }
Expand All @@ -46,6 +56,7 @@ public final class IntReportConfig extends Config<ApplicationId> {
private static final String COLLECTOR_NEXT_HOP_MAC = "collectorNextHopMac";
private static final String SINK_IP = "sinkIp";
private static final String SINK_MAC = "sinkMac";
private static final String WATCH_SUBNETS = "watchSubnets";

/**
* IP address of the collector.
Expand Down Expand Up @@ -145,6 +156,24 @@ public MacAddress sinkMac() {
}
}

/**
* Gets subnets to be watched.
*
* @return subnets to be watched
*/
public Set<IpPrefix> watchSubnets() {
if (object.hasNonNull(WATCH_SUBNETS) && object.path(WATCH_SUBNETS).isArray()) {
Set<IpPrefix> subnets = Sets.newHashSet();
ArrayNode subnetArray = (ArrayNode) object.path(WATCH_SUBNETS);
subnetArray.forEach(subnetNode -> {
subnets.add(IpPrefix.valueOf(subnetNode.asText()));
});
return subnets;
} else {
return Collections.EMPTY_SET;
}
}

/**
* Sets the collector IP to the config.
*
Expand Down Expand Up @@ -205,4 +234,14 @@ public IntReportConfig setSinkIp(IpAddress sinkIp) {
public IntReportConfig setSinkMac(MacAddress sinkMac) {
return (IntReportConfig) setOrClear(SINK_MAC, sinkMac.toString());
}

/**
* Sets subnets to be watched.
*
* @param subnets subnets to be watched.
* @return the config
*/
public IntReportConfig setWatchSubnets(Set<IpPrefix> subnets) {
return (IntReportConfig) setOrClear(WATCH_SUBNETS, subnets);
}
}

0 comments on commit 83a640a

Please sign in to comment.