| /* |
| * Copyright 2015 Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.openstackswitching; |
| |
| import org.onlab.packet.Ethernet; |
| import org.onlab.packet.IPv4; |
| import org.onlab.packet.Ip4Address; |
| import org.onlab.packet.Ip4Prefix; |
| import org.onlab.packet.MacAddress; |
| import org.onlab.packet.TpPort; |
| import org.onosproject.core.ApplicationId; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.Port; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.flow.DefaultTrafficSelector; |
| import org.onosproject.net.flow.DefaultTrafficTreatment; |
| import org.onosproject.net.flow.TrafficSelector; |
| import org.onosproject.net.flow.TrafficTreatment; |
| import org.onosproject.net.flowobjective.DefaultForwardingObjective; |
| import org.onosproject.net.flowobjective.FlowObjectiveService; |
| import org.onosproject.net.flowobjective.ForwardingObjective; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * It populates switching flow rules. |
| * |
| */ |
| public class OpenstackSwitchingRulePopulator { |
| |
| private static Logger log = LoggerFactory |
| .getLogger(OpenstackSwitchingRulePopulator.class); |
| |
| private FlowObjectiveService flowObjectiveService; |
| private ApplicationId appId; |
| |
| /** |
| * Creates OpenstackSwitchingRulPopulator. |
| * |
| * @param appId application id |
| * @param flowObjectiveService FlowObjectiveService reference |
| */ |
| public OpenstackSwitchingRulePopulator(ApplicationId appId, |
| FlowObjectiveService flowObjectiveService) { |
| this.flowObjectiveService = flowObjectiveService; |
| this.appId = appId; |
| } |
| |
| /** |
| * Populates flows rules for forwarding packets to and from VMs. |
| * |
| * @param ip v4 IP Address |
| * @param id device ID |
| * @param port port |
| * @param cidr v4 IP prefix |
| * @return true if it succeeds to populate rules, false otherwise. |
| */ |
| public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) { |
| |
| |
| setFlowRuleForVMsInSameCnode(ip, id, port, cidr); |
| |
| return true; |
| } |
| |
| /** |
| * Populates the common flows rules for all VMs. |
| * |
| * - Send ARP packets to the controller |
| * - Send DHCP packets to the controller |
| * |
| * @param id Device ID to populates rules to |
| */ |
| public void populateDefaultRules(DeviceId id) { |
| |
| setFlowRuleForArp(id); |
| |
| log.warn("Default rule has been set"); |
| } |
| |
| /** |
| * Populates the forwarding rules for VMs with the same VNI but in other Code. |
| * |
| * @param vni VNI for the networks |
| * @param id device ID to populates the flow rules |
| * @param hostIp host IP address of the VM |
| * @param vmIp fixed IP address for the VM |
| * @param vmMac MAC address for the VM |
| * @param tunnelPort tunnel port number for the VM |
| * @param idx device ID for OVS of the other VM |
| * @param hostIpx host IP address of the other VM |
| * @param vmIpx fixed IP address of the other VM |
| * @param vmMacx MAC address for the other VM |
| * @param tunnelPortx x tunnel port number for other VM |
| */ |
| public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp, |
| Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort, |
| DeviceId idx, Ip4Address hostIpx, |
| Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) { |
| setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort); |
| setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx); |
| } |
| |
| /** |
| * Populates the flow rules for DHCP packets from VMs. |
| * |
| * @param id device ID to set the rules |
| */ |
| private void setFlowRuleForDhcp(DeviceId id) { |
| TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); |
| TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); |
| |
| sBuilder.matchEthType(Ethernet.TYPE_IPV4) |
| .matchIPProtocol(IPv4.PROTOCOL_UDP) |
| .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT)); |
| tBuilder.setOutput(PortNumber.CONTROLLER); |
| |
| ForwardingObjective fo = DefaultForwardingObjective.builder() |
| .withSelector(sBuilder.build()) |
| .withTreatment(tBuilder.build()) |
| .withPriority(5000) |
| .withFlag(ForwardingObjective.Flag.VERSATILE) |
| .fromApp(appId) |
| .add(); |
| |
| flowObjectiveService.forward(id, fo); |
| } |
| |
| /** |
| * Populates the flow rules for ARP packets from VMs. |
| * |
| * @param id device ID to put rules. |
| */ |
| private void setFlowRuleForArp(DeviceId id) { |
| TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); |
| TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); |
| |
| sBuilder.matchEthType(Ethernet.TYPE_ARP); |
| tBuilder.setOutput(PortNumber.CONTROLLER); |
| |
| ForwardingObjective fo = DefaultForwardingObjective.builder() |
| .withSelector(sBuilder.build()) |
| .withTreatment(tBuilder.build()) |
| .withPriority(5000) |
| .withFlag(ForwardingObjective.Flag.VERSATILE) |
| .fromApp(appId) |
| .add(); |
| |
| flowObjectiveService.forward(id, fo); |
| } |
| |
| /** |
| * Sets the flow rules for traffic between VMs in the same Cnode. |
| * |
| * @param ip4Address VM IP address |
| * @param id device ID to put rules |
| * @param port VM port |
| * @param cidr subnet info of the VMs |
| */ |
| private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id, |
| Port port, Ip4Prefix cidr) { |
| TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); |
| TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); |
| |
| sBuilder.matchEthType(Ethernet.TYPE_IPV4) |
| .matchIPDst(ip4Address.toIpPrefix()) |
| .matchIPSrc(cidr); |
| tBuilder.setOutput(port.number()); |
| |
| ForwardingObjective fo = DefaultForwardingObjective.builder() |
| .withSelector(sBuilder.build()) |
| .withTreatment(tBuilder.build()) |
| .withPriority(5000) |
| .withFlag(ForwardingObjective.Flag.VERSATILE) |
| .fromApp(appId) |
| .add(); |
| |
| flowObjectiveService.forward(id, fo); |
| } |
| |
| /** |
| * Sets the flow rules between traffic from VMs in different Cnode. |
| * |
| * @param vni VNI |
| * @param id device ID |
| * @param hostIp host IP of the VM |
| * @param vmIp fixed IP of the VM |
| * @param vmMac MAC address of the VM |
| * @param tunnelPort tunnel port to forward traffic to |
| */ |
| private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp, |
| Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) { |
| TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); |
| TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); |
| |
| sBuilder.matchEthType(Ethernet.TYPE_IPV4) |
| .matchIPDst(vmIp.toIpPrefix()); |
| tBuilder.setTunnelId(Long.parseLong(vni)) |
| //.setTunnelDst() <- for Nicira ext |
| //.setEthDst(vmMac) |
| .setOutput(tunnelPort); |
| |
| ForwardingObjective fo = DefaultForwardingObjective.builder() |
| .withSelector(sBuilder.build()) |
| .withTreatment(tBuilder.build()) |
| .withPriority(5000) |
| .withFlag(ForwardingObjective.Flag.VERSATILE) |
| .fromApp(appId) |
| .add(); |
| |
| flowObjectiveService.forward(id, fo); |
| } |
| } |