List<Flow> flowlist = getFlowlist(al);
InetAddress waypoint = NetUtils.parseInetAddress(al.getWaypoint());
NFchainconfig nfcc = new NFchainconfig(al.getName(), flowlist, waypoint);
- /* Only one hop initially... */
- List<NFchainconfig> nfclist = new ArrayList<NFchainconfig>();
String key = al.getName();
- nfclist.add(nfcc);
- nfchainagent.addNfchain(key, nfclist);
+ nfchainagent.addNfchain(key, nfcc);
log.info("Added nfchain {}", al.getName());
return new Status(StatusCode.SUCCESS);
}
<build>
<pluginManagement>
<plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
return new AffinityGroupList(affinityManager.getAllAffinityGroups());
}
+ /**
+ @Path("/{containerName}/")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @TypeHint(AffinityGroupList.class)
+ @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
+ @ResponseCode(code = 404, condition = "The containerName is not found"),
+ @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
+ public AffinityGroupList getAllAffinityGroups(@PathParam("containerName") String containerName) {
+
+ // if (!isValidContainer(containerName)) {
+ // throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
+ //}
+
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
+ }
+
+ IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
+ if (affinityManager == null) {
+ throw new ServiceUnavailableException("Affinity Manager "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ log.info("getallgroups");
+ return new AffinityGroupList(affinityManager.getAllAffinityGroups());
+ }
+ */
+
}
<artifactId>model-inventory</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-base</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-ext</artifactId>
<version>2013.09.07-SNAPSHOT</version>
</dependency> -->
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1-SNAPSHOT</version>
- </dependency>
</dependencies>
</project>
}
}
+ typedef level {
+ type enumeration {
+ enum high;
+ enum medium;
+ enum low;
+ }
+ }
+
//**************************************************
// Affinity attribute. Each is expanded in their own grouping construct below.
//**************************************************
uses access-control;
}
}
+ // Assign a priority
+ case set-priority {
+ leaf priority {
+ type level;
+ }
+ }
}
}
--- /dev/null
+Affinity endpoint:
+=================
+
+This identifies an application endpoint, and may be one of the
+following. This is a location wthin the combined physical + virtual
+network and may be a stationary location referring to a switch/port or
+a virtual endpoint that may move within the network as the
+corresponding virtual machine is moved.
+
+ (a) Reference to VM or PM object in the database. In a controller
+ that tracks data center compute resources (such as Open Stack or
+ vCenter) this represents a reference to the database object such as
+ Uuid for that object. A controller such as Open Daylight does not
+ track external compute resource objects and therefore will not
+ support this type of affinity endpoint.
+
+ (b) Node connector, which is a combination of switch + port in an ODL
+ network. This may represent either a physical network interface or a
+ virtual network interface.
+
+Affinity address domain:
+=======================
+
+This represents a domain (i.e, set) of one or more addresses. An
+affinity address may not have a corresponding endpoint on the network,
+for example, for traffic from a set of external addresses (north-south
+traffic in a data center), the source IP address domain is not
+required to map exactly to endpoints or node connectors on the
+network.
+
+Affinity address specifies one or more of the following:
+
+ (a) VLAN + MAC address, or range of MAC addresses.
+
+ (b) Network layer address, IP address, or range of addresses, or
+ prefix/mask representing multiple sources.
+
+ (c) Transport layer address, which is the transport protocol type and
+ port number.
+
+Affinity Group:
+==============
+Affinity group which is an enumeration of one or more items where each
+item is an affinity endpoint or affinity address domain. An affintiy
+group may also contain other affinity groups in addition to endpoints
+and address domains.
+
+Affinity Link:
+=============
+Affinity link connects one group (from group) to another (to
+group). It represents a set of flows that start from the source group
+and end in the destination group. An affinity link has attributes
+(policies) attached to it that represent how these flows must be
+handled. An affinity link also has directionality associated with
+it. A bidirectional affinity link is equivalent to two unidirectional
+affinity links, one in each direction.
+
+Affinity attribute:
+==================
+An affinity attribute is assigned to an affinity link. An attribute is
+one of the following:
+
+ (a) Path affinity. Path affinities define the type of path required
+ by the application. It may be one of the following types -- latency
+ sensitive for applications that require low latency between their
+ components. Examples include access to block storage and network
+ connections between the application and database tier. Bandwidth
+ sensitive applications include video or audio streaming or bulk data
+ operations desiring high throughput. Isolated paths may be required
+ for applications requiring dedicated paths without sharing or
+ interference from other applications.
+
+ * Isolation. This is an attribute that specifies that the
+ application flow must be assigned an isolated path on the
+ network from flows from other affinity links. While flows
+ within the same affinity link may share one or more network
+ links of the path, flows from different affinity links will be
+ allocated to non-overlapping paths.
+
+ // Isolate flows according to certain constraints. No sharing with any other traffic.
+ grouping isolate-path {
+ // Average bandwidth requirement for each flow is estimated in Mbps.
+ leaf average-bandwidth-per-flow {
+ type uint16;
+ }
+ // Peak burst bandwidth, total per affinity link.
+ leaf burst-bandwidth {
+ type uint16;
+ }
+ }
+
+ * Low latency path. This is an attribute that specifies that the
+ flow is allocated lowest hopcount paths between source and
+ destination.
+
+ // Route through low latency path. May share with other types of traffic.
+ grouping low-latency-path {
+ // Average bandwidth estimated per flow, in Mbps.
+ leaf average-bandwidth-per-flow {
+ type uint16;
+ }
+ // Peak burst bandwidth, total per affinity link.
+ leaf burst-bandwidth {
+ type uint16;
+ }
+ }
+
+ * Bandwidth Optimized. Allocate a path of specified bandwidth to
+ this application.
+
+ // Optimize this path such that specified bandwidth is available to it. May share
+ // with other types of traffic.
+ grouping bandwidth-optimized-path {
+ // Average bandwidth estimated per flow, in Mbps.
+ leaf average-bandwidth-per-flow {
+ type uint16;
+ }
+ // Peak burst bandwidth, total per affinity link.
+ leaf burst-bandwidth {
+ type uint16;
+ }
+ }
+
+Flows from affinity links are interpreted as unicast (point to point)
+flows by an implementation of this API.
+
+The following types of affinity dictate a strict action or rule.
+
+ (b) Access control affinity. This is an attribute that specifies that
+ the application flow must either be permitted (PERMIT) or denied (DENY).
+
+ (c) Path redirect affinity. This affinity link must traverse specified
+ chain of waypoint locations, each specified by an IP address or Mac address.
+
+ (d) Tap affinity. All traffic belonging to this affinity link must be
+ mirrored to specified endpoint location. The endpoint location is
+ carried in the affinity attribute configuration.
+
+ (e) Priority forwarding. All traffic belonging to this affinity link
+ must be assigned a priority level. Setting this priority level
+ provides differential treatment for this traffic relative to other
+ flows on the network. One of five levels of priority must be
+ specified (very low=0, low, normal, high, very high=5).
+
+Strict vs. sensitive:
+=====================
+Note that the attribute may be a goal (not strict) -- latency or
+bandwidth sensitive, or an action (strict) -- forward to this port,
+tunnel to this endpoint.
+
+++ /dev/null
-Affinity endpoint:
-=================
-
-This identifies an application endpoint, and may be one of the
-following. This is a stationary location wthin the combined physical +
-virtual network which does not move as VMs are migrated.
-
- (a) Reference to VM or PM object in the database. In a controller
- that tracks data center compute resources (such as Open Stack or
- vCenter) this represents a reference to the database object such as
- Uuid for that object. A controller such as Open Daylight does not
- track external compute resource objects and therefore will not
- support this type of affinity endpoint.
-
- (b) Node connector, which is a combination of switch + port in an ODL
- network. This may represent either a physical network interface or a
- virtual network interface.
-
-Affinity address domain:
-=======================
-
-This represents a domain (i.e, set) of one or more addresses. An
-affinity address may not have a corresponding endpoint on the network,
-for example, for traffic from a set of external addresses (north-south
-traffic in a data center), the source IP address domain is not
-required to map exactly to endpoints or node connectors on the
-network.
-
-Affinity address specifies one or more of the following:
-
- (a) VLAN + MAC address, or range of MAC addresses.
-
- (b) Network layer address, IP address, or range of addresses, or
- prefix/mask representing multiple sources.
-
- (c) Transport layer address, which is the transport protocol type and
- port number.
-
-Affinity Group:
-==============
-Affinity group which is an enumeration of one or more items where each
-item is an affinity endpoint or affinity address domain. An affintiy
-group may also contain other affinity groups in addition to endpoints
-and address domains.
-
-Affinity Link:
-=============
-Affinity link connects one group (from group) to another (to
-group). It represents a set of flows that start from the source group
-and end in the destination group. An affinity link has attributes
-(policies) attached to it that represent how these flows must be
-handled. An affinity link also has directionality associated with
-it. A bidirectional affinity link is equivalent to two unidirectional
-affinity links, one in each direction.
-
-Affinity attribute:
-==================
-An affinity attribute is assigned to an affinity link. An attribute is
-one of the following:
-
- (a) Path affinity. Path affinities may be one of the following types
- -- latency sensitive, bandwidth sensitive, or isolate.
-
- (b) Access control affinity. This is an attribute that specifies that
- the application flow must either be permitted (PERMIT) or denied (DENY).
-
- (c) Network service chain. This affinity link must traverse specified
- chain of application gateways. This is called the network service chain.
-
-Note that the attribute may be a goal (not strict) -- latency or
-bandwidth sensitive, or an action (strict) -- forward to this port,
-tunnel to this endpoint.
-
</parent>
<groupId>org.opendaylight.affinity</groupId>
- <artifactId>nfchain</artifactId>
+ <artifactId>nfchain.api</artifactId>
<version>0.4.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<artifactId>opendaylight-l2-types</artifactId>
<version>2013.08.27.1-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-base</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
import yang-ext { prefix ext; }
import opendaylight-inventory {prefix inv;}
import opendaylight-l2-types { prefix l2types; }
+ import opendaylight-flow-types { prefix flow-types; }
revision "2013-10-20" {
description "Initial revision of affinity model to be reviewed";
leaf id {
type string;
}
- // Address is either an IP address, MAC address, or switch/port.
+ // xxx address is an IP prefix.
leaf location {
- description "Mac or Inet address";
- type union {
- type inv:node-connector-id;
- type inet:ip-address;
- }
+ description "Inet address";
+ type inet:ipv4-prefix;
}
}
// Each nf chain has an id, a flowspec and a list of gateways.
grouping chain {
- leaf id {
- type chain-id;
- }
- leaf flowSpec {
- type uint32; // tbd
+ leaf name {
+ type string;
}
+
+ list flow {
+ uses flow-types:flow;
+ }
+
list gateway {
key id;
ext:context-instance "gateway-context";
container nfdb {
list chain {
key id;
- ext:context-instance "chain";
+ ext:context-instance "chain-context";
uses chain;
}
}
- typedef chain-id {
- type inet:uri;
- }
+ identity gateway-context;
typedef gateway-ref {
type instance-identifier;
}
- identity gateway-context;
-
// nf chain reference.
typedef chain-ref {
type instance-identifier;
identity chain-context;
//**************************************************
- // Gateway chain.
+ // Add a chain to the service.
//**************************************************
- rpc add {
+ rpc addchain {
input {
- leaf chain {
- type chain-id;
- }
- container gateway {
- uses gateway;
+ container chain {
+ uses chain;
}
}
}
- rpc list {
+
+ rpc enablechain {
+ input {
+ leaf chain {
+ type chain-ref;
+ }
+ }
}
+
}
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>nfchain</artifactId>
+ <artifactId>nfchain.api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.affinity</groupId>
+ <artifactId>nfchainagent</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-compability</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
package org.opendaylight.affinity.nfchain.provider;
import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.NfchainData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.NfdbBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.ChainId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.Gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.chain.Gateway;
import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.Nfdb;
import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.NfdbBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.AddInput;
+
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.AddchainInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.EnablechainInput;
+
+import org.opendaylight.affinity.nfchainagent.NFchainconfig;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.IfNewHostNotify;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.addchain.input.Chain;
+import java.net.InetAddress;
+import org.opendaylight.controller.sal.compability.ToSalConversionsUtils;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.affinity.nfchain.rev131020.chain.Flow;
+
/**
* NfchainManager -- sends flow programming rules to flow programming service.
*/
protected static final Logger log = LoggerFactory.getLogger(NfchainManager.class);
private NotificationProviderService notificationProvider;
- private final ExecutorService executor;
private Future<RpcResult<Void>> currentTask;
- private IFlowProgrammerService programmer = null;
- private ISwitchManager switchManager = null;
-
public NfchainManager() {
- executor = Executors.newFixedThreadPool(1);
}
@Override
return builder.build();
}
- @Override
- public Future<RpcResult<Void>> add(AddInput input) {
- // TODO Auto-generated method stub
- log.info("add gateway - Received input chain = {}, gateway = {}.", input.getChain(), input.getGateway());
- if (currentTask != null) {
- return inProgressError();
+ /**
+ * Convert API Flow objects to flow programmer flow objects.
+ */
+ List<org.opendaylight.controller.sal.flowprogrammer.Flow> fromAPIFlowlist(List<Flow> fl) {
+ List<org.opendaylight.controller.sal.flowprogrammer.Flow> flowlist = new ArrayList<org.opendaylight.controller.sal.flowprogrammer.Flow>();
+
+ for (Flow f: fl) {
+ org.opendaylight.controller.sal.flowprogrammer.Flow fp_flow = ToSalConversionsUtils.toFlow(f);
+ flowlist.add(fp_flow);
}
- currentTask = executor.submit(new addGatewayTask(input));
- return currentTask;
+ return flowlist;
}
-
+
+ /**
+ * addchain synchronous.
+ */
@Override
- public Future<RpcResult<Void>> list() {
- log.info("List command received");
- RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Collections.<RpcError> emptySet());
- return Futures.immediateFuture(result);
- }
-
- private Future<RpcResult<Void>> inProgressError() {
- RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Collections.<RpcError> emptySet());
- return Futures.immediateFuture(result);
- }
-
- private void cancel() {
- currentTask.cancel(true);
- }
-
- public void setNotificationProvider(NotificationProviderService salService) {
- this.notificationProvider = salService;
- }
+ public Future<RpcResult<Void>> addchain(AddchainInput input) {
+ // TODO Auto-generated method stub
+ Chain chain = input.getChain();
- public void setFlowProgrammerService(IFlowProgrammerService s)
- {
- this.programmer = s;
- }
+ List<org.opendaylight.controller.sal.flowprogrammer.Flow> flowlist = fromAPIFlowlist(chain.getFlow());
+ List<Gateway> gatewaylist = chain.getGateway();
+ String name = chain.getName();
- public void unsetFlowProgrammerService(IFlowProgrammerService s) {
- if (this.programmer == s) {
- this.programmer = null;
- }
- }
+ if (gatewaylist.size() > 1) {
+ log.info("addNfchain function chain has {} elements", gatewaylist.size());
+ } else {
- void setSwitchManager(ISwitchManager s)
- {
- this.switchManager = s;
- }
-
- void unsetSwitchManager(ISwitchManager s) {
- if (this.switchManager == s) {
- this.switchManager = null;
+ log.info("add gateway - Received input chain = {}, gateway = {}.", input.getChain(), chain.getGateway());
+ Gateway gw = gatewaylist.get(0);
+ InetAddress ip = ToSalConversionsUtils.inetAddressFrom(gw.getLocation());
+ NFchainconfig nfcc = new NFchainconfig(name, flowlist, ip);
+ /* nfchainagent.addNfchain(); */
}
+ RpcResult<Void> result = Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ return Futures.immediateFuture(result);
}
+ @Override
+ public Future<RpcResult<java.lang.Void>> enablechain(EnablechainInput input) {
+ log.info("enable chain");
- /* Include this once dependencies are correctly established in osgi.
- /**
- * Fetch all node connectors. Each switch port will receive a flow
- * rule. Do not stop on error. Pass in the waypointMAC address so
- * that the correct output port can be determined.
- */
- public Status pushFlowRule(InetAddress from, InetAddress to, byte [] waypointMAC) {
- /* Get all node connectors. */
- Set<Node> nodes = switchManager.getNodes();
- Status success = new Status(StatusCode.SUCCESS);
- Status notfound = new Status(StatusCode.NOTFOUND);
-
- if (nodes == null) {
- log.debug("No nodes in network.");
- return success;
- }
-
- /* Send this flow rule to all nodes in the network. */
- for (Node node: nodes) {
- List<Action> actions = new ArrayList<Action>();
- Match match = new Match();
- match.setField(new MatchField(MatchType.NW_SRC, from, null));
- match.setField(new MatchField(MatchType.NW_DST, to, null));
- match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue());
-
- Flow f = new Flow(match, actions);
- f.setMatch(match);
- f.setPriority(REDIRECT_IPSWITCH_PRIORITY);
-
- /* Look up the output port leading to the waypoint. */
- NodeConnector dst_connector = l2agent.lookup_output_port(node, waypointMAC);
-
- log.debug("Waypoint direction: node {} and connector {}", node, dst_connector);
- if (dst_connector != null) {
- f.setActions(actions);
- f.addAction(new Output(dst_connector));
- log.debug("flow push flow = {} to node = {} ", f, node);
- /* Status status = installRedirectionFlow(node, flow);*/
- Status status = programmer.addFlow(node, f);
- if (!status.isSuccess()) {
- log.debug("Error during addFlow: {} on {}. The failure is: {}",
- f, node, status.getDescription());
- }
- }
- }
- return success;
+ RpcResult<Void> result = Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ return Futures.immediateFuture(result);
}
- */
-
- private class addGatewayTask implements Callable<RpcResult<Void>> {
-
- final AddInput input;
- public addGatewayTask(AddInput input) {
- this.input = input;
- }
-
- @Override
- public RpcResult<Void> call() throws Exception {
- Thread.sleep(1000);
- log.info("add gateway returning");
- currentTask = null;
- return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
- }
+ public void setNotificationProvider(NotificationProviderService salService) {
+ this.notificationProvider = salService;
}
}
private IfIptoHost hostTracker = null;
private ISwitchManager switchManager = null;
- private HashMap<String, List<NFchainconfig>> allconfigs;
+ private HashMap<String, NFchainconfig> allconfigs;
void init() {
log.debug("INIT called!");
}
}
- public Status addNfchain(String key, List<NFchainconfig> nfclist) {
+ public Status addNfchain(String key, NFchainconfig nfcc) {
String name;
if (allconfigs == null) {
- allconfigs = new HashMap<String, List<NFchainconfig>>();
+ allconfigs = new HashMap<String, NFchainconfig>();
}
/* xxx compute changelist and push flow changes. */
if (allconfigs.containsKey(key)) {
return new Status(StatusCode.CONFLICT,
"NFchain with the specified name already configured.");
}
- List<NFchainconfig> oldcfg = allconfigs.get(key);
+ NFchainconfig oldcfg = allconfigs.get(key);
if (oldcfg == null) {
- if (allconfigs.put(key, nfclist) == null) {
+ if (allconfigs.put(key, nfcc) == null) {
return new Status(StatusCode.SUCCESS);
}
}
public Status enable(String cfgname) throws Exception {
/* Get all node connectors. */
Set<Node> nodes = switchManager.getNodes();
- NFchainconfig cfg = allconfigs.get(cfgname).get(0);
+ NFchainconfig cfg = allconfigs.get(cfgname);
Status success = new Status(StatusCode.SUCCESS);
Status notfound = new Status(StatusCode.NOTFOUND);
public Status disable(String cfgname) throws Exception {
/* Get all node connectors. */
Set<Node> nodes = switchManager.getNodes();
- NFchainconfig cfg = allconfigs.get(cfgname).get(0);
+ NFchainconfig cfg = allconfigs.get(cfgname);
Status success = new Status(StatusCode.SUCCESS);
Status notfound = new Status(StatusCode.NOTFOUND);