Bug-2094 : L3 North-South does not work -- fix inbound rewrite
[ovsdb.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / services / RoutingService.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Authors : Madhu Venugopal, Dave Tucker
9  */
10
11 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
12
13 import java.math.BigInteger;
14 import java.net.InetAddress;
15 import java.util.List;
16
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
20 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
21 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
22 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provider;
23 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
24 import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
25 import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
26 import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
27 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
42 //import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
44
45 import com.google.common.collect.Lists;
46 import org.osgi.framework.BundleContext;
47 import org.osgi.framework.ServiceReference;
48
49 public class RoutingService extends AbstractServiceInstance implements RoutingProvider, ConfigInterface {
50     public RoutingService() {
51         super(Service.ROUTING);
52     }
53
54     public RoutingService(Service service) {
55         super(service);
56     }
57
58     @Override
59     public Status programRouterInterface(Long dpid, String sourceSegId, String destSegId, String macAddress,
60                                          InetAddress address, int mask, Action action) {
61
62         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
63
64         MatchBuilder matchBuilder = new MatchBuilder();
65         NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
66
67         // Instructions List Stores Individual Instructions
68         InstructionsBuilder isb = new InstructionsBuilder();
69         List<Instruction> instructions = Lists.newArrayList();
70         InstructionBuilder ib = new InstructionBuilder();
71         ApplyActionsBuilder aab = new ApplyActionsBuilder();
72         ActionBuilder ab = new ActionBuilder();
73         List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
74
75         if (sourceSegId.equals(Constants.EXTERNAL_NETWORK)) {
76             // If matching on external network, use register reserved for InboundNatService to ensure that
77             // ip rewrite is meant to be consumed by this destination tunnel id.
78             MatchUtils.addNxRegMatch(matchBuilder,
79                     new MatchUtils.RegMatch(InboundNatService.REG_FIELD, Long.valueOf(destSegId)));
80         } else {
81             MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId));
82         }
83
84         final String prefixString = address.getHostAddress() + "/" + mask;
85         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
86
87         // Set source Mac address
88         ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
89         ab.setOrder(0);
90         ab.setKey(new ActionKey(0));
91         actionList.add(ab.build());
92
93         // DecTTL
94         ab.setAction(ActionUtils.decNwTtlAction());
95         ab.setOrder(1);
96         ab.setKey(new ActionKey(1));
97         actionList.add(ab.build());
98
99         // Set Destination Tunnel ID
100         ab.setAction(ActionUtils.setTunnelIdAction(new BigInteger(destSegId)));
101         ab.setOrder(2);
102         ab.setKey(new ActionKey(2));
103         actionList.add(ab.build());
104
105         // Create Apply Actions Instruction
106         aab.setAction(actionList);
107         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
108         ib.setOrder(0);
109         ib.setKey(new InstructionKey(0));
110         instructions.add(ib.build());
111
112         // Goto Next Table
113         ib = getMutablePipelineInstructionBuilder();
114         ib.setOrder(2);
115         ib.setKey(new InstructionKey(2));
116         instructions.add(ib.build());
117
118         FlowBuilder flowBuilder = new FlowBuilder();
119         flowBuilder.setMatch(matchBuilder.build());
120         flowBuilder.setInstructions(isb.setInstruction(instructions).build());
121
122         String flowId = "Routing_" + sourceSegId + "_" + destSegId + "_" + prefixString;
123         flowBuilder.setId(new FlowId(flowId));
124         FlowKey key = new FlowKey(new FlowId(flowId));
125         flowBuilder.setBarrier(true);
126         flowBuilder.setTableId(this.getTable());
127         flowBuilder.setKey(key);
128         flowBuilder.setPriority(2048);
129         flowBuilder.setFlowName(flowId);
130         flowBuilder.setHardTimeout(0);
131         flowBuilder.setIdleTimeout(0);
132
133         if (action.equals(Action.ADD)) {
134             writeFlow(flowBuilder, nodeBuilder);
135         } else {
136             removeFlow(flowBuilder, nodeBuilder);
137         }
138
139         // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
140         return new Status(StatusCode.SUCCESS);
141     }
142
143     @Override
144     public Status programDefaultRouteEntry(Long dpid, String segmentationId, String macAddress,
145                                            InetAddress nextHop, Action action) {
146
147         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
148
149         MatchBuilder matchBuilder = new MatchBuilder();
150         NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
151
152         MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
153
154         // Instructions List Stores Individual Instructions
155         InstructionsBuilder isb = new InstructionsBuilder();
156         List<Instruction> instructions = Lists.newArrayList();
157         InstructionBuilder ib = new InstructionBuilder();
158         ApplyActionsBuilder aab = new ApplyActionsBuilder();
159         ActionBuilder ab = new ActionBuilder();
160         List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
161
162
163         // Set source Mac address
164         ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
165         ab.setOrder(0);
166         ab.setKey(new ActionKey(0));
167         actionList.add(ab.build());
168
169         // DecTTL
170         ab.setAction(ActionUtils.decNwTtlAction());
171         ab.setOrder(1);
172         ab.setKey(new ActionKey(1));
173         actionList.add(ab.build());
174
175         // Create Apply Actions Instruction
176         aab.setAction(actionList);
177         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
178         ib.setOrder(0);
179         ib.setKey(new InstructionKey(0));
180         instructions.add(ib.build());
181
182         // Goto Next Table
183         ib = getMutablePipelineInstructionBuilder();
184         ib.setOrder(1);
185         ib.setKey(new InstructionKey(1));
186         instructions.add(ib.build());
187
188         FlowBuilder flowBuilder = new FlowBuilder();
189         flowBuilder.setMatch(matchBuilder.build());
190         flowBuilder.setInstructions(isb.setInstruction(instructions).build());
191
192         String flowId = "DefaultRoute_" + nextHop.getHostAddress();
193         flowBuilder.setId(new FlowId(flowId));
194         FlowKey key = new FlowKey(new FlowId(flowId));
195         flowBuilder.setBarrier(true);
196         flowBuilder.setTableId(this.getTable());
197         flowBuilder.setKey(key);
198         flowBuilder.setPriority(1024);
199         flowBuilder.setFlowName(flowId);
200         flowBuilder.setHardTimeout(0);
201         flowBuilder.setIdleTimeout(0);
202
203         if (action.equals(Action.ADD)) {
204             writeFlow(flowBuilder, nodeBuilder);
205         } else {
206             removeFlow(flowBuilder, nodeBuilder);
207         }
208
209         // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
210         return new Status(StatusCode.SUCCESS);
211     }
212
213     @Override
214     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
215         super.setDependencies(bundleContext.getServiceReference(RoutingProvider.class.getName()), this);
216     }
217
218     @Override
219     public void setDependencies(Object impl) {
220
221     }
222 }