module Nettle.OpenFlow.Statistics (
StatsRequest (..)
, TableQuery (..)
#if OPENFLOW_VERSION==1
, PortQuery (..)
, QueueQuery (..)
#endif
, StatsReply (..)
, MoreToFollowFlag
, FlowStats (..)
, AggregateFlowStats (..)
, TableStats (..)
, PortStats (..)
, nullPortStats
, zeroPortStats
, liftIntoPortStats1
, liftIntoPortStats2
, Description (..)
#if OPENFLOW_VERSION==1
, QueueStats (..)
#endif
) where
import Data.Word
import Nettle.OpenFlow.Port
import Nettle.OpenFlow.Match
import Nettle.OpenFlow.Action
import Nettle.OpenFlow.FlowTable
import Control.Monad (liftM,liftM2)
data StatsRequest
= FlowStatsRequest {
statsRequestMatch :: Match,
statsRequestTableID :: TableQuery,
statsRequestPort :: Maybe PseudoPort
}
| AggregateFlowStatsRequest {
statsRequestMatch :: Match,
statsRequestTableID :: TableQuery,
statsRequestPort :: Maybe PseudoPort
}
| TableStatsRequest
| DescriptionRequest
#if OPENFLOW_VERSION==151 || OPENFLOW_VERSION==152
| PortStatsRequest
#endif
#if OPENFLOW_VERSION==1
| PortStatsRequest {
portStatsQuery :: PortQuery
}
| QueueStatsRequest { queueStatsPort :: PortQuery, queueStatsQuery:: QueueQuery }
#endif
deriving (Show,Eq)
#if OPENFLOW_VERSION==1
data PortQuery = AllPorts | SinglePort PortID deriving (Show,Eq,Ord)
data QueueQuery = AllQueues | SingleQueue QueueID deriving (Show,Eq,Ord)
#endif
data TableQuery = AllTables
#if OPENFLOW_VERSION==1
| EmergencyTable
#endif
| Table FlowTableID
deriving (Show,Eq)
data StatsReply
= DescriptionReply Description
| FlowStatsReply MoreToFollowFlag [FlowStats]
| AggregateFlowStatsReply AggregateFlowStats
| TableStatsReply MoreToFollowFlag [TableStats]
| PortStatsReply MoreToFollowFlag [(PortID,PortStats)]
#if OPENFLOW_VERSION==1
| QueueStatsReply MoreToFollowFlag [QueueStats]
#endif
deriving (Show,Eq)
type MoreToFollowFlag = Bool
data Description = Description { manufacturerDesc :: String
, hardwareDesc :: String
, softwareDesc :: String
, serialNumber :: String
#if OPENFLOW_VERSION==1
, datapathDesc :: String
#endif
} deriving (Show,Eq)
data AggregateFlowStats =
AggregateFlowStats { aggregateFlowStatsPacketCount :: Integer,
aggregateFlowStatsByteCount :: Integer,
aggregateFlowStatsFlowCount :: Integer
} deriving (Show, Eq)
data FlowStats = FlowStats {
flowStatsTableID :: FlowTableID,
flowStatsMatch :: Match,
flowStatsActions :: [Action],
flowStatsPriority :: Priority,
#if OPENFLOW_VERSION==1
flowStatsCookie :: Cookie,
#endif
flowStatsDurationSeconds :: Integer,
#if OPENFLOW_VERSION==1
flowStatsDurationNanoseconds :: Integer,
#endif
flowStatsIdleTimeout :: Integer,
flowStatsHardTimeout :: Integer,
flowStatsPacketCount :: Integer,
flowStatsByteCount :: Integer
}
deriving (Show,Eq)
data TableStats =
TableStats {
tableStatsTableID :: FlowTableID,
tableStatsTableName :: String,
tableStatsMaxEntries :: Integer,
tableStatsActiveCount :: Integer,
tableStatsLookupCount :: Integer,
tableStatsMatchedCount :: Integer } deriving (Show,Eq)
data PortStats
= PortStats {
portStatsReceivedPackets :: Maybe Double,
portStatsSentPackets :: Maybe Double,
portStatsReceivedBytes :: Maybe Double,
portStatsSentBytes :: Maybe Double,
portStatsReceiverDropped :: Maybe Double,
portStatsSenderDropped :: Maybe Double,
portStatsReceiveErrors :: Maybe Double,
portStatsTransmitError :: Maybe Double,
portStatsReceivedFrameErrors :: Maybe Double,
portStatsReceiverOverrunError :: Maybe Double,
portStatsReceiverCRCError :: Maybe Double,
portStatsCollisions :: Maybe Double
} deriving (Show,Eq)
nullPortStats :: PortStats
nullPortStats = PortStats {
portStatsReceivedPackets = Nothing,
portStatsSentPackets = Nothing,
portStatsReceivedBytes = Nothing,
portStatsSentBytes = Nothing,
portStatsReceiverDropped = Nothing,
portStatsSenderDropped = Nothing,
portStatsReceiveErrors = Nothing,
portStatsTransmitError = Nothing,
portStatsReceivedFrameErrors = Nothing,
portStatsReceiverOverrunError = Nothing,
portStatsReceiverCRCError = Nothing,
portStatsCollisions = Nothing
}
zeroPortStats :: PortStats
zeroPortStats =
PortStats {
portStatsReceivedPackets = Just 0,
portStatsSentPackets = Just 0,
portStatsReceivedBytes = Just 0,
portStatsSentBytes = Just 0,
portStatsReceiverDropped = Just 0,
portStatsSenderDropped = Just 0,
portStatsReceiveErrors = Just 0,
portStatsTransmitError = Just 0,
portStatsReceivedFrameErrors = Just 0,
portStatsReceiverOverrunError = Just 0,
portStatsReceiverCRCError = Just 0,
portStatsCollisions = Just 0
}
liftIntoPortStats1 :: (Double -> Double) -> PortStats -> PortStats
liftIntoPortStats1 f pr1 =
PortStats { portStatsReceivedPackets = liftM f (portStatsReceivedPackets pr1),
portStatsSentPackets = liftM f (portStatsSentPackets pr1),
portStatsReceivedBytes = liftM f (portStatsReceivedBytes pr1),
portStatsSentBytes = liftM f (portStatsSentBytes pr1),
portStatsReceiverDropped = liftM f (portStatsReceiverDropped pr1),
portStatsSenderDropped = liftM f (portStatsSenderDropped pr1),
portStatsReceiveErrors = liftM f (portStatsReceiveErrors pr1),
portStatsTransmitError = liftM f (portStatsTransmitError pr1),
portStatsReceivedFrameErrors = liftM f (portStatsReceivedFrameErrors pr1),
portStatsReceiverOverrunError = liftM f (portStatsReceiverOverrunError pr1),
portStatsReceiverCRCError = liftM f (portStatsReceiverCRCError pr1),
portStatsCollisions = liftM f (portStatsCollisions pr1)
}
liftIntoPortStats2 :: (Double -> Double -> Double) -> PortStats -> PortStats -> PortStats
liftIntoPortStats2 f pr1 pr2 =
PortStats { portStatsReceivedPackets = liftM2 f (portStatsReceivedPackets pr1) (portStatsReceivedPackets pr2),
portStatsSentPackets = liftM2 f (portStatsSentPackets pr1) (portStatsSentPackets pr2),
portStatsReceivedBytes = liftM2 f (portStatsReceivedBytes pr1) (portStatsReceivedBytes pr2),
portStatsSentBytes = liftM2 f (portStatsSentBytes pr1) (portStatsSentBytes pr2),
portStatsReceiverDropped = liftM2 f (portStatsReceiverDropped pr1) (portStatsReceiverDropped pr2),
portStatsSenderDropped = liftM2 f (portStatsSenderDropped pr1) (portStatsSenderDropped pr2),
portStatsReceiveErrors = liftM2 f (portStatsReceiveErrors pr1) (portStatsReceiveErrors pr2),
portStatsTransmitError = liftM2 f (portStatsTransmitError pr1) (portStatsTransmitError pr2),
portStatsReceivedFrameErrors = liftM2 f (portStatsReceivedFrameErrors pr1) (portStatsReceivedFrameErrors pr2),
portStatsReceiverOverrunError = liftM2 f (portStatsReceiverOverrunError pr1) (portStatsReceiverOverrunError pr2),
portStatsReceiverCRCError = liftM2 f (portStatsReceiverCRCError pr1) (portStatsReceiverCRCError pr2),
portStatsCollisions = liftM2 f (portStatsCollisions pr1) (portStatsCollisions pr2)
}
#if OPENFLOW_VERSION==1
data QueueStats = QueueStats { queueStatsPortID :: PortID,
queueStatsQueueID :: QueueID,
queueStatsTransmittedBytes :: Integer,
queueStatsTransmittedPackets :: Integer,
queueStatsTransmittedErrors :: Integer } deriving (Show,Eq)
#endif