9ead05f00886199ca076bbc34896d07b80a31add
[onosfw.git] /
1 /*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.onosproject.openstackswitching;
18
19 import org.onlab.packet.Ethernet;
20 import org.onlab.packet.IPv4;
21 import org.onlab.packet.Ip4Address;
22 import org.onlab.packet.Ip4Prefix;
23 import org.onlab.packet.MacAddress;
24 import org.onlab.packet.TpPort;
25 import org.onosproject.core.ApplicationId;
26 import org.onosproject.net.DeviceId;
27 import org.onosproject.net.Port;
28 import org.onosproject.net.PortNumber;
29 import org.onosproject.net.flow.DefaultTrafficSelector;
30 import org.onosproject.net.flow.DefaultTrafficTreatment;
31 import org.onosproject.net.flow.TrafficSelector;
32 import org.onosproject.net.flow.TrafficTreatment;
33 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
34 import org.onosproject.net.flowobjective.FlowObjectiveService;
35 import org.onosproject.net.flowobjective.ForwardingObjective;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * It populates switching flow rules.
41  *
42  */
43 public class OpenstackSwitchingRulePopulator {
44
45     private static Logger log = LoggerFactory
46             .getLogger(OpenstackSwitchingRulePopulator.class);
47
48     private FlowObjectiveService flowObjectiveService;
49     private ApplicationId appId;
50
51     /**
52      * Creates OpenstackSwitchingRulPopulator.
53      *
54      * @param appId application id
55      * @param flowObjectiveService FlowObjectiveService reference
56      */
57     public OpenstackSwitchingRulePopulator(ApplicationId appId,
58                                            FlowObjectiveService flowObjectiveService) {
59         this.flowObjectiveService = flowObjectiveService;
60         this.appId = appId;
61     }
62
63     /**
64      * Populates flows rules for forwarding packets to and from VMs.
65      *
66      * @param ip v4 IP Address
67      * @param  id device ID
68      * @param port port
69      * @param cidr v4 IP prefix
70      * @return true if it succeeds to populate rules, false otherwise.
71      */
72     public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) {
73
74
75         setFlowRuleForVMsInSameCnode(ip, id, port, cidr);
76
77         return true;
78     }
79
80     /**
81      * Populates the common flows rules for all VMs.
82      *
83      * - Send ARP packets to the controller
84      * - Send DHCP packets to the controller
85      *
86      * @param id Device ID to populates rules to
87      */
88     public void populateDefaultRules(DeviceId id) {
89
90         //setFlowRuleForDHCP(id);
91         setFlowRuleForArp(id);
92
93         log.warn("Default rule has been set");
94     }
95
96     /**
97      * Populates the forwarding rules for VMs with the same VNI but in other Code.
98      *
99      * @param vni VNI for the networks
100      * @param id device ID to populates the flow rules
101      * @param hostIp host IP address of the VM
102      * @param vmIp fixed IP address for the VM
103      * @param vmMac MAC address for the VM
104      * @param tunnelPort tunnel port number for the VM
105      * @param idx device ID for OVS of the other VM
106      * @param hostIpx host IP address of the other VM
107      * @param vmIpx fixed IP address of the other VM
108      * @param vmMacx MAC address for the other VM
109      * @param tunnelPortx x tunnel port number for other VM
110      */
111     public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp,
112                                                     Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort,
113                                                     DeviceId idx, Ip4Address hostIpx,
114                                                     Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) {
115         setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort);
116         setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx);
117     }
118
119     /**
120      * Populates the flow rules for DHCP packets from VMs.
121      *
122      * @param id device ID to set the rules
123      */
124     private void setFlowRuleForDHCP(DeviceId id) {
125         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
126         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
127
128         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
129                 .matchIPProtocol(IPv4.PROTOCOL_UDP)
130                 .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT));
131         tBuilder.setOutput(PortNumber.CONTROLLER);
132
133         ForwardingObjective fo = DefaultForwardingObjective.builder()
134                 .withSelector(sBuilder.build())
135                 .withTreatment(tBuilder.build())
136                 .withPriority(5000)
137                 .withFlag(ForwardingObjective.Flag.VERSATILE)
138                 .fromApp(appId)
139                 .add();
140
141         flowObjectiveService.forward(id, fo);
142     }
143
144     /**
145      * Populates the flow rules for ARP packets from VMs.
146      *
147      * @param id device ID to put rules.
148      */
149     private void setFlowRuleForArp(DeviceId id) {
150         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
151         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
152
153         sBuilder.matchEthType(Ethernet.TYPE_ARP);
154         tBuilder.setOutput(PortNumber.CONTROLLER);
155
156         ForwardingObjective fo = DefaultForwardingObjective.builder()
157                 .withSelector(sBuilder.build())
158                 .withTreatment(tBuilder.build())
159                 .withPriority(5000)
160                 .withFlag(ForwardingObjective.Flag.VERSATILE)
161                 .fromApp(appId)
162                 .add();
163
164         flowObjectiveService.forward(id, fo);
165     }
166
167     /**
168      * Sets the flow rules for traffic between VMs in the same Cnode.
169      *
170      * @param ip4Address VM IP address
171      * @param id device ID to put rules
172      * @param port VM port
173      * @param cidr subnet info of the VMs
174      */
175     private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
176                                               Port port, Ip4Prefix cidr) {
177         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
178         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
179
180         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
181                 .matchIPDst(ip4Address.toIpPrefix())
182                 .matchIPSrc(cidr);
183         tBuilder.setOutput(port.number());
184
185         ForwardingObjective fo = DefaultForwardingObjective.builder()
186                 .withSelector(sBuilder.build())
187                 .withTreatment(tBuilder.build())
188                 .withPriority(5000)
189                 .withFlag(ForwardingObjective.Flag.VERSATILE)
190                 .fromApp(appId)
191                 .add();
192
193         flowObjectiveService.forward(id, fo);
194     }
195
196     /**
197      * Sets the flow rules between traffic from VMs in different Cnode.
198      *
199      * @param vni  VNI
200      * @param id device ID
201      * @param hostIp host IP of the VM
202      * @param vmIp fixed IP of the VM
203      * @param vmMac MAC address of the VM
204      * @param tunnelPort tunnel port to forward traffic to
205      */
206     private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp,
207                                   Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) {
208         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
209         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
210
211         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
212                 .matchIPDst(vmIp.toIpPrefix());
213         tBuilder.setTunnelId(Long.parseLong(vni))
214                 //.setTunnelDst() <- for Nicira ext
215                 //.setEthDst(vmMac)
216                 .setOutput(tunnelPort);
217
218         ForwardingObjective fo = DefaultForwardingObjective.builder()
219                 .withSelector(sBuilder.build())
220                 .withTreatment(tBuilder.build())
221                 .withPriority(5000)
222                 .withFlag(ForwardingObjective.Flag.VERSATILE)
223                 .fromApp(appId)
224                 .add();
225
226         flowObjectiveService.forward(id, fo);
227     }
228 }