use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method populateArpNdpPunts.
/**
* Creates forwarding objectives to punt ARP and NDP packets, to the controller.
* Furthermore, these are applied only by the master instance. Deferred actions
* are not cleared such that packets can be flooded in the cross connect use case
*
* @param deviceId the switch dpid for the router
*/
void populateArpNdpPunts(DeviceId deviceId) {
// We are not the master just skip.
if (!srManager.shouldProgram(deviceId)) {
log.debug("Not installing ARP/NDP punts - not handling programming for dev:{} ", deviceId);
return;
}
ForwardingObjective fwdObj;
// We punt all ARP packets towards the controller.
fwdObj = arpFwdObjective(null, true, ARP_NDP_PRIORITY).add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install forwarding objective to punt ARP to {}: {}", deviceId, error);
}
});
srManager.flowObjectiveService.forward(deviceId, fwdObj);
if (isIpv6Configured(deviceId)) {
// We punt all NDP packets towards the controller.
ndpFwdObjective(null, true, ARP_NDP_PRIORITY).forEach(builder -> {
ForwardingObjective obj = builder.add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install forwarding objective to punt NDP to {}: {}", deviceId, error);
}
});
srManager.flowObjectiveService.forward(deviceId, obj);
});
}
srManager.getPairLocalPort(deviceId).ifPresent(port -> {
ForwardingObjective pairFwdObj;
// Do not punt ARP packets from pair port
pairFwdObj = arpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1).add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install forwarding objective to ignore ARP to {}: {}", deviceId, error);
}
});
srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
if (isIpv6Configured(deviceId)) {
// Do not punt NDP packets from pair port
ndpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1).forEach(builder -> {
ForwardingObjective obj = builder.add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install forwarding objective to ignore ARP to {}: {}", deviceId, error);
}
});
srManager.flowObjectiveService.forward(deviceId, obj);
});
// Do not forward DAD packets from pair port
pairFwdObj = dad6FwdObjective(port, PacketPriority.CONTROL.priorityValue() + 2).add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install forwarding objective to drop DAD to {}: {}", deviceId, error);
}
});
srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
}
});
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method updateFwdObj.
/**
* Update Forwarding objective for each host and IP address connected to given port.
* And create corresponding Simple Next objective if it does not exist.
* Applied only when populating Forwarding objective
* @param deviceId switch ID to set the rule
* @param portNumber port number
* @param prefix IP prefix of the route
* @param hostMac MAC address of the next hop
* @param vlanId Vlan ID of the port
* @param popVlan true to pop vlan tag in TrafficTreatment
* @param install true to populate the forwarding objective, false to revoke
* @return a completable future that completes when the fwdobj completes. In case of removal,
* the completable future completes when also the nextobj completes.
*/
CompletableFuture<Objective> updateFwdObj(DeviceId deviceId, PortNumber portNumber, IpPrefix prefix, MacAddress hostMac, VlanId vlanId, boolean popVlan, boolean install) {
ForwardingObjective.Builder fob;
TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
MacAddress deviceMac;
try {
deviceMac = config.getDeviceMac(deviceId);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting updateFwdObj.");
return CompletableFuture.completedFuture(null);
}
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
tbuilder.deferred().setEthDst(hostMac).setEthSrc(deviceMac).setOutput(portNumber);
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
if (!popVlan) {
mbuilder.matchVlanId(vlanId);
tbuilder.setVlanId(vlanId);
} else {
mbuilder.matchVlanId(vlanId);
tbuilder.popVlan();
}
// if the objective is to revoke an existing rule, and for some reason
// the next-objective does not exist, then a new one should not be created
int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNumber, tbuilder.build(), mbuilder.build(), install);
CompletableFuture<Objective> future = new CompletableFuture<>();
if (portNextObjId == -1) {
// Warning log will come from getPortNextObjective method
return CompletableFuture.completedFuture(null);
}
fob = DefaultForwardingObjective.builder().withSelector(sbuilder.build()).nextStep(portNextObjId).fromApp(srManager.appId).makePermanent().withPriority(getPriorityFromPrefix(prefix)).withFlag(ForwardingObjective.Flag.SPECIFIC);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
log.debug("IP rule for route {} {}", prefix, install ? "installed" : "revoked");
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to {} IP rule for route {}: {}", install ? "install" : "revoke", prefix, error);
future.complete(null);
});
srManager.flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
if (!install) {
if (!srManager.getVlanPortMap(deviceId).containsKey(vlanId) || !srManager.getVlanPortMap(deviceId).get(vlanId).contains(portNumber)) {
DefaultGroupHandler grpHandler = srManager.getGroupHandler(deviceId);
if (grpHandler == null) {
log.warn("updateFwdObj: groupHandler for device {} not found", deviceId);
} else {
// Before moving forward we have to be sure flow has been removed;
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
log.warn("Exception caught when executing IP rule removal for route {}", prefix);
}
// Flow future has been already consumed (normally or exceptionally)
return grpHandler.removeGroupFromPort(portNumber, tbuilder.build(), mbuilder.build());
}
}
}
return future;
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method updateBridging.
/**
* Populate or revoke a bridging rule on given deviceId that matches given vlanId,
* and hostMAC connected to given port, and output to given port only when
* vlan information is valid.
*
* @param deviceId device ID that host attaches to
* @param portNum port number that host attaches to
* @param hostMac mac address of the host connected to the switch port
* @param vlanId Vlan ID configured on the switch port
* @param popVlan true to pop Vlan tag at TrafficTreatment, false otherwise
* @param install true to populate the objective, false to revoke
* @return a completable future that completes when the update of the bridging rule completes
*/
// TODO Refactor. There are a lot of duplications between this method, populateBridging,
// revokeBridging and bridgingFwdObjBuilder.
CompletableFuture<Objective> updateBridging(DeviceId deviceId, PortNumber portNum, MacAddress hostMac, VlanId vlanId, boolean popVlan, boolean install) {
// Create host selector
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
sbuilder.matchEthDst(hostMac);
// Create host meta
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
sbuilder.matchVlanId(vlanId);
mbuilder.matchVlanId(vlanId);
// Create host treatment
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
tbuilder.immediate().setOutput(portNum);
if (popVlan) {
tbuilder.immediate().popVlan();
}
int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNum, tbuilder.build(), mbuilder.build(), install);
CompletableFuture<Objective> future = new CompletableFuture<>();
if (portNextObjId != -1) {
ForwardingObjective.Builder fob = DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.SPECIFIC).withSelector(sbuilder.build()).nextStep(portNextObjId).withPriority(100).fromApp(srManager.appId).makePermanent();
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
log.debug("Brigding rule for {}/{} {}", hostMac, vlanId, install ? "populated" : "revoked");
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to {} bridging rule for {}/{}: {}", install ? "populate" : "revoke", hostMac, vlanId, error);
future.complete(null);
});
srManager.flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
} else {
log.warn("Failed to retrieve next objective for {}/{}", hostMac, vlanId);
return CompletableFuture.completedFuture(null);
}
return future;
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class HostHandler method processIntfVlanUpdatedEventInternal.
private void processIntfVlanUpdatedEventInternal(Host host, DeviceId deviceId, PortNumber portNum, VlanId vlanId, boolean popVlan, boolean install) {
MacAddress mac = host.mac();
VlanId hostVlanId = host.vlan();
List<CompletableFuture<Objective>> futures = Lists.newArrayList();
if (!install) {
// Do not check the host validity. Just remove all rules corresponding to the vlan id
// Revoke forwarding objective for bridging to the host
futures.add(srManager.defaultRoutingHandler.updateBridging(deviceId, portNum, mac, vlanId, popVlan, false));
// Revoke forwarding objective and corresponding simple Next objective
// for each Host and IP address connected to given port
host.ipAddresses().forEach(ipAddress -> futures.add(srManager.defaultRoutingHandler.updateFwdObj(deviceId, portNum, ipAddress.toIpPrefix(), mac, vlanId, popVlan, false)));
} else {
// Check whether the host vlan is valid for new interface configuration
if ((!popVlan && hostVlanId.equals(vlanId)) || (popVlan && hostVlanId.equals(VlanId.NONE))) {
futures.add(srManager.defaultRoutingHandler.updateBridging(deviceId, portNum, mac, vlanId, popVlan, true));
// Update Forwarding objective and corresponding simple Next objective
// for each Host and IP address connected to given port
host.ipAddresses().forEach(ipAddress -> futures.add(srManager.defaultRoutingHandler.updateFwdObj(deviceId, portNum, ipAddress.toIpPrefix(), mac, vlanId, popVlan, true)));
}
}
// Let's wait for the completion of update procedure
try {
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenApply(objectives -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList())).get();
} catch (InterruptedException | ExecutionException e) {
log.warn("Exception caught when executing processIntfVlanUpdatedEventInternal futures");
futures.forEach(future -> future.cancel(false));
}
}
Aggregations