2 * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
11 import java.math.BigInteger;
12 import java.net.Inet6Address;
13 import java.net.InetAddress;
14 import java.util.List;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
19 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
20 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
21 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provider;
22 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
23 import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
24 import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
25 import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
26 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
41 //import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
44 import com.google.common.collect.Lists;
45 import org.osgi.framework.BundleContext;
46 import org.osgi.framework.ServiceReference;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class RoutingService extends AbstractServiceInstance implements RoutingProvider, ConfigInterface {
51 private static final Logger LOG = LoggerFactory.getLogger(RoutingService.class);
52 public RoutingService() {
53 super(Service.ROUTING);
56 public RoutingService(Service service) {
61 public Status programRouterInterface(Long dpid, String sourceSegId, String destSegId, String macAddress,
62 InetAddress address, int mask, Action action) {
64 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
66 MatchBuilder matchBuilder = new MatchBuilder();
67 NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
69 // Instructions List Stores Individual Instructions
70 InstructionsBuilder isb = new InstructionsBuilder();
71 List<Instruction> instructions = Lists.newArrayList();
72 InstructionBuilder ib = new InstructionBuilder();
73 ApplyActionsBuilder aab = new ApplyActionsBuilder();
74 ActionBuilder ab = new ActionBuilder();
75 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
77 if (sourceSegId.equals(Constants.EXTERNAL_NETWORK)) {
78 // If matching on external network, use register reserved for InboundNatService to ensure that
79 // ip rewrite is meant to be consumed by this destination tunnel id.
80 MatchUtils.addNxRegMatch(matchBuilder,
81 new MatchUtils.RegMatch(InboundNatService.REG_FIELD, Long.valueOf(destSegId)));
83 MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId));
86 if (address instanceof Inet6Address) {
87 // WORKAROUND: For now ipv6 is not supported
88 // TODO: implement ipv6 case
89 LOG.debug("ipv6 address is not implemented yet. address {}",
91 new Status(StatusCode.NOTIMPLEMENTED);
93 final String prefixString = address.getHostAddress() + "/" + mask;
94 MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
96 // Set source Mac address
97 ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
99 ab.setKey(new ActionKey(0));
100 actionList.add(ab.build());
103 ab.setAction(ActionUtils.decNwTtlAction());
105 ab.setKey(new ActionKey(1));
106 actionList.add(ab.build());
108 // Set Destination Tunnel ID
109 ab.setAction(ActionUtils.setTunnelIdAction(new BigInteger(destSegId)));
111 ab.setKey(new ActionKey(2));
112 actionList.add(ab.build());
114 // Create Apply Actions Instruction
115 aab.setAction(actionList);
116 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
118 ib.setKey(new InstructionKey(0));
119 instructions.add(ib.build());
122 ib = getMutablePipelineInstructionBuilder();
124 ib.setKey(new InstructionKey(2));
125 instructions.add(ib.build());
127 FlowBuilder flowBuilder = new FlowBuilder();
128 flowBuilder.setMatch(matchBuilder.build());
129 flowBuilder.setInstructions(isb.setInstruction(instructions).build());
131 String flowId = "Routing_" + sourceSegId + "_" + destSegId + "_" + prefixString;
132 flowBuilder.setId(new FlowId(flowId));
133 FlowKey key = new FlowKey(new FlowId(flowId));
134 flowBuilder.setBarrier(true);
135 flowBuilder.setTableId(this.getTable());
136 flowBuilder.setKey(key);
137 flowBuilder.setPriority(2048);
138 flowBuilder.setFlowName(flowId);
139 flowBuilder.setHardTimeout(0);
140 flowBuilder.setIdleTimeout(0);
142 if (action.equals(Action.ADD)) {
143 writeFlow(flowBuilder, nodeBuilder);
145 removeFlow(flowBuilder, nodeBuilder);
148 // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
149 return new Status(StatusCode.SUCCESS);
153 public Status programDefaultRouteEntry(Long dpid, String segmentationId, String macAddress,
154 InetAddress nextHop, Action action) {
156 String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
158 MatchBuilder matchBuilder = new MatchBuilder();
159 NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
161 MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
163 // Instructions List Stores Individual Instructions
164 InstructionsBuilder isb = new InstructionsBuilder();
165 List<Instruction> instructions = Lists.newArrayList();
166 InstructionBuilder ib = new InstructionBuilder();
167 ApplyActionsBuilder aab = new ApplyActionsBuilder();
168 ActionBuilder ab = new ActionBuilder();
169 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
172 // Set source Mac address
173 ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
175 ab.setKey(new ActionKey(0));
176 actionList.add(ab.build());
179 ab.setAction(ActionUtils.decNwTtlAction());
181 ab.setKey(new ActionKey(1));
182 actionList.add(ab.build());
184 // Create Apply Actions Instruction
185 aab.setAction(actionList);
186 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
188 ib.setKey(new InstructionKey(0));
189 instructions.add(ib.build());
192 ib = getMutablePipelineInstructionBuilder();
194 ib.setKey(new InstructionKey(1));
195 instructions.add(ib.build());
197 FlowBuilder flowBuilder = new FlowBuilder();
198 flowBuilder.setMatch(matchBuilder.build());
199 flowBuilder.setInstructions(isb.setInstruction(instructions).build());
201 String flowId = "DefaultRoute_" + nextHop.getHostAddress();
202 flowBuilder.setId(new FlowId(flowId));
203 FlowKey key = new FlowKey(new FlowId(flowId));
204 flowBuilder.setBarrier(true);
205 flowBuilder.setTableId(this.getTable());
206 flowBuilder.setKey(key);
207 flowBuilder.setPriority(1024);
208 flowBuilder.setFlowName(flowId);
209 flowBuilder.setHardTimeout(0);
210 flowBuilder.setIdleTimeout(0);
212 if (action.equals(Action.ADD)) {
213 writeFlow(flowBuilder, nodeBuilder);
215 removeFlow(flowBuilder, nodeBuilder);
218 // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
219 return new Status(StatusCode.SUCCESS);
223 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
224 super.setDependencies(bundleContext.getServiceReference(RoutingProvider.class.getName()), this);
228 public void setDependencies(Object impl) {