use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class SimpleIntManager method configDevice.
protected boolean configDevice(DeviceId deviceId) {
// Returns true if config was successful, false if not and a clean up is
// needed.
final Device device = deviceService.getDevice(deviceId);
if (device == null || !device.is(IntProgrammable.class)) {
return true;
}
if (isNotIntConfigured()) {
log.warn("Missing INT config, aborting programming of INT device {}", deviceId);
return true;
}
final boolean isEdge = !hostService.getConnectedHosts(deviceId).isEmpty();
final IntDeviceRole intDeviceRole = isEdge ? IntDeviceRole.SOURCE_SINK : IntDeviceRole.TRANSIT;
log.info("Started programming of INT device {} with role {}...", deviceId, intDeviceRole);
final IntProgrammable intProg = device.as(IntProgrammable.class);
if (!isIntStarted()) {
// Leave device with no INT configuration.
return true;
}
if (!intProg.init()) {
log.warn("Unable to init INT pipeline on {}", deviceId);
return false;
}
boolean supportSource = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SOURCE);
boolean supportSink = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SINK);
boolean supportPostcard = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.POSTCARD);
if (intDeviceRole != IntDeviceRole.SOURCE_SINK && !supportPostcard) {
// Stop here, no more configuration needed for transit devices unless it support postcard.
return true;
}
if (supportSink || supportPostcard) {
if (!intProg.setupIntConfig(intConfig.get())) {
log.warn("Unable to apply INT report config on {}", deviceId);
return false;
}
}
// Port configuration.
final Set<PortNumber> hostPorts = deviceService.getPorts(deviceId).stream().map(port -> new ConnectPoint(deviceId, port.number())).filter(cp -> !hostService.getConnectedHosts(cp).isEmpty()).map(ConnectPoint::port).collect(Collectors.toSet());
for (PortNumber port : hostPorts) {
if (supportSource) {
log.info("Setting port {}/{} as INT source port...", deviceId, port);
if (!intProg.setSourcePort(port)) {
log.warn("Unable to set INT source port {} on {}", port, deviceId);
return false;
}
}
if (supportSink) {
log.info("Setting port {}/{} as INT sink port...", deviceId, port);
if (!intProg.setSinkPort(port)) {
log.warn("Unable to set INT sink port {} on {}", port, deviceId);
return false;
}
}
}
if (!supportSource && !supportPostcard) {
// it supports postcard mode.
return true;
}
// Apply intents.
// This is a trivial implementation where we simply get the
// corresponding INT objective from an intent and we apply to all
// device which support reporting.
int appliedCount = 0;
for (Versioned<IntIntent> versionedIntent : intentMap.values()) {
IntIntent intent = versionedIntent.value();
IntObjective intObjective = getIntObjective(intent);
if (intent.telemetryMode() == IntIntent.TelemetryMode.INBAND_TELEMETRY && supportSource) {
intProg.addIntObjective(intObjective);
appliedCount++;
} else if (intent.telemetryMode() == IntIntent.TelemetryMode.POSTCARD && supportPostcard) {
intProg.addIntObjective(intObjective);
appliedCount++;
} else {
log.warn("Device {} does not support intent {}.", deviceId, intent);
}
}
log.info("Completed programming of {}, applied {} INT objectives of {} total", deviceId, appliedCount, intentMap.size());
return true;
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class K8sFlowRuleManager method setAnyRoutingRule.
private void setAnyRoutingRule(IpPrefix srcIpPrefix, MacAddress mac, K8sNetwork k8sNetwork) {
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).matchIPSrc(srcIpPrefix).matchIPDst(IpPrefix.valueOf(k8sNetwork.cidr()));
for (K8sNode node : k8sNodeService.completeNodes()) {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder().setTunnelId(Long.valueOf(k8sNetwork.segmentId()));
if (node.hostname().equals(k8sNetwork.name())) {
if (mac != null) {
tBuilder.setEthSrc(mac);
}
tBuilder.transition(STAT_EGRESS_TABLE);
} else {
K8sNode localNode = k8sNodeService.node(k8sNetwork.name());
tBuilder.setOutput(node.intgToTunPortNum());
// install flows into tunnel bridge
PortNumber portNum = tunnelPortNumByNetId(k8sNetwork.networkId(), k8sNetworkService, node);
TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder().extension(buildExtension(deviceService, node.tunBridge(), localNode.dataIp().getIp4Address()), node.tunBridge()).setTunnelId(Long.valueOf(k8sNetwork.segmentId())).setOutput(portNum).build();
FlowRule remoteFlowRule = DefaultFlowRule.builder().forDevice(node.tunBridge()).withSelector(sBuilder.build()).withTreatment(treatmentToRemote).withPriority(PRIORITY_CIDR_RULE).fromApp(appId).makePermanent().forTable(TUN_ENTRY_TABLE).build();
applyRule(remoteFlowRule, true);
}
FlowRule flowRule = DefaultFlowRule.builder().forDevice(node.intgBridge()).withSelector(sBuilder.build()).withTreatment(tBuilder.build()).withPriority(PRIORITY_CIDR_RULE).fromApp(appId).makePermanent().forTable(ROUTING_TABLE).build();
applyRule(flowRule, true);
}
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class K8sSwitchingGatewayHandler method setGatewayRule.
private void setGatewayRule(K8sNetwork k8sNetwork, boolean install) {
for (K8sNode node : k8sNodeService.completeNodes()) {
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).matchIPDst(IpPrefix.valueOf(k8sNetwork.gatewayIp(), HOST_PREFIX));
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
if (node.hostname().equals(k8sNetwork.name())) {
tBuilder.setEthDst(node.intgBridgeMac()).setOutput(node.intgEntryPortNum());
} else {
K8sNode localNode = k8sNodeService.node(k8sNetwork.name());
tBuilder.setOutput(node.intgToTunPortNum());
// install flows into tunnel bridge
PortNumber portNum = tunnelPortNumByNetId(k8sNetwork.networkId(), k8sNetworkService, node);
TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder().extension(buildExtension(deviceService, node.tunBridge(), localNode.dataIp().getIp4Address()), node.tunBridge()).setTunnelId(Long.valueOf(k8sNetwork.segmentId())).setOutput(portNum).build();
k8sFlowRuleService.setRule(appId, node.tunBridge(), sBuilder.build(), treatmentToRemote, PRIORITY_GATEWAY_RULE, TUN_ENTRY_TABLE, install);
}
k8sFlowRuleService.setRule(appId, node.intgBridge(), sBuilder.build(), tBuilder.build(), PRIORITY_GATEWAY_RULE, ROUTING_TABLE, install);
if (node.hostname().equals(k8sNetwork.name())) {
sBuilder = DefaultTrafficSelector.builder().matchInPort(node.intgEntryPortNum()).matchEthType(Ethernet.TYPE_IPV4).matchIPDst(IpPrefix.valueOf(k8sNetwork.gatewayIp(), HOST_PREFIX));
tBuilder = DefaultTrafficTreatment.builder().setOutput(node.intgToLocalPatchPortNum());
k8sFlowRuleService.setRule(appId, node.intgBridge(), sBuilder.build(), tBuilder.build(), PRIORITY_LOCAL_BRIDGE_RULE, ROUTING_TABLE, install);
}
}
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class K8sSwitchingArpHandler method processArpRequest.
private void processArpRequest(PacketContext context, Ethernet ethPacket) {
ARP arpPacket = (ARP) ethPacket.getPayload();
K8sPort srcK8sPort = k8sNetworkService.ports().stream().filter(p -> p.macAddress().equals(ethPacket.getSourceMAC())).findAny().orElse(null);
PortNumber srcPortNum = context.inPacket().receivedFrom().port();
DeviceId srcDeviceId = context.inPacket().receivedFrom().deviceId();
boolean isEntryPort = false;
for (K8sNode node : k8sNodeService.completeNodes()) {
if (srcDeviceId.equals(node.intgBridge()) && srcPortNum.equals(node.intgEntryPortNum())) {
isEntryPort = true;
}
}
// integration bridge entry port, we simply ignore the ARP request...
if (srcK8sPort == null && !isEntryPort) {
log.warn("Failed to find source port(MAC:{})", ethPacket.getSourceMAC());
return;
}
IpAddress targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
// look up the MAC address from regular k8s ports
MacAddress replyMac = k8sNetworkService.ports().stream().filter(p -> p.ipAddress().equals(targetIp)).map(K8sPort::macAddress).findAny().orElse(null);
// look up the MAC address from special integration entry port (e.g., LOCAL, k8s-int-os)
for (K8sNetwork network : k8sNetworkService.networks()) {
if (network.gatewayIp().equals(targetIp)) {
K8sNode node = k8sNodeService.node(network.name());
replyMac = node.intgEntryPortMac();
}
}
if (replyMac == null) {
String cidr = k8sNetworkService.networks().stream().map(K8sNetwork::cidr).findAny().orElse(null);
if (cidr != null) {
String unshiftedIp = unshiftIpDomain(targetIp.toString(), SHIFTED_IP_PREFIX, cidr);
replyMac = k8sNetworkService.ports().stream().filter(p -> p.ipAddress().equals(IpAddress.valueOf(unshiftedIp))).map(K8sPort::macAddress).findAny().orElse(null);
}
}
if (replyMac == null) {
Set<String> serviceIps = k8sServiceService.services().stream().map(s -> s.getSpec().getClusterIP()).collect(Collectors.toSet());
if (serviceIps.contains(targetIp.toString())) {
replyMac = MacAddress.valueOf(SERVICE_FAKE_MAC_STR);
}
}
if (replyMac == null) {
if (targetIp.toString().startsWith(NODE_IP_PREFIX)) {
String targetIpPrefix = targetIp.toString().split("\\.")[1];
String nodePrefix = NODE_IP_PREFIX + "." + targetIpPrefix;
String origNodeCidr = k8sNodeService.completeNodes().stream().map(n -> n.nodeIp().toString()).findAny().orElse(null);
if (origNodeCidr != null) {
String origNodeIp = unshiftIpDomain(targetIp.toString(), nodePrefix, origNodeCidr);
IpPrefix k8sNodeIpCidr = IpPrefix.valueOf(IpAddress.valueOf(origNodeCidr), 24);
SubnetUtils k8sNodeSubnet = new SubnetUtils(k8sNodeIpCidr.toString());
String k8sNodeGateway = getGatewayIp(k8sNodeIpCidr.toString()).toString();
String seekIp = "";
if (!k8sNodeSubnet.getInfo().isInRange(origNodeIp)) {
replyMac = extHostMacStore.asJavaMap().get(IpAddress.valueOf(k8sNodeGateway));
seekIp = k8sNodeGateway;
} else {
replyMac = extHostMacStore.asJavaMap().get(IpAddress.valueOf(origNodeIp));
seekIp = origNodeIp;
}
// we need to manually learn their MAC addresses
if (replyMac == null) {
ConnectPoint cp = context.inPacket().receivedFrom();
K8sNode k8sNode = k8sNodeService.node(cp.deviceId());
if (k8sNode != null) {
// we use fake IP and MAC address as a source to
// query destination MAC address
setArpRequest(MacAddress.valueOf(NODE_FAKE_MAC_STR).toBytes(), IpAddress.valueOf(NODE_FAKE_IP_STR).toOctets(), IpAddress.valueOf(seekIp).toOctets(), k8sNode);
context.block();
return;
}
}
}
}
}
if (replyMac == null) {
replyMac = MacAddress.valueOf(gatewayMac);
}
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), replyMac, ethPacket);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(context.inPacket().receivedFrom().port()).build();
packetService.emit(new DefaultOutboundPacket(context.inPacket().receivedFrom().deviceId(), treatment, ByteBuffer.wrap(ethReply.serialize())));
context.block();
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class K8sNetworkingUtil method syncPortFromPod.
/**
* Synchronizes port from kubernetes POD.
*
* @param pod kubernetes POD
* @param adminService admin service
*/
public static void syncPortFromPod(Pod pod, K8sNetworkAdminService adminService) {
Map<String, String> annotations = pod.getMetadata().getAnnotations();
if (annotations != null && !annotations.isEmpty() && annotations.get(PORT_ID) != null) {
String portId = annotations.get(PORT_ID);
K8sPort oldPort = adminService.port(portId);
String networkId = annotations.get(NETWORK_ID);
DeviceId deviceId = DeviceId.deviceId(annotations.get(DEVICE_ID));
PortNumber portNumber = PortNumber.portNumber(annotations.get(PORT_NUMBER));
IpAddress ipAddress = IpAddress.valueOf(annotations.get(IP_ADDRESS));
MacAddress macAddress = MacAddress.valueOf(annotations.get(MAC_ADDRESS));
K8sPort newPort = DefaultK8sPort.builder().portId(portId).networkId(networkId).deviceId(deviceId).ipAddress(ipAddress).macAddress(macAddress).portNumber(portNumber).state(INACTIVE).build();
if (oldPort == null) {
adminService.createPort(newPort);
} else {
adminService.updatePort(newPort);
}
}
}
Aggregations