blob: 1db262d2d9fa41c7b0a2155304b4fb088e859828 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* Copyright 2011, Big Switch Networks, Inc.
3* Originally created by David Erickson, Stanford University
4*
5* Licensed under the Apache License, Version 2.0 (the "License"); you may
6* not use this file except in compliance with the License. You may obtain
7* a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14* License for the specific language governing permissions and limitations
15* under the License.
16**/
17
18package net.floodlightcontroller.staticflowentry.web;
19
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080020import java.util.Map;
21
Jonathan Hart2fa28062013-11-25 20:16:28 -080022import net.floodlightcontroller.core.annotations.LogMessageCategory;
23import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
24
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080025import org.restlet.resource.ServerResource;
26import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080029/**
30 * Pushes a static flow entry to the storage source
31 * @author alexreimers
32 *
33 */
34@LogMessageCategory("Static Flow Pusher")
35public class StaticFlowEntryPusherResource extends ServerResource {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070036 protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037
38 /**
39 * Checks to see if the user matches IP information without
40 * checking for the correct ether-type (2048).
41 * @param rows The Map that is a string representation of
42 * the static flow.
43 * @reutrn True if they checked the ether-type, false otherwise
44 */
45 private boolean checkMatchIp(Map<String, Object> rows) {
46 boolean matchEther = false;
47 String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
48 if (val != null) {
49 int type = 0;
50 // check both hex and decimal
51 if (val.startsWith("0x")) {
52 type = Integer.parseInt(val.substring(2), 16);
53 } else {
54 try {
55 type = Integer.parseInt(val);
56 } catch (NumberFormatException e) { /* fail silently */}
57 }
58 if (type == 2048) matchEther = true;
59 }
60
61 if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) ||
62 rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
63 rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
64 rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
65 (matchEther == false))
66 return false;
67
68 return true;
69 }
70
71 /**
72 * Takes a Static Flow Pusher string in JSON format and parses it into
73 * our database schema then pushes it to the database.
74 * @param fmJson The Static Flow Pusher entry in JSON format.
75 * @return A string status message
76 */
Jonathan Hart2fa28062013-11-25 20:16:28 -080077 /*
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080078 @Post
79 @LogMessageDoc(level="ERROR",
80 message="Error parsing push flow mod request: {request}",
81 explanation="An invalid request was sent to static flow pusher",
82 recommendation="Fix the format of the static flow mod request")
83 public String store(String fmJson) {
84 IStorageSourceService storageSource =
85 (IStorageSourceService)getContext().getAttributes().
86 get(IStorageSourceService.class.getCanonicalName());
87
88 Map<String, Object> rowValues;
89 try {
90 rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
91 String status = null;
92 if (!checkMatchIp(rowValues)) {
93 status = "Warning! Pushing a static flow entry that matches IP " +
94 "fields without matching for IP payload (ether-type 2048) will cause " +
95 "the switch to wildcard higher level fields.";
96 log.error(status);
97 } else {
98 status = "Entry pushed";
99 }
100 storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
101 return ("{\"status\" : \"" + status + "\"}");
102 } catch (IOException e) {
103 log.error("Error parsing push flow mod request: " + fmJson, e);
104 e.printStackTrace();
105 return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
106 }
107 }
108
109 @Delete
110 @LogMessageDoc(level="ERROR",
111 message="Error deleting flow mod request: {request}",
112 explanation="An invalid delete request was sent to static flow pusher",
113 recommendation="Fix the format of the static flow mod request")
114 public String del(String fmJson) {
115 IStorageSourceService storageSource =
116 (IStorageSourceService)getContext().getAttributes().
117 get(IStorageSourceService.class.getCanonicalName());
118 String fmName = null;
119 if (fmJson == null) {
120 return "{\"status\" : \"Error! No data posted.\"}";
121 }
122 try {
123 fmName = StaticFlowEntries.getEntryNameFromJson(fmJson);
124 if (fmName == null) {
125 return "{\"status\" : \"Error deleting entry, no name provided\"}";
126 }
127 } catch (IOException e) {
128 log.error("Error deleting flow mod request: " + fmJson, e);
129 e.printStackTrace();
130 return "{\"status\" : \"Error deleting entry, see log for details\"}";
131 }
132
133 storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName);
134 return "{\"status\" : \"Entry " + fmName + " deleted\"}";
135 }
Jonathan Hart2fa28062013-11-25 20:16:28 -0800136 */
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800137}