2 * Copyright (c) 2013 Plexxi, Inc. 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
10 package org.opendaylight.affinity.nfchainagent;
12 import java.lang.Short;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
20 import java.util.Map.Entry;
23 import org.opendaylight.controller.sal.utils.NetUtils;
24 import org.opendaylight.controller.sal.utils.Status;
25 import org.opendaylight.controller.sal.utils.StatusCode;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 import org.opendaylight.affinity.affinity.IAffinityManager;
31 import org.opendaylight.controller.hosttracker.IfIptoHost;
32 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
33 import org.opendaylight.controller.sal.core.Host;
34 import org.opendaylight.controller.sal.core.Node;
35 import org.opendaylight.controller.sal.core.NodeConnector;
36 import org.opendaylight.controller.sal.flowprogrammer.Flow;
37 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
38 import org.opendaylight.controller.sal.action.Action;
39 import org.opendaylight.controller.sal.action.Output;
40 import org.opendaylight.controller.sal.match.Match;
41 import org.opendaylight.controller.sal.match.MatchField;
42 import org.opendaylight.controller.sal.match.MatchType;
43 import org.opendaylight.controller.sal.packet.address.EthernetAddress;
45 import org.opendaylight.affinity.l2agent.IfL2Agent;
46 import org.opendaylight.controller.switchmanager.ISwitchManager;
48 import java.io.Serializable;
50 public class NFchainAgent implements Serializable {
52 private static final Logger log = LoggerFactory.getLogger(NFchainAgent.class);
53 private IFlowProgrammerService programmer = null;
54 private IfL2Agent l2agent = null;
55 private IfIptoHost hostTracker = null;
56 private ISwitchManager switchManager = null;
58 private HashMap<String, NFchainconfig> allconfigs;
61 log.debug("INIT called!");
65 log.debug("DESTROY called!");
69 log.debug("START called!");
76 log.debug("STOP called!");
79 void setHostTracker(IfIptoHost h) {
80 log.info("Setting hosttracker {}", h);
84 void unsetHostTracker(IfIptoHost h) {
85 if (this.hostTracker.equals(h)) {
86 this.hostTracker = null;
89 public void setFlowProgrammerService(IFlowProgrammerService s)
94 public void unsetFlowProgrammerService(IFlowProgrammerService s) {
95 if (this.programmer == s) {
96 this.programmer = null;
99 void setL2Agent(IfL2Agent s)
101 log.info("Setting l2agent {}", s);
105 void unsetL2Agent(IfL2Agent s) {
106 if (this.l2agent == s) {
111 void setSwitchManager(ISwitchManager s)
113 this.switchManager = s;
116 void unsetSwitchManager(ISwitchManager s) {
117 if (this.switchManager == s) {
118 this.switchManager = null;
122 public Status addNfchain(String key, NFchainconfig nfcc) {
125 if (allconfigs == null) {
126 allconfigs = new HashMap<String, NFchainconfig>();
128 /* xxx compute changelist and push flow changes. */
129 if (allconfigs.containsKey(key)) {
130 return new Status(StatusCode.CONFLICT,
131 "NFchain with the specified name already configured.");
133 NFchainconfig oldcfg = allconfigs.get(key);
134 if (oldcfg == null) {
135 if (allconfigs.put(key, nfcc) == null) {
136 return new Status(StatusCode.SUCCESS);
139 return new Status(StatusCode.CONFLICT,
140 "Unknown error during addNFchain.");
144 * add flow rules for set of flows in nfchainconfig. Do this for
145 * each node connector in the network proactively.
147 public Status addrules(Node node, NFchainconfig nfcc) throws Exception {
148 List<Flow> flowlist = nfcc.getFlowList();
149 for (Flow f: flowlist) {
150 HostNodeConnector wphost = (HostNodeConnector) hostTracker.hostFind(nfcc.getWaypointIP());
151 List<Action> actions = new ArrayList<Action>();
152 /* Look up the output port leading to the waypoint. */
153 NodeConnector dst_connector = l2agent.lookup_output_port(node, wphost.getDataLayerAddressBytes());
155 log.debug("Waypoint direction added: node {} and connector {}", node, dst_connector);
156 if (dst_connector != null) {
157 f.setActions(actions);
158 f.addAction(new Output(dst_connector));
159 log.debug("flow push add flow = {} to node = {} ", f, node);
160 Status status = programmer.addFlow(node, f);
161 if (!status.isSuccess()) {
162 log.debug("Error during addFlow: {} on {}. The failure is: {}",
163 f, node, status.getDescription());
167 return new Status(StatusCode.SUCCESS);
173 * remove flow rules for set of flows in nfchainconfig. Do this for
174 * each node connector in the network proactively.
176 public Status removerules(Node node, NFchainconfig nfcc) throws Exception {
177 List<Flow> flowlist = nfcc.getFlowList();
178 for (Flow f: flowlist) {
179 HostNodeConnector wphost = (HostNodeConnector) hostTracker.hostFind(nfcc.getWaypointIP());
180 List<Action> actions = new ArrayList<Action>();
181 /* Look up the output port leading to the waypoint. */
182 NodeConnector dst_connector = l2agent.lookup_output_port(node, wphost.getDataLayerAddressBytes());
184 log.debug("Waypoint settings removed: node {} and connector {}", node, dst_connector);
185 if (dst_connector != null) {
186 f.setActions(actions);
187 f.addAction(new Output(dst_connector));
188 log.debug("flow push remove flow = {} to node = {} ", f, node);
189 Status status = programmer.removeFlow(node, f);
190 if (!status.isSuccess()) {
191 log.debug("Error during removeFlow: {} on {}. The failure is: {}",
192 f, node, status.getDescription());
196 return new Status(StatusCode.SUCCESS);
200 public Status removeNfchain(String key) {
201 if (allconfigs != null) {
202 allconfigs.remove(key);
204 return new Status(StatusCode.SUCCESS);
208 * Enable the nfchain by programming flow rules on its behalf.
210 public Status enable(String cfgname) throws Exception {
211 /* Get all node connectors. */
212 Set<Node> nodes = switchManager.getNodes();
213 NFchainconfig cfg = allconfigs.get(cfgname);
215 Status success = new Status(StatusCode.SUCCESS);
216 Status notfound = new Status(StatusCode.NOTFOUND);
220 log.debug("No nodes in network.");
224 /* Send this flow rule to all nodes in the network. */
225 for (Node node: nodes) {
226 ret = addrules(node, cfg);
228 return new Status(StatusCode.SUCCESS);
232 * Remove openflow rules added earlier. Restore default routing via standard L2 learning methods.
234 public Status disable(String cfgname) throws Exception {
235 /* Get all node connectors. */
236 Set<Node> nodes = switchManager.getNodes();
237 NFchainconfig cfg = allconfigs.get(cfgname);
239 Status success = new Status(StatusCode.SUCCESS);
240 Status notfound = new Status(StatusCode.NOTFOUND);
244 log.debug("No nodes in network.");
248 /* Send this flow rule to all nodes in the network. */
249 for (Node node: nodes) {
250 ret = removerules(node, cfg);
252 return new Status(StatusCode.SUCCESS);