Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
floodlight
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
croft1
floodlight
Commits
a91b65fb
Commit
a91b65fb
authored
12 years ago
by
Andreas Wundsam
Browse files
Options
Downloads
Patches
Plain Diff
floodlight/Controller: fix whitespace + import
parent
d80c5557
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/main/java/net/floodlightcontroller/core/internal/Controller.java
+231
-228
231 additions, 228 deletions
...va/net/floodlightcontroller/core/internal/Controller.java
with
231 additions
and
228 deletions
src/main/java/net/floodlightcontroller/core/internal/Controller.java
+
231
−
228
View file @
a91b65fb
/**
* Copyright 2011, Big Switch Networks, Inc.
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
...
...
@@ -20,8 +20,8 @@ package net.floodlightcontroller.core.internal;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.net.InetSocketAddress
;
import
java.util.ArrayList
;
import
java.nio.channels.ClosedChannelException
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashMap
;
...
...
@@ -41,12 +41,13 @@ import java.util.concurrent.CopyOnWriteArraySet;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.LinkedBlockingQueue
;
import
java.util.concurrent.RejectedExecutionException
;
import
net.floodlightcontroller.core.FloodlightContext
;
import
net.floodlightcontroller.core.IFloodlightProviderService
;
import
net.floodlightcontroller.core.IHAListener
;
import
net.floodlightcontroller.core.IInfoProvider
;
import
net.floodlightcontroller.core.IOFMessageListener
;
import
net.floodlightcontroller.core.IListener.Command
;
import
net.floodlightcontroller.core.IOFMessageListener
;
import
net.floodlightcontroller.core.IOFSwitch
;
import
net.floodlightcontroller.core.IOFSwitchDriver
;
import
net.floodlightcontroller.core.IOFSwitchFilter
;
...
...
@@ -114,13 +115,10 @@ import org.openflow.protocol.factory.MessageParseException;
import
org.openflow.protocol.statistics.OFDescriptionStatistics
;
import
org.openflow.protocol.statistics.OFStatistics
;
import
org.openflow.protocol.statistics.OFStatisticsType
;
import
org.openflow.protocol.vendor.OFBasicVendorDataType
;
import
org.openflow.protocol.vendor.OFBasicVendorId
;
import
org.openflow.protocol.vendor.OFVendorId
;
import
org.openflow.util.HexString
;
import
org.openflow.vendor.nicira.OFNiciraVendorData
;
import
org.openflow.vendor.nicira.OFNiciraVendorExtensions
;
import
org.openflow.vendor.nicira.OFRoleReplyVendorData
;
import
org.openflow.vendor.nicira.OFRoleRequestVendorData
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -128,22 +126,22 @@ import org.slf4j.LoggerFactory;
/**
* The main controller class. Handles all setup and network listeners
*/
public
class
Controller
implements
IFloodlightProviderService
,
public
class
Controller
implements
IFloodlightProviderService
,
IStorageSourceListener
{
protected
static
Logger
log
=
LoggerFactory
.
getLogger
(
Controller
.
class
);
private
static
final
String
ERROR_DATABASE
=
private
static
final
String
ERROR_DATABASE
=
"The controller could not communicate with the system database."
;
protected
BasicFactory
factory
;
protected
ConcurrentMap
<
OFType
,
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>
messageListeners
;
// OFSwitch driver binding map and order
protected
Map
<
String
,
IOFSwitchDriver
>
switchBindingMap
;
protected
List
<
String
>
switchDescSortedList
;
// The activeSwitches map contains only those switches that are actively
// being controlled by us -- it doesn't contain switches that are
// in the slave role
...
...
@@ -154,16 +152,16 @@ public class Controller implements IFloodlightProviderService,
// We add a switch to this set after it successfully completes the
// handshake. Access to this Set needs to be synchronized with roleChanger
protected
HashSet
<
IOFSwitch
>
connectedSwitches
;
// The controllerNodeIPsCache maps Controller IDs to their IP address.
// The controllerNodeIPsCache maps Controller IDs to their IP address.
// It's only used by handleControllerNodeIPsChanged
protected
HashMap
<
String
,
String
>
controllerNodeIPsCache
;
protected
Set
<
IOFSwitchListener
>
switchListeners
;
protected
Set
<
IHAListener
>
haListeners
;
protected
Map
<
String
,
List
<
IInfoProvider
>>
providerMap
;
protected
BlockingQueue
<
IUpdate
>
updates
;
// Module dependencies
protected
IRestApiService
restApi
;
protected
ICounterStoreService
counterStore
=
null
;
...
...
@@ -171,40 +169,40 @@ public class Controller implements IFloodlightProviderService,
protected
IStorageSourceService
storageSource
;
protected
IPktInProcessingTimeService
pktinProcTime
;
protected
IThreadPoolService
threadPool
;
// Configuration options
protected
int
openFlowPort
=
6633
;
protected
int
workerThreads
=
0
;
// The id for this controller node. Should be unique for each controller
// node in a controller cluster.
protected
String
controllerId
=
"localhost"
;
// The current role of the controller.
// If the controller isn't configured to support roles, then this is null.
protected
Role
role
;
// A helper that handles sending and timeout handling for role requests
protected
RoleChanger
roleChanger
;
// Start time of the controller
protected
long
systemStartTime
;
// Flag to always flush flow table on switch reconnect (HA or otherwise)
protected
boolean
alwaysClearFlowsOnSwAdd
=
false
;
// Storage table names
protected
static
final
String
CONTROLLER_TABLE_NAME
=
"controller_controller"
;
protected
static
final
String
CONTROLLER_ID
=
"id"
;
protected
static
final
String
SWITCH_CONFIG_TABLE_NAME
=
"controller_switchconfig"
;
protected
static
final
String
SWITCH_CONFIG_CORE_SWITCH
=
"core_switch"
;
protected
static
final
String
CONTROLLER_INTERFACE_TABLE_NAME
=
"controller_controllerinterface"
;
protected
static
final
String
CONTROLLER_INTERFACE_ID
=
"id"
;
protected
static
final
String
CONTROLLER_INTERFACE_CONTROLLER_ID
=
"controller_id"
;
protected
static
final
String
CONTROLLER_INTERFACE_TYPE
=
"type"
;
protected
static
final
String
CONTROLLER_INTERFACE_NUMBER
=
"number"
;
protected
static
final
String
CONTROLLER_INTERFACE_DISCOVERED_IP
=
"discovered_ip"
;
// Perf. related configuration
protected
static
final
int
SEND_BUFFER_SIZE
=
4
*
1024
*
1024
;
public
static
final
int
BATCH_MAX_SIZE
=
100
;
...
...
@@ -216,10 +214,10 @@ public class Controller implements IFloodlightProviderService,
protected
final
LoadMonitor
loadmonitor
=
new
LoadMonitor
(
log
);
/**
* Updates handled by the main loop
* Updates handled by the main loop
*/
protected
interface
IUpdate
{
/**
/**
* Calls the appropriate listeners
*/
public
void
dispatch
();
...
...
@@ -230,7 +228,7 @@ public class Controller implements IFloodlightProviderService,
PORTCHANGED
}
/**
* Update message indicating a switch was added or removed
* Update message indicating a switch was added or removed
*/
protected
class
SwitchUpdate
implements
IUpdate
{
public
IOFSwitch
sw
;
...
...
@@ -239,6 +237,7 @@ public class Controller implements IFloodlightProviderService,
this
.
sw
=
sw
;
this
.
switchUpdateType
=
switchUpdateType
;
}
@Override
public
void
dispatch
()
{
if
(
log
.
isTraceEnabled
())
{
log
.
trace
(
"Dispatching switch update {} {}"
,
...
...
@@ -261,7 +260,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
/**
* Update message indicating controller's role has changed
*/
...
...
@@ -272,6 +271,7 @@ public class Controller implements IFloodlightProviderService,
this
.
oldRole
=
oldRole
;
this
.
newRole
=
newRole
;
}
@Override
public
void
dispatch
()
{
// Make sure that old and new roles are different.
if
(
oldRole
==
newRole
)
{
...
...
@@ -293,7 +293,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
/**
* Update message indicating
* IPs of controllers in controller cluster have changed.
...
...
@@ -303,13 +303,14 @@ public class Controller implements IFloodlightProviderService,
public
Map
<
String
,
String
>
addedControllerNodeIPs
;
public
Map
<
String
,
String
>
removedControllerNodeIPs
;
public
HAControllerNodeIPUpdate
(
HashMap
<
String
,
String
>
curControllerNodeIPs
,
HashMap
<
String
,
String
>
addedControllerNodeIPs
,
HashMap
<
String
,
String
>
curControllerNodeIPs
,
HashMap
<
String
,
String
>
addedControllerNodeIPs
,
HashMap
<
String
,
String
>
removedControllerNodeIPs
)
{
this
.
curControllerNodeIPs
=
curControllerNodeIPs
;
this
.
addedControllerNodeIPs
=
addedControllerNodeIPs
;
this
.
removedControllerNodeIPs
=
removedControllerNodeIPs
;
}
@Override
public
void
dispatch
()
{
if
(
log
.
isTraceEnabled
())
{
log
.
trace
(
"Dispatching HA Controller Node IP update "
...
...
@@ -326,31 +327,31 @@ public class Controller implements IFloodlightProviderService,
}
}
}
// ***************
// Getters/Setters
// ***************
public
void
setStorageSourceService
(
IStorageSourceService
storageSource
)
{
this
.
storageSource
=
storageSource
;
}
public
void
setCounterStore
(
ICounterStoreService
counterStore
)
{
this
.
counterStore
=
counterStore
;
}
public
void
setFlowCacheMgr
(
IFlowCacheService
flowCacheMgr
)
{
this
.
bigFlowCacheMgr
=
flowCacheMgr
;
}
public
void
setPktInProcessingService
(
IPktInProcessingTimeService
pits
)
{
this
.
pktinProcTime
=
pits
;
}
public
void
setRestApiService
(
IRestApiService
restApi
)
{
this
.
restApi
=
restApi
;
}
public
void
setThreadPoolService
(
IThreadPoolService
tp
)
{
this
.
threadPool
=
tp
;
}
...
...
@@ -361,14 +362,14 @@ public class Controller implements IFloodlightProviderService,
return
role
;
}
}
@Override
public
void
setRole
(
Role
role
)
{
if
(
role
==
null
)
throw
new
NullPointerException
(
"Role can not be null."
);
// Need to synchronize to ensure a reliable ordering on role request
// messages send and to ensure the list of connected switches is stable
// RoleChanger will handle the actual sending of the message and
// RoleChanger will handle the actual sending of the message and
// timeout handling
// @see RoleChanger
synchronized
(
roleChanger
)
{
...
...
@@ -379,10 +380,10 @@ public class Controller implements IFloodlightProviderService,
Role
oldRole
=
this
.
role
;
this
.
role
=
role
;
log
.
debug
(
"Submitting role change request to role {}"
,
role
);
roleChanger
.
submitRequest
(
connectedSwitches
,
role
);
// Enqueue an update for our listeners.
try
{
this
.
updates
.
put
(
new
HARoleUpdate
(
role
,
oldRole
));
...
...
@@ -391,13 +392,13 @@ public class Controller implements IFloodlightProviderService,
}
}
}
// **********************
// ChannelUpstreamHandler
// **********************
/**
* Return a new channel handler for processing a switch connections
* @param state The channel state object for the connection
...
...
@@ -406,28 +407,28 @@ public class Controller implements IFloodlightProviderService,
protected
ChannelUpstreamHandler
getChannelHandler
(
OFChannelState
state
)
{
return
new
OFChannelHandler
(
state
);
}
/**
* Channel handler deals with the switch connection and dispatches
* switch messages to the appropriate locations.
* @author readams
*/
protected
class
OFChannelHandler
protected
class
OFChannelHandler
extends
IdleStateAwareChannelUpstreamHandler
{
protected
IOFSwitch
sw
;
protected
Channel
channel
;
protected
OFChannelState
state
;
public
OFChannelHandler
(
OFChannelState
state
)
{
this
.
state
=
state
;
}
@Override
@LogMessageDoc
(
message
=
"New switch connection from {ip address}"
,
explanation
=
"A new switch has connected from the "
+
explanation
=
"A new switch has connected from the "
+
"specified IP address"
)
public
void
channelConnected
(
ChannelHandlerContext
ctx
,
ChannelStateEvent
e
)
throws
Exception
{
ChannelStateEvent
e
)
throws
Exception
{
channel
=
e
.
getChannel
();
log
.
info
(
"New switch connection from {}"
,
channel
.
getRemoteAddress
());
...
...
@@ -442,7 +443,7 @@ public class Controller implements IFloodlightProviderService,
if
(
sw
!=
null
&&
state
.
hsState
==
HandshakeState
.
READY
)
{
if
(
activeSwitches
.
containsKey
(
sw
.
getId
()))
{
// It's safe to call removeSwitch even though the map might
// not contain this particular switch but another with the
// not contain this particular switch but another with the
// same DPID
removeSwitch
(
sw
);
}
...
...
@@ -458,13 +459,13 @@ public class Controller implements IFloodlightProviderService,
@LogMessageDocs
({
@LogMessageDoc
(
level
=
"ERROR"
,
message
=
"Disconnecting switch {switch} due to read timeout"
,
explanation
=
"The connected switch has failed to send any "
+
explanation
=
"The connected switch has failed to send any "
+
"messages or respond to echo requests"
,
recommendation
=
LogMessageDoc
.
CHECK_SWITCH
),
@LogMessageDoc
(
level
=
"ERROR"
,
message
=
"Disconnecting switch {switch}: failed to "
+
message
=
"Disconnecting switch {switch}: failed to "
+
"complete handshake"
,
explanation
=
"The switch did not respond correctly "
+
explanation
=
"The switch did not respond correctly "
+
"to handshake messages"
,
recommendation
=
LogMessageDoc
.
CHECK_SWITCH
),
@LogMessageDoc
(
level
=
"ERROR"
,
...
...
@@ -472,7 +473,7 @@ public class Controller implements IFloodlightProviderService,
explanation
=
"There was an error communicating with the switch"
,
recommendation
=
LogMessageDoc
.
CHECK_SWITCH
),
@LogMessageDoc
(
level
=
"ERROR"
,
message
=
"Disconnecting switch {switch} due to switch "
+
message
=
"Disconnecting switch {switch} due to switch "
+
"state error: {error}"
,
explanation
=
"The switch sent an unexpected message"
,
recommendation
=
LogMessageDoc
.
CHECK_SWITCH
),
...
...
@@ -503,7 +504,7 @@ public class Controller implements IFloodlightProviderService,
log
.
error
(
"Disconnecting switch {} due to read timeout"
,
sw
);
ctx
.
getChannel
().
close
();
}
else
if
(
e
.
getCause
()
instanceof
HandshakeTimeoutException
)
{
log
.
error
(
"Disconnecting switch {}: failed to complete handshake"
,
log
.
error
(
"Disconnecting switch {}: failed to complete handshake"
,
sw
);
ctx
.
getChannel
().
close
();
}
else
if
(
e
.
getCause
()
instanceof
ClosedChannelException
)
{
...
...
@@ -513,16 +514,16 @@ public class Controller implements IFloodlightProviderService,
sw
,
e
.
getCause
().
getMessage
());
ctx
.
getChannel
().
close
();
}
else
if
(
e
.
getCause
()
instanceof
SwitchStateException
)
{
log
.
error
(
"Disconnecting switch {} due to switch state error: {}"
,
log
.
error
(
"Disconnecting switch {} due to switch state error: {}"
,
sw
,
e
.
getCause
().
getMessage
());
ctx
.
getChannel
().
close
();
}
else
if
(
e
.
getCause
()
instanceof
MessageParseException
)
{
log
.
error
(
"Disconnecting switch "
+
sw
+
" due to message parse failure"
,
" due to message parse failure"
,
e
.
getCause
());
ctx
.
getChannel
().
close
();
}
else
if
(
e
.
getCause
()
instanceof
StorageException
)
{
log
.
error
(
"Terminating controller due to storage exception"
,
log
.
error
(
"Terminating controller due to storage exception"
,
e
.
getCause
());
terminate
();
}
else
if
(
e
.
getCause
()
instanceof
RejectedExecutionException
)
{
...
...
@@ -605,8 +606,8 @@ public class Controller implements IFloodlightProviderService,
}
catch
(
Exception
ex
)
{
// We are the last handler in the stream, so run the
// exception through the channel again by passing in
// We are the last handler in the stream, so run the
// exception through the channel again by passing in
// ctx.getChannel().
Channels
.
fireExceptionCaught
(
ctx
.
getChannel
(),
ex
);
}
...
...
@@ -629,21 +630,21 @@ public class Controller implements IFloodlightProviderService,
bigFlowCacheMgr
.
updateFlush
();
}
}
/**
* Process the request for the switch description
*/
@LogMessageDoc
(
level
=
"ERROR"
,
message
=
"Exception in reading description "
+
message
=
"Exception in reading description "
+
" during handshake {exception}"
,
explanation
=
"Could not process the switch description string"
,
recommendation
=
LogMessageDoc
.
CHECK_SWITCH
)
void
processSwitchDescReply
(
OFStatisticsReply
m
)
{
try
{
// Read description, if it has been updated
OFDescriptionStatistics
description
=
OFDescriptionStatistics
description
=
new
OFDescriptionStatistics
();
ChannelBuffer
data
=
ChannelBuffer
data
=
ChannelBuffers
.
buffer
(
description
.
getLength
());
OFStatistics
f
=
m
.
getFirstStatistics
();
f
.
writeTo
(
data
);
...
...
@@ -653,7 +654,7 @@ public class Controller implements IFloodlightProviderService,
checkSwitchReady
();
}
catch
(
Exception
ex
)
{
log
.
error
(
"Exception in reading description "
+
log
.
error
(
"Exception in reading description "
+
" during handshake"
,
ex
);
}
}
...
...
@@ -669,7 +670,7 @@ public class Controller implements IFloodlightProviderService,
msglist
.
add
(
factory
.
getMessage
(
type
));
channel
.
write
(
msglist
);
}
/**
* Send the configuration requests we can only do after we have
* the features reply
...
...
@@ -685,7 +686,7 @@ public class Controller implements IFloodlightProviderService,
.
setLengthU
(
OFSwitchConfig
.
MINIMUM_LENGTH
);
configSet
.
setXid
(-
4
);
msglist
.
add
(
configSet
);
// Verify (need barrier?)
OFGetConfigRequest
configReq
=
(
OFGetConfigRequest
)
factory
.
getMessage
(
OFType
.
GET_CONFIG_REQUEST
);
...
...
@@ -698,10 +699,10 @@ public class Controller implements IFloodlightProviderService,
req
.
setXid
(-
2
);
// something "large"
req
.
setLengthU
(
req
.
getLengthU
());
msglist
.
add
(
req
);
channel
.
write
(
msglist
);
}
protected
void
checkSwitchReady
()
{
if
(!
state
.
switchBindingDone
)
{
bindSwitchToDriver
();
...
...
@@ -709,27 +710,27 @@ public class Controller implements IFloodlightProviderService,
if
(
state
.
hsState
==
HandshakeState
.
FEATURES_REPLY
&&
state
.
switchBindingDone
)
{
state
.
hsState
=
HandshakeState
.
READY
;
synchronized
(
roleChanger
)
{
// We need to keep track of all of the switches that are connected
// to the controller, in any role, so that we can later send the
// to the controller, in any role, so that we can later send the
// role request messages when the controller role changes.
// We need to be synchronized while doing this: we must not
// We need to be synchronized while doing this: we must not
// send a another role request to the connectedSwitches until
// we were able to add this new switch to connectedSwitches
// we were able to add this new switch to connectedSwitches
// *and* send the current role to the new switch.
connectedSwitches
.
add
(
sw
);
// Send a role request.
// This is a probe that we'll use to determine if the switch
// actually supports the role request message. If it does we'll
// get back a role reply message. If it doesn't we'll get back an
// OFError message.
// OFError message.
// If role is MASTER we will promote switch to active
// list when we receive the switch's role reply messages
log
.
debug
(
"This controller's role is {}, "
+
log
.
debug
(
"This controller's role is {}, "
+
"sending initial role request msg to {}"
,
role
,
sw
);
Collection
<
IOFSwitch
>
swList
=
new
ArrayList
<
IOFSwitch
>(
1
);
...
...
@@ -738,7 +739,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
protected
void
bindSwitchToDriver
()
{
if
(!
state
.
hasGetConfigReply
)
{
log
.
debug
(
"Waiting for config reply from switch {}"
,
...
...
@@ -750,7 +751,7 @@ public class Controller implements IFloodlightProviderService,
channel
.
getRemoteAddress
());
return
;
}
for
(
String
desc
:
switchDescSortedList
)
{
if
(
state
.
description
.
getManufacturerDescription
()
.
startsWith
(
desc
))
{
...
...
@@ -781,27 +782,27 @@ public class Controller implements IFloodlightProviderService,
state
.
description
=
null
;
state
.
switchBindingDone
=
true
;
}
private
void
readPropertyFromStorage
()
{
// At this time, also set other switch properties from storage
boolean
is_core_switch
=
false
;
IResultSet
resultSet
=
null
;
try
{
String
swid
=
sw
.
getStringId
();
resultSet
=
resultSet
=
storageSource
.
getRow
(
SWITCH_CONFIG_TABLE_NAME
,
swid
);
for
(
Iterator
<
IResultSet
>
it
=
for
(
Iterator
<
IResultSet
>
it
=
resultSet
.
iterator
();
it
.
hasNext
();)
{
// In case of multiple rows, use the status
// in last row?
Map
<
String
,
Object
>
row
=
it
.
next
().
getRow
();
if
(
row
.
containsKey
(
SWITCH_CONFIG_CORE_SWITCH
))
{
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"Reading SWITCH_IS_CORE_SWITCH "
+
log
.
debug
(
"Reading SWITCH_IS_CORE_SWITCH "
+
"config for switch={}, is-core={}"
,
sw
,
row
.
get
(
SWITCH_CONFIG_CORE_SWITCH
));
}
String
ics
=
String
ics
=
(
String
)
row
.
get
(
SWITCH_CONFIG_CORE_SWITCH
);
is_core_switch
=
ics
.
equals
(
"true"
);
}
...
...
@@ -812,7 +813,7 @@ public class Controller implements IFloodlightProviderService,
resultSet
.
close
();
}
if
(
is_core_switch
)
{
sw
.
setAttribute
(
IOFSwitch
.
SWITCH_IS_CORE_SWITCH
,
sw
.
setAttribute
(
IOFSwitch
.
SWITCH_IS_CORE_SWITCH
,
new
Boolean
(
true
));
}
}
...
...
@@ -842,7 +843,7 @@ public class Controller implements IFloodlightProviderService,
log
.
warn
(
"Unhandled VENDOR message; vendor id = {}"
,
vendor
);
break
;
}
return
shouldHandleMessage
;
}
...
...
@@ -851,7 +852,7 @@ public class Controller implements IFloodlightProviderService,
* handler.
* @param m The message to process
* @throws IOException
* @throws SwitchStateException
* @throws SwitchStateException
*/
@LogMessageDocs
({
@LogMessageDoc
(
level
=
"WARN"
,
...
...
@@ -873,17 +874,17 @@ public class Controller implements IFloodlightProviderService,
protected
void
processOFMessage
(
OFMessage
m
)
throws
IOException
,
SwitchStateException
{
boolean
shouldHandleMessage
=
false
;
switch
(
m
.
getType
())
{
case
HELLO:
if
(
log
.
isTraceEnabled
())
log
.
trace
(
"HELLO from {}"
,
sw
);
if
(
state
.
hsState
.
equals
(
HandshakeState
.
START
))
{
state
.
hsState
=
HandshakeState
.
HELLO
;
sendHandShakeMessage
(
OFType
.
FEATURES_REQUEST
);
}
else
{
throw
new
SwitchStateException
(
"Unexpected HELLO from "
throw
new
SwitchStateException
(
"Unexpected HELLO from "
+
sw
);
}
break
;
...
...
@@ -900,7 +901,7 @@ public class Controller implements IFloodlightProviderService,
case
FEATURES_REPLY:
if
(
log
.
isTraceEnabled
())
log
.
trace
(
"Features Reply from {}"
,
sw
);
if
(
state
.
hsState
.
equals
(
HandshakeState
.
HELLO
))
{
sendFeatureReplyConfiguration
();
state
.
featuresReply
=
(
OFFeaturesReply
)
m
;
...
...
@@ -917,18 +918,18 @@ public class Controller implements IFloodlightProviderService,
case
GET_CONFIG_REPLY:
if
(
log
.
isTraceEnabled
())
log
.
trace
(
"Get config reply from {}"
,
sw
);
if
(!
state
.
hsState
.
equals
(
HandshakeState
.
FEATURES_REPLY
))
{
String
em
=
"Unexpected GET_CONFIG_REPLY from "
+
sw
;
throw
new
SwitchStateException
(
em
);
}
OFGetConfigReply
cr
=
(
OFGetConfigReply
)
m
;
if
(
cr
.
getMissSendLength
()
==
(
short
)
0xffff
)
{
log
.
trace
(
"Config Reply from {} confirms "
+
log
.
trace
(
"Config Reply from {} confirms "
+
"miss length set to 0xffff"
,
sw
);
}
else
{
log
.
warn
(
"Config Reply from {} has "
+
"miss length set to {}"
,
"miss length set to {}"
,
sw
,
cr
.
getMissSendLength
()
&
0xffff
);
}
state
.
hasGetConfigReply
=
true
;
...
...
@@ -938,9 +939,9 @@ public class Controller implements IFloodlightProviderService,
shouldHandleMessage
=
handleVendorMessage
((
OFVendor
)
m
);
break
;
case
ERROR:
// TODO: we need better error handling. Especially for
// TODO: we need better error handling. Especially for
// request/reply style message (stats, roles) we should have
// a unified way to lookup the xid in the error message.
// a unified way to lookup the xid in the error message.
// This will probable involve rewriting the way we handle
// request/reply style messages.
OFError
error
=
(
OFError
)
m
;
...
...
@@ -953,9 +954,9 @@ public class Controller implements IFloodlightProviderService,
boolean
isBadVendorError
=
(
error
.
getErrorType
()
==
OFError
.
OFErrorType
.
OFPET_BAD_REQUEST
.
getValue
());
// We expect to receive a bad vendor error when
// we're connected to a switch that doesn't support
// the Nicira vendor extensions (i.e. not OVS or
// We expect to receive a bad vendor error when
// we're connected to a switch that doesn't support
// the Nicira vendor extensions (i.e. not OVS or
// derived from OVS). By protocol, it should also be
// BAD_VENDOR, but too many switch implementations
// get it wrong and we can already check the xid()
...
...
@@ -975,42 +976,42 @@ public class Controller implements IFloodlightProviderService,
if
(
Controller
.
this
.
role
==
Role
.
SLAVE
)
{
// the switch doesn't understand role request
// messages and the current controller role is
// slave. We need to disconnect the switch.
// slave. We need to disconnect the switch.
// @see RoleChanger for rationale
sw
.
disconnectOutputStream
();
}
else
{
// Controller's role is master: add to
// active
// active
// TODO: check if clearing flow table is
// right choice here.
// Need to clear FlowMods before we add the switch
// and dispatch updates otherwise we have a race condition.
// TODO: switch update is async. Won't we still have a potential
// race condition?
// race condition?
addSwitch
(
sw
,
true
);
}
}
}
else
{
// TODO: Is this the right thing to do if we receive
// some other error besides a bad vendor error?
// some other error besides a bad vendor error?
// Presumably that means the switch did actually
// understand the role request message, but there
// understand the role request message, but there
// was some other error from processing the message.
// OF 1.2 specifies a OFPET_ROLE_REQUEST_FAILED
// error code, but it doesn't look like the Nicira
// role request has that. Should check OVS source
// error code, but it doesn't look like the Nicira
// role request has that. Should check OVS source
// code to see if it's possible for any other errors
// to be returned.
// If we received an error the switch is not
// in the correct role, so we need to disconnect it.
// in the correct role, so we need to disconnect it.
// We could also resend the request but then we need to
// check if there are other pending request in which
// case we shouldn't resend. If we do resend we need
// to make sure that the switch eventually accepts one
// of our requests or disconnect the switch. This feels
// cumbersome.
// cumbersome.
sw
.
disconnectOutputStream
();
}
}
...
...
@@ -1021,12 +1022,12 @@ public class Controller implements IFloodlightProviderService,
logError
(
sw
,
error
);
break
;
case
STATS_REPLY:
if
(
state
.
hsState
.
ordinal
()
<
if
(
state
.
hsState
.
ordinal
()
<
HandshakeState
.
FEATURES_REPLY
.
ordinal
())
{
String
em
=
"Unexpected STATS_REPLY from "
+
sw
;
throw
new
SwitchStateException
(
em
);
}
if
(
sw
==
null
)
{
if
(
sw
==
null
)
{
processSwitchDescReply
((
OFStatisticsReply
)
m
);
}
else
{
sw
.
deliverStatisticsReply
(
m
);
...
...
@@ -1041,32 +1042,32 @@ public class Controller implements IFloodlightProviderService,
shouldHandleMessage
=
true
;
break
;
}
if
(
shouldHandleMessage
)
{
// WARNING: sw is null if handshake is not complete
if
(!
state
.
hsState
.
equals
(
HandshakeState
.
READY
))
{
log
.
debug
(
"Ignoring message type {} received "
+
"from switch {} before switch is "
+
log
.
debug
(
"Ignoring message type {} received "
+
"from switch {} before switch is "
+
"fully configured."
,
m
.
getType
(),
sw
);
}
else
{
sw
.
getListenerReadLock
().
lock
();
try
{
if
(
sw
.
isConnected
())
{
// Check if the controller is in the slave role for the
// switch. If it is, then don't dispatch the message to
// Check if the controller is in the slave role for the
// switch. If it is, then don't dispatch the message to
// the listeners.
// TODO: Should we dispatch messages that we expect to
// receive when we're in the slave role, e.g. port
// status messages? Since we're "hiding" switches from
// the listeners when we're in the slave role, then it
// TODO: Should we dispatch messages that we expect to
// receive when we're in the slave role, e.g. port
// status messages? Since we're "hiding" switches from
// the listeners when we're in the slave role, then it
// seems a little weird to dispatch port status messages
// to them. On the other hand there might be special
// to them. On the other hand there might be special
// modules that care about all of the connected switches
// and would like to receive port status notifications.
if
(
sw
.
getHARole
()
==
Role
.
SLAVE
)
{
// Don't log message if it's a port status message
// since we expect to receive those from the switch
// Don't log message if it's a port status message
// since we expect to receive those from the switch
// and don't want to emit spurious messages.
if
(
m
.
getType
()
!=
OFType
.
PORT_STATUS
)
{
log
.
debug
(
"Ignoring message type {} received "
+
...
...
@@ -1089,7 +1090,7 @@ public class Controller implements IFloodlightProviderService,
// ****************
// Message handlers
// ****************
protected
void
handlePortStatusMessage
(
IOFSwitch
sw
,
OFPortStatus
m
)
{
short
portNumber
=
m
.
getDesc
().
getPortNumber
();
OFPhysicalPort
port
=
m
.
getDesc
();
...
...
@@ -1099,7 +1100,7 @@ public class Controller implements IFloodlightProviderService,
}
else
if
(
m
.
getReason
()
==
(
byte
)
OFPortReason
.
OFPPR_ADD
.
ordinal
())
{
sw
.
setPort
(
port
);
log
.
debug
(
"Port #{} added for {}"
,
portNumber
,
sw
);
}
else
if
(
m
.
getReason
()
==
}
else
if
(
m
.
getReason
()
==
(
byte
)
OFPortReason
.
OFPPR_DELETE
.
ordinal
())
{
sw
.
deletePort
(
portNumber
);
log
.
debug
(
"Port #{} deleted for {}"
,
portNumber
,
sw
);
...
...
@@ -1111,7 +1112,7 @@ public class Controller implements IFloodlightProviderService,
log
.
error
(
"Failure adding update to queue"
,
e
);
}
}
/**
* flcontext_cache - Keep a thread local stack of contexts
*/
...
...
@@ -1177,13 +1178,13 @@ public class Controller implements IFloodlightProviderService,
switch
(
m
.
getType
())
{
case
PACKET_IN:
OFPacketIn
pi
=
(
OFPacketIn
)
m
;
if
(
pi
.
getPacketData
().
length
<=
0
)
{
log
.
error
(
"Ignoring PacketIn (Xid = "
+
pi
.
getXid
()
+
log
.
error
(
"Ignoring PacketIn (Xid = "
+
pi
.
getXid
()
+
") because the data field is empty."
);
return
;
}
if
(
Controller
.
ALWAYS_DECODE_ETH
)
{
eth
=
new
Ethernet
();
eth
.
deserialize
(
pi
.
getPacketData
(),
0
,
...
...
@@ -1193,17 +1194,17 @@ public class Controller implements IFloodlightProviderService,
// fall through to default case...
default
:
List
<
IOFMessageListener
>
listeners
=
null
;
if
(
messageListeners
.
containsKey
(
m
.
getType
()))
{
listeners
=
messageListeners
.
get
(
m
.
getType
()).
getOrderedListeners
();
}
FloodlightContext
bc
=
null
;
if
(
listeners
!=
null
)
{
// Check if floodlight context is passed from the calling
// function, if so use that floodlight context, otherwise
// Check if floodlight context is passed from the calling
// function, if so use that floodlight context, otherwise
// allocate one
if
(
bContext
==
null
)
{
bc
=
flcontext_alloc
();
...
...
@@ -1211,16 +1212,16 @@ public class Controller implements IFloodlightProviderService,
bc
=
bContext
;
}
if
(
eth
!=
null
)
{
IFloodlightProviderService
.
bcStore
.
put
(
bc
,
IFloodlightProviderService
.
CONTEXT_PI_PAYLOAD
,
IFloodlightProviderService
.
bcStore
.
put
(
bc
,
IFloodlightProviderService
.
CONTEXT_PI_PAYLOAD
,
eth
);
}
// Get the starting time (overall and per-component) of
// Get the starting time (overall and per-component) of
// the processing chain for this packet if performance
// monitoring is turned on
pktinProcTime
.
bootstrap
(
listeners
);
pktinProcTime
.
recordStartTimePktIn
();
pktinProcTime
.
recordStartTimePktIn
();
Command
cmd
;
for
(
IOFMessageListener
listener
:
listeners
)
{
if
(
listener
instanceof
IOFSwitchFilter
)
{
...
...
@@ -1232,7 +1233,7 @@ public class Controller implements IFloodlightProviderService,
pktinProcTime
.
recordStartTimeComp
(
listener
);
cmd
=
listener
.
receive
(
sw
,
m
,
bc
);
pktinProcTime
.
recordEndTimeComp
(
listener
);
if
(
Command
.
STOP
.
equals
(
cmd
))
{
break
;
}
...
...
@@ -1241,11 +1242,11 @@ public class Controller implements IFloodlightProviderService,
}
else
{
log
.
warn
(
"Unhandled OF Message: {} from {}"
,
m
,
sw
);
}
if
((
bContext
==
null
)
&&
(
bc
!=
null
))
flcontext_free
(
bc
);
}
}
/**
* Log an OpenFlow error message from a switch
* @param sw The switch that sent the error
...
...
@@ -1267,12 +1268,12 @@ public class Controller implements IFloodlightProviderService,
OFErrorType
et
=
OFErrorType
.
values
()[
etint
];
switch
(
et
)
{
case
OFPET_HELLO_FAILED:
OFHelloFailedCode
hfc
=
OFHelloFailedCode
hfc
=
OFHelloFailedCode
.
values
()[
0xffff
&
error
.
getErrorCode
()];
log
.
error
(
"Error {} {} from {}"
,
new
Object
[]
{
et
,
hfc
,
sw
});
break
;
case
OFPET_BAD_REQUEST:
OFBadRequestCode
brc
=
OFBadRequestCode
brc
=
OFBadRequestCode
.
values
()[
0xffff
&
error
.
getErrorCode
()];
log
.
error
(
"Error {} {} from {}"
,
new
Object
[]
{
et
,
brc
,
sw
});
break
;
...
...
@@ -1300,16 +1301,16 @@ public class Controller implements IFloodlightProviderService,
break
;
}
}
/**
* Add a switch to the active switch list and call the switch listeners.
* This happens either when a switch first connects (and the controller is
* not in the slave role) or when the role of the controller changes from
* slave to master.
*
* FIXME: remove shouldReadSwitchPortStateFromStorage argument once
*
* FIXME: remove shouldReadSwitchPortStateFromStorage argument once
* performance problems are solved. We should call it always or never.
*
*
* @param sw the switch that has been added
*/
// TODO: need to rethink locking and the synchronous switch update.
...
...
@@ -1328,7 +1329,7 @@ public class Controller implements IFloodlightProviderService,
"network problem that can be ignored."
)
protected
void
addSwitch
(
IOFSwitch
sw
,
boolean
shouldClearFlowMods
)
{
// TODO: is it safe to modify the HashMap without holding
// TODO: is it safe to modify the HashMap without holding
// the old switch's lock?
IOFSwitch
oldSw
=
this
.
activeSwitches
.
put
(
sw
.
getId
(),
sw
);
if
(
sw
==
oldSw
)
{
...
...
@@ -1336,9 +1337,9 @@ public class Controller implements IFloodlightProviderService,
log
.
info
(
"New add switch for pre-existing switch {}"
,
sw
);
return
;
}
if
(
oldSw
!=
null
)
{
oldSw
.
getListenerWriteLock
().
lock
();
try
{
...
...
@@ -1347,10 +1348,10 @@ public class Controller implements IFloodlightProviderService,
// Set the connected flag to false to suppress calling
// the listeners for this switch in processOFMessage
oldSw
.
setConnected
(
false
);
oldSw
.
cancelAllStatisticsReplies
();
// we need to clean out old switch state definitively
// we need to clean out old switch state definitively
// before adding the new switch
// FIXME: It seems not completely kosher to call the
// switch listeners here. I thought one of the points of
...
...
@@ -1373,10 +1374,10 @@ public class Controller implements IFloodlightProviderService,
oldSw
.
getListenerWriteLock
().
unlock
();
}
}
if
(
shouldClearFlowMods
)
sw
.
clearAllFlowMods
();
SwitchUpdate
update
=
new
SwitchUpdate
(
sw
,
SwitchUpdateType
.
ADDED
);
try
{
this
.
updates
.
put
(
update
);
...
...
@@ -1401,11 +1402,11 @@ public class Controller implements IFloodlightProviderService,
return
;
}
// We cancel all outstanding statistics replies if the switch transition
// from active. In the future we might allow statistics requests
// from active. In the future we might allow statistics requests
// from slave controllers. Then we need to move this cancelation
// to switch disconnect
sw
.
cancelAllStatisticsReplies
();
// FIXME: I think there's a race condition if we call updateInactiveSwitchInfo
// here if role support is enabled. In that case if the switch is being
// removed because we've been switched to being in the slave role, then I think
...
...
@@ -1414,7 +1415,7 @@ public class Controller implements IFloodlightProviderService,
// updateInactiveSwitchInfo we may wipe out all of the state that was
// written out by the new master. Maybe need to revisit how we handle all
// of the switch state that's written to storage.
SwitchUpdate
update
=
new
SwitchUpdate
(
sw
,
SwitchUpdateType
.
REMOVED
);
try
{
this
.
updates
.
put
(
update
);
...
...
@@ -1422,15 +1423,15 @@ public class Controller implements IFloodlightProviderService,
log
.
error
(
"Failure adding update to queue"
,
e
);
}
}
// ***************
// IFloodlightProvider
// ***************
@Override
public
synchronized
void
addOFMessageListener
(
OFType
type
,
public
synchronized
void
addOFMessageListener
(
OFType
type
,
IOFMessageListener
listener
)
{
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
messageListeners
.
get
(
type
);
if
(
ldd
==
null
)
{
ldd
=
new
ListenerDispatcher
<
OFType
,
IOFMessageListener
>();
...
...
@@ -1442,23 +1443,23 @@ public class Controller implements IFloodlightProviderService,
@Override
public
synchronized
void
removeOFMessageListener
(
OFType
type
,
IOFMessageListener
listener
)
{
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
messageListeners
.
get
(
type
);
if
(
ldd
!=
null
)
{
ldd
.
removeListener
(
listener
);
}
}
private
void
logListeners
()
{
for
(
Map
.
Entry
<
OFType
,
ListenerDispatcher
<
OFType
,
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>
entry
:
messageListeners
.
entrySet
())
{
OFType
type
=
entry
.
getKey
();
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
ListenerDispatcher
<
OFType
,
IOFMessageListener
>
ldd
=
entry
.
getValue
();
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
"OFListeners for "
);
sb
.
append
(
type
);
...
...
@@ -1467,10 +1468,10 @@ public class Controller implements IFloodlightProviderService,
sb
.
append
(
l
.
getName
());
sb
.
append
(
","
);
}
log
.
debug
(
sb
.
toString
());
log
.
debug
(
sb
.
toString
());
}
}
public
void
removeOFMessageListeners
(
OFType
type
)
{
messageListeners
.
remove
(
type
);
}
...
...
@@ -1492,15 +1493,15 @@ public class Controller implements IFloodlightProviderService,
@Override
public
Map
<
OFType
,
List
<
IOFMessageListener
>>
getListeners
()
{
Map
<
OFType
,
List
<
IOFMessageListener
>>
lers
=
Map
<
OFType
,
List
<
IOFMessageListener
>>
lers
=
new
HashMap
<
OFType
,
List
<
IOFMessageListener
>>();
for
(
Entry
<
OFType
,
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>
e
:
for
(
Entry
<
OFType
,
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>
e
:
messageListeners
.
entrySet
())
{
lers
.
put
(
e
.
getKey
(),
e
.
getValue
().
getOrderedListeners
());
}
return
Collections
.
unmodifiableMap
(
lers
);
}
@Override
@LogMessageDocs
({
@LogMessageDoc
(
message
=
"Failed to inject OFMessage {message} onto "
+
...
...
@@ -1519,7 +1520,7 @@ public class Controller implements IFloodlightProviderService,
log
.
info
(
"Failed to inject OFMessage {} onto a null switch"
,
msg
);
return
false
;
}
// FIXME: Do we need to be able to inject messages to switches
// where we're the slave controller (i.e. they're connected but
// not active)?
...
...
@@ -1528,14 +1529,14 @@ public class Controller implements IFloodlightProviderService,
// discussions it sounds like the right thing to do here would be to
// inject the message as a netty upstream channel event so it goes
// through the normal netty event processing, including being
// handled
// handled
if
(!
activeSwitches
.
containsKey
(
sw
.
getId
()))
return
false
;
try
{
// Pass Floodlight context to the handleMessages()
handleMessage
(
sw
,
msg
,
bc
);
}
catch
(
IOException
e
)
{
log
.
error
(
"Error reinjecting OFMessage on switch {}"
,
log
.
error
(
"Error reinjecting OFMessage on switch {}"
,
HexString
.
toHexString
(
sw
.
getId
()));
return
false
;
}
...
...
@@ -1549,13 +1550,13 @@ public class Controller implements IFloodlightProviderService,
log
.
info
(
"Calling System.exit"
);
System
.
exit
(
1
);
}
@Override
public
boolean
injectOfMessage
(
IOFSwitch
sw
,
OFMessage
msg
)
{
// call the overloaded version with floodlight context set to null
// call the overloaded version with floodlight context set to null
return
injectOfMessage
(
sw
,
msg
,
null
);
}
@Override
public
void
handleOutgoingMessage
(
IOFSwitch
sw
,
OFMessage
m
,
FloodlightContext
bc
)
{
...
...
@@ -1566,11 +1567,11 @@ public class Controller implements IFloodlightProviderService,
List
<
IOFMessageListener
>
listeners
=
null
;
if
(
messageListeners
.
containsKey
(
m
.
getType
()))
{
listeners
=
listeners
=
messageListeners
.
get
(
m
.
getType
()).
getOrderedListeners
();
}
if
(
listeners
!=
null
)
{
if
(
listeners
!=
null
)
{
for
(
IOFMessageListener
listener
:
listeners
)
{
if
(
listener
instanceof
IOFSwitchFilter
)
{
if
(!((
IOFSwitchFilter
)
listener
).
isInterested
(
sw
))
{
...
...
@@ -1588,12 +1589,12 @@ public class Controller implements IFloodlightProviderService,
public
BasicFactory
getOFMessageFactory
()
{
return
factory
;
}
@Override
public
String
getControllerId
()
{
return
controllerId
;
}
// **************
// Initialization
// **************
...
...
@@ -1605,7 +1606,7 @@ public class Controller implements IFloodlightProviderService,
controllerInfo
.
put
(
CONTROLLER_ID
,
id
);
storageSource
.
updateRow
(
CONTROLLER_TABLE_NAME
,
controllerInfo
);
}
/**
* Sets the initial role based on properties in the config params.
...
...
@@ -1632,7 +1633,7 @@ public class Controller implements IFloodlightProviderService,
explanation
=
"Setting the initial HA role to "
),
@LogMessageDoc
(
level
=
"ERROR"
,
message
=
"Invalid current role value: {role}"
,
explanation
=
"An invalid HA role value was read from the "
+
explanation
=
"An invalid HA role value was read from the "
+
"properties file"
,
recommendation
=
LogMessageDoc
.
CHECK_CONTROLLER
)
})
...
...
@@ -1656,7 +1657,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
if
(
roleString
!=
null
)
{
// Canonicalize the string to the form used for the enum constants
roleString
=
roleString
.
trim
().
toUpperCase
();
...
...
@@ -1667,21 +1668,22 @@ public class Controller implements IFloodlightProviderService,
log
.
error
(
"Invalid current role value: {}"
,
roleString
);
}
}
log
.
info
(
"Controller role set to {}"
,
role
);
return
role
;
}
/**
* Tell controller that we're ready to accept switches loop
* @throws IOException
* @throws IOException
*/
@Override
@LogMessageDocs
({
@LogMessageDoc
(
message
=
"Listening for switch connections on {address}"
,
explanation
=
"The controller is ready and listening for new"
+
" switch connections"
),
@LogMessageDoc
(
message
=
"Storage exception in controller "
+
@LogMessageDoc
(
message
=
"Storage exception in controller "
+
"updates loop; terminating process"
,
explanation
=
ERROR_DATABASE
,
recommendation
=
LogMessageDoc
.
CHECK_CONTROLLER
),
...
...
@@ -1694,8 +1696,8 @@ public class Controller implements IFloodlightProviderService,
if
(
log
.
isDebugEnabled
())
{
logListeners
();
}
try
{
try
{
final
ServerBootstrap
bootstrap
=
createServerBootStrap
();
bootstrap
.
setOption
(
"reuseAddr"
,
true
);
...
...
@@ -1703,13 +1705,13 @@ public class Controller implements IFloodlightProviderService,
bootstrap
.
setOption
(
"child.tcpNoDelay"
,
true
);
bootstrap
.
setOption
(
"child.sendBufferSize"
,
Controller
.
SEND_BUFFER_SIZE
);
ChannelPipelineFactory
pfact
=
ChannelPipelineFactory
pfact
=
new
OpenflowPipelineFactory
(
this
,
null
);
bootstrap
.
setPipelineFactory
(
pfact
);
InetSocketAddress
sa
=
new
InetSocketAddress
(
openFlowPort
);
final
ChannelGroup
cg
=
new
DefaultChannelGroup
();
cg
.
add
(
bootstrap
.
bind
(
sa
));
log
.
info
(
"Listening for switch connections on {}"
,
sa
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
...
...
@@ -1723,7 +1725,7 @@ public class Controller implements IFloodlightProviderService,
}
catch
(
InterruptedException
e
)
{
return
;
}
catch
(
StorageException
e
)
{
log
.
error
(
"Storage exception in controller "
+
log
.
error
(
"Storage exception in controller "
+
"updates loop; terminating process"
,
e
);
return
;
}
catch
(
Exception
e
)
{
...
...
@@ -1745,7 +1747,7 @@ public class Controller implements IFloodlightProviderService,
Executors
.
newCachedThreadPool
(),
workerThreads
));
}
}
public
void
setConfigParams
(
Map
<
String
,
String
>
configParams
)
{
String
ofPort
=
configParams
.
get
(
"openflowport"
);
if
(
ofPort
!=
null
)
{
...
...
@@ -1777,8 +1779,8 @@ public class Controller implements IFloodlightProviderService,
// These data structures are initialized here because other
// module's startUp() might be called before ours
this
.
messageListeners
=
new
ConcurrentHashMap
<
OFType
,
ListenerDispatcher
<
OFType
,
new
ConcurrentHashMap
<
OFType
,
ListenerDispatcher
<
OFType
,
IOFMessageListener
>>();
this
.
switchListeners
=
new
CopyOnWriteArraySet
<
IOFSwitchListener
>();
this
.
haListeners
=
new
CopyOnWriteArraySet
<
IHAListener
>();
...
...
@@ -1797,7 +1799,7 @@ public class Controller implements IFloodlightProviderService,
initVendorMessages
();
this
.
systemStartTime
=
System
.
currentTimeMillis
();
}
/**
* Startup all of the controller's components
*/
...
...
@@ -1814,7 +1816,7 @@ public class Controller implements IFloodlightProviderService,
storageSource
.
setTablePrimaryKeyName
(
CONTROLLER_TABLE_NAME
,
CONTROLLER_ID
);
storageSource
.
addListener
(
CONTROLLER_INTERFACE_TABLE_NAME
,
this
);
while
(
true
)
{
try
{
updateControllerInfo
();
...
...
@@ -1828,7 +1830,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
// Startup load monitoring
if
(
overload_drop
)
{
this
.
loadmonitor
.
startMonitoring
(
...
...
@@ -1853,18 +1855,19 @@ public class Controller implements IFloodlightProviderService,
log
.
debug
(
"Provider type {} doesn't exist."
,
type
);
return
;
}
providerMap
.
get
(
type
).
remove
(
provider
);
}
@Override
public
Map
<
String
,
Object
>
getControllerInfo
(
String
type
)
{
if
(!
providerMap
.
containsKey
(
type
))
return
null
;
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<
String
,
Object
>();
for
(
IInfoProvider
provider
:
providerMap
.
get
(
type
))
{
result
.
putAll
(
provider
.
getInfo
(
type
));
}
return
result
;
}
...
...
@@ -1877,26 +1880,26 @@ public class Controller implements IFloodlightProviderService,
public
void
removeHAListener
(
IHAListener
listener
)
{
this
.
haListeners
.
remove
(
listener
);
}
/**
* Handle changes to the controller nodes IPs and dispatch update.
* Handle changes to the controller nodes IPs and dispatch update.
*/
@SuppressWarnings
(
"unchecked"
)
protected
void
handleControllerNodeIPChanges
()
{
HashMap
<
String
,
String
>
curControllerNodeIPs
=
new
HashMap
<
String
,
String
>();
HashMap
<
String
,
String
>
addedControllerNodeIPs
=
new
HashMap
<
String
,
String
>();
HashMap
<
String
,
String
>
removedControllerNodeIPs
=
new
HashMap
<
String
,
String
>();
String
[]
colNames
=
{
CONTROLLER_INTERFACE_CONTROLLER_ID
,
CONTROLLER_INTERFACE_TYPE
,
CONTROLLER_INTERFACE_NUMBER
,
String
[]
colNames
=
{
CONTROLLER_INTERFACE_CONTROLLER_ID
,
CONTROLLER_INTERFACE_TYPE
,
CONTROLLER_INTERFACE_NUMBER
,
CONTROLLER_INTERFACE_DISCOVERED_IP
};
synchronized
(
controllerNodeIPsCache
)
{
// We currently assume that interface Ethernet0 is the relevant
// controller interface. Might change.
// We could (should?) implement this using
// We could (should?) implement this using
// predicates, but creating the individual and compound predicate
// seems more overhead then just checking every row. Particularly,
// seems more overhead then just checking every row. Particularly,
// since the number of rows is small and changes infrequent
IResultSet
res
=
storageSource
.
executeQuery
(
CONTROLLER_INTERFACE_TABLE_NAME
,
colNames
,
null
,
null
);
...
...
@@ -1906,14 +1909,14 @@ public class Controller implements IFloodlightProviderService,
String
controllerID
=
res
.
getString
(
CONTROLLER_INTERFACE_CONTROLLER_ID
);
String
discoveredIP
=
res
.
getString
(
CONTROLLER_INTERFACE_DISCOVERED_IP
);
String
curIP
=
controllerNodeIPsCache
.
get
(
controllerID
);
curControllerNodeIPs
.
put
(
controllerID
,
discoveredIP
);
if
(
curIP
==
null
)
{
// new controller node IP
addedControllerNodeIPs
.
put
(
controllerID
,
discoveredIP
);
}
}
else
if
(
curIP
!=
discoveredIP
)
{
// IP changed
// IP changed
removedControllerNodeIPs
.
put
(
controllerID
,
curIP
);
addedControllerNodeIPs
.
put
(
controllerID
,
discoveredIP
);
}
...
...
@@ -1940,7 +1943,7 @@ public class Controller implements IFloodlightProviderService,
}
}
}
@Override
public
Map
<
String
,
String
>
getControllerNodeIPs
()
{
// We return a copy of the mapping so we can guarantee that
...
...
@@ -1958,7 +1961,7 @@ public class Controller implements IFloodlightProviderService,
if
(
tableName
.
equals
(
CONTROLLER_INTERFACE_TABLE_NAME
))
{
handleControllerNodeIPChanges
();
}
}
@Override
...
...
@@ -1977,7 +1980,7 @@ public class Controller implements IFloodlightProviderService,
public
void
setAlwaysClearFlowsOnSwAdd
(
boolean
value
)
{
this
.
alwaysClearFlowsOnSwAdd
=
value
;
}
public
boolean
getAlwaysClearFlowsOnSwAdd
()
{
return
this
.
alwaysClearFlowsOnSwAdd
;
}
...
...
@@ -2005,5 +2008,5 @@ public class Controller implements IFloodlightProviderService,
switchDescSortedList
.
add
(
description
);
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment