use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method bridgingFwdObjBuilder.
/**
* Generates a forwarding objective builder for bridging rules.
* <p>
* The forwarding objective bridges packets destined to a given MAC to
* given port on given device.
*
* @param deviceId Device that host attaches to
* @param mac MAC address of the host
* @param hostVlanId VLAN ID of the host
* @param outport Port that host attaches to
* @param revoke true if forwarding objective is meant to revoke forwarding rule
* @return Forwarding objective builder
*/
private ForwardingObjective.Builder bridgingFwdObjBuilder(DeviceId deviceId, MacAddress mac, VlanId hostVlanId, PortNumber outport, boolean revoke) {
ConnectPoint connectPoint = new ConnectPoint(deviceId, outport);
VlanId untaggedVlan = srManager.interfaceService.getUntaggedVlanId(connectPoint);
Set<VlanId> taggedVlans = srManager.interfaceService.getTaggedVlanId(connectPoint);
VlanId nativeVlan = srManager.interfaceService.getNativeVlanId(connectPoint);
// Create host selector
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
sbuilder.matchEthDst(mac);
// Create host treatment
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
tbuilder.immediate().setOutput(outport);
// Create host meta
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
// Adjust the selector, treatment and meta according to VLAN configuration
if (taggedVlans.contains(hostVlanId)) {
sbuilder.matchVlanId(hostVlanId);
mbuilder.matchVlanId(hostVlanId);
} else if (hostVlanId.equals(VlanId.NONE)) {
if (untaggedVlan != null) {
sbuilder.matchVlanId(untaggedVlan);
mbuilder.matchVlanId(untaggedVlan);
tbuilder.immediate().popVlan();
} else if (nativeVlan != null) {
sbuilder.matchVlanId(nativeVlan);
mbuilder.matchVlanId(nativeVlan);
tbuilder.immediate().popVlan();
} else {
log.warn("Untagged host {}/{} is not allowed on {} without untagged or native " + "vlan config", mac, hostVlanId, connectPoint);
return null;
}
} else {
log.warn("Tagged host {}/{} is not allowed on {} without VLAN listed in tagged vlan", mac, hostVlanId, connectPoint);
return null;
}
// All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
// 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, outport, tbuilder.build(), mbuilder.build(), !revoke);
if (portNextObjId == -1) {
// Warning log will come from getPortNextObjective method
return null;
}
return DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.SPECIFIC).withSelector(sbuilder.build()).nextStep(portNextObjId).withPriority(100).fromApp(srManager.appId).makePermanent();
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method getTreatmentAndMeta.
private ImmutablePair<TrafficTreatment, TrafficSelector> getTreatmentAndMeta(DeviceId deviceId, MacAddress hostMac, VlanId hostVlanId, PortNumber outPort, VlanId innerVlan, EthType outerTpid) throws DeviceConfigNotFoundException {
MacAddress routerMac;
routerMac = config.getDeviceMac(deviceId);
ConnectPoint connectPoint = new ConnectPoint(deviceId, outPort);
VlanId untaggedVlan = srManager.interfaceService.getUntaggedVlanId(connectPoint);
Set<VlanId> taggedVlans = srManager.interfaceService.getTaggedVlanId(connectPoint);
VlanId nativeVlan = srManager.interfaceService.getNativeVlanId(connectPoint);
// Create route treatment
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder().deferred().setEthDst(hostMac).setEthSrc(routerMac).setOutput(outPort);
// Create route meta
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
// Adjust treatment and meta according to VLAN configuration
if (taggedVlans.contains(hostVlanId)) {
mbuilder.matchVlanId(hostVlanId);
tbuilder.setVlanId(hostVlanId);
} else if (hostVlanId.equals(VlanId.NONE)) {
if (untaggedVlan != null) {
mbuilder.matchVlanId(untaggedVlan);
tbuilder.popVlan();
} else if (nativeVlan != null) {
mbuilder.matchVlanId(nativeVlan);
tbuilder.popVlan();
} else {
log.warn("Untagged nexthop {}/{} is not allowed on {} without untagged or native vlan", hostMac, hostVlanId, connectPoint);
return null;
}
} else {
// Double tagged hosts
if (innerVlan == null || outerTpid == null) {
log.warn("Failed to construct NextObj for double tagged hosts {}/{}. {} {}", hostMac, hostVlanId, (innerVlan == null) ? "innerVlan = null." : "", (outerTpid == null) ? "outerTpid = null." : "");
return null;
}
tbuilder.setVlanId(innerVlan);
tbuilder.pushVlan(outerTpid);
tbuilder.setVlanId(hostVlanId);
mbuilder.matchVlanId(VlanId.ANY);
}
return ImmutablePair.of(tbuilder.build(), mbuilder.build());
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class SegmentRoutingManager method getInternalVlanId.
@Override
public VlanId getInternalVlanId(ConnectPoint connectPoint) {
VlanId untaggedVlanId = interfaceService.getUntaggedVlanId(connectPoint);
VlanId nativeVlanId = interfaceService.getNativeVlanId(connectPoint);
return untaggedVlanId != null ? untaggedVlanId : nativeVlanId;
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class SegmentRoutingManager method modified.
@Modified
private void modified(ComponentContext context) {
Dictionary<?, ?> properties = context.getProperties();
if (properties == null) {
return;
}
String strActiveProbing = Tools.get(properties, PROP_ACTIVE_PROBING);
boolean expectActiveProbing = Boolean.parseBoolean(strActiveProbing);
if (expectActiveProbing != activeProbing) {
activeProbing = expectActiveProbing;
log.info("{} active probing", activeProbing ? "Enabling" : "Disabling");
}
String strSymmetricProbing = Tools.get(properties, PROP_SYMMETRIC_PROBING);
boolean expectSymmetricProbing = Boolean.parseBoolean(strSymmetricProbing);
if (expectSymmetricProbing != symmetricProbing) {
symmetricProbing = expectSymmetricProbing;
log.info("{} symmetric probing", symmetricProbing ? "Enabling" : "Disabling");
}
String strSingleHomedDown = Tools.get(properties, PROP_SINGLE_HOMED_DOWN);
boolean expectSingleHomedDown = Boolean.parseBoolean(strSingleHomedDown);
if (expectSingleHomedDown != singleHomedDown) {
singleHomedDown = expectSingleHomedDown;
log.info("{} downing of single homed hosts for lost uplinks", singleHomedDown ? "Enabling" : "Disabling");
if (singleHomedDown && linkHandler != null) {
hostService.getHosts().forEach(host -> host.locations().forEach(loc -> {
if (interfaceService.isConfigured(loc)) {
linkHandler.checkUplinksForHost(loc);
}
}));
} else {
log.warn("Disabling singleHomedDown does not re-enable already " + "downed ports for single-homed hosts");
}
}
String strRespondToUnknownHosts = Tools.get(properties, PROP_RESPOND_TO_UNKNOWN_HOSTS);
boolean expectRespondToUnknownHosts = Boolean.parseBoolean(strRespondToUnknownHosts);
if (expectRespondToUnknownHosts != respondToUnknownHosts) {
respondToUnknownHosts = expectRespondToUnknownHosts;
log.info("{} responding to ARPs/NDPs from unknown hosts", respondToUnknownHosts ? "Enabling" : "Disabling");
}
String strRouteDoubleTaggedHosts = Tools.get(properties, PROP_ROUTE_DOUBLE_TAGGED_HOSTS);
boolean expectRouteDoubleTaggedHosts = Boolean.parseBoolean(strRouteDoubleTaggedHosts);
if (expectRouteDoubleTaggedHosts != routeDoubleTaggedHosts) {
routeDoubleTaggedHosts = expectRouteDoubleTaggedHosts;
log.info("{} routing for double tagged hosts", routeDoubleTaggedHosts ? "Enabling" : "Disabling");
if (routeDoubleTaggedHosts) {
hostHandler.populateAllDoubleTaggedHost();
} else {
hostHandler.revokeAllDoubleTaggedHost();
}
}
String strDefaultInternalVlan = Tools.get(properties, PROP_DEFAULT_INTERNAL_VLAN);
int defIntVlan = Integer.parseInt(strDefaultInternalVlan);
if (defIntVlan != defaultInternalVlan) {
if (canUseVlanId(defIntVlan)) {
log.warn("Default internal vlan value changed from {} to {}.. " + "re-programming filtering rules, but NOT any groups already " + "created with the former value", defaultInternalVlan, defIntVlan);
VlanId oldDefIntVlan = VlanId.vlanId((short) defaultInternalVlan);
defaultInternalVlan = defIntVlan;
routingRulePopulator.updateSpecialVlanFilteringRules(true, oldDefIntVlan, VlanId.vlanId((short) defIntVlan));
} else {
log.warn("Cannot change default internal vlan to unusable " + "value {}", defIntVlan);
}
}
String strPwTxpVlan = Tools.get(properties, PROP_PW_TRANSPORT_VLAN);
int pwTxpVlan = Integer.parseInt(strPwTxpVlan);
if (pwTxpVlan != pwTransportVlan) {
if (canUseVlanId(pwTxpVlan)) {
log.warn("Pseudowire transport vlan value changed from {} to {}.. " + "re-programming filtering rules, but NOT any groups already " + "created with the former value", pwTransportVlan, pwTxpVlan);
VlanId oldPwTxpVlan = VlanId.vlanId((short) pwTransportVlan);
pwTransportVlan = pwTxpVlan;
routingRulePopulator.updateSpecialVlanFilteringRules(false, oldPwTxpVlan, VlanId.vlanId((short) pwTxpVlan));
} else {
log.warn("Cannot change pseudowire transport vlan to unusable " + "value {}", pwTxpVlan);
}
}
String strRouteSimplification = Tools.get(properties, PROP_ROUTE_SIMPLIFICATION);
boolean expectRouteSimplification = Boolean.parseBoolean(strRouteSimplification);
if (expectRouteSimplification != routeSimplification) {
routeSimplification = expectRouteSimplification;
log.info("{} route simplification", routeSimplification ? "Enabling" : "Disabling");
}
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class SegmentRoutingManager method updateInterface.
private void updateInterface(InterfaceConfig conf, InterfaceConfig prevConf) {
try {
Set<Interface> intfs = conf.getInterfaces();
Set<Interface> prevIntfs = prevConf.getInterfaces();
// Now we only handle one interface config at each port.
if (intfs.size() != 1 || prevIntfs.size() != 1) {
log.warn("Interface update aborted - one at a time is allowed, " + "but {} / {}(prev) received.", intfs.size(), prevIntfs.size());
return;
}
// The system is in an incoherent state, abort
if (defaultRoutingHandler == null) {
log.warn("Interface update aborted, defaultRoutingHandler is null");
return;
}
Interface intf = intfs.stream().findFirst().get();
Interface prevIntf = prevIntfs.stream().findFirst().get();
DeviceId deviceId = intf.connectPoint().deviceId();
PortNumber portNum = intf.connectPoint().port();
if (!shouldProgram(deviceId)) {
log.debug("Not leading the programming of {} skip update interface {}", deviceId, intf);
return;
}
// We need to do nexthop update al least one time for each
// interface config change. There is no difference when it is done;
boolean updateNexthop = false;
removeSubnetConfig(prevIntf.connectPoint(), Sets.difference(new HashSet<>(prevIntf.ipAddressesList()), new HashSet<>(intf.ipAddressesList())));
if (!prevIntf.vlanNative().equals(VlanId.NONE) && !prevIntf.vlanNative().equals(intf.vlanUntagged()) && !prevIntf.vlanNative().equals(intf.vlanNative())) {
if (intf.vlanTagged().contains(prevIntf.vlanNative())) {
// Update filtering objective and L2IG group bucket
updatePortVlanTreatment(deviceId, portNum, prevIntf.vlanNative(), false);
} else {
// RemoveVlanNative - affected scenarios:
// (T,N)->U; (T*,N)->U; (T,N)->(T,N); (T,N)->T
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanNative(), true, false);
// Update the nexthops of the indirect routes
updateNexthop = true;
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
}
if (!prevIntf.vlanUntagged().equals(VlanId.NONE) && !prevIntf.vlanUntagged().equals(intf.vlanUntagged()) && !prevIntf.vlanUntagged().equals(intf.vlanNative())) {
if (intf.vlanTagged().contains(prevIntf.vlanUntagged())) {
// Update filtering objective and L2IG group bucket - affected scenarios:
// U->(T*,N); U->T*
updatePortVlanTreatment(deviceId, portNum, prevIntf.vlanUntagged(), false);
if (!updateNexthop) {
updateNexthop = true;
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
} else {
// RemoveVlanUntagged - affected scenarios:
// U->U; U->(T,N); U->T
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanUntagged(), true, false);
if (!updateNexthop) {
updateNexthop = true;
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
}
}
if (!prevIntf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
// RemoveVlanTagged - affected scenarios:
// T->U; T->T; (T,N*)->U; (T,N)->(T,N)
Sets.difference(prevIntf.vlanTagged(), intf.vlanTagged()).stream().filter(i -> !intf.vlanUntagged().equals(i)).filter(i -> !intf.vlanNative().equals(i)).forEach(vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, false));
}
if (!intf.vlanNative().equals(VlanId.NONE) && !prevIntf.vlanNative().equals(intf.vlanNative()) && !prevIntf.vlanUntagged().equals(intf.vlanNative())) {
if (prevIntf.vlanTagged().contains(intf.vlanNative())) {
// Update filtering objective and L2IG group bucket
updatePortVlanTreatment(deviceId, portNum, intf.vlanNative(), true);
} else {
// AddVlanNative - affected scenarios
// U->(T,N); U->(T*,N); T->(T,N)
updateVlanConfigInternal(deviceId, portNum, intf.vlanNative(), true, true);
if (!updateNexthop) {
updateNexthop = true;
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
}
}
if (!intf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
// AddVlanTagged - affected scenarios
// U->T; U->(T,N*); T->T; (T,N)->(T,N)
Sets.difference(intf.vlanTagged(), prevIntf.vlanTagged()).stream().filter(i -> !prevIntf.vlanUntagged().equals(i)).filter(i -> !prevIntf.vlanNative().equals(i)).forEach(vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, true));
}
if (!intf.vlanUntagged().equals(VlanId.NONE) && !prevIntf.vlanUntagged().equals(intf.vlanUntagged()) && !prevIntf.vlanNative().equals(intf.vlanUntagged())) {
if (prevIntf.vlanTagged().contains(intf.vlanUntagged())) {
// Update filtering objective and L2IG group bucket - affected scenarios
// (T*,N)->U; T*->U
updatePortVlanTreatment(deviceId, portNum, intf.vlanUntagged(), true);
if (!updateNexthop) {
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
} else {
// AddVlanUntagged - affected scenarios
// U->U; (T,N)->U; T->U
updateVlanConfigInternal(deviceId, portNum, intf.vlanUntagged(), true, true);
if (!updateNexthop) {
routeEventExecutor.execute(() -> routeHandler.processIntfVlanUpdatedEvent(deviceId, portNum));
}
}
}
addSubnetConfig(prevIntf.connectPoint(), Sets.difference(new HashSet<>(intf.ipAddressesList()), new HashSet<>(prevIntf.ipAddressesList())));
} catch (ConfigException e) {
log.error("Error in configuration");
}
}
Aggregations