f6e98060ee7fea2ac74357ae126893470946c76e
[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         setFlowRuleForArp(id);
91
92         log.warn("Default rule has been set");
93     }
94
95     /**
96      * Populates the forwarding rules for VMs with the same VNI but in other Code.
97      *
98      * @param vni VNI for the networks
99      * @param id device ID to populates the flow rules
100      * @param hostIp host IP address of the VM
101      * @param vmIp fixed IP address for the VM
102      * @param vmMac MAC address for the VM
103      * @param tunnelPort tunnel port number for the VM
104      * @param idx device ID for OVS of the other VM
105      * @param hostIpx host IP address of the other VM
106      * @param vmIpx fixed IP address of the other VM
107      * @param vmMacx MAC address for the other VM
108      * @param tunnelPortx x tunnel port number for other VM
109      */
110     public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp,
111                                                     Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort,
112                                                     DeviceId idx, Ip4Address hostIpx,
113                                                     Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) {
114         setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort);
115         setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx);
116     }
117
118     /**
119      * Populates the flow rules for DHCP packets from VMs.
120      *
121      * @param id device ID to set the rules
122      */
123     private void setFlowRuleForDhcp(DeviceId id) {
124         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
125         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
126
127         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
128                 .matchIPProtocol(IPv4.PROTOCOL_UDP)
129                 .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT));
130         tBuilder.setOutput(PortNumber.CONTROLLER);
131
132         ForwardingObjective fo = DefaultForwardingObjective.builder()
133                 .withSelector(sBuilder.build())
134                 .withTreatment(tBuilder.build())
135                 .withPriority(5000)
136                 .withFlag(ForwardingObjective.Flag.VERSATILE)
137                 .fromApp(appId)
138                 .add();
139
140         flowObjectiveService.forward(id, fo);
141     }
142
143     /**
144      * Populates the flow rules for ARP packets from VMs.
145      *
146      * @param id device ID to put rules.
147      */
148     private void setFlowRuleForArp(DeviceId id) {
149         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
150         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
151
152         sBuilder.matchEthType(Ethernet.TYPE_ARP);
153         tBuilder.setOutput(PortNumber.CONTROLLER);
154
155         ForwardingObjective fo = DefaultForwardingObjective.builder()
156                 .withSelector(sBuilder.build())
157                 .withTreatment(tBuilder.build())
158                 .withPriority(5000)
159                 .withFlag(ForwardingObjective.Flag.VERSATILE)
160                 .fromApp(appId)
161                 .add();
162
163         flowObjectiveService.forward(id, fo);
164     }
165
166     /**
167      * Sets the flow rules for traffic between VMs in the same Cnode.
168      *
169      * @param ip4Address VM IP address
170      * @param id device ID to put rules
171      * @param port VM port
172      * @param cidr subnet info of the VMs
173      */
174     private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
175                                               Port port, Ip4Prefix cidr) {
176         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
177         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
178
179         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
180                 .matchIPDst(ip4Address.toIpPrefix())
181                 .matchIPSrc(cidr);
182         tBuilder.setOutput(port.number());
183
184         ForwardingObjective fo = DefaultForwardingObjective.builder()
185                 .withSelector(sBuilder.build())
186                 .withTreatment(tBuilder.build())
187                 .withPriority(5000)
188                 .withFlag(ForwardingObjective.Flag.VERSATILE)
189                 .fromApp(appId)
190                 .add();
191
192         flowObjectiveService.forward(id, fo);
193     }
194
195     /**
196      * Sets the flow rules between traffic from VMs in different Cnode.
197      *
198      * @param vni  VNI
199      * @param id device ID
200      * @param hostIp host IP of the VM
201      * @param vmIp fixed IP of the VM
202      * @param vmMac MAC address of the VM
203      * @param tunnelPort tunnel port to forward traffic to
204      */
205     private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp,
206                                   Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) {
207         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
208         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
209
210         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
211                 .matchIPDst(vmIp.toIpPrefix());
212         tBuilder.setTunnelId(Long.parseLong(vni))
213                 //.setTunnelDst() <- for Nicira ext
214                 //.setEthDst(vmMac)
215                 .setOutput(tunnelPort);
216
217         ForwardingObjective fo = DefaultForwardingObjective.builder()
218                 .withSelector(sBuilder.build())
219                 .withTreatment(tBuilder.build())
220                 .withPriority(5000)
221                 .withFlag(ForwardingObjective.Flag.VERSATILE)
222                 .fromApp(appId)
223                 .add();
224
225         flowObjectiveService.forward(id, fo);
226     }
227 }