ebabdaab0a79ead9727fca64d9add3893c8f3c6e
[affinity.git] / nfchainagent / src / main / java / org / opendaylight / affinity / nfchainagent / NFchainAgent.java
1 /*
2  * Copyright (c) 2013 Plexxi, Inc.  All rights reserved.
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
9
10 package org.opendaylight.affinity.nfchainagent;
11
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;
19 import java.util.Map;
20 import java.util.Map.Entry;
21 import java.util.Set;
22
23 import org.opendaylight.controller.sal.utils.NetUtils;
24 import org.opendaylight.controller.sal.utils.Status;
25 import org.opendaylight.controller.sal.utils.StatusCode;
26
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
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;
44
45 import org.opendaylight.affinity.l2agent.IfL2Agent;
46 import org.opendaylight.controller.switchmanager.ISwitchManager;
47
48 import java.io.Serializable;
49
50 public class NFchainAgent implements Serializable {
51
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;
57     
58     private HashMap<String, NFchainconfig> allconfigs;
59
60     void init() {
61         log.debug("INIT called!");
62     }
63
64     void destroy() {
65         log.debug("DESTROY called!");
66     }
67
68     void start() {
69         log.debug("START called!");
70     }
71
72     void started(){
73     }
74
75     void stop() {
76         log.debug("STOP called!");
77     }
78
79     void setHostTracker(IfIptoHost h) {
80         log.info("Setting hosttracker {}", h);
81         this.hostTracker = h;
82     }
83
84     void unsetHostTracker(IfIptoHost h) {
85         if (this.hostTracker.equals(h)) {
86             this.hostTracker = null;
87         }
88     }
89     public void setFlowProgrammerService(IFlowProgrammerService s)
90     {
91         this.programmer = s;
92     }
93
94     public void unsetFlowProgrammerService(IFlowProgrammerService s) {
95         if (this.programmer == s) {
96             this.programmer = null;
97         }
98     }
99     void setL2Agent(IfL2Agent s)
100     {
101         log.info("Setting l2agent {}", s);
102         this.l2agent = s;
103     }
104
105     void unsetL2Agent(IfL2Agent s) {
106         if (this.l2agent == s) {
107             this.l2agent = null;
108         }
109     }
110
111     void setSwitchManager(ISwitchManager s)
112     {
113         this.switchManager = s;
114     }
115
116     void unsetSwitchManager(ISwitchManager s) {
117         if (this.switchManager == s) {
118             this.switchManager = null;
119         }
120     }
121
122     public Status addNfchain(String key, NFchainconfig nfcc) {
123         String name;
124
125         if (allconfigs == null) {
126             allconfigs = new HashMap<String, NFchainconfig>();
127         }
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.");
132         } 
133         NFchainconfig oldcfg = allconfigs.get(key);
134         if (oldcfg == null) {
135             if (allconfigs.put(key, nfcc) == null) {
136                 return new Status(StatusCode.SUCCESS); 
137             } 
138         }
139         return new Status(StatusCode.CONFLICT,
140                           "Unknown error during addNFchain.");
141     }
142
143     /** 
144      * add flow rules for set of flows in nfchainconfig. Do this for
145      * each node connector in the network proactively.
146      */
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());
154
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());
164                 }
165             }
166         }
167         return new Status(StatusCode.SUCCESS); 
168     }
169
170
171
172     /** 
173      * remove flow rules for set of flows in nfchainconfig. Do this for
174      * each node connector in the network proactively.
175      */
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());
183
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());
193                 }
194             }
195         }
196         return new Status(StatusCode.SUCCESS); 
197     }
198
199
200     public Status removeNfchain(String key) {
201         if (allconfigs != null) {
202             allconfigs.remove(key);
203         }
204         return new Status(StatusCode.SUCCESS); 
205     }
206
207     /** 
208      * Enable the nfchain by programming flow rules on its behalf. 
209      */
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);
214
215         Status success = new Status(StatusCode.SUCCESS);
216         Status notfound = new Status(StatusCode.NOTFOUND);
217         Status ret;
218
219         if (nodes == null) {
220             log.debug("No nodes in network.");
221             return success;
222         } 
223
224         /* Send this flow rule to all nodes in the network. */
225         for (Node node: nodes) {
226             ret = addrules(node, cfg);
227         }
228         return new Status(StatusCode.SUCCESS);         
229     }
230
231     /** 
232      * Remove openflow rules added earlier. Restore default routing via standard L2 learning methods. 
233      */
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);
238
239         Status success = new Status(StatusCode.SUCCESS);
240         Status notfound = new Status(StatusCode.NOTFOUND);
241         Status ret;
242
243         if (nodes == null) {
244             log.debug("No nodes in network.");
245             return success;
246         } 
247
248         /* Send this flow rule to all nodes in the network. */
249         for (Node node: nodes) {
250             ret = removerules(node, cfg);
251         }
252         return new Status(StatusCode.SUCCESS);         
253     }
254 }
255