/** * Copyright (c) <2013> <Radware Ltd.> and others. All rights reserved. * * This program and the accompanying materials are made available under the terms of the Eclipse Public License * v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html * @author Gera Goft * @version 0.1 */ package org.opendaylight.defense4all.core; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import me.prettyprint.cassandra.serializers.ShortSerializer; import me.prettyprint.cassandra.serializers.StringSerializer; import org.opendaylight.defense4all.framework.core.RepoCD; public class TrafficFloor { /* TrafficFloor Repo common columns */ public static final String KEY = "key"; public static final String PNKEY = "pnKey"; public static final String NODE_LABEL = "node_label"; public static final String NODE_ID = "node_id"; public static final String FLOOR_BASE = "floor_base"; public static final String FLOOR_CURRENT_HEIGHT = "floor_current_height"; public static final String FLOW_CONFIG_INFO_KEY_PREFIX = "flow_config_info_key_"; public static final String STATUS = "status"; public final static short FLOOR_INVALID = -1; public final static short FLOOR_STEP = 20; public final static short FLOOR_COMMON_START = 10; public final static short FLOOR_PEACETIME_START = FLOOR_COMMON_START + FLOOR_STEP; public final static short FLOOR_OTHER_ATTACK_START = FLOOR_PEACETIME_START + FLOOR_STEP; public final static short FLOOR_ATTACK_START = FLOOR_OTHER_ATTACK_START + FLOOR_STEP; public final static short FLOOR_ATTACK_END = 32000; /* "common" floor - 10-29; peace-time floor - 30-49 * "other" attack floor - 50-69; tcp/udp/icmp attack1 floor - 70-89; tcp/udp/icmp attack2 floor - 90-109... * * For "other" attacks we allocate a dedicated floor with priority lower than any other attack floor, but higher than * peace time. This is because the way to divert "other" traffic only is to put higher priority flows to send TCP, UDP * ICMP traffic straight and another lower priority flow to divert all (remaining) traffic. Had this floor been higher * than other attack floors, the "straight" flow of this entry would cancel diversion of such a flow in a lower floor.*/ public final static short FLOOR_TCP_PRIORITY = 4; public final static short FLOOR_UDP_PRIORITY = 3; public final static short FLOOR_ICMP_PRIORITY = 2; public final static short FLOOR_OTHER_PRIORITY = 1; protected static ArrayList<RepoCD> trafficFloorRCDs = null; public String key; public String pnKey; public String nodeLabel; public String nodeId; public short floorBase; public short floorCurrentHeight; public Status status; public HashMap<String,Object> flowConfigInfoKeys; public enum Status { ACTIVE, REMOVED } public String generateAndSetKey() { StringBuilder sb = new StringBuilder(); sb.append(nodeLabel); sb.append(":"); sb.append(pnKey); sb.append(":"); sb.append(floorBase); key = sb.toString(); return key; } public static String generateAndSetKey(String node, String pnKey, short floor) { StringBuilder sb = new StringBuilder(); sb.append(node); sb.append(":"); sb.append(pnKey); sb.append(":"); sb.append(floor); return sb.toString(); } public static String generatePeacetimeFloorKey(String node, String pnKey) { StringBuilder sb = new StringBuilder(); sb.append(node); sb.append(":"); sb.append(pnKey); sb.append(":"); sb.append(FLOOR_PEACETIME_START); return sb.toString(); } /* ### Description ### * @param param_name */ public TrafficFloor() { key = null; pnKey = null; nodeLabel = null; nodeId = null; floorBase = FLOOR_INVALID; floorCurrentHeight = floorBase; flowConfigInfoKeys = new HashMap<String,Object>(); status = Status.ACTIVE; } public TrafficFloor(Hashtable<String, Object> row) { this(); key = (String) row.get(KEY); pnKey = (String) row.get(PNKEY); nodeLabel = (String) row.get(NODE_LABEL); nodeId = (String) row.get(NODE_ID); floorBase = (Short) row.get(FLOOR_BASE); floorCurrentHeight= (Short) row.get(FLOOR_CURRENT_HEIGHT); status = Status.valueOf((String) row.get(STATUS)); Iterator<Map.Entry<String,Object>> iter = row.entrySet().iterator(); Map.Entry<String,Object> entry; while(iter.hasNext()) { entry = iter.next(); if(entry.getKey().startsWith(FLOW_CONFIG_INFO_KEY_PREFIX)) flowConfigInfoKeys.put((String) entry.getValue(), null); } } public Hashtable<String, Object> toRow() { /* Change any null value to empty, otherwise Hashtable.put() will throw an exception */ if(key == null) key = ""; if(pnKey == null) pnKey = ""; if(nodeLabel == null ) nodeLabel = ""; if(nodeId == null ) nodeId = ""; Hashtable<String, Object> row = new Hashtable<String, Object>(); row.put(KEY, key); row.put(PNKEY, pnKey); row.put(NODE_LABEL, nodeLabel); row.put(NODE_ID, nodeId); row.put(FLOOR_BASE, floorBase); row.put(FLOOR_CURRENT_HEIGHT, floorCurrentHeight); row.put(STATUS, status.name()); Iterator<Map.Entry<String,Object>> iter = flowConfigInfoKeys.entrySet().iterator(); String flowConfigInfoKey; while(iter.hasNext()) { flowConfigInfoKey = iter.next().getKey(); row.put(FLOW_CONFIG_INFO_KEY_PREFIX + flowConfigInfoKey, flowConfigInfoKey); } return row; } public static List<RepoCD> getRCDs() { if(trafficFloorRCDs == null) { RepoCD rcd; trafficFloorRCDs = new ArrayList<RepoCD>(); rcd = new RepoCD(KEY, StringSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(PNKEY, StringSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(NODE_LABEL, StringSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(NODE_ID, StringSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(FLOOR_BASE, ShortSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(FLOOR_CURRENT_HEIGHT, ShortSerializer.get(), null); trafficFloorRCDs.add(rcd); rcd = new RepoCD(STATUS, StringSerializer.get(), null); trafficFloorRCDs.add(rcd); } return trafficFloorRCDs; } }