@Override public void removeRule(int id) throws ConfigError { Connection conn = null; PreparedStatement ps = null; try { conn = settings.getConnection(); ps = conn.prepareStatement(DFLOWRULE); ps.setInt(1, id); int affected = -1; if ((affected = ps.executeUpdate()) != 1) { FVLog.log( LogLevel.ALERT, null, "Failed to delete rule with id ", id, " : rows affected ", affected); throw new ConfigError("Unable to remove rule with id " + id); } } catch (SQLException e) { FVLog.log(LogLevel.DEBUG, null, e.getMessage()); throw new ConfigError("Unable to remove rule with id " + id); } finally { close(ps); close(conn); } }
@Override public void close(Connection conn) { settings.returnConnection(conn); try { conn.close(); } catch (SQLException e) { // don't care } }
private void processAlter(String alter) { Connection conn = null; PreparedStatement ps = null; try { conn = settings.getConnection(); ps = conn.prepareStatement(alter); ps.execute(); } catch (SQLException e) { System.err.println("WARN: " + e.getMessage()); } finally { close(ps); close(conn); } }
private void reset() { Connection conn = null; PreparedStatement ps = null; try { conn = settings.getConnection(); ps = conn.prepareStatement(DFLOWMAP); ps.execute(); ps = conn.prepareStatement(RESETFLOWTABLE); ps.execute(); } catch (SQLException e) { System.err.println("Reseting index on flowtable failed : " + e.getMessage()); } finally { close(ps); close(conn); } }
@SuppressWarnings("unchecked") private void insert(HashMap<String, Object> row) throws IOException { Connection conn = null; PreparedStatement ps = null; ResultSet set = null; int sliceid = -1; int ruleid = -1; try { conn = settings.getConnection(); ps = conn.prepareStatement(SFLOWMAP, Statement.RETURN_GENERATED_KEYS); if (row.get(DPID) == null) ps.setNull(1, Types.BIGINT); else ps.setLong(1, FlowSpaceUtil.parseDPID(((String) row.get(DPID)))); if (row.get(PRIO) == null) ps.setNull(2, Types.INTEGER); else ps.setInt(2, ((Double) row.get(PRIO)).intValue()); if (row.get(INPORT) == null) ps.setNull(3, Types.SMALLINT); else ps.setShort(3, ((Double) row.get(INPORT)).shortValue()); if (row.get(VLAN) == null) ps.setNull(4, Types.SMALLINT); else ps.setShort(4, ((Double) row.get(VLAN)).shortValue()); if (row.get(VPCP) == null) ps.setNull(5, Types.SMALLINT); else ps.setShort(5, ((Double) row.get(VPCP)).shortValue()); if (row.get(DLSRC) == null) ps.setNull(6, Types.BIGINT); else ps.setLong(6, FlowSpaceUtil.parseMac(((String) row.get(DLSRC)))); if (row.get(DLDST) == null) ps.setNull(7, Types.BIGINT); else ps.setLong(7, FlowSpaceUtil.parseMac(((String) row.get(DLDST)))); if (row.get(DLTYPE) == null) ps.setNull(8, Types.SMALLINT); else ps.setShort(8, ((Double) row.get(DLTYPE)).shortValue()); if (row.get(NWSRC) == null) ps.setNull(9, Types.INTEGER); else ps.setInt(9, ((Double) row.get(NWSRC)).intValue()); if (row.get(NWDST) == null) ps.setNull(10, Types.INTEGER); else ps.setInt(10, ((Long) row.get(NWDST)).intValue()); if (row.get(NWPROTO) == null) ps.setNull(11, Types.SMALLINT); else ps.setShort(11, ((Double) row.get(NWPROTO)).shortValue()); if (row.get(NWTOS) == null) ps.setNull(12, Types.SMALLINT); else ps.setShort(12, ((Double) row.get(NWTOS)).shortValue()); if (row.get(TPSRC) == null) ps.setNull(13, Types.SMALLINT); else ps.setShort(13, ((Double) row.get(TPSRC)).shortValue()); if (row.get(TPDST) == null) ps.setNull(14, Types.SMALLINT); else ps.setShort(14, ((Double) row.get(TPDST)).shortValue()); if (row.get(FORCED_QUEUE) == null) ps.setInt(15, -1); else ps.setInt(15, ((Double) row.get(FORCED_QUEUE)).intValue()); if (row.get(WILDCARDS) == null) ps.setNull(16, Types.INTEGER); else ps.setInt(16, ((Double) row.get(WILDCARDS)).intValue()); if (ps.executeUpdate() == 0) FVLog.log(LogLevel.WARN, null, "Flow rule insertion failed... siliently."); set = ps.getGeneratedKeys(); set.next(); ruleid = set.getInt(1); for (HashMap<String, Double> item : ((ArrayList<HashMap<String, Double>>) row.get(ACTION))) { for (Entry<String, Double> entry : item.entrySet()) { ps = conn.prepareStatement(SLICEID); ps.setString(1, entry.getKey()); set = ps.executeQuery(); if (set.next()) sliceid = set.getInt("id"); else { sliceid = -1; System.err.println( "Inserting rule with action on unknown slice " + entry.getKey() + "; hope you know what you are doing..."); } ps = conn.prepareStatement(SACTIONS); ps.setInt(1, ruleid); ps.setInt(2, sliceid); ps.setInt(3, ((Double) entry.getValue()).intValue()); if (ps.executeUpdate() == 0) FVLog.log(LogLevel.WARN, null, "Action insertion failed... siliently."); } } if (row.get(QUEUE) == null) return; ps = conn.prepareStatement(SQUEUES); ps.setInt(1, ruleid); for (Double queue_id : (ArrayList<Double>) row.get(QUEUE)) { ps.setInt(2, queue_id.intValue()); if (ps.executeUpdate() == 0) FVLog.log(LogLevel.WARN, null, "Queue insertion failed... siliently."); } } catch (SQLException e) { e.printStackTrace(); } finally { close(set); close(ps); close(conn); } }
@Override public HashMap<String, Object> toJson(HashMap<String, Object> output) { Connection conn = null; PreparedStatement ps = null; PreparedStatement actions = null; PreparedStatement queues = null; ResultSet set = null; ResultSet actionSet = null; ResultSet queueSet = null; HashMap<String, Object> fs = new HashMap<String, Object>(); HashMap<String, Object> action = new HashMap<String, Object>(); LinkedList<Object> list = new LinkedList<Object>(); LinkedList<Object> actionList = new LinkedList<Object>(); LinkedList<Integer> queueList = new LinkedList<Integer>(); try { int wildcards = -1; conn = settings.getConnection(); ps = conn.prepareStatement(GFLOWMAP); set = ps.executeQuery(); // writer.name(FS); // writer.beginArray(); while (set.next()) { // writer.beginObject(); wildcards = set.getInt(WILDCARDS); fs.put(DPID, FlowSpaceUtil.dpidToString(set.getLong(DPID))); fs.put(PRIO, set.getInt(PRIO)); if ((wildcards & FVMatch.OFPFW_IN_PORT) == 0) fs.put(INPORT, set.getInt(INPORT)); if ((wildcards & FVMatch.OFPFW_DL_VLAN) == 0) fs.put(VLAN, set.getShort(VLAN)); if ((wildcards & FVMatch.OFPFW_DL_VLAN_PCP) == 0) fs.put(VPCP, set.getShort(VPCP)); if ((wildcards & FVMatch.OFPFW_DL_SRC) == 0) fs.put(DLSRC, FlowSpaceUtil.macToString(set.getLong(DLSRC))); if ((wildcards & FVMatch.OFPFW_DL_DST) == 0) fs.put(DLDST, FlowSpaceUtil.macToString(set.getLong(DLDST))); if ((wildcards & FVMatch.OFPFW_DL_TYPE) == 0) fs.put(DLTYPE, set.getShort(DLTYPE)); if ((wildcards & FVMatch.OFPFW_NW_SRC_ALL) == 0) fs.put(NWSRC, set.getInt(NWSRC)); if ((wildcards & FVMatch.OFPFW_NW_DST_ALL) == 0) fs.put(NWDST, set.getInt(NWDST)); if ((wildcards & FVMatch.OFPFW_NW_PROTO) == 0) fs.put(NWPROTO, set.getShort(NWPROTO)); if ((wildcards & FVMatch.OFPFW_NW_TOS) == 0) fs.put(NWTOS, set.getShort(NWTOS)); if ((wildcards & FVMatch.OFPFW_TP_DST) == 0) fs.put(TPDST, set.getShort(TPDST)); if ((wildcards & FVMatch.OFPFW_TP_SRC) == 0) fs.put(TPSRC, set.getShort(TPSRC)); fs.put(FORCED_QUEUE, set.getInt(FORCED_QUEUE)); fs.put(WILDCARDS, wildcards); // fs.put(QUEUE, set.getInt(QUEUE)); actions = conn.prepareStatement(GACTIONS); actions.setInt(1, set.getInt("id")); actionSet = actions.executeQuery(); // writer.name(ACTION); // writer.beginArray(); while (actionSet.next()) { action.put(actionSet.getString(Slice.SLICE), actionSet.getInt(ACTION)); actionList.add(action.clone()); action.clear(); } fs.put(ACTION, actionList.clone()); actionList.clear(); queues = conn.prepareStatement(GQUEUES); queues.setInt(1, set.getInt("id")); queueSet = queues.executeQuery(); while (queueSet.next()) { queueList.add(queueSet.getInt(QUEUE)); } fs.put(QUEUE, queueList.clone()); queueList.clear(); list.add(fs.clone()); fs.clear(); } output.put(FS, list); } catch (SQLException e) { FVLog.log(LogLevel.CRIT, null, "Failed to write flowspace config : " + e.getMessage()); } finally { close(set); close(ps); close(actionSet); close(actions); close(queueSet); close(queues); close(conn); } return output; }
@Override public int addRule(FlowEntry fe) throws ConfigError { Connection conn = null; PreparedStatement ps = null; PreparedStatement slice = null; PreparedStatement queues = null; ResultSet set = null; try { conn = settings.getConnection(); int sliceid = -1; int ruleid = -1; int wildcards = -1; wildcards = fe.getRuleMatch().getWildcards(); ps = conn.prepareStatement(SFLOWMAP, Statement.RETURN_GENERATED_KEYS); ps.setLong(1, fe.getDpid()); ps.setInt(2, fe.getPriority()); ps.setShort(3, fe.getRuleMatch().getInputPort()); if ((wildcards & FVMatch.OFPFW_DL_VLAN) != 0) ps.setNull(4, Types.SMALLINT); else ps.setShort(4, fe.getRuleMatch().getDataLayerVirtualLan()); if ((wildcards & FVMatch.OFPFW_DL_VLAN_PCP) != 0) ps.setNull(5, Types.SMALLINT); else ps.setShort(5, fe.getRuleMatch().getDataLayerVirtualLanPriorityCodePoint()); if ((wildcards & FVMatch.OFPFW_DL_SRC) != 0) ps.setNull(6, Types.BIGINT); else ps.setLong(6, FlowSpaceUtil.toLong(fe.getRuleMatch().getDataLayerSource())); if ((wildcards & FVMatch.OFPFW_DL_DST) != 0) ps.setNull(7, Types.BIGINT); else ps.setLong(7, FlowSpaceUtil.toLong(fe.getRuleMatch().getDataLayerDestination())); if ((wildcards & FVMatch.OFPFW_DL_TYPE) != 0) ps.setNull(8, Types.SMALLINT); else ps.setShort(8, fe.getRuleMatch().getDataLayerType()); if ((wildcards & FVMatch.OFPFW_NW_SRC_ALL) != 0) ps.setNull(9, Types.INTEGER); else ps.setInt(9, fe.getRuleMatch().getNetworkSource()); if ((wildcards & FVMatch.OFPFW_NW_DST_ALL) != 0) ps.setNull(10, Types.INTEGER); else ps.setInt(10, fe.getRuleMatch().getNetworkDestination()); if ((wildcards & FVMatch.OFPFW_NW_PROTO) != 0) ps.setNull(11, Types.SMALLINT); else ps.setShort(11, fe.getRuleMatch().getNetworkProtocol()); if ((wildcards & FVMatch.OFPFW_NW_TOS) != 0) ps.setNull(12, Types.SMALLINT); else ps.setShort(12, fe.getRuleMatch().getNetworkTypeOfService()); if ((wildcards & FVMatch.OFPFW_TP_SRC) != 0) ps.setNull(13, Types.SMALLINT); else ps.setShort(13, fe.getRuleMatch().getTransportSource()); if ((wildcards & FVMatch.OFPFW_TP_DST) != 0) ps.setNull(14, Types.SMALLINT); else ps.setShort(14, fe.getRuleMatch().getTransportDestination()); ps.setInt(15, (int) fe.getForcedQueue()); ps.setInt(16, wildcards); ps.executeUpdate(); set = ps.getGeneratedKeys(); set.next(); ruleid = set.getInt(1); slice = conn.prepareStatement(GSLICEID); ps = conn.prepareStatement(SACTIONS); for (OFAction act : fe.getActionsList()) { slice.setString(1, ((SliceAction) act).getSliceName()); set = slice.executeQuery(); if (set.next()) sliceid = set.getInt("id"); else { FVLog.log( LogLevel.WARN, null, "Slice name " + ((SliceAction) act).getSliceName() + " does not exist... skipping."); continue; } ps.setInt(1, ruleid); ps.setInt(2, sliceid); ps.setInt(3, ((SliceAction) act).getSlicePerms()); // ps.setInt(4, fe.getQueueId()); ps.executeUpdate(); } queues = conn.prepareStatement(SQUEUES); queues.setInt(1, ruleid); for (Integer queue_id : fe.getQueueId()) { queues.setInt(2, queue_id); queues.executeUpdate(); } return ruleid; } catch (SQLException e) { FVLog.log(LogLevel.DEBUG, null, e.getMessage()); throw new ConfigError("Unable to set the flowmap in db"); } finally { close(set); close(ps); close(slice); close(queues); close(conn); } }
/* * In theory, we could return a different flowmap per slice. * Currently the assumption is that either each slice maintains * the flowmap relevant to itself or has a reference to the * entire flowspace. * * If we want to support different flowmaps per slice we simply * need to pass the slice name to this method and adapt the * sql accordingly. * */ @Override public FlowMap getFlowMap() throws ConfigError { if (cachedFlowMap != null) return cachedFlowMap; Connection conn = null; PreparedStatement ps = null; PreparedStatement actions = null; PreparedStatement queues = null; ResultSet set = null; ResultSet actionSet = null; ResultSet queueSet = null; try { conn = settings.getConnection(); ps = conn.prepareStatement(GFLOWMAP); set = ps.executeQuery(); FlowMap map = null; LinkedList<OFAction> actionsList = null; LinkedList<Integer> queueList = null; FlowEntry fe = null; SliceAction act = null; int wildcards = -1; int fsr_id = -1; while (set.next()) { if (map == null) map = FlowSpaceUtil.getNewFlowMap(set.getInt(Slice.FMTYPE)); FVMatch match = new FVMatch(); actionsList = new LinkedList<OFAction>(); queueList = new LinkedList<Integer>(); wildcards = set.getInt(WILDCARDS); fsr_id = set.getInt("id"); match.setInputPort(set.getShort(INPORT)); if ((wildcards & FVMatch.OFPFW_DL_VLAN) == 0) match.setDataLayerVirtualLan(set.getShort(VLAN)); if ((wildcards & FVMatch.OFPFW_DL_VLAN_PCP) == 0) match.setDataLayerVirtualLanPriorityCodePoint(set.getByte(VPCP)); if ((wildcards & FVMatch.OFPFW_DL_SRC) == 0) match.setDataLayerSource(set.getLong(DLSRC)); if ((wildcards & FVMatch.OFPFW_DL_DST) == 0) match.setDataLayerDestination(set.getLong(DLDST)); if ((wildcards & FVMatch.OFPFW_DL_TYPE) == 0) match.setDataLayerType(set.getShort(DLTYPE)); if ((wildcards & FVMatch.OFPFW_NW_SRC_ALL) == 0) match.setNetworkSource(set.getInt(NWSRC)); if ((wildcards & FVMatch.OFPFW_NW_DST_ALL) == 0) match.setNetworkDestination(set.getInt(NWDST)); if ((wildcards & FVMatch.OFPFW_NW_PROTO) == 0) match.setNetworkProtocol(set.getByte(NWPROTO)); if ((wildcards & FVMatch.OFPFW_NW_TOS) == 0) match.setNetworkTypeOfService(set.getByte(NWTOS)); if ((wildcards & FVMatch.OFPFW_TP_SRC) == 0) match.setTransportSource(set.getShort(TPSRC)); if ((wildcards & FVMatch.OFPFW_TP_DST) == 0) match.setTransportDestination(set.getShort(TPDST)); match.setWildcards(wildcards); actions = conn.prepareStatement(GACTIONS); actions.setInt(1, fsr_id); actionSet = actions.executeQuery(); while (actionSet.next()) { act = new SliceAction(actionSet.getString(Slice.SLICE), actionSet.getInt(ACTION)); actionsList.add(act); } queues = conn.prepareStatement(GQUEUES); queues.setInt(1, fsr_id); queueSet = queues.executeQuery(); while (queueSet.next()) { queueList.add(queueSet.getInt(QUEUE)); } fe = new FlowEntry( set.getLong(DPID), match, set.getInt("id"), set.getInt(PRIO), actionsList); fe.setQueueId(queueList); fe.setForcedQueue(set.getInt(FORCED_QUEUE)); map.addRule(fe); } if (map == null) map = new FederatedFlowMap(); cachedFlowMap = map; return map; } catch (SQLException e) { throw new ConfigError("Unable to retrieve flowmap from db : " + e.getMessage()); } finally { close(set); close(ps); close(actionSet); close(actions); close(queueSet); close(queues); close(conn); } }