CORD-512 Support vSG <-> vRouter default route
- Support multiple subnets per port. getIpPort() will only return the first non-/32 and non-/0 subnet
/32 is used as vSG subnet
/0 is used as default gateway
- Support multiple L3 unicast group on a single port
Change the way to generate the group ID and group key
- Special case for 0.0.0.0 host. Push a /0 to IP table instead of /32
- Implement vRouterConfig
Put VR MAC to TMAC table of all leaves when config added
When processEthDst see PortNumber.ANY in key, match ETH_DST only
- For OFDPA, wipe existing instruction before sending to controller
So packet that misses L3 unicast table won't be sent to controller twice
- For SpringOpenTTP, pop VLAN before sending to controller
- Move several constant definitions to SegmentRoutingService
- Add minimum priority for IP rules such that /0 won't collide with zero priority default rules
- Update the config sample
Use VLAN=-1 for hosts
Add example for default route
Change-Id: Id751697ce36a7e5c13b3859350ff21b585c38525
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 592c0b1..32e03de 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -54,7 +54,8 @@
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
-import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
import org.onosproject.segmentrouting.grouphandler.NeighborSet;
import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
@@ -130,6 +131,12 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry cfgService;
+
protected ArpHandler arpHandler = null;
protected IcmpHandler icmpHandler = null;
protected IpHandler ipHandler = null;
@@ -143,7 +150,9 @@
private InternalPacketProcessor processor = null;
private InternalLinkListener linkListener = null;
private InternalDeviceListener deviceListener = null;
+ private NetworkConfigEventHandler netcfgHandler = null;
private InternalEventHandler eventHandler = new InternalEventHandler();
+ private final InternalHostListener hostListener = new InternalHostListener();
private ScheduledExecutorService executorService = Executors
.newScheduledThreadPool(1);
@@ -181,27 +190,28 @@
private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
private EventuallyConsistentMap<String, Policy> policyStore = null;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected StorageService storageService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry cfgService;
-
private final InternalConfigListener cfgListener =
new InternalConfigListener(this);
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private final ConfigFactory cfgFactory =
- new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY,
- SegmentRoutingConfig.class,
+ private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> cfgDeviceFactory =
+ new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
+ SegmentRoutingDeviceConfig.class,
"segmentrouting") {
@Override
- public SegmentRoutingConfig createConfig() {
- return new SegmentRoutingConfig();
+ public SegmentRoutingDeviceConfig createConfig() {
+ return new SegmentRoutingDeviceConfig();
}
};
- private final InternalHostListener hostListener = new InternalHostListener();
+ private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> cfgAppFactory =
+ new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(SubjectFactories.APP_SUBJECT_FACTORY,
+ SegmentRoutingAppConfig.class,
+ "segmentrouting") {
+ @Override
+ public SegmentRoutingAppConfig createConfig() {
+ return new SegmentRoutingAppConfig();
+ }
+ };
private Object threadSchedulerLock = new Object();
private static int numOfEventsQueued = 0;
@@ -223,7 +233,7 @@
@Activate
protected void activate() {
appId = coreService
- .registerApplication("org.onosproject.segmentrouting");
+ .registerApplication(SR_APP_ID);
kryoBuilder = new KryoNamespace.Builder()
.register(NeighborSetNextObjectiveStoreKey.class,
@@ -309,14 +319,15 @@
.build();
cfgService.addListener(cfgListener);
- cfgService.registerConfigFactory(cfgFactory);
-
- hostService.addListener(hostListener);
+ cfgService.registerConfigFactory(cfgDeviceFactory);
+ cfgService.registerConfigFactory(cfgAppFactory);
processor = new InternalPacketProcessor();
linkListener = new InternalLinkListener();
deviceListener = new InternalDeviceListener();
+ netcfgHandler = new NetworkConfigEventHandler(this);
+ hostService.addListener(hostListener);
packetService.addProcessor(processor, PacketProcessor.director(2));
linkService.addListener(linkListener);
deviceService.addListener(deviceListener);
@@ -334,7 +345,8 @@
@Deactivate
protected void deactivate() {
cfgService.removeListener(cfgListener);
- cfgService.unregisterConfigFactory(cfgFactory);
+ cfgService.unregisterConfigFactory(cfgDeviceFactory);
+ cfgService.unregisterConfigFactory(cfgAppFactory);
// Withdraw ARP packet-in
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
@@ -456,10 +468,17 @@
nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1);
}
for (Ip4Prefix unsub : unassignedSubnets) {
- subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub),
- VlanId.vlanId(nextAssignedVlan--));
- log.info("Assigned vlan: {} to subnet: {} on device: {}",
- nextAssignedVlan + 1, unsub, deviceId);
+ // Special case for default route. Assign default VLAN ID to /32 and /0 subnets
+ if (unsub.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH ||
+ unsub.prefixLength() == 0) {
+ subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub),
+ VlanId.vlanId(ASSIGNED_VLAN_NO_SUBNET));
+ } else {
+ subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub),
+ VlanId.vlanId(nextAssignedVlan--));
+ log.info("Assigned vlan: {} to subnet: {} on device: {}",
+ nextAssignedVlan + 1, unsub, deviceId);
+ }
}
return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet));
@@ -766,6 +785,8 @@
groupHandler.createGroupsForXConnect(device.id());
routingRulePopulator.populateXConnectBroadcastRule(device.id());
}
+
+ netcfgHandler.initVRouters(device.id());
}
private void processPortRemoved(Device device, Port port) {
@@ -851,14 +872,33 @@
@Override
public void event(NetworkConfigEvent event) {
- if (event.configClass().equals(SegmentRoutingConfig.class)) {
- if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) {
- log.info("Network configuration added.");
- configureNetwork();
+ // TODO move this part to NetworkConfigEventHandler
+ if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) {
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ log.info("Segment Routing Config added.");
+ configureNetwork();
+ break;
+ case CONFIG_UPDATED:
+ log.info("Segment Routing Config updated.");
+ // TODO support dynamic configuration
+ break;
+ default:
+ break;
}
- if (event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) {
- log.info("Network configuration updated.");
- // TODO support dynamic configuration
+ } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) {
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ netcfgHandler.processVRouterConfigAdded(event);
+ break;
+ case CONFIG_UPDATED:
+ netcfgHandler.processVRouterConfigUpdated(event);
+ break;
+ case CONFIG_REMOVED:
+ netcfgHandler.processVRouterConfigRemoved(event);
+ break;
+ default:
+ break;
}
}
}