Adding EVPN App code

Change-Id: Id3b2192f56f054cadcd8384092245b8757a781a9
This commit is contained in:
Mohammad Shahid 2017-08-09 18:02:10 +05:30 committed by Jonathan Hart
parent 0f26ac8fa2
commit 4c30ea3979
50 changed files with 5194 additions and 2 deletions

27
apps/evpnopenflow/BUCK Executable file
View File

@ -0,0 +1,27 @@
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:org.apache.karaf.shell.console',
'//cli:onos-cli',
'//incubator/api:onos-incubator-api',
'//core/store/serializers:onos-core-serializers',
'//apps/gluon:onos-apps-gluon',
'//apps/vtn/vtnrsc:onos-apps-vtn-vtnrsc',
]
TEST_DEPS = [
'//lib:TEST_ADAPTERS',
'//lib:TEST',
]
osgi_jar_with_tests(
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
)
onos_app(
title = 'Evpn-openflow App',
category = 'Traffic Steering',
url = 'http://onosproject.org',
description = 'Ethernet VPN (EVPN) introduces a new model for Ethernet services delivery.' +
'It enables integrated Layer 2 service over Ethernet with multihoming.',
)

109
apps/evpnopenflow/pom.xml Executable file
View File

@ -0,0 +1,109 @@
<?xml version="1.0"?>
<!--
~ Copyright 2017-present Open Networking Laboratory
~
~ 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
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.11.0-SNAPSHOT</version>
</parent>
<artifactId>onos-app-evpnopenflow</artifactId>
<packaging>bundle</packaging>
<description>ONOS EVPN application</description>
<properties>
<onos.app.name>org.onosproject.evpnopenflow</onos.app.name>
<onos.app.title>ONOS EVPN openflow App</onos.app.title>
<onos.app.category>Traffic steering</onos.app.category>
<onos.app.url>http://onosproject.org</onos.app.url>
<onos.app.readme>ONOS EVPN openflow application.</onos.app.readme>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-osgi</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-serializers</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-osgi</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-gluon</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-vtn-rsc</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,76 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.manager;
import org.onosproject.evpnopenflow.rsc.VpnPort;
import org.onosproject.incubator.net.routing.EvpnRoute;
import org.onosproject.net.Host;
/**
* Service for interacting with the route and host events.
*/
public interface EvpnService {
/**
* Transfer remote route to private route and set mpls flows out when
* BgpRoute update.
*
* @param route evpn route
*/
void onBgpEvpnRouteUpdate(EvpnRoute route);
/**
* Transfer remote route to private route and delete mpls flows out when
* BgpRoute delete.
*
* @param route evpn route
*/
void onBgpEvpnRouteDelete(EvpnRoute route);
/**
* Get VPN info from EVPN app store and create route, set flows when host
* detected.
*
* @param host host information
*/
void onHostDetected(Host host);
/**
* Get VPN info from EVPN app store and delete route, set flows when
* host
* vanished.
*
* @param host host information
*/
void onHostVanished(Host host);
/**
* Get VPN info from EVPN app store and create route, set flows when
* host
* detected.
*
* @param vpnPort vpnPort information
*/
void onVpnPortSet(VpnPort vpnPort);
/**
* Get VPN info from EVPN app store and delete route, set flows when host
* vanished.
*
* @param vpnPort vpnPort information
*/
void onVpnPortDelete(VpnPort vpnPort);
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EVPN application that process configuration and host, vpn-port, route
* events.
*/
package org.onosproject.evpnopenflow.manager.impl;

View File

@ -0,0 +1,21 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EVPN application that process configuration and host, vpn-port, route
* events.
*/
package org.onosproject.evpnopenflow.manager;

View File

@ -0,0 +1,163 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import java.util.Collection;
import java.util.Set;
/**
* Representation of a Base port.
*/
public interface BasePort {
/**
* Coarse classification of the type of the virtual port.
*/
enum State {
/**
* Signifies that a basePort is currently active,This state mean that
* this basePort is available.
*/
ACTIVE,
/**
* Signifies that a basePort is currently unavailable.
*/
DOWN;
}
/**
* Returns the basePort identifier.
*
* @return basePort identifier
*/
BasePortId portId();
/**
* Returns the network identifier.
*
* @return tenantNetwork identifier
*/
TenantNetworkId networkId();
/**
* Returns the symbolic name for the basePort.
*
* @return basePort name
*/
String name();
/**
* Returns the administrative status of the port,which is up(true) or
* down(false).
*
* @return true if the administrative status of the port is up
*/
boolean adminStateUp();
/**
* Returns the state.
*
* @return state
*/
String state();
/**
* Returns the MAC address.
*
* @return MAC Address
*/
MacAddress macAddress();
/**
* Returns the port tenantId.
*
* @return port tenantId
*/
TenantId tenantId();
/**
* Returns the device identifier.
*
* @return deviceId
*/
DeviceId deviceId();
/**
* Returns the identifier of the entity that uses this port.
*
* @return deviceOwner
*/
String deviceOwner();
/**
* Returns the basePort allowedAddressPairs.
*
* @return basePort allowedAddressPairs
*/
Collection<AllowedAddressPair> allowedAddressPairs();
/**
* Returns set of IP addresses for the port, include the IP addresses and subnet
* identity.
*
* @return FixedIps Set of fixedIp
*/
Set<FixedIp> fixedIps();
/**
* Returns the basePort bindinghostId.
*
* @return basePort bindinghostId
*/
BindingHostId bindingHostId();
/**
* Returns the basePort bindingVnicType.
*
* @return basePort bindingVnicType
*/
String bindingVnicType();
/**
* Returns the basePort bindingVifType.
*
* @return basePort bindingVifType
*/
String bindingVifType();
/**
* Returns the basePort bindingvifDetail.
*
* @return basePort bindingvifDetail
*/
String bindingVifDetails();
/**
* Returns the security groups.
*
* @return port security groups
*/
Iterable<SecurityGroup> securityGroups();
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onlab.util.Identifier;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Immutable representation of a base port identifier.
*/
public final class BasePortId extends Identifier<String> {
// Public construction is prohibited
private BasePortId(String basePortId) {
super(checkNotNull(basePortId, "BasePortId cannot be null"));
}
public String portId() {
return identifier;
}
/**
* Creates a virtualPort id using the supplied portId.
*
* @param portId baseport identifier
* @return BasePortId
*/
public static BasePortId portId(String portId) {
return new BasePortId(portId);
}
}

View File

@ -0,0 +1,236 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Default implementation of Base port.
*/
public final class DefaultBasePort implements BasePort {
private final BasePortId id;
private final TenantNetworkId networkId;
private final Boolean adminStateUp;
private final String name;
private final String state;
private final MacAddress macAddress;
private final TenantId tenantId;
private final String deviceOwner;
private final DeviceId deviceId;
private final Set<FixedIp> fixedIps;
private final BindingHostId bindingHostId;
private final String bindingVnicType;
private final String bindingVifType;
private final String bindingVifDetails;
private final Set<AllowedAddressPair> allowedAddressPairs;
private final Set<SecurityGroup> securityGroups;
/**
* Creates a BasePort object.
*
* @param id the base port identifier
* @param networkId the network identifier
* @param adminStateUp adminStateup true or false
* @param strMap the map of properties of base port
* @param state base port state
* @param macAddress the MAC address
* @param tenantId the tenant identifier
* @param deviceId the device identifier
* @param fixedIps set of fixed IP
* @param bindingHostId the binding host identifier
* @param allowedAddressPairs the collection of allowdeAddressPairs
* @param securityGroups the collection of securityGroups
*/
public DefaultBasePort(BasePortId id,
TenantNetworkId networkId,
Boolean adminStateUp,
Map<String, String> strMap,
String state,
MacAddress macAddress,
TenantId tenantId,
DeviceId deviceId,
Set<FixedIp> fixedIps,
BindingHostId bindingHostId,
Set<AllowedAddressPair> allowedAddressPairs,
Set<SecurityGroup> securityGroups) {
this.id = id;
this.networkId = networkId;
this.adminStateUp = adminStateUp;
this.name = strMap.get("name");
this.state = state;
this.macAddress = macAddress;
this.tenantId = tenantId;
this.deviceOwner = strMap.get("deviceOwner");
this.deviceId = deviceId;
this.fixedIps = fixedIps;
this.bindingHostId = bindingHostId;
this.bindingVnicType = strMap.get("bindingVnicType");
this.bindingVifType = strMap.get("bindingVifType");
this.bindingVifDetails = strMap.get("bindingVifDetails");
this.allowedAddressPairs = allowedAddressPairs;
this.securityGroups = securityGroups;
}
@Override
public BasePortId portId() {
return id;
}
@Override
public TenantNetworkId networkId() {
return networkId;
}
@Override
public String name() {
return name;
}
@Override
public boolean adminStateUp() {
return adminStateUp;
}
@Override
public String state() {
return state;
}
@Override
public MacAddress macAddress() {
return macAddress;
}
@Override
public TenantId tenantId() {
return tenantId;
}
@Override
public DeviceId deviceId() {
return deviceId;
}
@Override
public String deviceOwner() {
return deviceOwner;
}
@Override
public Collection<AllowedAddressPair> allowedAddressPairs() {
return allowedAddressPairs;
}
@Override
public Set<FixedIp> fixedIps() {
return fixedIps;
}
@Override
public BindingHostId bindingHostId() {
return bindingHostId;
}
@Override
public String bindingVnicType() {
return bindingVifType;
}
@Override
public String bindingVifType() {
return bindingVifType;
}
@Override
public String bindingVifDetails() {
return bindingVifDetails;
}
@Override
public Collection<SecurityGroup> securityGroups() {
return securityGroups;
}
@Override
public int hashCode() {
return Objects.hash(id, networkId, adminStateUp, name, state,
macAddress, tenantId, deviceId, deviceOwner,
allowedAddressPairs, fixedIps, bindingHostId,
bindingVnicType, bindingVifType, bindingVifDetails,
securityGroups);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DefaultBasePort) {
final DefaultBasePort that = (DefaultBasePort) obj;
return Objects.equals(this.id, that.id)
&& Objects.equals(this.networkId, that.networkId)
&& Objects.equals(this.adminStateUp, that.adminStateUp)
&& Objects.equals(this.state, that.state)
&& Objects.equals(this.name, that.name)
&& Objects.equals(this.tenantId, that.tenantId)
&& Objects.equals(this.macAddress, that.macAddress)
&& Objects.equals(this.deviceId, that.deviceId)
&& Objects.equals(this.deviceOwner, that.deviceOwner)
&& Objects.equals(this.allowedAddressPairs,
that.allowedAddressPairs)
&& Objects.equals(this.fixedIps, that.fixedIps)
&& Objects.equals(this.bindingHostId, that.bindingHostId)
&& Objects.equals(this.bindingVifDetails,
that.bindingVifDetails)
&& Objects.equals(this.bindingVifType, that.bindingVifType)
&& Objects.equals(this.bindingVnicType,
that.bindingVnicType)
&& Objects.equals(this.securityGroups, that.securityGroups);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add("id", id).add("network_id", networkId)
.add("adminStateUp", adminStateUp).add("state", state)
.add("name", name).add("state", state)
.add("macAddress", macAddress).add("tenantId", tenantId)
.add("deviced", deviceId).add("deviceOwner", deviceOwner)
.add("allowedAddressPairs", allowedAddressPairs)
.add("fixedIp", fixedIps).add("bindingHostId", bindingHostId)
.add("bindingVnicType", bindingVnicType)
.add("bindingVifDetails", bindingVifDetails)
.add("bindingVifType", bindingVifType)
.add("securityGroups", securityGroups).toString();
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RT_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RT_TYPE_CANNOT_BE_NULL;
/**
* Default implementation of VPN AF configuration.
*/
public class DefaultVpnAfConfig implements VpnAfConfig {
private final String exportRoutePolicy;
private final String importRoutePolicy;
private final VpnRouteTarget routeTarget;
private final String routeTargetType;
/**
* creates vpn af configuration object.
*
* @param exportRoutePolicy export route policy
* @param importRoutePolicy import route policy
* @param routeTarget route target value
* @param routeTargetType route target type
*/
public DefaultVpnAfConfig(String exportRoutePolicy,
String importRoutePolicy,
VpnRouteTarget routeTarget,
String routeTargetType) {
this.exportRoutePolicy = checkNotNull(exportRoutePolicy,
ID_CANNOT_BE_NULL);
this.importRoutePolicy = checkNotNull(importRoutePolicy,
ID_CANNOT_BE_NULL);
this.routeTarget = checkNotNull(routeTarget, RT_CANNOT_BE_NULL);
this.routeTargetType = checkNotNull(routeTargetType,
RT_TYPE_CANNOT_BE_NULL);
}
@Override
public String exportRoutePolicy() {
return exportRoutePolicy;
}
@Override
public String importRoutePolicy() {
return importRoutePolicy;
}
@Override
public VpnRouteTarget routeTarget() {
return routeTarget;
}
@Override
public String routeTargetType() {
return routeTargetType;
}
@Override
public String toString() {
return toStringHelper(this)
.add("exportRoutePolicy", exportRoutePolicy)
.add("importRoutePolicy", importRoutePolicy)
.add("routeTarget", routeTarget)
.add("routeTargetType", routeTargetType)
.toString();
}
}

View File

@ -0,0 +1,153 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onosproject.incubator.net.routing.EvpnInstanceName;
import org.onosproject.incubator.net.routing.RouteDistinguisher;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import java.util.Objects;
import java.util.Set;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CONFIG_RT_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_RT_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_RT_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INSTANCE_NAME_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RD_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_DISTINGUISHER;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPNINSTANCE_NAME;
/**
* Default implementation of VPN instance.
*/
public class DefaultVpnInstance implements VpnInstance {
private final VpnInstanceId id;
private final String description;
private final EvpnInstanceName name;
private final RouteDistinguisher routeDistinguisher;
private final Set<VpnRouteTarget> exportRtSet;
private final Set<VpnRouteTarget> importRtSet;
private final Set<VpnRouteTarget> configRtSet;
/**
* creates vpn instance object.
*
* @param id vpn instance identifier
* @param instanceName the name of vpn instance
* @param description the description of vpn instance
* @param routeDistinguisher the routeDistinguisher of vpn instance
* @param exportRtSet the export route target information
* @param importRtSet the import route target information
* @param configRtSet the config route target information
*/
public DefaultVpnInstance(VpnInstanceId id, EvpnInstanceName instanceName,
String description,
RouteDistinguisher routeDistinguisher,
Set<VpnRouteTarget> exportRtSet,
Set<VpnRouteTarget> importRtSet,
Set<VpnRouteTarget> configRtSet) {
this.id = checkNotNull(id, ID_CANNOT_BE_NULL);
this.name = checkNotNull(instanceName, INSTANCE_NAME_CANNOT_BE_NULL);
this.description = checkNotNull(description,
DESCRIPTION_CANNOT_BE_NULL);
this.routeDistinguisher = checkNotNull(routeDistinguisher,
RD_CANNOT_BE_NULL);
this.exportRtSet = checkNotNull(exportRtSet, EXPORT_RT_CANNOT_BE_NULL);
this.importRtSet = checkNotNull(importRtSet, IMPORT_RT_CANNOT_BE_NULL);
this.configRtSet = checkNotNull(configRtSet, CONFIG_RT_CANNOT_BE_NULL);
}
@Override
public VpnInstanceId id() {
return id;
}
@Override
public String description() {
return description;
}
@Override
public RouteDistinguisher routeDistinguisher() {
return routeDistinguisher;
}
@Override
public EvpnInstanceName vpnInstanceName() {
return name;
}
@Override
public Set<VpnRouteTarget> getExportRouteTargets() {
return exportRtSet;
}
@Override
public Set<VpnRouteTarget> getImportRouteTargets() {
return importRtSet;
}
@Override
public Set<VpnRouteTarget> getConfigRouteTargets() {
return configRtSet;
}
@Override
public int hashCode() {
return Objects.hash(id, name, description, routeDistinguisher,
exportRtSet, importRtSet, configRtSet);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DefaultVpnInstance) {
final DefaultVpnInstance that = (DefaultVpnInstance) obj;
return Objects.equals(this.id, that.id)
&& Objects.equals(this.name, that.name)
&& Objects.equals(this.description, that.description)
&& Objects.equals(this.routeDistinguisher,
that.routeDistinguisher)
&& Objects.equals(this.exportRtSet, that.exportRtSet)
&& Objects.equals(this.importRtSet, that.importRtSet)
&& Objects.equals(this.configRtSet, that.configRtSet);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add(ID, id)
.add(DESCRIPTION, description)
.add(VPNINSTANCE_NAME, name)
.add(ROUTE_DISTINGUISHER, routeDistinguisher)
.add("exportRtSet", exportRtSet)
.add("importRtSet", importRtSet)
.add("configRtSet", configRtSet)
.toString();
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_CANNOT_BE_NULL;
/**
* Default implementation of VPN port.
*/
public class DefaultVpnPort implements VpnPort {
private final VpnPortId id;
private final VpnInstanceId vpnInstanceId;
/**
* creates vpn port object.
*
* @param id vpn port id
* @param vpnInstanceId vpn instance id
*/
public DefaultVpnPort(VpnPortId id, VpnInstanceId vpnInstanceId) {
this.id = checkNotNull(id, ID_CANNOT_BE_NULL);
this.vpnInstanceId = checkNotNull(vpnInstanceId,
VPN_INSTANCE_ID_CANNOT_BE_NULL);
}
@Override
public VpnPortId id() {
return id;
}
@Override
public VpnInstanceId vpnInstanceId() {
return vpnInstanceId;
}
@Override
public int hashCode() {
return Objects.hash(id, vpnInstanceId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DefaultVpnPort) {
final DefaultVpnPort that = (DefaultVpnPort) obj;
return Objects.equals(this.id, that.id)
&& Objects.equals(this.vpnInstanceId, that.vpnInstanceId);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add(ID, id)
.add(VPN_INSTANCE_ID, vpnInstanceId).toString();
}
}

View File

@ -0,0 +1,186 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
/**
* Provides constants used in EVPN openflow application.
*/
public final class EvpnConstants {
private EvpnConstants() {
}
public static final String APP_ID = "org.onosproject.evpnopenflow";
public static final String EVPN_OPENFLOW_START = "evpn-openflow app is " +
"started";
public static final String EVPN_OPENFLOW_STOP = "evpn-openflow app is " +
"stopped";
public static final String EVPN_VPN_PORT_START = "EVPN port started";
public static final String EVPN_VPN_PORT_STOP = "EVPN port stopped";
public static final String EVPN_VPN_INSTANCE_START = "EVPN instance " +
"started";
public static final String EVPN_VPN_INSTANCE_STOP = "EVPN instance " +
"stopped";
public static final String HOST_DETECT = "Host detected {}";
public static final String HOST_VANISHED = "Host vanished {}";
public static final String IFACEID = "ifaceid";
public static final String IFACEID_OF_HOST_IS_NULL =
"The ifaceId of host is null";
public static final String CANT_FIND_VPN_PORT = "Can't find vpnport {}";
public static final String CANT_FIND_VPN_INSTANCE = "EVPN instance {} is " +
"not exist";
public static final String CANT_FIND_CONTROLLER_DEVICE = "Can't find " +
"controller of device: {}";
public static final String GET_PRIVATE_LABEL = "Get private label {}";
public static final String RELEASE_LABEL_FAILED = "Release resoure label " +
"{} failed";
public static final String VPN_PORT_UNBIND = "On EVPN port unbind";
public static final String VPN_PORT_BIND = "On EVPN port bind";
public static final String SLASH = "/";
public static final String COMMA = ",";
public static final String VPN_INSTANCE_TARGET = "VpnService";
public static final String VPN_PORT_TARGET = "VpnBinding";
public static final String BASEPORT = "Port";
public static final String VPN_AF_TARGET = "VpnAfConfig";
public static final String BGP_PEERING = "BGPPeering";
public static final String DATA_PLANE_TUNNEL = "DataplaneTunnel";
public static final String VPN_PORT_STORE = "evpn-port-store";
public static final String BASE_PORT_STORE = "evpn-baseport-store";
public static final String VPN_INSTANCE_STORE =
"evpn-instance-store";
public static final String VPN_PORT_ID_NOT_NULL = "EVPN port ID cannot be" +
" null";
public static final String VPN_PORT_NOT_NULL = "EVPN port cannot be null";
public static final String RESPONSE_NOT_NULL = "JsonNode can not be null";
public static final String LISTENER_NOT_NULL = "Listener cannot be null";
public static final String EVENT_NOT_NULL = "Event cannot be null";
public static final String DELETE = "delete";
public static final String SET = "set";
public static final String UPDATE = "update";
public static final String VPN_PORT_ID = "EVPN port ID is {} ";
public static final String VPN_PORT_CREATION_FAILED = "The EVPN port " +
"creation is failed whose identifier is {} ";
public static final String VPN_PORT_IS_NOT_EXIST = "The EVPN port is not " +
"exist whose identifier is {}";
public static final String VPN_PORT_UPDATE_FAILED = "The EVPN port update" +
" is failed whose identifier is {}";
public static final String VPN_PORT_DELETE_FAILED =
"The EVPN port delete is failed whose identifier is {}";
public static final String INTERFACE_ID = "interface_id";
public static final String ID = "id";
public static final String VPN_INSTANCE = "service_id";
public static final String VPN_INSTANCE_ID_NOT_NULL = "EVPN instance ID " +
"cannot be null";
public static final String VPN_INSTANCE_NOT_NULL = "EVPN instance cannot " +
"be null";
public static final String JSON_NOT_NULL = "JsonNode can not be null";
public static final String INSTANCE_ID = "EVPN instance ID is {} ";
public static final String VPN_INSTANCE_CREATION_FAILED = "The " +
"EVPN instance creation is failed whose identifier is {} ";
public static final String VPN_INSTANCE_IS_NOT_EXIST = "The EVPN instance" +
" is not exist whose identifier is {}";
public static final String VPN_INSTANCE_UPDATE_FAILED = "The EVPN " +
"instance update is failed whose identifier is {}";
public static final String VPN_INSTANCE_DELETE_FAILED = "The EVPN " +
"instance delete is failed whose identifier is {}";
public static final String VPN_INSTANCE_NAME = "name";
public static final String DESCRIPTION = "description";
public static final String ROUTE_DISTINGUISHERS = "route_distinguishers";
public static final String IPV4_FAMILY = "ipv4_family";
static final String ID_CANNOT_BE_NULL = "ID cannot be null";
static final String INSTANCE_NAME_CANNOT_BE_NULL = "Instance name cannot " +
"be null";
static final String DESCRIPTION_CANNOT_BE_NULL = "Description cannot be " +
"null";
static final String RD_CANNOT_BE_NULL = "RouteDistinguisher cannot be null";
static final String RT_CANNOT_BE_NULL = "RouteTarget cannot be null";
static final String VPNINSTANCE_NAME = "vpnInstanceName";
static final String ROUTE_DISTINGUISHER = "routeDistinguisher";
static final String VPN_INSTANCE_ID_CANNOT_BE_NULL = "EVPN instance ID " +
"cannot be null";
static final String VPN_INSTANCE_ID = "vpnInstanceId";
public static final String FORMAT_VPN_INSTANCE = "Id=%s, description=%s,"
+ " name=%s, routeDistinguisher=%s, routeTarget=%s";
public static final String FORMAT_VPN_PORT = " EVPN port id=%-32s, " +
"EVPN instance id=%-18s";
public static final String FORMAT_PRIVATE_ROUTE = " %-18s %-15s %-10s";
public static final String FORMAT_PUBLIC_ROUTE = " %-18s %-18s %-10s";
public static final String SWITCH_CHANNEL_ID = "channelId";
public static final String NOT_MASTER_FOR_SPECIFIC_DEVICE = "The local " +
"controller is not master for the specified deviceId";
public static final String VPN_AF_CONFIG_STORE =
"evpn-vpn-af-config-store";
public static final String EVPN_VPN_AF_CONFIG_START = "EVPN af config" +
" started";
public static final String EVPN_VPN_AF_CONFIG_STOP = "EVPN af config" +
" stopped";
static final String RT_TYPE_CANNOT_BE_NULL = "Route target type " +
"cannot be null";
public static final String VPN_AF_CONFIG_NOT_NULL = "EVPN af config be " +
"null";
public static final String ROUTE_TARGET_VALUE = "Route target value is {} ";
public static final String VPN_AF_CONFIG_CREATION_FAILED = "The " +
"EVPN af config creation is failed whose route target is {} ";
public static final String VPN_AF_CONFIG_UPDATE_FAILED = "The EVPN af " +
"config update is failed whose identifier is {}";
public static final String VPN_AF_CONFIG_IS_NOT_EXIST = "The EVPN AF " +
"config is not exist whose identifier is {}";
public static final String ROUTE_TARGET_CANNOT_NOT_NULL = "Route target " +
"value cannot be null";
public static final String ROUTE_TARGET_DELETE_FAILED = "The route target" +
" delete is failed whose route target value is {}";
static final String EXPORT_RT_CANNOT_BE_NULL = "export route " +
"target set cannot be null";
static final String IMPORT_RT_CANNOT_BE_NULL = "import route " +
"target set cannot be null";
static final String CONFIG_RT_CANNOT_BE_NULL = "import route " +
"target set cannot be null";
public static final String EXPORT_EXTCOMMUNITY = "export_extcommunity";
public static final String IMPORT_EXTCOMMUNITY = "import_extcommunity";
public static final String BOTH = "both";
public static final String INVALID_ROUTE_TARGET_TYPE
= "Invalid route target type has received";
public static final String INVALID_EVENT_RECEIVED
= "Invalid event is received while processing network " +
"configuration event";
public static final String NETWORK_CONFIG_EVENT_IS_RECEIVED
= "Event is received from network configuration {}";
public static final int ARP_PRIORITY = 0xffff;
public static final short ARP_RESPONSE = 0x2;
public static final String INVALID_TARGET_RECEIVED
= "Invalid target type has received";
public static final String INVALID_ACTION_VPN_AF_CONFIG
= "Invalid action is received while processing VPN af" +
" configuration";
public static final String EXPORT_ROUTE_POLICY = "export_route_policy";
public static final String IMPORT_ROUTE_POLICY = "import_route_policy";
public static final String VRF_RT_TYPE = "vrf_rt_type";
public static final String VRF_RT_VALUE = "vrf_rt_value";
public static final String BGP_EVPN_ROUTE_UPDATE_START
= "bgp evpn route update start {}";
public static final String MPLS_OUT_FLOWS = "mpls out flows --> {}";
public static final String BGP_EVPN_ROUTE_DELETE_START
= "bgp route delete start {}";
public static final String ROUTE_ADD_ARP_RULES = "Route ARP Rules-->ADD";
public static final String ROUTE_REMOVE_ARP_RULES
= "Route ARP Rules-->REMOVE";
public static final String TUNNEL_DST = "tunnelDst";
public static final String FAILED_TO_SET_TUNNEL_DST
= "Failed to get extension instruction to set tunnel dst {}";
public static final String VXLAN = "vxlan";
public static final String CANNOT_FIND_TUNNEL_PORT_DEVICE =
"Can't find tunnel port in device {}";
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
/**
* Representation of a VPN af configuration.
*/
public interface VpnAfConfig {
/**
* Returns the export route policy information.
*
* @return export route policy
*/
String exportRoutePolicy();
/**
* Returns the import route policy information.
*
* @return export route policy
*/
String importRoutePolicy();
/**
* Returns the route target value.
*
* @return route target value
*/
VpnRouteTarget routeTarget();
/**
* Returns the route target type.
*
* @return route target type
*/
String routeTargetType();
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onosproject.incubator.net.routing.EvpnInstanceName;
import org.onosproject.incubator.net.routing.RouteDistinguisher;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import java.util.Set;
/**
* Representation of a VPN instance.
*/
public interface VpnInstance {
/**
* Returns the VPN instance identifier.
*
* @return VPN instance identifier
*/
VpnInstanceId id();
/**
* Returns the VPN instance description.
*
* @return VPN instance description
*/
String description();
/**
* Returns the VPN instance route distinguishes.
*
* @return VPN instance route distinguishes
*/
RouteDistinguisher routeDistinguisher();
/**
* Returns the VPN instance name.
*
* @return VPN instance name
*/
EvpnInstanceName vpnInstanceName();
/**
* Returns the export route target information.
*
* @return export route target information
*/
Set<VpnRouteTarget> getExportRouteTargets();
/**
* Returns the import route target information.
*
* @return VPN instance ipv4 family
*/
Set<VpnRouteTarget> getImportRouteTargets();
/**
* Returns the config route target information.
*
* @return config route target information.
*/
Set<VpnRouteTarget> getConfigRouteTargets();
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onlab.util.Identifier;
/**
* Immutable representation of a VPN instance identity.
*/
public final class VpnInstanceId extends Identifier<String> {
// Public construction is prohibited
private VpnInstanceId(String vpnInstanceId) {
super(vpnInstanceId);
}
/**
* Creates a VPN instance identifier.
*
* @param vpnInstanceId VPN instance identify string
* @return VPN instance identifier
*/
public static VpnInstanceId vpnInstanceId(String vpnInstanceId) {
return new VpnInstanceId(vpnInstanceId);
}
/**
* Returns VPN instance identifier.
*
* @return the VPN instance identifier
*/
public String vpnInstanceId() {
return identifier;
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
/**
* Representation of a VPN port.
*/
public interface VpnPort {
/**
* Returns the VPN port identifier.
*
* @return VPN port identifier
*/
VpnPortId id();
/**
* Returns the VPN instance identifier.
*
* @return VPN instance identifier
*/
VpnInstanceId vpnInstanceId();
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc;
import org.onlab.util.Identifier;
/**
* Immutable representation of a VPN port identity.
*/
public final class VpnPortId extends Identifier<String> {
// Public construction is prohibited
private VpnPortId(String vpnPortId) {
super(vpnPortId);
}
/**
* Creates a VPN port identifier.
*
* @param vpnPortId VPN port identifier
* @return VPN port identifier
*/
public static VpnPortId vpnPortId(String vpnPortId) {
return new VpnPortId(vpnPortId);
}
/**
* Returns VPN port identifier.
*
* @return the VPN port identifier
*/
public String vpnPortId() {
return identifier;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.baseport;
import org.onosproject.event.AbstractEvent;
import org.onosproject.evpnopenflow.rsc.BasePort;
/**
* Describes base port event.
*/
public class BasePortEvent extends AbstractEvent<BasePortEvent.Type,
BasePort> {
/**
* Type of base port events.
*/
public enum Type {
/**
* Signifies that base port has been created.
*/
BASE_PORT_PUT,
/**
* Signifies that base port has been deleted.
*/
BASE_PORT_DELETE,
/**
* Signifies that base port has been updated.
*/
BASE_PORT_UPDATE
}
/**
* Creates an event of a given type and for the specified base port.
*
* @param type base port event type
* @param basePort base port subject
*/
public BasePortEvent(Type type, BasePort basePort) {
super(type, basePort);
}
/**
* Creates an event of a given type and for the specified base port.
*
* @param type base port event type
* @param basePort base port subject
* @param time occurrence time
*/
public BasePortEvent(Type type, BasePort basePort, long time) {
super(type, basePort, time);
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.baseport;
import org.onosproject.event.EventListener;
/**
* Entity capable of base port related events.
*/
public interface BasePortListener extends EventListener<BasePortEvent> {
}

View File

@ -0,0 +1,155 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.baseport;
import com.fasterxml.jackson.databind.JsonNode;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.evpnopenflow.rsc.BasePort;
import org.onosproject.evpnopenflow.rsc.BasePortId;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import java.util.Collection;
/**
* Service for interacting with the inventory of basePort.
*/
public interface BasePortService {
/**
* Returns if the basePort is existed.
*
* @param basePortId basePort identifier
* @return true or false if one with the given identifier is not existed.
*/
boolean exists(BasePortId basePortId);
/**
* Returns the basePort with the identifier.
*
* @param basePortId basePort ID
* @return BasePort or null if one with the given ID is not know.
*/
BasePort getPort(BasePortId basePortId);
/**
* Returns the basePort associated with the fixedIP.
*
* @param fixedIP the fixedIP identifier
* @return basePort.
*/
BasePort getPort(FixedIp fixedIP);
/**
* Returns the basePort associated with the mac address.
*
* @param mac the mac address
* @return basePort.
*/
BasePort getPort(MacAddress mac);
/**
* Returns the basePort associated with the networkId and ip.
*
* @param networkId the TenantNetworkId identifier
* @param ip the ip identifier
* @return basePort.
*/
BasePort getPort(TenantNetworkId networkId, IpAddress ip);
/**
* Returns the collection of the currently known basePort.
*
* @return collection of BasePort.
*/
Collection<BasePort> getPorts();
/**
* Returns the collection of the basePorts associated with the networkId.
*
* @param networkId the network identifer
* @return collection of basePort.
*/
Collection<BasePort> getPorts(TenantNetworkId networkId);
/**
* Returns the collection of the basePorts associated with the tenantId.
*
* @param tenantId the tenant identifier
* @return collection of basePorts.
*/
Collection<BasePort> getPorts(TenantId tenantId);
/**
* Returns the collection of the basePorts associated with the deviceId.
*
* @param deviceId the device identifier
* @return collection of basePort.
*/
Collection<BasePort> getPorts(DeviceId deviceId);
/**
* Creates basePorts by basePorts.
*
* @param basePorts the iterable collection of basePorts
* @return true if all given identifiers created successfully.
*/
boolean createPorts(Iterable<BasePort> basePorts);
/**
* Updates basePorts by basePorts.
*
* @param basePorts the iterable collection of basePorts
* @return true if all given identifiers updated successfully.
*/
boolean updatePorts(Iterable<BasePort> basePorts);
/**
* Deletes basePortIds by basePortIds.
*
* @param basePortIds the iterable collection of basePort identifiers
* @return true or false if one with the given identifier to delete is
* successfully.
*/
boolean removePorts(Iterable<BasePortId> basePortIds);
/**
* process gluon config for vpn port information.
*
* @param action can be either update or delete
* @param key can contain the id and also target information
* @param value content of the vpn port configuration
*/
void processGluonConfig(String action, String key, JsonNode value);
/**
* Adds the specified listener to Vpn Port manager.
*
* @param listener Vpn Port listener
*/
void addListener(BasePortListener listener);
/**
* Removes the specified listener to Vpn Port manager.
*
* @param listener Vpn Port listener
*/
void removeListener(BasePortListener listener);
}

View File

@ -0,0 +1,439 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.baseport.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.evpnopenflow.rsc.BasePort;
import org.onosproject.evpnopenflow.rsc.BasePortId;
import org.onosproject.evpnopenflow.rsc.DefaultBasePort;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortEvent;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortListener;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultFloatingIp;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.FloatingIp;
import org.onosproject.vtnrsc.FloatingIpId;
import org.onosproject.vtnrsc.RouterId;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.TenantRouter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASE_PORT_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
/**
* Provides implementation of the BasePort APIs.
*/
@Component(immediate = true)
@Service
public class BasePortManager implements BasePortService {
private final Set<BasePortListener> listeners = Sets
.newCopyOnWriteArraySet();
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String BASEPORT_ID_NULL = "BasePort ID cannot be " +
"null";
private static final String BASEPORT_NOT_NULL = "BasePort cannot be " +
"null";
private static final String TENANTID_NOT_NULL = "TenantId cannot be null";
private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null";
private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null";
private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null";
private static final String MAC_NOT_NULL = "Mac address cannot be null";
private static final String IP_NOT_NULL = "Ip cannot be null";
private static final String EVENT_NOT_NULL = "event cannot be null";
private static final String SET = "set";
private static final String UPDATE = "update";
private static final String DELETE = "delete";
private static final String SLASH = "/";
private static final String PROTON_BASE_PORT = "Port";
private static final String JSON_NOT_NULL = "JsonNode can not be null";
protected EventuallyConsistentMap<BasePortId, BasePort> vPortStore;
protected ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Activate
public void activate() {
appId = coreService.registerApplication(APP_ID);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
.register(MultiValuedTimestamp.class)
.register(TenantNetworkId.class)
.register(Host.class)
.register(TenantNetwork.class)
.register(TenantNetworkId.class)
.register(TenantId.class)
.register(SubnetId.class)
.register(BasePortId.class)
.register(BasePort.State.class)
.register(AllowedAddressPair.class)
.register(FixedIp.class)
.register(FloatingIp.class)
.register(FloatingIpId.class)
.register(FloatingIp.Status.class)
.register(UUID.class)
.register(DefaultFloatingIp.class)
.register(BindingHostId.class)
.register(SecurityGroup.class)
.register(IpAddress.class)
.register(DefaultBasePort.class)
.register(RouterId.class)
.register(TenantRouter.class)
.register(BasePort.class);
vPortStore = storageService
.<BasePortId, BasePort>eventuallyConsistentMapBuilder()
.withName(BASE_PORT_STORE).withSerializer(serializer)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
log.info("Started");
}
@Deactivate
public void deactivate() {
vPortStore.destroy();
log.info("Stoppped");
}
@Override
public boolean exists(BasePortId vPortId) {
checkNotNull(vPortId, BASEPORT_ID_NULL);
return vPortStore.containsKey(vPortId);
}
@Override
public BasePort getPort(BasePortId vPortId) {
checkNotNull(vPortId, BASEPORT_ID_NULL);
return vPortStore.get(vPortId);
}
@Override
public BasePort getPort(FixedIp fixedIP) {
checkNotNull(fixedIP, FIXEDIP_NOT_NULL);
List<BasePort> vPorts = new ArrayList<>();
vPortStore.values().forEach(p -> {
for (FixedIp fixedIp : p.fixedIps()) {
if (fixedIp.equals(fixedIP)) {
vPorts.add(p);
break;
}
}
});
if (vPorts.size() == 0) {
return null;
}
return vPorts.get(0);
}
@Override
public BasePort getPort(MacAddress mac) {
checkNotNull(mac, MAC_NOT_NULL);
List<BasePort> vPorts = new ArrayList<>();
vPortStore.values().forEach(p -> {
if (p.macAddress().equals(mac)) {
vPorts.add(p);
}
});
if (vPorts.size() == 0) {
return null;
}
return vPorts.get(0);
}
@Override
public BasePort getPort(TenantNetworkId networkId, IpAddress ip) {
checkNotNull(networkId, NETWORKID_NOT_NULL);
checkNotNull(ip, IP_NOT_NULL);
List<BasePort> vPorts = new ArrayList<>();
vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
.forEach(p -> {
for (FixedIp fixedIp : p.fixedIps()) {
if (fixedIp.ip().equals(ip)) {
vPorts.add(p);
break;
}
}
});
if (vPorts.size() == 0) {
return null;
}
return vPorts.get(0);
}
@Override
public Collection<BasePort> getPorts() {
return Collections.unmodifiableCollection(vPortStore.values());
}
@Override
public Collection<BasePort> getPorts(TenantNetworkId networkId) {
checkNotNull(networkId, NETWORKID_NOT_NULL);
return vPortStore.values().stream().filter(d -> d.networkId().equals(networkId))
.collect(Collectors.toList());
}
@Override
public Collection<BasePort> getPorts(TenantId tenantId) {
checkNotNull(tenantId, TENANTID_NOT_NULL);
return vPortStore.values().stream().filter(d -> d.tenantId().equals(tenantId))
.collect(Collectors.toList());
}
@Override
public Collection<BasePort> getPorts(DeviceId deviceId) {
checkNotNull(deviceId, DEVICEID_NOT_NULL);
return vPortStore.values().stream().filter(d -> d.deviceId().equals(deviceId))
.collect(Collectors.toList());
}
@Override
public boolean createPorts(Iterable<BasePort> vPorts) {
checkNotNull(vPorts, BASEPORT_NOT_NULL);
for (BasePort vPort : vPorts) {
log.info("vPortId is {} ", vPort.portId().toString());
vPortStore.put(vPort.portId(), vPort);
if (!vPortStore.containsKey(vPort.portId())) {
log.info("The basePort is created failed whose identifier is" +
" {} ",
vPort.portId().toString());
return false;
}
}
return true;
}
@Override
public boolean updatePorts(Iterable<BasePort> vPorts) {
checkNotNull(vPorts, BASEPORT_NOT_NULL);
for (BasePort vPort : vPorts) {
vPortStore.put(vPort.portId(), vPort);
if (!vPortStore.containsKey(vPort.portId())) {
log.info("The basePort is not exist whose identifier is {}",
vPort.portId().toString());
return false;
}
vPortStore.put(vPort.portId(), vPort);
if (!vPort.equals(vPortStore.get(vPort.portId()))) {
log.info("The basePort is updated failed whose identifier " +
"is {}",
vPort.portId().toString());
return false;
}
}
return true;
}
@Override
public boolean removePorts(Iterable<BasePortId> vPortIds) {
checkNotNull(vPortIds, BASEPORT_ID_NULL);
for (BasePortId vPortId : vPortIds) {
vPortStore.remove(vPortId);
if (vPortStore.containsKey(vPortId)) {
log.info("The basePort is removed failed whose identifier is" +
" {}",
vPortId.toString());
return false;
}
}
return true;
}
/**
* Returns a collection of basePorts from subnetNodes.
*
* @param vPortNodes the basePort json node
* @return BasePort collection of vpn ports
*/
private Collection<BasePort> changeJsonToSub(JsonNode vPortNodes) {
checkNotNull(vPortNodes, JSON_NOT_NULL);
Set<FixedIp> fixedIps = null;
TenantNetworkId tenantNetworkId = null;
Map<BasePortId, BasePort> vportMap = new HashMap<>();
Map<String, String> strMap = new HashMap<>();
BasePortId basePortId = BasePortId.portId(vPortNodes.get("id").asText());
String name = vPortNodes.get("name").asText();
TenantId tenantId = TenantId
.tenantId(vPortNodes.get("tenant_id").asText());
Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
String state = vPortNodes.get("status").asText();
MacAddress macAddress = MacAddress
.valueOf(vPortNodes.get("mac_address").asText());
DeviceId deviceId = DeviceId
.deviceId(vPortNodes.get("device_id").asText());
String deviceOwner = vPortNodes.get("device_owner").asText();
BindingHostId bindingHostId = BindingHostId
.bindingHostId(vPortNodes.get("host_id").asText());
String bindingVnicType = vPortNodes.get("vnic_type").asText();
String bindingVifType = vPortNodes.get("vif_type").asText();
String bindingVifDetails = vPortNodes.get("vif_details").asText();
strMap.put("name", name);
strMap.put("deviceOwner", deviceOwner);
strMap.put("bindingVnicType", bindingVnicType);
strMap.put("bindingVifType", bindingVifType);
strMap.put("bindingVifDetails", bindingVifDetails);
BasePort prevBasePort = getPort(basePortId);
if (prevBasePort != null) {
fixedIps = prevBasePort.fixedIps();
tenantNetworkId = prevBasePort.networkId();
}
BasePort vPort = new DefaultBasePort(basePortId,
tenantNetworkId,
adminStateUp,
strMap, state,
macAddress, tenantId,
deviceId, fixedIps,
bindingHostId,
null,
null);
vportMap.put(basePortId, vPort);
return Collections.unmodifiableCollection(vportMap.values());
}
/**
* Returns BasePort State.
*
* @param state the base port state
* @return the basePort state
*/
private BasePort.State isState(String state) {
if (state.equals("ACTIVE")) {
return BasePort.State.ACTIVE;
} else {
return BasePort.State.DOWN;
}
}
/**
* process Etcd response for port information.
*
* @param action can be either update or delete
* @param key can contain the id and also target information
* @param value content of the port configuration
*/
@Override
public void processGluonConfig(String action, String key, JsonNode value) {
Collection<BasePort> basePorts;
switch (action) {
case DELETE:
String[] list = key.split(SLASH);
BasePortId basePortId
= BasePortId.portId(list[list.length - 1]);
Set<BasePortId> basePortIds = Sets.newHashSet(basePortId);
removePorts(basePortIds);
break;
case SET:
checkNotNull(value, RESPONSE_NOT_NULL);
basePorts = changeJsonToSub(value);
createPorts(basePorts);
break;
case UPDATE:
checkNotNull(value, RESPONSE_NOT_NULL);
basePorts = changeJsonToSub(value);
updatePorts(basePorts);
break;
default:
log.info("Invalid action is received while processing VPN " +
"port configuration");
}
}
private void parseEtcdResponse(JsonNode jsonNode,
String key,
String action) {
JsonNode modifyValue = null;
if (action.equals(SET)) {
modifyValue = jsonNode.get(key);
}
String[] list = key.split(SLASH);
String target = list[list.length - 2];
if (target.equals(PROTON_BASE_PORT)) {
processGluonConfig(action, key, modifyValue);
}
}
@Override
public void addListener(BasePortListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.add(listener);
}
@Override
public void removeListener(BasePortListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.remove(listener);
}
/**
* Notifies specify event to all listeners.
*
* @param event vpn af config event
*/
private void notifyListeners(BasePortEvent event) {
checkNotNull(event, EVENT_NOT_NULL);
listeners.forEach(listener -> listener.event(event));
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by l3vpn.
*/
package org.onosproject.evpnopenflow.rsc.baseport.impl;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by l3vpn.
*/
package org.onosproject.evpnopenflow.rsc.baseport;

View File

@ -0,0 +1,53 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.evpnopenflow.manager.EvpnService;
import org.onosproject.evpnopenflow.manager.impl.EvpnManager;
import org.onosproject.incubator.net.routing.EvpnInstanceRoute;
import java.util.Collection;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_PRIVATE_ROUTE;
/**
* Support for displaying EVPN private routes.
*/
@Command(scope = "onos", name = "evpn-private-routes", description = "Lists" +
" all EVPN private routes")
public class EvpnPrivateRouteListCommand extends AbstractShellCommand {
private static final String FORMAT_HEADER =
" VPN name Prefix Next Hop";
@Override
protected void execute() {
EvpnService service = AbstractShellCommand.get(EvpnService.class);
EvpnManager evpnManager = (EvpnManager) service;
Collection<EvpnInstanceRoute> evpnRoutes = evpnManager.evpnInstanceRoutes;
if (evpnRoutes != null) {
print(FORMAT_HEADER);
evpnRoutes.forEach(evpnInstanceRoute -> {
print(FORMAT_PRIVATE_ROUTE, evpnInstanceRoute.evpnInstanceName(),
evpnInstanceRoute.prefix().address().getIp4Address(), evpnInstanceRoute
.getNextHopl());
});
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.routing.EvpnRoute;
import org.onosproject.incubator.net.routing.EvpnRouteSet;
import org.onosproject.incubator.net.routing.EvpnRouteStore;
import java.util.Collection;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_PUBLIC_ROUTE;
/**
* Support for displaying EVPN public routes.
*/
@Command(scope = "onos", name = "evpn-public-routes", description = "Lists" +
" all EVPN public routes")
public class EvpnPublicRouteListCommand extends AbstractShellCommand {
private static final String FORMAT_HEADER =
" MAC Prefix Next Hop";
@Override
protected void execute() {
EvpnRouteStore evpnRouteStore = AbstractShellCommand.get(EvpnRouteStore.class);
evpnRouteStore.getRouteTables().forEach(routeTableId -> {
Collection<EvpnRouteSet> routes
= evpnRouteStore.getRoutes(routeTableId);
if (routes != null) {
routes.forEach(route -> {
Collection<EvpnRoute> evpnRoutes = route.routes();
print(FORMAT_HEADER);
evpnRoutes.forEach(evpnRoute -> {
print(FORMAT_PUBLIC_ROUTE, evpnRoute.prefixMac(),
evpnRoute.prefixIp().address().getIp4Address(),
evpnRoute.ipNextHop());
});
});
}
});
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.evpnopenflow.rsc.EvpnConstants;
import org.onosproject.evpnopenflow.rsc.VpnInstance;
import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
import java.util.Collection;
/**
* Support for displaying EVPN VPN instances.
*/
@Command(scope = "onos", name = "evpn-instance-list", description = "Lists " +
"all EVPN instances")
public class VpnInstListCommand extends AbstractShellCommand {
@Override
protected void execute() {
VpnInstanceService service = get(VpnInstanceService.class);
Collection<VpnInstance> vpnInstances = service
.getInstances();
vpnInstances.forEach(vpnInstance -> {
print(EvpnConstants.FORMAT_VPN_INSTANCE, vpnInstance.id(),
vpnInstance.description(),
vpnInstance.vpnInstanceName(),
vpnInstance.routeDistinguisher(),
vpnInstance.getExportRouteTargets(),
vpnInstance.getImportRouteTargets());
});
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.evpnopenflow.rsc.VpnPort;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
import java.util.Collection;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_VPN_PORT;
/**
* Support for displaying EVPN VPN ports.
*/
@Command(scope = "onos", name = "evpn-port-list", description = "Lists all" +
"EVPN ports")
public class VpnPortListCommand extends AbstractShellCommand {
@Override
protected void execute() {
VpnPortService portService = get(VpnPortService.class);
Collection<VpnPort> ports = portService.getPorts();
ports.forEach(port -> {
print(FORMAT_VPN_PORT, port.id(), port.vpnInstanceId());
});
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Implementation CLI for EVPN services.
*/
package org.onosproject.evpnopenflow.rsc.cli;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EVPN resource package.
*/
package org.onosproject.evpnopenflow.rsc;

View File

@ -0,0 +1,65 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig;
import org.onosproject.event.AbstractEvent;
import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
/**
* Describes network VPN af config event.
*/
public class VpnAfConfigEvent extends AbstractEvent<VpnAfConfigEvent.Type, VpnAfConfig> {
/**
* Type of VPN port events.
*/
public enum Type {
/**
* Signifies that VPN af config has been set.
*/
VPN_AF_CONFIG_SET,
/**
* Signifies that VPN af config has been deleted.
*/
VPN_AF_CONFIG_DELETE,
/**
* Signifies that VPN af config has been updated.
*/
VPN_AF_CONFIG_UPDATE
}
/**
* Creates an event of a given type and for the specified VPN af config.
*
* @param type VPN af config type
* @param vpnAfConfig VPN af config subject
*/
public VpnAfConfigEvent(Type type, VpnAfConfig vpnAfConfig) {
super(type, vpnAfConfig);
}
/**
* Creates an event of a given type and for the specified VPN af config.
*
* @param type VPN af config type
* @param vpnAfConfig VPN af config subject
* @param time occurrence time
*/
public VpnAfConfigEvent(Type type, VpnAfConfig vpnAfConfig, long time) {
super(type, vpnAfConfig, time);
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig;
import org.onosproject.event.EventListener;
/**
* Entity capable of VPN af config related events.
*/
public interface VpnAfConfigListener extends EventListener<VpnAfConfigEvent> {
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig;
import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import java.util.Collection;
/**
* Service for interacting with the inventory of VPN af config instance.
*/
public interface VpnAfConfigService {
/**
* Returns if the route target is existed.
*
* @param routeTarget route target
* @return true or false if one with the given route target is not existed.
*/
boolean exists(VpnRouteTarget routeTarget);
/**
* Returns the VPN af config with the route target.
*
* @param routeTarget route target
* @return VPN af config or null if one with the given route target is not
* know.
*/
VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget);
/**
* Returns the collection of the currently known VPN af configurations.
*
* @return collection of VPN af configurations.
*/
Collection<VpnAfConfig> getVpnAfConfigs();
/**
* Creates VPN af configurations by vpnAfConfigs.
*
* @param vpnAfConfigs the iterable collection of vpnAfConfigs
* @return true if all given VPN af configs created successfully
*/
boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs);
/**
* Updates VPN af configurations by vpnAfConfigs.
*
* @param vpnAfConfigs the iterable collection of vpnAfConfigs
* @return true if all given VPN af configs created successfully.
*/
boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs);
/**
* Deletes vpnAfConfigs by route target.
*
* @param routeTarget the iterable collection of vpnAFConfigs
* @return true or false if one with the given route target to delete is
* successfully
*/
boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTarget);
/**
* process gluon config for vpn af configuration.
*
* @param action can be either update or delete
* @param key can contain the id and also target information
* @param value content of the route targets configuration
*/
void processGluonConfig(String action, String key, JsonNode value);
/**
* Adds the specified listener to Vpn Port manager.
*
* @param listener vpn af config listener
*/
void addListener(VpnAfConfigListener listener);
/**
* Removes the specified listener to vpn af config manager.
*
* @param listener vpn af config listener
*/
void removeListener(VpnAfConfigListener listener);
}

View File

@ -0,0 +1,268 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.CoreService;
import org.onosproject.evpnopenflow.rsc.DefaultVpnAfConfig;
import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_START;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_STOP;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_ROUTE_POLICY;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_ROUTE_POLICY;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ACTION_VPN_AF_CONFIG;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_CANNOT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_DELETE_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_VALUE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_CREATION_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_IS_NOT_EXIST;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_UPDATE_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_TYPE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_VALUE;
/**
* Provides implementation of the VPN af config APIs.
*/
@Component(immediate = true)
@Service
public class VpnAfConfigManager implements VpnAfConfigService {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Set<VpnAfConfigListener> listeners = Sets
.newCopyOnWriteArraySet();
protected EventuallyConsistentMap<VpnRouteTarget, VpnAfConfig>
vpnAfConfigStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Activate
public void activate() {
coreService.registerApplication(APP_ID);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API).register(VpnAfConfig.class)
.register(VpnRouteTarget.class);
vpnAfConfigStore = storageService
.<VpnRouteTarget, VpnAfConfig>eventuallyConsistentMapBuilder()
.withName(VPN_AF_CONFIG_STORE).withSerializer(serializer)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
log.info(EVPN_VPN_AF_CONFIG_START);
}
@Deactivate
public void deactivate() {
vpnAfConfigStore.destroy();
log.info(EVPN_VPN_AF_CONFIG_STOP);
}
@Override
public boolean exists(VpnRouteTarget routeTarget) {
checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
return vpnAfConfigStore.containsKey(routeTarget);
}
@Override
public VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget) {
checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
return vpnAfConfigStore.get(routeTarget);
}
@Override
public Collection<VpnAfConfig> getVpnAfConfigs() {
return Collections.unmodifiableCollection(vpnAfConfigStore.values());
}
@Override
public boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
log.info(ROUTE_TARGET_VALUE, vpnAfConfig
.routeTarget().getRouteTarget());
vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
log.info(VPN_AF_CONFIG_CREATION_FAILED,
vpnAfConfig.routeTarget().getRouteTarget());
return false;
}
notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
.Type
.VPN_AF_CONFIG_SET,
vpnAfConfig));
}
return true;
}
@Override
public boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
log.info(VPN_AF_CONFIG_IS_NOT_EXIST,
vpnAfConfig.routeTarget().getRouteTarget());
return false;
}
vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
if (!vpnAfConfig.equals(vpnAfConfigStore
.get(vpnAfConfig.routeTarget()))) {
log.info(VPN_AF_CONFIG_UPDATE_FAILED,
vpnAfConfig.routeTarget().getRouteTarget());
return false;
}
notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
.Type
.VPN_AF_CONFIG_UPDATE,
vpnAfConfig));
}
return true;
}
@Override
public boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTargets) {
checkNotNull(routeTargets, VPN_INSTANCE_ID_NOT_NULL);
for (VpnRouteTarget routeTarget : routeTargets) {
VpnAfConfig vpnAfConfig = vpnAfConfigStore.get(routeTarget);
vpnAfConfigStore.remove(routeTarget);
if (vpnAfConfigStore.containsKey(routeTarget)) {
log.info(ROUTE_TARGET_DELETE_FAILED,
routeTarget.getRouteTarget());
return false;
}
notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
.Type
.VPN_AF_CONFIG_DELETE,
vpnAfConfig));
}
return true;
}
@Override
public void processGluonConfig(String action, String key, JsonNode value) {
Collection<VpnAfConfig> vpnAfConfigs;
switch (action) {
case DELETE:
String[] list = key.split(SLASH);
VpnRouteTarget routeTarget = VpnRouteTarget
.routeTarget(list[list.length - 1]);
Set<VpnRouteTarget> routeTargets
= Sets.newHashSet(routeTarget);
removeVpnAfConfigs(routeTargets);
break;
case SET:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnAfConfigs = changeJsonToSub(value);
createVpnAfConfigs(vpnAfConfigs);
break;
case UPDATE:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnAfConfigs = changeJsonToSub(value);
updateVpnAfConfigs(vpnAfConfigs);
break;
default:
log.info(INVALID_ACTION_VPN_AF_CONFIG);
break;
}
}
/**
* Returns a collection of vpn af configuration.
*
* @param vpnAfConfigNode the vpn af configuration json node
* @return returns the collection of vpn af configuration
*/
private Collection<VpnAfConfig> changeJsonToSub(JsonNode vpnAfConfigNode) {
checkNotNull(vpnAfConfigNode, JSON_NOT_NULL);
Map<VpnRouteTarget, VpnAfConfig> vpnAfConfigMap = new HashMap<>();
String exportRoutePolicy
= vpnAfConfigNode.get(EXPORT_ROUTE_POLICY).asText();
String importRoutePolicy
= vpnAfConfigNode.get(IMPORT_ROUTE_POLICY).asText();
String routeTargetType = vpnAfConfigNode.get(VRF_RT_TYPE).asText();
VpnRouteTarget routeTarget = VpnRouteTarget
.routeTarget(vpnAfConfigNode.get(VRF_RT_VALUE).asText());
VpnAfConfig vpnAfConfig = new DefaultVpnAfConfig(exportRoutePolicy,
importRoutePolicy,
routeTarget,
routeTargetType);
vpnAfConfigMap.put(routeTarget, vpnAfConfig);
return Collections.unmodifiableCollection(vpnAfConfigMap.values());
}
@Override
public void addListener(VpnAfConfigListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.add(listener);
}
@Override
public void removeListener(VpnAfConfigListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.remove(listener);
}
/**
* Notifies specify event to all listeners.
*
* @param event vpn af config event
*/
private void notifyListeners(VpnAfConfigEvent event) {
checkNotNull(event, EVENT_NOT_NULL);
listeners.forEach(listener -> listener.event(event));
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN af configuration that used by l3vpn.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig.impl;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by Evpn.
*/
package org.onosproject.evpnopenflow.rsc.vpnafconfig;

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpninstance;
import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.evpnopenflow.rsc.VpnInstance;
import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import java.util.Collection;
import java.util.Set;
/**
* Service for interacting with the inventory of VPN instance.
*/
public interface VpnInstanceService {
/**
* Returns if the vpnInstance is existed.
*
* @param vpnInstanceId vpnInstance identifier
* @return true or false if one with the given identifier is not existed.
*/
boolean exists(VpnInstanceId vpnInstanceId);
/**
* Returns the vpnInstance with the identifier.
*
* @param vpnInstanceId vpnInstance ID
* @return VpnInstance or null if one with the given ID is not know.
*/
VpnInstance getInstance(VpnInstanceId vpnInstanceId);
/**
* Returns the collection of the currently known vpnInstance.
*
* @return collection of VpnInstance.
*/
Collection<VpnInstance> getInstances();
/**
* Creates vpnInstances by vpnInstances.
*
* @param vpnInstances the iterable collection of vpnInstances
* @return true if all given identifiers created successfully.
*/
boolean createInstances(Iterable<VpnInstance> vpnInstances);
/**
* Updates vpnInstances by vpnInstances.
*
* @param vpnInstances the iterable collection of vpnInstances
* @return true if all given identifiers updated successfully.
*/
boolean updateInstances(Iterable<VpnInstance> vpnInstances);
/**
* Deletes vpnInstanceIds by vpnInstanceIds.
*
* @param vpnInstanceIds the iterable collection of vpnInstance identifiers
* @return true or false if one with the given identifier to delete is
* successfully.
*/
boolean removeInstances(Iterable<VpnInstanceId> vpnInstanceIds);
/**
* process gluon config for vpn instance information.
*
* @param action can be either update or delete
* @param key can contain the id and also target information
* @param value content of the vpn instance configuration
*/
void processGluonConfig(String action, String key, JsonNode value);
/**
* process Etcd response for vpn instance information.
*
* @param routeTargetType route target type
* @param exportRouteTargets export route targets
* @param importRouteTargets import route targets
* @param vpnRouteTarget vpn route target
*/
void updateImpExpRouteTargets(String routeTargetType,
Set<VpnRouteTarget> exportRouteTargets,
Set<VpnRouteTarget> importRouteTargets,
VpnRouteTarget vpnRouteTarget);
}

View File

@ -0,0 +1,290 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpninstance.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.evpnopenflow.rsc.DefaultVpnInstance;
import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
import org.onosproject.evpnopenflow.rsc.VpnInstance;
import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
import org.onosproject.incubator.net.routing.EvpnInstanceName;
import org.onosproject.incubator.net.routing.RouteAdminService;
import org.onosproject.incubator.net.routing.RouteDistinguisher;
import org.onosproject.incubator.net.routing.VpnRouteTarget;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.COMMA;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_INSTANCE_START;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_INSTANCE_STOP;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INSTANCE_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IPV4_FAMILY;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_DISTINGUISHERS;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_CREATION_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_DELETE_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_IS_NOT_EXIST;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_NAME;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_UPDATE_FAILED;
/**
* Provides implementation of the VpnInstance APIs.
*/
@Component(immediate = true)
@Service
public class VpnInstanceManager implements VpnInstanceService {
private final Logger log = LoggerFactory.getLogger(getClass());
protected EventuallyConsistentMap<VpnInstanceId, VpnInstance> vpnInstanceStore;
protected ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RouteAdminService routeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VpnAfConfigService vpnAfConfigService;
@Activate
public void activate() {
appId = coreService.registerApplication(APP_ID);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API).register(VpnInstance.class)
.register(VpnInstanceId.class);
vpnInstanceStore = storageService
.<VpnInstanceId, VpnInstance>eventuallyConsistentMapBuilder()
.withName(VPN_INSTANCE_STORE).withSerializer(serializer)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
log.info(EVPN_VPN_INSTANCE_START);
}
@Deactivate
public void deactivate() {
vpnInstanceStore.destroy();
log.info(EVPN_VPN_INSTANCE_STOP);
}
@Override
public boolean exists(VpnInstanceId vpnInstanceId) {
checkNotNull(vpnInstanceId, VPN_INSTANCE_ID_NOT_NULL);
return vpnInstanceStore.containsKey(vpnInstanceId);
}
@Override
public VpnInstance getInstance(VpnInstanceId vpnInstanceId) {
checkNotNull(vpnInstanceId, VPN_INSTANCE_ID_NOT_NULL);
return vpnInstanceStore.get(vpnInstanceId);
}
@Override
public Collection<VpnInstance> getInstances() {
return Collections.unmodifiableCollection(vpnInstanceStore.values());
}
@Override
public boolean createInstances(Iterable<VpnInstance> vpnInstances) {
checkNotNull(vpnInstances, VPN_INSTANCE_NOT_NULL);
for (VpnInstance vpnInstance : vpnInstances) {
log.info(INSTANCE_ID, vpnInstance.id().toString());
vpnInstanceStore.put(vpnInstance.id(), vpnInstance);
if (!vpnInstanceStore.containsKey(vpnInstance.id())) {
log.info(VPN_INSTANCE_CREATION_FAILED,
vpnInstance.id().toString());
return false;
}
}
return true;
}
@Override
public boolean updateInstances(Iterable<VpnInstance> vpnInstances) {
checkNotNull(vpnInstances, VPN_INSTANCE_NOT_NULL);
for (VpnInstance vpnInstance : vpnInstances) {
if (!vpnInstanceStore.containsKey(vpnInstance.id())) {
log.info(VPN_INSTANCE_IS_NOT_EXIST,
vpnInstance.id().toString());
return false;
}
vpnInstanceStore.put(vpnInstance.id(), vpnInstance);
if (!vpnInstance.equals(vpnInstanceStore.get(vpnInstance.id()))) {
log.info(VPN_INSTANCE_UPDATE_FAILED,
vpnInstance.id().toString());
return false;
}
}
return true;
}
@Override
public boolean removeInstances(Iterable<VpnInstanceId> vpnInstanceIds) {
checkNotNull(vpnInstanceIds, VPN_INSTANCE_ID_NOT_NULL);
for (VpnInstanceId vpnInstanceId : vpnInstanceIds) {
vpnInstanceStore.remove(vpnInstanceId);
if (vpnInstanceStore.containsKey(vpnInstanceId)) {
log.info(VPN_INSTANCE_DELETE_FAILED, vpnInstanceId.toString());
return false;
}
}
return true;
}
@Override
public void processGluonConfig(String action, String key, JsonNode value) {
Collection<VpnInstance> vpnInstances;
switch (action) {
case DELETE:
String[] list = key.split(SLASH);
VpnInstanceId vpnInstanceId = VpnInstanceId
.vpnInstanceId(list[list.length - 1]);
Set<VpnInstanceId> vpnInstanceIds
= Sets.newHashSet(vpnInstanceId);
removeInstances(vpnInstanceIds);
break;
case SET:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnInstances = changeJsonToSub(value);
createInstances(vpnInstances);
break;
case UPDATE:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnInstances = changeJsonToSub(value);
updateInstances(vpnInstances);
break;
default:
log.info("Invalid action is received while processing VPN " +
"instance configuration");
}
}
@Override
public void updateImpExpRouteTargets(String routeTargetType,
Set<VpnRouteTarget> exportRouteTargets,
Set<VpnRouteTarget> importRouteTargets,
VpnRouteTarget vpnRouteTarget) {
switch (routeTargetType) {
case "export_extcommunity":
exportRouteTargets.add(vpnRouteTarget);
break;
case "import_extcommunity":
importRouteTargets.add(vpnRouteTarget);
break;
case "both":
exportRouteTargets.add(vpnRouteTarget);
importRouteTargets.add(vpnRouteTarget);
break;
default:
log.info("Invalid route target type has received");
break;
}
}
/**
* Returns a collection of vpnInstances from subnetNodes.
*
* @param vpnInstanceNodes the vpnInstance json node
* @return returns the collection of vpn instances
*/
private Collection<VpnInstance> changeJsonToSub(JsonNode vpnInstanceNodes) {
checkNotNull(vpnInstanceNodes, JSON_NOT_NULL);
Set<VpnRouteTarget> exportRouteTargets = new HashSet<>();
Set<VpnRouteTarget> importRouteTargets = new HashSet<>();
Set<VpnRouteTarget> configRouteTargets = new HashSet<>();
Map<VpnInstanceId, VpnInstance> vpnInstanceMap = new HashMap<>();
VpnInstanceId id = VpnInstanceId
.vpnInstanceId(vpnInstanceNodes.get(ID).asText());
EvpnInstanceName name = EvpnInstanceName
.evpnName(vpnInstanceNodes.get(VPN_INSTANCE_NAME).asText());
String description = vpnInstanceNodes.get(DESCRIPTION).asText();
RouteDistinguisher routeDistinguisher = RouteDistinguisher
.routeDistinguisher(vpnInstanceNodes.get(ROUTE_DISTINGUISHERS)
.asText());
String routeTargets = vpnInstanceNodes.get(IPV4_FAMILY).asText();
String[] list = routeTargets.split(COMMA);
for (String routeTarget : list) {
// Converting route target string into route target object and
// then storing into configuration route target set.
VpnRouteTarget vpnRouteTarget
= VpnRouteTarget.routeTarget(routeTarget);
configRouteTargets.add(vpnRouteTarget);
VpnAfConfig vpnAfConfig
= vpnAfConfigService.getVpnAfConfig(vpnRouteTarget);
if (vpnAfConfig == null) {
log.info("Not able to find vpn af config for the give vpn " +
"route target");
break;
}
updateImpExpRouteTargets(vpnAfConfig.routeTargetType(),
exportRouteTargets,
importRouteTargets,
vpnRouteTarget);
}
VpnInstance vpnInstance = new DefaultVpnInstance(id, name, description,
routeDistinguisher,
exportRouteTargets,
importRouteTargets,
configRouteTargets);
vpnInstanceMap.put(id, vpnInstance);
return Collections.unmodifiableCollection(vpnInstanceMap.values());
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by l3vpn.
*/
package org.onosproject.evpnopenflow.rsc.vpninstance.impl;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EVPN VPN instance implementation.
*/
package org.onosproject.evpnopenflow.rsc.vpninstance;

View File

@ -0,0 +1,65 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnport;
import org.onosproject.event.AbstractEvent;
import org.onosproject.evpnopenflow.rsc.VpnPort;
/**
* Describes network VPN port event.
*/
public class VpnPortEvent extends AbstractEvent<VpnPortEvent.Type, VpnPort> {
/**
* Type of VPN port events.
*/
public enum Type {
/**
* Signifies that VPN port has been set.
*/
VPN_PORT_SET,
/**
* Signifies that VPN port has been deleted.
*/
VPN_PORT_DELETE,
/**
* Signifies that VPN port has been updated.
*/
VPN_PORT_UPDATE
}
/**
* Creates an event of a given type and for the specified VPN port.
*
* @param type VPN port type
* @param vpnPort VPN port subject
*/
public VpnPortEvent(Type type, VpnPort vpnPort) {
super(type, vpnPort);
}
/**
* Creates an event of a given type and for the specified VPN port.
*
* @param type VPN port type
* @param vpnPort VPN port subject
* @param time occurrence time
*/
public VpnPortEvent(Type type, VpnPort vpnPort, long time) {
super(type, vpnPort, time);
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnport;
import org.onosproject.event.EventListener;
/**
* Entity capable of VPN port related events.
*/
public interface VpnPortListener extends EventListener<VpnPortEvent> {
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnport;
import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.evpnopenflow.rsc.VpnPort;
import org.onosproject.evpnopenflow.rsc.VpnPortId;
import java.util.Collection;
/**
* Service for interacting with the inventory of VPN port.
*/
public interface VpnPortService {
/**
* Returns if the vpnPort is existed.
*
* @param vpnPortId vpnPort identifier
* @return true or false if one with the given identifier is not existed.
*/
boolean exists(VpnPortId vpnPortId);
/**
* Returns the vpnPort with the identifier.
*
* @param vpnPortId vpnPort ID
* @return VpnPort or null if one with the given ID is not know.
*/
VpnPort getPort(VpnPortId vpnPortId);
/**
* Returns the collection of the currently known vpnPort.
*
* @return collection of VpnPort.
*/
Collection<VpnPort> getPorts();
/**
* Creates vpnPorts by vpnPorts.
*
* @param vpnPorts the iterable collection of vpnPorts
* @return true if all given identifiers created successfully.
*/
boolean createPorts(Iterable<VpnPort> vpnPorts);
/**
* Updates vpnPorts by vpnPorts.
*
* @param vpnPorts the iterable collection of vpnPorts
* @return true if all given identifiers updated successfully.
*/
boolean updatePorts(Iterable<VpnPort> vpnPorts);
/**
* Deletes vpnPortIds by vpnPortIds.
*
* @param vpnPortIds the iterable collection of vpnPort identifiers
* @return true or false if one with the given identifier to delete is
* successfully.
*/
boolean removePorts(Iterable<VpnPortId> vpnPortIds);
/**
* process gluon config for vpn port information.
*
* @param action can be either update or delete
* @param key can contain the id and also target information
* @param value content of the vpn port configuration
*/
void processGluonConfig(String action, String key, JsonNode value);
/**
* Adds the specified listener to Vpn Port manager.
*
* @param listener Vpn Port listener
*/
void addListener(VpnPortListener listener);
/**
* Removes the specified listener to Vpn Port manager.
*
* @param listener Vpn Port listener
*/
void removeListener(VpnPortListener listener);
}

View File

@ -0,0 +1,431 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.evpnopenflow.rsc.vpnport.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.evpnopenflow.rsc.BasePort;
import org.onosproject.evpnopenflow.rsc.BasePortId;
import org.onosproject.evpnopenflow.rsc.DefaultVpnPort;
import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
import org.onosproject.evpnopenflow.rsc.VpnPort;
import org.onosproject.evpnopenflow.rsc.VpnPortId;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
import org.onosproject.net.DeviceId;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.AllocationPool;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultSubnet;
import org.onosproject.vtnrsc.DefaultTenantNetwork;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.HostRoute;
import org.onosproject.vtnrsc.PhysicalNetwork;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.Subnet;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_START;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_STOP;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INTERFACE_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_CREATION_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_DELETE_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_IS_NOT_EXIST;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UPDATE_FAILED;
/**
* Provides implementation of the VpnPort service.
*/
@Component(immediate = true)
@Service
public class VpnPortManager implements VpnPortService {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Set<VpnPortListener> listeners = Sets
.newCopyOnWriteArraySet();
protected EventuallyConsistentMap<VpnPortId, VpnPort> vpnPortStore;
protected ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected BasePortService basePortService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VirtualPortService virtualPortService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TenantNetworkService tenantNetworkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected SubnetService subnetService;
@Activate
public void activate() {
appId = coreService.registerApplication(APP_ID);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API).register(VpnPort.class)
.register(VpnPortId.class);
vpnPortStore = storageService
.<VpnPortId, VpnPort>eventuallyConsistentMapBuilder()
.withName(VPN_PORT_STORE).withSerializer(serializer)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
log.info(EVPN_VPN_PORT_START);
}
@Deactivate
public void deactivate() {
vpnPortStore.destroy();
log.info(EVPN_VPN_PORT_STOP);
}
@Override
public boolean exists(VpnPortId vpnPortId) {
checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
return vpnPortStore.containsKey(vpnPortId);
}
@Override
public VpnPort getPort(VpnPortId vpnPortId) {
checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
return vpnPortStore.get(vpnPortId);
}
@Override
public Collection<VpnPort> getPorts() {
return Collections.unmodifiableCollection(vpnPortStore.values());
}
@Override
public boolean createPorts(Iterable<VpnPort> vpnPorts) {
checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
for (VpnPort vpnPort : vpnPorts) {
log.info(VPN_PORT_ID, vpnPort.id().toString());
vpnPortStore.put(vpnPort.id(), vpnPort);
if (!vpnPortStore.containsKey(vpnPort.id())) {
log.info(VPN_PORT_CREATION_FAILED, vpnPort.id().toString());
return false;
}
notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_SET,
vpnPort));
}
return true;
}
@Override
public boolean updatePorts(Iterable<VpnPort> vpnPorts) {
checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
for (VpnPort vpnPort : vpnPorts) {
if (!vpnPortStore.containsKey(vpnPort.id())) {
log.info(VPN_PORT_IS_NOT_EXIST, vpnPort.id().toString());
return false;
}
vpnPortStore.put(vpnPort.id(), vpnPort);
if (!vpnPort.equals(vpnPortStore.get(vpnPort.id()))) {
log.info(VPN_PORT_UPDATE_FAILED, vpnPort.id().toString());
return false;
}
notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_UPDATE,
vpnPort));
}
return true;
}
@Override
public boolean removePorts(Iterable<VpnPortId> vpnPortIds) {
checkNotNull(vpnPortIds, VPN_PORT_NOT_NULL);
for (VpnPortId vpnPortid : vpnPortIds) {
VpnPort vpnPort = vpnPortStore.get(vpnPortid);
vpnPortStore.remove(vpnPortid);
if (vpnPortStore.containsKey(vpnPortid)) {
log.info(VPN_PORT_DELETE_FAILED, vpnPortid.toString());
return false;
}
notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_DELETE,
vpnPort));
}
return true;
}
@Override
public void processGluonConfig(String action, String key, JsonNode value) {
Collection<VpnPort> vpnPorts;
switch (action) {
case DELETE:
String[] list = key.split(SLASH);
VpnPortId vpnPortId
= VpnPortId.vpnPortId(list[list.length - 1]);
Set<VpnPortId> vpnPortIds = Sets.newHashSet(vpnPortId);
removePorts(vpnPortIds);
// After removing vpn port and also remove virtual port from vtn
VirtualPortId virtualPortId
= VirtualPortId.portId(list[list.length - 1]);
Set<VirtualPortId> virtualPortIds
= Sets.newHashSet(virtualPortId);
virtualPortService.removePorts(virtualPortIds);
break;
case SET:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnPorts = changeJsonToSub(value);
createPorts(vpnPorts);
break;
case UPDATE:
checkNotNull(value, RESPONSE_NOT_NULL);
vpnPorts = changeJsonToSub(value);
updatePorts(vpnPorts);
break;
default:
log.info("Invalid action is received while processing VPN " +
"port configuration");
}
}
/**
* Creates dummy gluon network to the VTN.
*
* @param state the base port state
* @param adminStateUp the base port admin status
* @param tenantID the base port tenant ID
*/
private void createDummyGluonNetwork(boolean adminStateUp, String state,
TenantId tenantID) {
String id = "11111111-1111-1111-1111-111111111111";
String name = "GluonNetwork";
String segmentationID = "50";
String physicalNetwork = "None";
TenantNetwork network = new DefaultTenantNetwork(TenantNetworkId.networkId(id), name,
adminStateUp,
TenantNetwork.State.valueOf(state),
false, tenantID,
false,
TenantNetwork.Type.LOCAL,
PhysicalNetwork.physicalNetwork(physicalNetwork),
SegmentationId.segmentationId(segmentationID));
Set<TenantNetwork> networksSet = Sets.newHashSet(network);
tenantNetworkService.createNetworks(networksSet);
}
/**
* Creates dummy gluon subnet to the VTN.
*
* @param tenantId the base port tenant ID
*/
public void createDummySubnet(TenantId tenantId) {
String id = "22222222-2222-2222-2222-222222222222";
String subnetName = "GluonSubnet";
String cidr = "0.0.0.0/0";
String gatewayIp = "0.0.0.0";
Set<HostRoute> hostRoutes = Sets.newHashSet();
String ipV6AddressMode = null;
String ipV6RaMode = null;
TenantNetworkId tenantNetworkId = null;
Set<AllocationPool> allocationPools = Sets.newHashSet();
Iterable<TenantNetwork> networks
= tenantNetworkService.getNetworks();
for (TenantNetwork tenantNetwork : networks) {
if (tenantNetwork.name().equals("GluonNetwork")) {
tenantNetworkId = tenantNetwork.id();
break;
}
}
Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
tenantNetworkId,
tenantId, IpAddress.Version.INET,
cidr == null ? null : IpPrefix.valueOf(cidr),
gatewayIp == null ? null : IpAddress.valueOf(gatewayIp),
false, false, hostRoutes,
ipV6AddressMode == null ? null : Subnet.Mode.valueOf(ipV6AddressMode),
ipV6RaMode == null ? null : Subnet.Mode.valueOf(ipV6RaMode),
allocationPools);
Set<Subnet> subnetsSet = Sets.newHashSet(subnet);
subnetService.createSubnets(subnetsSet);
}
/**
* Returns a collection of vpnPort from subnetNodes.
*
* @param vpnPortNodes the vpnPort json node
* @return list of vpnports
*/
private Collection<VpnPort> changeJsonToSub(JsonNode vpnPortNodes) {
checkNotNull(vpnPortNodes, JSON_NOT_NULL);
Map<VpnPortId, VpnPort> vpnPortMap = new HashMap<>();
String interfaceId = vpnPortNodes.get(INTERFACE_ID).asText();
VpnPortId vpnPortId = VpnPortId.vpnPortId(interfaceId);
VpnInstanceId vpnInstanceId = VpnInstanceId
.vpnInstanceId(vpnPortNodes.get(VPN_INSTANCE).asText());
VpnPort vpnPort = new DefaultVpnPort(vpnPortId, vpnInstanceId);
vpnPortMap.put(vpnPortId, vpnPort);
// update ip address and tenant network information in vtn
TenantNetworkId tenantNetworkId = null;
Map<VirtualPortId, VirtualPort> vPortMap = new HashMap<>();
BasePortId basePortId = BasePortId.portId(interfaceId);
VirtualPortId virtualPortId = VirtualPortId.portId(interfaceId);
BasePort bPort = basePortService.getPort(basePortId);
if (bPort != null) {
FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(basePortId.toString()),
IpAddress.valueOf(vpnPortNodes
.get("ipaddress").asText()));
Set<FixedIp> fixedIps = new HashSet<>();
fixedIps.add(fixedIp);
Map<String, String> strMap = new HashMap<>();
boolean adminStateUp = bPort.adminStateUp();
strMap.put("name", bPort.name());
strMap.put("deviceOwner", bPort.deviceOwner());
strMap.put("bindingVnicType", bPort.bindingVnicType());
strMap.put("bindingVifType", bPort.bindingVifType());
strMap.put("bindingVifDetails", bPort.bindingVifDetails());
String state = bPort.state();
MacAddress macAddress = bPort.macAddress();
TenantId tenantId = bPort.tenantId();
DeviceId deviceId = bPort.deviceId();
BindingHostId bindingHostId = bPort.bindingHostId();
// Creates Dummy Gluon Network and Subnet
createDummyGluonNetwork(adminStateUp, state, tenantId);
createDummySubnet(tenantId);
Iterable<TenantNetwork> networks
= tenantNetworkService.getNetworks();
for (TenantNetwork tenantNetwork : networks) {
if (tenantNetwork.name().equals("GluonNetwork")) {
tenantNetworkId = tenantNetwork.id();
break;
}
}
if (tenantNetworkId != null) {
DefaultVirtualPort vPort = new DefaultVirtualPort(virtualPortId,
tenantNetworkId,
adminStateUp,
strMap, isState(state),
macAddress, tenantId,
deviceId, fixedIps,
bindingHostId,
null,
null);
vPortMap.put(virtualPortId, vPort);
Collection<VirtualPort> virtualPorts
= Collections.unmodifiableCollection(vPortMap.values());
virtualPortService.createPorts(virtualPorts);
}
}
return Collections.unmodifiableCollection(vpnPortMap.values());
}
/**
* Returns BasePort State.
*
* @param state the base port state
* @return the basePort state
*/
private VirtualPort.State isState(String state) {
if (state.equals("ACTIVE")) {
return VirtualPort.State.ACTIVE;
} else {
return VirtualPort.State.DOWN;
}
}
@Override
public void addListener(VpnPortListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.add(listener);
}
@Override
public void removeListener(VpnPortListener listener) {
checkNotNull(listener, LISTENER_NOT_NULL);
listeners.remove(listener);
}
/**
* Notifies specify event to all listeners.
*
* @param event Vpn Port event
*/
private void notifyListeners(VpnPortEvent event) {
checkNotNull(event, EVENT_NOT_NULL);
listeners.forEach(listener -> {
listener.event(event);
});
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by l3vpn.
*/
package org.onosproject.evpnopenflow.rsc.vpnport.impl;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* VPN resources that used by evpn.
*/
package org.onosproject.evpnopenflow.rsc.vpnport;

View File

@ -0,0 +1,33 @@
<!--
~ Copyright 2017-present Open Networking Laboratory
~
~ 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
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.evpnopenflow.rsc.cli.EvpnPublicRouteListCommand"/>
</command>
<command>
<action class="org.onosproject.evpnopenflow.rsc.cli.EvpnPrivateRouteListCommand"/>
</command>
<command>
<action class="org.onosproject.evpnopenflow.rsc.cli.VpnPortListCommand"/>
</command>
<command>
<action class="org.onosproject.evpnopenflow.rsc.cli.VpnInstListCommand"/>
</command>
</command-bundle>
</blueprint>

View File

@ -90,6 +90,7 @@
<module>openroadm</module>
<module>netconf/client</module>
<module>gluon</module>
<module>evpnopenflow</module>
</modules>
<properties>

View File

@ -62,7 +62,6 @@ public class EvpnRoute {
* @param source route source
* @param prefixMac mac address
* @param prefix ip address
* @param prefix
* @param nextHop evpn nexthop
* @param rd route distinguisher
* @param importRtList import route targets
@ -104,7 +103,6 @@ public class EvpnRoute {
* @param importRtList import route targets
* @param exportRtList export route targets
* @param labelToInt evpn route label
* @param prefix
*/
public EvpnRoute(Source source,
MacAddress prefixMac,

View File

@ -209,6 +209,7 @@ ONOS_APPS = [
'//apps/openroadm:onos-apps-openroadm-oar',
'//apps/artemis:onos-apps-artemis-oar',
'//apps/gluon:onos-apps-gluon-oar',
'//apps/evpnopenflow:onos-apps-evpnopenflow-oar',
]
PROTOCOL_APPS = [