Adding BGP provider code to support EVPN
Change-Id: Ic5508749b64a47a70f1aabd9324e9f89e85fa39f
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
index 992862c..ca462ec 100644
--- a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
@@ -345,4 +345,18 @@
* @param rpdCapability flow specification RPD capability
*/
void setFlowSpecRpdCapability(boolean rpdCapability);
+
+ /**
+ * Sets the evpn capability.
+ *
+ * @param evpnCapability evpn capability
+ */
+ void setEvpnCapability(boolean evpnCapability);
+ /**
+ * Gets the evpn capability.
+ *
+ * @return evpn capability
+ */
+ boolean getEvpnCapability();
+
}
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
index bb2b505..b5cfe5a 100644
--- a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
@@ -179,5 +179,25 @@
* @return closedSessionMap
*/
Map<String, List<String>> closedSessionMap();
+ /**
+ * Register a listener for BGP message events.
+ *
+ * @param listener the listener to notify
+ */
+ void addRouteListener(BgpRouteListener listener);
+
+ /**
+ * Unregister a listener.
+ *
+ * @param listener the listener to unregister
+ */
+ void removeRouteListener(BgpRouteListener listener);
+
+ /**
+ * Return BGP route listener.
+ *
+ * @return route listener
+ */
+ Set<BgpRouteListener> routeListener();
}
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java
index 0dbddeb..ab26173 100644
--- a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java
@@ -16,7 +16,9 @@
package org.onosproject.bgp.controller;
import java.util.List;
import org.jboss.netty.channel.Channel;
+import org.onlab.packet.IpAddress;
import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
import org.onosproject.bgpio.protocol.BgpFactory;
import org.onosproject.bgpio.protocol.BgpMessage;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
@@ -140,5 +142,17 @@
* @param wideCommunity for route policy
*/
void updateFlowSpec(FlowSpecOperation operType, BgpFlowSpecRouteKey routeKey,
- BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity);
+ BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity);
+
+ /**
+ * Updates evpn rule.
+ *
+ * @param operType operation type add or delete or update
+ * @param nextHop next Hop
+ * @param extcommunity extended community
+ * @param evpnNlris list of evpnNlri
+ */
+ void updateEvpnNlri(FlowSpecOperation operType, IpAddress nextHop,
+ List<BgpValueType> extcommunity,
+ List<BgpEvpnNlri> evpnNlris);
}
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpRouteListener.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpRouteListener.java
new file mode 100755
index 0000000..f2df135
--- /dev/null
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpRouteListener.java
@@ -0,0 +1,31 @@
+/*
+ * 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.bgp.controller;
+
+import org.onosproject.bgpio.protocol.BgpUpdateMsg;
+
+public interface BgpRouteListener {
+
+ /**
+ * Notify that got an update message and operate route.
+ *
+ * @param bgpId bgp identifier
+ * @param msg BGP update message
+ */
+ void processRoute(BgpId bgpId, BgpUpdateMsg msg);
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java
new file mode 100755
index 0000000..212b921
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java
@@ -0,0 +1,41 @@
+/*
+ * 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.bgpio.protocol;
+
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriData;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType;
+import org.onosproject.bgpio.types.BgpValueType;
+
+/**
+ * Abstraction of an entity providing BGP-EVPN NLRI.
+ */
+public interface BgpEvpnNlri extends BgpValueType {
+
+ /**
+ * Returns route type in Nlri.
+ *
+ * @return route type in Nlri
+ */
+ BgpEvpnRouteType getRouteType();
+
+ /**
+ * Returns route type specific Nlri.
+ *
+ * @return route type in Nlri
+ */
+ BgpEvpnNlriData getNlri();
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
index 708bc06..4346b86 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
@@ -148,6 +148,16 @@
*/
Builder setFlowSpecRpdCapabilityTlv(boolean isFlowSpecRpdCapabilitySet);
+ /**
+ * Sets Evpn capability and return its builder.
+ *
+ * @param isEvpnCapabilitySet boolean value to know whether evpn
+ * capability is set or not
+ *
+ * @return builder by setting capabilities
+ */
+ Builder setEvpnCapabilityTlv(boolean isEvpnCapabilitySet);
+
@Override
Builder setHeader(BgpHeader bgpMsgHeader);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java
new file mode 100755
index 0000000..e91e94a
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java
@@ -0,0 +1,38 @@
+/*
+ * 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.bgpio.protocol.evpn;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+public interface BgpEvpnNlriData {
+
+ /**
+ * Returns the Type of RouteTypeSpefic.
+ *
+ * @return short value of type
+ */
+ BgpEvpnRouteType getType();
+
+ /**
+ * Writes the byte Stream of BGP Message to channel buffer.
+ *
+ * @param cb channel buffer
+ * @return length written to channel buffer
+ */
+ int write(ChannelBuffer cb);
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java
new file mode 100755
index 0000000..cfe0530
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java
@@ -0,0 +1,172 @@
+/*
+ * 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.bgpio.protocol.evpn;
+
+import com.google.common.base.MoreObjects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
+import org.onosproject.bgpio.types.BgpErrorType;
+import org.onosproject.bgpio.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of Evpn NLRI.
+ */
+public class BgpEvpnNlriImpl implements BgpEvpnNlri {
+
+ /*
+ * REFERENCE : RFC 7432 BGP MPLS-Based Ethernet VPN
+ +-----------------------------------+
+ | Route Type (1 octet) |
+ +-----------------------------------+
+ | Length (1 octet) |
+ +-----------------------------------+
+ | Route Type specific (variable) |
+ +-----------------------------------+
+
+ Figure : The format of the EVPN NLRI
+ */
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(BgpEvpnNlriImpl.class);
+
+ // total length of route type and length
+ public static final short TYPE_AND_LEN = 2;
+ private byte routeType;
+ private BgpEvpnNlriData routeTypeSpec;
+
+ /**
+ * Resets parameters.
+ */
+ public BgpEvpnNlriImpl() {
+ this.routeType = Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT;
+ this.routeTypeSpec = null;
+
+ }
+
+ /**
+ * Constructor to initialize parameters for BGP EvpnNlri.
+ *
+ * @param routeType route Type
+ * @param routeTypeSpefic route type specific
+ */
+ public BgpEvpnNlriImpl(byte routeType, BgpEvpnNlriData routeTypeSpefic) {
+ this.routeType = routeType;
+ this.routeTypeSpec = routeTypeSpefic;
+ }
+
+ /**
+ * Reads from channelBuffer and parses Evpn Nlri.
+ *
+ * @param cb ChannelBuffer
+ * @return object of BgpEvpnNlriVer4
+ * @throws BgpParseException while parsing Bgp Evpn Nlri
+ */
+ public static BgpEvpnNlriImpl read(ChannelBuffer cb)
+ throws BgpParseException {
+
+ BgpEvpnNlriData routeNlri = null;
+
+ if (cb.readableBytes() > 0) {
+ ChannelBuffer tempBuf = cb.copy();
+ byte type = cb.readByte();
+ byte length = cb.readByte();
+ if (cb.readableBytes() < length) {
+ throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
+ BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+ tempBuf.readBytes(cb.readableBytes()
+ + TYPE_AND_LEN));
+ }
+ ChannelBuffer tempCb = cb.readBytes(length);
+ switch (type) {
+ case BgpEvpnRouteType2Nlri.TYPE:
+ routeNlri = BgpEvpnRouteType2Nlri.read(tempCb);
+ break;
+ default:
+ log.info("Discarding, EVPN route type {}", type);
+ throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
+ BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE, null);
+ // break;
+ }
+ return new BgpEvpnNlriImpl(type, routeNlri);
+ } else {
+ return new BgpEvpnNlriImpl();
+ }
+
+ }
+
+ @Override
+ public BgpEvpnNlriData getNlri() {
+ return routeTypeSpec;
+ }
+
+ @Override
+ public BgpEvpnRouteType getRouteType() {
+ switch (routeType) {
+ case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+ return BgpEvpnRouteType.ETHERNET_AUTO_DISCOVERY;
+ case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+ return BgpEvpnRouteType.MAC_IP_ADVERTISEMENT;
+ case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+ return BgpEvpnRouteType.INCLUSIVE_MULTICASE_ETHERNET;
+ case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+ return BgpEvpnRouteType.ETHERNET_SEGMENT;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).omitNullValues()
+ .add("routeType", routeType)
+ .add("routeTypeSpefic ", routeTypeSpec).toString();
+ }
+
+ @Override
+ public short getType() {
+ return routeType;
+ }
+
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeByte(routeType);
+ int iSpecStartIndex = cb.writerIndex();
+ cb.writeByte(0);
+ switch (routeType) {
+ case BgpEvpnRouteType2Nlri.TYPE:
+ ((BgpEvpnRouteType2Nlri) routeTypeSpec).write(cb);
+ break;
+ default:
+ break;
+ }
+ cb.setByte(iSpecStartIndex,
+ (short) (cb.writerIndex() - iSpecStartIndex + 1));
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return 0;
+ }
+
+
+}
+
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java
new file mode 100755
index 0000000..6b919c3
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java
@@ -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.bgpio.protocol.evpn;
+
+/**
+ * Enum to provide EVPN RouteType.
+ */
+public enum BgpEvpnRouteType {
+ ETHERNET_AUTO_DISCOVERY(1), MAC_IP_ADVERTISEMENT(2),
+ INCLUSIVE_MULTICASE_ETHERNET(3), ETHERNET_SEGMENT(4);
+ int value;
+
+ /**
+ * Assign val with the value as the route type.
+ *
+ * @param val route type
+ */
+ BgpEvpnRouteType(int val) {
+ value = val;
+ }
+
+ /**
+ * Returns value of route type.
+ *
+ * @return route type
+ */
+ public byte getType() {
+ return (byte) value;
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java
new file mode 100755
index 0000000..76fcbce
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java
@@ -0,0 +1,314 @@
+/*
+ * 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.bgpio.protocol.evpn;
+
+import com.google.common.base.MoreObjects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onlab.packet.MacAddress;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.types.BgpEvpnEsi;
+import org.onosproject.bgpio.types.BgpEvpnLabel;
+import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.util.Constants;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+
+public class BgpEvpnRouteType2Nlri implements BgpEvpnNlriData {
+
+ /*
+ * REFERENCE : RFC 7432 BGP MPLS-Based Ethernet VPN
+ +---------------------------------------+
+ | RD (8 octets) |
+ +---------------------------------------+
+ |Ethernet Segment Identifier (10 octets)|
+ +---------------------------------------+
+ | Ethernet Tag ID (4 octets) |
+ +---------------------------------------+
+ | MAC Address Length (1 octet) |
+ +---------------------------------------+
+ | MAC Address (6 octets) |
+ +---------------------------------------+
+ | IP Address Length (1 octet) |
+ +---------------------------------------+
+ | IP Address (0, 4, or 16 octets) |
+ +---------------------------------------+
+ | MPLS Label1 (3 octets) |
+ +---------------------------------------+
+ | MPLS Label2 (0 or 3 octets) |
+ +---------------------------------------+
+
+ Figure : A MAC/IP Advertisement route type specific EVPN NLRI
+
+ */
+
+ public static final short TYPE = Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT;
+ protected static final Logger log = LoggerFactory.getLogger(BgpEvpnRouteType2Nlri.class);
+ // unit of length is bit
+ public static final short IPV4_ADDRESS_LENGTH = 32;
+ public static final short MAC_ADDRESS_LENGTH = 48;
+ private RouteDistinguisher rd;
+ private BgpEvpnEsi esi;
+ private int ethernetTagID;
+ private byte macAddressLength;
+ private MacAddress macAddress;
+ private byte ipAddressLength;
+ private InetAddress ipAddress;
+ private BgpEvpnLabel mplsLabel1;
+ private BgpEvpnLabel mplsLabel2;
+
+ /**
+ * Resets parameters.
+ */
+ public BgpEvpnRouteType2Nlri() {
+ this.rd = null;
+ this.esi = null;
+ this.ethernetTagID = 0;
+ this.macAddressLength = 0;
+ this.macAddress = null;
+ this.ipAddressLength = 0;
+ this.ipAddress = null;
+ this.mplsLabel1 = null;
+ this.mplsLabel2 = null;
+ }
+
+ /**
+ * Creates the Evpn route type 2 route.
+ *
+ * @param rd route distinguisher
+ * @param esi esi
+ * @param ethernetTagID ethernet tag id
+ * @param macAddress mac
+ * @param ipAddress ip
+ * @param mplsLabel1 label
+ * @param mplsLabel2 label
+ */
+ public BgpEvpnRouteType2Nlri(RouteDistinguisher rd,
+ BgpEvpnEsi esi,
+ int ethernetTagID, MacAddress macAddress,
+ InetAddress ipAddress, BgpEvpnLabel mplsLabel1,
+ BgpEvpnLabel mplsLabel2) {
+ this.rd = rd;
+ this.esi = esi;
+ this.ethernetTagID = ethernetTagID;
+ this.macAddressLength = MAC_ADDRESS_LENGTH;
+ this.macAddress = macAddress;
+ if (ipAddress != null) {
+ this.ipAddressLength = IPV4_ADDRESS_LENGTH;
+ this.ipAddress = ipAddress;
+ } else {
+ this.ipAddressLength = 0;
+ this.ipAddress = null;
+ }
+ this.mplsLabel1 = mplsLabel1;
+ this.mplsLabel2 = mplsLabel2;
+ }
+
+ /**
+ * Reads the Evpn type 2 attributes.
+ *
+ * @param cb channel buffer
+ * @return type2 route
+ * @throws BgpParseException parse exception
+ */
+ public static BgpEvpnRouteType2Nlri read(ChannelBuffer cb) throws BgpParseException {
+ if (cb.readableBytes() == 0) {
+ return null;
+ }
+ RouteDistinguisher rd = RouteDistinguisher.read(cb);
+ BgpEvpnEsi esi = BgpEvpnEsi.read(cb);
+ int ethernetTagID = cb.readInt();
+ byte macAddressLength = cb.readByte();
+ MacAddress macAddress = Validation.toMacAddress(macAddressLength / 8, cb);
+ byte ipAddressLength = cb.readByte();
+ InetAddress ipAddress = null;
+ if (ipAddressLength > 0) {
+ ipAddress = Validation.toInetAddress(ipAddressLength / 8, cb);
+ }
+ BgpEvpnLabel mplsLabel1 = BgpEvpnLabel.read(cb);
+ BgpEvpnLabel mplsLabel2 = null;
+ if (cb.readableBytes() > 0) {
+ mplsLabel2 = BgpEvpnLabel.read(cb);
+ }
+
+ return new BgpEvpnRouteType2Nlri(rd, esi, ethernetTagID, macAddress,
+ ipAddress, mplsLabel1,
+ mplsLabel2);
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeLong(rd.getRouteDistinguisher());
+ esi.write(cb);
+ cb.writeInt(ethernetTagID);
+ cb.writeByte(macAddressLength);
+ cb.writeBytes(macAddress.toBytes());
+ cb.writeByte(ipAddressLength);
+ if (ipAddressLength > 0) {
+ cb.writeBytes(ipAddress.getAddress());
+ }
+ mplsLabel1.write(cb);
+ if (mplsLabel2 != null) {
+ mplsLabel2.write(cb);
+ }
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ /**
+ * Returns the rd.
+ *
+ * @return rd route distinguisher
+ */
+ public RouteDistinguisher getRouteDistinguisher() {
+ return rd;
+ }
+
+ /**
+ * Returns the esi.
+ *
+ * @return esi ethernet segment identifier
+ */
+ public BgpEvpnEsi getEthernetSegmentidentifier() {
+ return esi;
+ }
+
+ /**
+ * Returns the ethernet tag id.
+ *
+ * @return macAddress macadress
+ */
+ public int getEthernetTagID() {
+ return ethernetTagID;
+ }
+
+ public MacAddress getMacAddress() {
+ return macAddress;
+ }
+
+ /**
+ * Returns the ip address.
+ *
+ * @return ipAddress ipaddress
+ */
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ /**
+ * Returns the mpls label.
+ *
+ * @return mplsLabel1 mpls label
+ */
+ public BgpEvpnLabel getMplsLable1() {
+ return mplsLabel1;
+ }
+
+ /**
+ * Returns the mpls label.
+ *
+ * @return mplsLabel2 mpls label
+ */
+ public BgpEvpnLabel getMplsLable2() {
+ return mplsLabel2;
+ }
+
+ /**
+ * Set the rd.
+ *
+ * @param rd route distinguisher
+ */
+ public void setRouteDistinguisher(RouteDistinguisher rd) {
+ this.rd = rd;
+ }
+
+ /**
+ * Set the ESI.
+ *
+ * @param esi esi
+ */
+ public void setEthernetSegmentidentifier(BgpEvpnEsi esi) {
+ this.esi = esi;
+ }
+
+ /**
+ * Set the ethernet tag id.
+ *
+ * @param ethernetTagID ethernet tag id.
+ */
+ public void setEthernetTagID(int ethernetTagID) {
+ this.ethernetTagID = ethernetTagID;
+ }
+
+ /**
+ * Set the mac address.
+ *
+ * @param macAddress mac
+ */
+ public void setMacAddress(MacAddress macAddress) {
+ this.macAddress = macAddress;
+ }
+
+ /**
+ * Set the ip address.
+ *
+ * @param ipAddress ip
+ */
+ public void setIpAddress(InetAddress ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ /**
+ * Set the mpls label.
+ *
+ * @param mplsLabel1 label
+ */
+ public void setMplsLable1(BgpEvpnLabel mplsLabel1) {
+ this.mplsLabel1 = mplsLabel1;
+ }
+
+ /**
+ * Set the mpls label.
+ *
+ * @param mplsLabel2 label
+ */
+ public void setMplsLable2(BgpEvpnLabel mplsLabel2) {
+ this.mplsLabel2 = mplsLabel2;
+ }
+
+ @Override
+ public BgpEvpnRouteType getType() {
+ return BgpEvpnRouteType.MAC_IP_ADVERTISEMENT;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).omitNullValues()
+ .add("rd ", rd)
+ .add("esi", esi)
+ .add("ethernetTagID", ethernetTagID)
+ .add("macAddressLength", macAddressLength)
+ .add("macAddress ", macAddress)
+ .add("ipAddressLength", ipAddressLength)
+ .add("ipAddress", ipAddress)
+ .add("mplsLabel1 ", mplsLabel1)
+ .add("mplsLabel2", mplsLabel2).toString();
+ }
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java
new file mode 100755
index 0000000..69ee80b
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java
@@ -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.
+ */
+
+/**
+ * BGP Protocol evpn components.
+ */
+package org.onosproject.bgpio.protocol.evpn;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
index 9e6b86c..41ece38 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
@@ -322,6 +322,7 @@
private boolean isFlowSpecCapabilityTlvSet = false;
private boolean isVpnFlowSpecCapabilityTlvSet = false;
private boolean isFlowSpecRpdCapabilityTlvSet = false;
+ private boolean isEvpnCapabilityTlvSet = false;
LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
@@ -378,6 +379,12 @@
this.capabilityTlv.add(tlv);
}
+ if (this.isEvpnCapabilityTlvSet) {
+ BgpValueType tlv;
+ tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_EVPN_VALUE,
+ RES, Constants.SAFI_EVPN_VALUE);
+ this.capabilityTlv.add(tlv);
+ }
return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId,
this.capabilityTlv);
@@ -445,6 +452,12 @@
this.isFlowSpecRpdCapabilityTlvSet = isFlowSpecRpdCapabilityTlvSet;
return this;
}
+
+ @Override
+ public Builder setEvpnCapabilityTlv(boolean isEvpnCapabilitySet) {
+ this.isEvpnCapabilityTlvSet = isEvpnCapabilitySet;
+ return this;
+ }
}
@Override
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
index 77c3b50..0c12525 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
@@ -246,11 +246,17 @@
}
}
- if ((afi == Constants.AFI_FLOWSPEC_VALUE) || (afi == Constants.AFI_VALUE)) {
+ if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+ || (afi == Constants.AFI_VALUE)) {
//unfeasible route length
cb.writeShort(0);
}
+ if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+ cb.writeShort(0);
+ }
+
}
if (message.bgpPathAttributes != null) {
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java
new file mode 100755
index 0000000..b6816e8
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java
@@ -0,0 +1,111 @@
+/*
+ * 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.bgpio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of EthernetSegmentidentifier.
+ */
+public class BgpEvpnEsi
+ implements Comparable<BgpEvpnEsi> {
+
+ public static final int ESI_LENGTH = 10;
+ private byte[] ethernetSegmentidentifier;
+
+ /**
+ * Resets fields.
+ */
+ public BgpEvpnEsi() {
+ this.ethernetSegmentidentifier = null;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param ethernetSegmentidentifier Ethernet Segment identifier
+ */
+ public BgpEvpnEsi(byte[] ethernetSegmentidentifier) {
+ this.ethernetSegmentidentifier = ethernetSegmentidentifier;
+ }
+
+ /**
+ * Reads Ethernet Segment identifier from channelBuffer.
+ *
+ * @param cb channelBuffer
+ * @return object of EthernetSegmentidentifier
+ */
+ public static BgpEvpnEsi read(ChannelBuffer cb) {
+ return new BgpEvpnEsi(cb.readBytes(10).array());
+ }
+
+ /**
+ * writes Ethernet Segment identifier into channelBuffer.
+ *
+ * @param cb channelBuffer
+ * @return length length of written data
+ */
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeBytes(ethernetSegmentidentifier);
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ /**
+ * Returns Ethernet Segment identifier.
+ *
+ * @return Ethernet Segment identifier.
+ */
+ public byte[] getEthernetSegmentidentifier() {
+ return this.ethernetSegmentidentifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ethernetSegmentidentifier);
+ };
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof BgpEvpnEsi) {
+ BgpEvpnEsi that = (BgpEvpnEsi) obj;
+ if (this.ethernetSegmentidentifier == that.ethernetSegmentidentifier) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("ethernetSegmentidentifier", ethernetSegmentidentifier)
+ .toString();
+ }
+
+ @Override
+ public int compareTo(BgpEvpnEsi rd) {
+ return 0;
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java
new file mode 100755
index 0000000..60348ac
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java
@@ -0,0 +1,108 @@
+/*
+ * 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.bgpio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import com.google.common.base.MoreObjects;
+
+public class BgpEvpnLabel implements Comparable<BgpEvpnLabel> {
+
+ public static final int MPLS_LABEL_LENGTH = 3;
+ private byte[] mplsLabel;
+
+ /**
+ * Resets fields.
+ */
+ public BgpEvpnLabel() {
+ this.mplsLabel = null;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param bgpEvpnLabel mpls label
+ */
+ public BgpEvpnLabel(byte[] bgpEvpnLabel) {
+ this.mplsLabel = bgpEvpnLabel;
+ }
+
+ /**
+ * Reads mpls label from channelBuffer.
+ *
+ * @param cb channelBuffer
+ * @return object of mpls label
+ */
+ public static BgpEvpnLabel read(ChannelBuffer cb) {
+ return new BgpEvpnLabel(cb.readBytes(3).array());
+ }
+
+ /**
+ * writes mpls label into channelBuffer.
+ *
+ * @param cb channelBuffer
+ * @return length length of written data
+ */
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeBytes(mplsLabel);
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ /**
+ * Returns mpls label.
+ *
+ * @return mpls label
+ */
+ public byte[] getMplsLabel() {
+ return this.mplsLabel;
+ }
+
+ @Override
+ public int compareTo(BgpEvpnLabel mplsLabel) {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof BgpEvpnLabel) {
+
+ BgpEvpnLabel that = (BgpEvpnLabel) obj;
+
+ if (this.mplsLabel == that.mplsLabel) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mplsLabel);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("mplsLabel", mplsLabel).toString();
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java
new file mode 100755
index 0000000..142b12e
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java
@@ -0,0 +1,144 @@
+/*
+ * 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.bgpio.types;
+
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Represents the Evpn prefix.
+ */
+public class BgpEvpnPrefix {
+ private Ip4Address nextHop;
+ private RouteTarget rt;
+ BgpEvpnLabel label;
+
+ /**
+ * Constructor for initializing the evpn prefix.
+ *
+ * @param nextHop next hop
+ * @param rt route target
+ * @param label label
+ */
+ public BgpEvpnPrefix(Ip4Address nextHop, RouteTarget rt, BgpEvpnLabel label) {
+ this.nextHop = nextHop;
+ this.rt = rt;
+ this.label = label;
+ }
+
+ /**
+ * Constructor for initializing the evpn prefix.
+ *
+ * @param nextHop next hop
+ * @param label label
+ */
+ public BgpEvpnPrefix(Ip4Address nextHop, BgpEvpnLabel label) {
+ this.nextHop = nextHop;
+ this.label = label;
+ }
+
+ /**
+ * Get next hop address.
+ *
+ * @return next hop
+ */
+ public Ip4Address getNextHop() {
+ return nextHop;
+ }
+
+ /**
+ * Get the route target.
+ *
+ * @return route target
+ */
+ public RouteTarget getRouteTarget() {
+ return rt;
+ }
+
+ /**
+ * Get the label.
+ *
+ * @return label
+ */
+ public BgpEvpnLabel getLabel() {
+ return label;
+
+ }
+
+ /**
+ * Set the next hop address.
+ *
+ * @param nextHop next hop
+ */
+ public void setNetHop(Ip4Address nextHop) {
+ this.nextHop = nextHop;
+ }
+
+ /**
+ * Set the route target.
+ *
+ * @param rt route target
+ */
+ public void setRouteTarget(RouteTarget rt) {
+ this.rt = rt;
+ }
+
+ /**
+ * Set the label.
+ *
+ * @param label label.
+ */
+ public void setLabel(BgpEvpnLabel label) {
+ this.label = label;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nextHop,
+ rt,
+ label);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof BgpEvpnPrefix)) {
+ return false;
+ }
+
+ BgpEvpnPrefix that = (BgpEvpnPrefix) other;
+
+ return Objects.equals(nextHop, that.nextHop)
+ && Objects.equals(rt, that.rt)
+ && Objects.equals(label, that.label);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("next hop", nextHop)
+ .add("route target", rt)
+ .add("label", label)
+ .toString();
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
index 7462bc8..941ed26 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
@@ -90,6 +90,11 @@
while (actionBuf.readableBytes() > 0) {
short actionType = actionBuf.readShort();
switch (actionType) {
+ case Constants.BGP_ROUTE_TARGET_AS:
+ case Constants.BGP_ROUTE_TARGET_IP:
+ case Constants.BGP_ROUTE_TARGET_LARGEAS:
+ fsActionTlv = RouteTarget.read(actionType, actionBuf);
+ break;
case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION:
fsActionTlv = BgpFsActionTrafficAction.read(actionBuf);
break;
@@ -102,7 +107,8 @@
case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT:
fsActionTlv = BgpFsActionReDirect.read(actionBuf);
break;
- default: log.debug("Other type Not Supported:" + actionType);
+ default:
+ log.debug("Other type Not Supported:" + actionType);
break;
}
if (fsActionTlv != null) {
@@ -156,7 +162,13 @@
while (listIterator.hasNext()) {
BgpValueType fsTlv = listIterator.next();
- if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
+ if (fsTlv.getType() == Constants.BGP_ROUTE_TARGET_AS
+ || fsTlv.getType() == Constants.BGP_ROUTE_TARGET_IP
+ || fsTlv.getType() == Constants.BGP_ROUTE_TARGET_LARGEAS) {
+ RouteTarget routeTarget = (RouteTarget) fsTlv;
+ routeTarget.write(cb);
+ } else if (fsTlv.getType() == Constants
+ .BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
BgpFsActionTrafficAction trafficAction = (BgpFsActionTrafficAction) fsTlv;
trafficAction.write(cb);
} else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING) {
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java
new file mode 100755
index 0000000..29b318d
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java
@@ -0,0 +1,34 @@
+/*
+ * 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.bgpio.types;
+
+public enum BgpNlriType {
+
+ /**
+ * Signifies Link State Nlri.
+ */
+ LINK_STATE,
+ /**
+ * Signifies Flow Spec Nlri.
+ */
+ FLOW_SPEC,
+ /**
+ * Signifies Evpn Nlri.
+ */
+ EVPN;
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
index 328b623..106c4bb 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
@@ -16,25 +16,27 @@
package org.onosproject.bgpio.types;
-import java.net.InetAddress;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
+import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.Ip4Address;
import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
-import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.MoreObjects;
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
/*
* Provides Implementation of MpReach Nlri BGP Path Attribute.
@@ -52,6 +54,7 @@
private final byte safi;
private final Ip4Address ipNextHop;
private BgpFlowSpecNlri bgpFlowSpecNlri;
+ private List<BgpEvpnNlri> evpnNlri;
/**
* Constructor to initialize parameters.
@@ -71,6 +74,13 @@
this.length = length;
}
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param bgpFlowSpecNlri bgpFlowSpecNlri
+ * @param afi afi
+ * @param safi safi
+ */
public MpReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
this.mpReachNlri = null;
this.isMpReachNlri = true;
@@ -82,6 +92,24 @@
}
/**
+ * Constructor to initialize parameters.
+ *
+ * @param evpnNlri evpnNlri
+ * @param afi afi
+ * @param safi safi
+ * @param ipNextHop IP Nexthop
+ */
+ public MpReachNlri(List<BgpEvpnNlri> evpnNlri, short afi, byte safi, Ip4Address ipNextHop) {
+ this.mpReachNlri = null;
+ this.length = 42;
+ this.ipNextHop = ipNextHop;
+ this.isMpReachNlri = true;
+ this.evpnNlri = evpnNlri;
+ this.afi = afi;
+ this.safi = safi;
+ }
+
+ /**
* Returns whether MpReachNlri is present.
*
* @return whether MpReachNlri is present
@@ -118,6 +146,60 @@
}
/**
+ * Returns BGP Evpn info.
+ *
+ * @return BGP Evpn info
+ */
+ public List<BgpEvpnNlri> bgpEvpnNlri() {
+ return this.evpnNlri;
+ }
+
+ /**
+ * Returns afi.
+ *
+ * @return afi
+ */
+ public short getAfi() {
+ return this.afi;
+ }
+
+ /**
+ * Returns safi.
+ *
+ * @return safi
+ */
+ public byte getSafi() {
+ return this.safi();
+ }
+
+ /**
+ * Returns mpReachNlri details type.
+ *
+ * @return type
+ */
+ public BgpNlriType getNlriDetailsType() {
+ if ((this.afi == Constants.AFI_VALUE)
+ && (this.safi == Constants.SAFI_VALUE)
+ || (this.afi == Constants.AFI_VALUE)
+ && (this.safi == Constants.VPN_SAFI_VALUE)) {
+ return BgpNlriType.LINK_STATE;
+ }
+
+ if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+ && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
+ || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
+ return BgpNlriType.FLOW_SPEC;
+ }
+
+ if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+ return BgpNlriType.EVPN;
+ }
+
+ return null;
+ }
+
+ /**
* Reads from ChannelBuffer and parses MpReachNlri.
*
* @param cb channelBuffer
@@ -272,6 +354,29 @@
BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
return new MpReachNlri(flowSpecDetails, afi, safi);
+ } else if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+ List<BgpEvpnNlri> eVpnComponents = null;
+
+ byte nextHopLen = tempCb.readByte();
+ InetAddress ipAddress = Validation.toInetAddress(nextHopLen,
+ tempCb);
+ if (ipAddress.isMulticastAddress()) {
+ throw new BgpParseException("Multicast not supported");
+ }
+ ipNextHop = Ip4Address.valueOf(ipAddress);
+ byte reserved = tempCb.readByte();
+ while (tempCb.readableBytes() > 0) {
+ BgpEvpnNlri eVpnComponent = BgpEvpnNlriImpl.read(tempCb);
+ eVpnComponents = new LinkedList<>();
+ eVpnComponents.add(eVpnComponent);
+ log.info("=====evpn Component is {} ======", eVpnComponent);
+ }
+
+ return new MpReachNlri(eVpnComponents, afi, safi, ipNextHop);
+
+
} else {
throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
}
@@ -358,6 +463,48 @@
int fsNlriLen = cb.writerIndex() - mpReachDataIndx;
cb.setShort(mpReachDataIndx, (short) (fsNlriLen - 2));
+ } else if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+ cb.writeByte(FLAGS);
+ cb.writeByte(MPREACHNLRI_TYPE);
+
+ int mpReachDataIndex = cb.writerIndex();
+ cb.writeShort(0);
+ cb.writeShort(afi);
+ cb.writeByte(safi);
+ // ip address length
+ cb.writeByte(0x04);
+ cb.writeInt(ipNextHop.toInt());
+ //sub network points of attachment
+ cb.writeByte(0);
+
+ for (BgpEvpnNlri element : evpnNlri) {
+ short routeType = element.getType();
+ switch (routeType) {
+ case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+ cb.writeByte(element.getType());
+ int iSpecStartIndex = cb.writerIndex();
+ cb.writeByte(0);
+ BgpEvpnRouteType2Nlri macIpAdvNlri = (BgpEvpnRouteType2Nlri) element
+ .getNlri();
+ macIpAdvNlri.write(cb);
+ cb.setByte(iSpecStartIndex, (byte) (cb.writerIndex()
+ - iSpecStartIndex - 1));
+ //ChannelBuffer temcb = cb.copy();
+ break;
+ case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+ break;
+ case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+ break;
+ case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+ break;
+ default:
+ break;
+ }
+ }
+ int evpnNlriLen = cb.writerIndex() - mpReachDataIndex;
+ cb.setShort(mpReachDataIndex, (short) (evpnNlriLen - 2));
}
return cb.writerIndex() - iLenStartIndex;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
index 9bc0189..e06fb0a 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
@@ -16,23 +16,25 @@
package org.onosproject.bgpio.types;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
+import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.MoreObjects;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
/**
* Provides Implementation of MpUnReach Nlri BGP Path Attribute.
@@ -49,6 +51,7 @@
private final List<BgpLSNlri> mpUnReachNlri;
private final int length;
private BgpFlowSpecNlri bgpFlowSpecNlri;
+ private List<BgpEvpnNlri> evpnNlri;
/**
* Constructor to initialize parameters.
@@ -67,6 +70,13 @@
this.length = length;
}
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param bgpFlowSpecNlri bgpFlowSpecNlri
+ * @param afi afi
+ * @param safi safi
+ */
public MpUnReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
this.mpUnReachNlri = null;
this.isMpUnReachNlri = true;
@@ -77,6 +87,22 @@
}
/**
+ * Constructor to initialize parameters.
+ *
+ * @param evpnNlri evpnNlri
+ * @param afi afi
+ * @param safi safi
+ */
+ public MpUnReachNlri(List<BgpEvpnNlri> evpnNlri, short afi, byte safi) {
+ this.mpUnReachNlri = null;
+ this.isMpUnReachNlri = true;
+ this.length = 0;
+ this.evpnNlri = evpnNlri;
+ this.afi = afi;
+ this.safi = safi;
+ }
+
+ /**
* Returns BGP flow specification info.
*
* @return BGP flow specification info
@@ -86,6 +112,60 @@
}
/**
+ * Returns BGP Evpn info.
+ *
+ * @return BGP Evpn info
+ */
+ public List<BgpEvpnNlri> bgpEvpnNlri() {
+ return this.evpnNlri;
+ }
+
+ /**
+ * Returns afi.
+ *
+ * @return afi
+ */
+ public short getAfi() {
+ return this.afi;
+ }
+
+ /**
+ * Returns safi.
+ *
+ * @return safi
+ */
+ public byte getSafi() {
+ return this.safi();
+ }
+
+ /**
+ * Returns mpUnReachNlri details type.
+ *
+ * @return type
+ */
+ public BgpNlriType getNlriDetailsType() {
+ if ((this.afi == Constants.AFI_VALUE)
+ && (this.safi == Constants.SAFI_VALUE)
+ || (this.afi == Constants.AFI_VALUE)
+ && (this.safi == Constants.VPN_SAFI_VALUE)) {
+ return BgpNlriType.LINK_STATE;
+ }
+
+ if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+ && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
+ || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
+ return BgpNlriType.FLOW_SPEC;
+ }
+
+ if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+ return BgpNlriType.EVPN;
+ }
+
+ return null;
+ }
+
+ /**
* Reads from ChannelBuffer and parses MpUnReachNlri.
*
* @param cb ChannelBuffer
@@ -226,6 +306,17 @@
BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
return new MpUnReachNlri(flowSpecDetails, afi, safi);
+ } else if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+ List<BgpEvpnNlri> eVpnComponents = null;
+ while (tempCb.readableBytes() > 0) {
+ BgpEvpnNlri eVpnComponent = BgpEvpnNlriImpl.read(tempCb);
+ eVpnComponents = new LinkedList<>();
+ eVpnComponents.add(eVpnComponent);
+ log.info("=====evpn Component is {} ======", eVpnComponent);
+ }
+
+ return new MpUnReachNlri(eVpnComponents, afi, safi);
} else {
//TODO: check with the values got from capability
throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
@@ -326,6 +417,45 @@
}
int fsNlriLen = cb.writerIndex() - mpUnReachIndx;
cb.setShort(mpUnReachIndx, (short) (fsNlriLen - 2));
+ } else if ((afi == Constants.AFI_EVPN_VALUE)
+ && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+ cb.writeByte(FLAGS);
+ cb.writeByte(MPUNREACHNLRI_TYPE);
+
+ int mpUnReachDataIndex = cb.writerIndex();
+ cb.writeShort(0);
+ cb.writeShort(afi);
+ cb.writeByte(safi);
+
+ for (BgpEvpnNlri element : evpnNlri) {
+ short routeType = element.getType();
+ switch (routeType) {
+ case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+ cb.writeByte(element.getType());
+ int iSpecStartIndex = cb.writerIndex();
+ cb.writeByte(0);
+ BgpEvpnRouteType2Nlri macIpAdvNlri =
+ (BgpEvpnRouteType2Nlri) element
+ .getNlri();
+
+ macIpAdvNlri.write(cb);
+ cb.setByte(iSpecStartIndex, (short) (cb.writerIndex()
+ - iSpecStartIndex - 1));
+ break;
+ case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+ break;
+ case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+ break;
+ case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+ break;
+ default:
+ break;
+ }
+ }
+
+ int evpnNlriLen = cb.writerIndex() - mpUnReachDataIndex;
+ cb.setShort(mpUnReachDataIndex, (short) (evpnNlriLen - 2));
}
return cb.writerIndex() - iLenStartIndex;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java
new file mode 100755
index 0000000..5a009f9
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java
@@ -0,0 +1,145 @@
+/*
+ * 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.bgpio.types;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+
+/**
+ * Implementation of RouteTarget.
+ */
+public class RouteTarget implements BgpValueType {
+
+ /*
+ * Type 0x00: Local Administrator sub-field uses 2 octets with AS number and
+ * Assigned number uses 4 octests Type 0x01: Local Administrator sub-field
+ * uses 4 octets with IP address and Assigned number uses 2 octests Type
+ * 0x02: Local Administrator sub-field uses 4 octets with AS number and
+ * Assigned number uses 2 octests
+ */
+ private byte[] routeTarget;
+ private short type;
+
+ public enum RouteTargetype {
+
+ AS((short) 0x0002), IP((short) 0x0102), LARGEAS((short) 0x0202);
+ short value;
+
+ /**
+ * Assign val with the value as the tunnel type.
+ *
+ * @param val tunnel type
+ */
+ RouteTargetype(short val) {
+ value = val;
+ }
+
+ /**
+ * Returns value of route type.
+ *
+ * @return route type
+ */
+ public short getType() {
+ return value;
+ }
+ }
+
+ /**
+ * Resets fields.
+ */
+ public RouteTarget() {
+ this.type = 0;
+ this.routeTarget = null;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param type type
+ * @param routeTarget route target
+ */
+ public RouteTarget(short type, byte[] routeTarget) {
+ this.type = type;
+ this.routeTarget = routeTarget;
+ }
+
+ /**
+ * Reads route target from channelBuffer.
+ *
+ * @param type type
+ * @param cb channelBuffer
+ * @return object of RouteTarget
+ */
+ public static RouteTarget read(short type, ChannelBuffer cb) {
+ return new RouteTarget(type, cb.readBytes(6).array());
+ }
+
+ /**
+ * Returns route target.
+ *
+ * @return route target
+ */
+ public byte[] getRouteTarget() {
+ return this.routeTarget;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouteTarget) {
+ RouteTarget that = (RouteTarget) obj;
+ if (this.type == that.type
+ && this.routeTarget == that.routeTarget) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(routeTarget);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).add("type", type)
+ .add("routeTarget", routeTarget).toString();
+ }
+
+ @Override
+ public short getType() {
+ return type;
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeShort(type);
+ cb.writeBytes(routeTarget);
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ @Override
+ public int compareTo(Object rd) {
+ return 0;
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
index 43d31c5..1839a31 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
@@ -46,6 +46,9 @@
public static final byte SAFI_FLOWSPEC_RPD_VALUE = (byte) 133;
public static final byte VPN_SAFI_FLOWSPEC_RDP_VALUE = (byte) 134;
+ public static final short AFI_EVPN_VALUE = 25;
+ public static final byte SAFI_EVPN_VALUE = (byte) 70;
+
public static final byte RPD_CAPABILITY_RECEIVE_VALUE = 0;
public static final byte RPD_CAPABILITY_SEND_VALUE = 1;
public static final byte RPD_CAPABILITY_SEND_RECEIVE_VALUE = 2;
@@ -73,6 +76,15 @@
public static final byte BGP_FLOWSPEC_DSCP = 0x0b;
public static final byte BGP_FLOWSPEC_FRAGMENT = 0x0c;
+ // for EVPN
+ public static final short BGP_ROUTE_TARGET_AS = (short) 0x0002;
+ public static final short BGP_ROUTE_TARGET_IP = (short) 0x0102;
+ public static final short BGP_ROUTE_TARGET_LARGEAS = (short) 0x0202;
+ public static final short BGP_EVPN_ETHERNET_AUTO_DISCOVERY = (short) 0x01;
+ public static final short BGP_EVPN_MAC_IP_ADVERTISEMENT = (short) 0x02;
+ public static final short BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET = (short) 0x03;
+ public static final short BGP_EVPN_ETHERNET_SEGMENT = (short) 0x04;
+
public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_RATE = (short) 0x8006;
public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION = (short) 0x8007;
public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT = (short) 0x8008;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
index 93eb376..3f06487 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
@@ -24,6 +24,7 @@
import org.jboss.netty.buffer.ChannelBuffers;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -151,7 +152,19 @@
}
return ipAddress;
}
-
+ /**
+ * Convert byte array to MacAddress.
+ *
+ * @param length of MacAddress
+ * @param cb channelBuffer
+ * @return macAddress
+ */
+ public static MacAddress toMacAddress(int length, ChannelBuffer cb) {
+ byte[] address = new byte[length];
+ cb.readBytes(address, 0, length);
+ MacAddress macAddress = MacAddress.valueOf(address);
+ return macAddress;
+ }
/**
* Returns first bit in type flags.
*
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
index e2f83d4..036d8e6 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
@@ -677,6 +677,8 @@
bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt();
+ boolean evpnCapability = bgpconfig.getEvpnCapability();
+
if (flowSpec == BgpCfg.FlowSpec.IPV4) {
flowSpecStatus = true;
} else if (flowSpec == BgpCfg.FlowSpec.VPNV4) {
@@ -692,6 +694,7 @@
.setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability())
.setFlowSpecCapabilityTlv(flowSpecStatus)
.setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus)
+ .setEvpnCapabilityTlv(evpnCapability)
.setFlowSpecRpdCapabilityTlv(bgpconfig.flowSpecRpdCapability()).build();
log.debug("Sending open message to {}", channel.getRemoteAddress());
channel.write(Collections.singletonList(msg));
@@ -808,6 +811,9 @@
boolean isMultiProtocolFlowSpecCapability = false;
boolean isMultiProtocolVpnFlowSpecCapability = false;
BgpCfg.FlowSpec flowSpec = h.bgpconfig.flowSpecCapability();
+ boolean isEvpnCapability = false;
+ boolean isEvpnCapabilityCfg = h.bgpconfig
+ .getEvpnCapability();
if (flowSpec == BgpCfg.FlowSpec.IPV4) {
isFlowSpecIpv4CapabilityCfg = true;
@@ -826,6 +832,10 @@
isMultiProtocolFlowSpecCapability = true;
}
+ if (Constants.SAFI_EVPN_VALUE == tempCapability.getSafi()) {
+ isEvpnCapability = true;
+ }
+
if (Constants.VPN_SAFI_FLOWSPEC_VALUE == tempCapability.getSafi()) {
isMultiProtocolVpnFlowSpecCapability = true;
}
@@ -878,6 +888,15 @@
}
}
+ if (isEvpnCapabilityCfg) {
+ if (!isEvpnCapability) {
+ tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_EVPN_VALUE,
+ RES,
+ Constants.SAFI_EVPN_VALUE);
+ unSupportedCapabilityTlv.add(tempTlv);
+ }
+ }
+
if (isFlowSpecVpnv4CapabilityCfg) {
if (!isMultiProtocolVpnFlowSpecCapability) {
tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE,
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
index f98f4bb..b15cfb8 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
@@ -15,13 +15,6 @@
*/
package org.onosproject.bgp.controller.impl;
-import java.util.Iterator;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.List;
-import java.util.ArrayList;
-
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onosproject.bgp.controller.BgpCfg;
@@ -34,6 +27,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
/**
* Provides BGP configuration of this BGP speaker.
*/
@@ -60,6 +60,7 @@
private BgpPeerManagerImpl peerManager;
private BgpController bgpController;
private boolean rpdCapability;
+ private boolean evpnCapability;
/*
* Constructor to initialize the values.
@@ -142,6 +143,16 @@
}
@Override
+ public boolean getEvpnCapability() {
+ return this.evpnCapability;
+ }
+
+ @Override
+ public void setEvpnCapability(boolean evpnCapability) {
+ this.evpnCapability = evpnCapability;
+ }
+
+ @Override
public String getRouterId() {
if (this.routerId != null) {
return this.routerId.toString();
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
index d9e0c2f..92ca7a4 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
@@ -28,6 +28,7 @@
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpPeerManager;
+import org.onosproject.bgp.controller.BgpRouteListener;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpMessage;
import org.onosproject.bgpio.protocol.BgpUpdateMsg;
@@ -69,6 +70,7 @@
private LinkedList<String> closedExceptionList = new LinkedList<String>();
private Map<String, List<String>> activeSessionExceptionMap = new TreeMap<>();
private Map<String, List<String>> closedSessionExceptionMap = new TreeMap<>();
+ protected Set<BgpRouteListener> bgpRouteListener = new CopyOnWriteArraySet<>();
@Override
public void activeSessionExceptionAdd(String peerId, String exception) {
@@ -111,6 +113,21 @@
return closedSessionExceptionMap;
}
+ @Override
+ public void addRouteListener(BgpRouteListener listener) {
+ this.bgpRouteListener.add(listener);
+ }
+
+ @Override
+ public void removeRouteListener(BgpRouteListener listener) {
+ this.bgpRouteListener.remove(listener);
+ }
+
+ @Override
+ public Set<BgpRouteListener> routeListener() {
+ return bgpRouteListener;
+ }
+
@Activate
public void activate() {
this.ctrl.start();
@@ -163,46 +180,60 @@
BgpPeer peer = getPeer(bgpId);
switch (msg.getType()) {
- case OPEN:
- // TODO: Process Open message
- break;
- case KEEP_ALIVE:
- // TODO: Process keepalive message
- break;
- case NOTIFICATION:
- // TODO: Process notificatoin message
- break;
- case UPDATE:
- BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
- List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
- if (pathAttr == null) {
- log.debug("llPathAttr is null, cannot process update message");
- break;
- }
- Iterator<BgpValueType> listIterator = pathAttr.iterator();
- boolean isLinkstate = false;
+ case OPEN:
+ // TODO: Process Open message
+ break;
+ case KEEP_ALIVE:
+ // TODO: Process keepalive message
+ break;
+ case NOTIFICATION:
+ // TODO: Process notificatoin message
+ break;
+ case UPDATE:
+ BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
+ List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
+ if (pathAttr == null) {
+ log.debug("llPathAttr is null, cannot process update message");
+ break;
+ }
+ Iterator<BgpValueType> listIterator = pathAttr.iterator();
+ boolean isLinkstate = false;
+ boolean isEvpn = false;
- while (listIterator.hasNext()) {
- BgpValueType attr = listIterator.next();
- if (attr instanceof MpReachNlri) {
- MpReachNlri mpReach = (MpReachNlri) attr;
- if (mpReach.bgpFlowSpecNlri() == null) {
- isLinkstate = true;
- }
- } else if (attr instanceof MpUnReachNlri) {
- MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
- if (mpUnReach.bgpFlowSpecNlri() == null) {
- isLinkstate = true;
+ while (listIterator.hasNext()) {
+ BgpValueType attr = listIterator.next();
+ if (attr instanceof MpReachNlri) {
+ MpReachNlri mpReach = (MpReachNlri) attr;
+ if (mpReach.bgpFlowSpecNlri() == null
+ && mpReach.bgpEvpnNlri() == null) {
+ isLinkstate = true;
+ }
+ if (mpReach.bgpEvpnNlri() != null) {
+ isEvpn = true;
+ }
+ } else if (attr instanceof MpUnReachNlri) {
+ MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
+ if (mpUnReach.bgpFlowSpecNlri() == null
+ && mpUnReach.bgpEvpnNlri() == null) {
+ isLinkstate = true;
+ }
+ if (mpUnReach.bgpEvpnNlri() != null) {
+ isEvpn = true;
+ }
}
}
- }
- if (isLinkstate) {
- peer.buildAdjRibIn(pathAttr);
- }
- break;
- default:
- // TODO: Process other message
- break;
+ if (isLinkstate) {
+ peer.buildAdjRibIn(pathAttr);
+ }
+ if (isEvpn) {
+ for (BgpRouteListener listener : bgpRouteListener) {
+ listener.processRoute(bgpId, updateMsg);
+ }
+ }
+ break;
+ default:
+ // TODO: Process other message
+ break;
}
}
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
index 34f4ec6..4dc8fee 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -26,6 +26,7 @@
import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpSessionInfo;
import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
import org.onosproject.bgpio.protocol.BgpFactories;
import org.onosproject.bgpio.protocol.BgpFactory;
import org.onosproject.bgpio.protocol.BgpLSNlri;
@@ -36,8 +37,8 @@
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
-import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.As4Path;
+import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.BgpExtendedCommunity;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LocalPref;
@@ -46,8 +47,8 @@
import org.onosproject.bgpio.types.MpUnReachNlri;
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.onosproject.bgpio.types.Origin;
-import org.onosproject.bgpio.types.attr.WideCommunity;
import org.onosproject.bgpio.types.RpdCapabilityTlv;
+import org.onosproject.bgpio.types.attr.WideCommunity;
import org.onosproject.bgpio.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -256,6 +257,69 @@
}
@Override
+ public void updateEvpnNlri(FlowSpecOperation operType, IpAddress nextHop,
+ List<BgpValueType> extcommunity,
+ List<BgpEvpnNlri> evpnNlris) {
+ Preconditions.checkNotNull(operType, "Operation type cannot be null");
+ Preconditions.checkNotNull(evpnNlris, "Evpn nlri cannot be null");
+ sendEvpnUpdateMessageToPeer(operType, nextHop, extcommunity, evpnNlris);
+ }
+
+ private void sendEvpnUpdateMessageToPeer(FlowSpecOperation operType,
+ IpAddress nextHop,
+ List<BgpValueType> extcommunity,
+ List<BgpEvpnNlri> evpnNlris) {
+ List<BgpValueType> attributesList = new LinkedList<>();
+ byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
+ short afi = Constants.AFI_EVPN_VALUE;
+ byte safi = Constants.SAFI_EVPN_VALUE;
+ boolean isEvpnCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
+ afi, safi);
+ if (!isEvpnCapabilitySet) {
+ log.debug("Peer do not support BGP Evpn capability",
+ channel.getRemoteAddress());
+ return;
+ }
+ attributesList.add(new Origin((byte) 0));
+
+ if (sessionType != 0) {
+ // EBGP
+ if (!bgpController.getConfig().getLargeASCapability()) {
+ List<Short> aspathSet = new ArrayList<>();
+ List<Short> aspathSeq = new ArrayList<>();
+ aspathSeq.add((short) bgpController.getConfig().getAsNumber());
+
+ AsPath asPath = new AsPath(aspathSet, aspathSeq);
+ attributesList.add(asPath);
+ } else {
+ List<Integer> aspathSet = new ArrayList<>();
+ List<Integer> aspathSeq = new ArrayList<>();
+ aspathSeq.add(bgpController.getConfig().getAsNumber());
+
+ As4Path as4Path = new As4Path(aspathSet, aspathSeq);
+ attributesList.add(as4Path);
+ }
+ } else {
+ attributesList.add(new AsPath());
+ }
+
+ if (!extcommunity.isEmpty()) {
+ attributesList.add(new BgpExtendedCommunity(extcommunity));
+ }
+ if (operType == FlowSpecOperation.ADD || operType == FlowSpecOperation.UPDATE) {
+ attributesList
+ .add(new MpReachNlri(evpnNlris, afi, safi, nextHop.getIp4Address()));
+ } else if (operType == FlowSpecOperation.DELETE) {
+ attributesList.add(new MpUnReachNlri(evpnNlris, afi, safi));
+ }
+
+ BgpMessage msg = Controller.getBgpMessageFactory4()
+ .updateMessageBuilder().setBgpPathAttributes(attributesList)
+ .build();
+ channel.write(Collections.singletonList(msg));
+ }
+
+ @Override
public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
ListIterator<BgpValueType> iterator = pathAttr.listIterator();
while (iterator.hasNext()) {
diff --git a/providers/bgp/BUCK b/providers/bgp/BUCK
index b5f516e..c6560b9 100644
--- a/providers/bgp/BUCK
+++ b/providers/bgp/BUCK
@@ -1,6 +1,7 @@
BUNDLES = [
'//providers/bgp/cfg:onos-providers-bgp-cfg',
'//providers/bgp/topology:onos-providers-bgp-topology',
+ '//providers/bgp/route:onos-providers-bgp-route',
'//providers/bgp/cli:onos-providers-bgp-cli',
'//protocols/bgp/api:onos-protocols-bgp-api',
'//protocols/bgp/ctl:onos-protocols-bgp-ctl',
diff --git a/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpAppConfig.java b/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpAppConfig.java
index f6583d4..23a4f5a 100644
--- a/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpAppConfig.java
+++ b/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpAppConfig.java
@@ -30,9 +30,9 @@
import java.util.ArrayList;
import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
-import static com.google.common.base.Preconditions.checkNotNull;
/**
* Configuration object for BGP.
@@ -52,6 +52,7 @@
public static final String LARGE_AS_CAPABILITY = "largeAsCapability";
public static final String FLOW_SPEC_CAPABILITY = "flowSpecCapability";
public static final String FLOW_SPEC_RPD_CAPABILITY = "flowSpecRpdCapability";
+ public static final String EVPN_CAPABILITY = "evpnCapability";
public static final String BGP_PEER = "bgpPeer";
public static final String PEER_IP = "peerIp";
@@ -78,12 +79,14 @@
bgpConfig = bgpController.getConfig();
fields = hasOnlyFields(ROUTER_ID, LOCAL_AS, MAX_SESSION, LS_CAPABILITY,
- HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY, FLOW_SPEC_RPD_CAPABILITY, BGP_PEER) &&
+ HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY,
+ FLOW_SPEC_RPD_CAPABILITY, BGP_PEER, EVPN_CAPABILITY) &&
isIpAddress(ROUTER_ID, MANDATORY) && isNumber(LOCAL_AS, MANDATORY) &&
isNumber(MAX_SESSION, OPTIONAL, MIN_SESSION_NUMBER, MAX_SESSION_NUMBER)
&& isNumber(HOLD_TIME, OPTIONAL, MIN_HOLDTIME, MAX_HOLDTIME) &&
isBoolean(LS_CAPABILITY, OPTIONAL) && isBoolean(LARGE_AS_CAPABILITY, OPTIONAL) &&
- isString(FLOW_SPEC_CAPABILITY, OPTIONAL) && isBoolean(FLOW_SPEC_RPD_CAPABILITY, OPTIONAL);
+ isString(FLOW_SPEC_CAPABILITY, OPTIONAL) && isBoolean(FLOW_SPEC_RPD_CAPABILITY, OPTIONAL)
+ && isBoolean(EVPN_CAPABILITY, OPTIONAL);
if (!fields) {
return fields;
@@ -182,6 +185,15 @@
}
/**
+ * Returns evpn capability support from the configuration.
+ *
+ * @return evpn capability
+ */
+ public boolean evpnCapability() {
+ return Boolean.parseBoolean(get(EVPN_CAPABILITY, null));
+ }
+
+ /**
* Validates the hold time value.
*
* @return true if valid else false
diff --git a/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpCfgProvider.java b/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpCfgProvider.java
index 48eaa73..ad06c1d 100644
--- a/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpCfgProvider.java
+++ b/providers/bgp/cfg/src/main/java/org/onosproject/provider/bgp/cfg/impl/BgpCfgProvider.java
@@ -127,6 +127,7 @@
bgpConfig.setHoldTime(config.holdTime());
bgpConfig.setMaxSession(config.maxSession());
bgpConfig.setLargeASCapability(config.largeAsCapability());
+ bgpConfig.setEvpnCapability(config.evpnCapability());
if (config.flowSpecCapability() == null) {
bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE);
diff --git a/providers/bgp/pom.xml b/providers/bgp/pom.xml
index d2ef820..cd4c214 100644
--- a/providers/bgp/pom.xml
+++ b/providers/bgp/pom.xml
@@ -28,7 +28,8 @@
<module>cfg</module>
<module>app</module>
<module>cli</module>
- </modules>
+ <module>route</module>
+ </modules>
<dependencies>
<dependency>
diff --git a/providers/bgp/route/BUCK b/providers/bgp/route/BUCK
new file mode 100755
index 0000000..bf38465
--- /dev/null
+++ b/providers/bgp/route/BUCK
@@ -0,0 +1,16 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//protocols/bgp/api:onos-protocols-bgp-api',
+ '//protocols/bgp/bgpio:onos-protocols-bgp-bgpio',
+ '//incubator/store:onos-incubator-store',
+ '//incubator/api:onos-incubator-api',
+]
+
+TEST_DEPS = [
+ '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+ test_deps = TEST_DEPS,
+)
diff --git a/providers/bgp/route/pom.xml b/providers/bgp/route/pom.xml
new file mode 100755
index 0000000..e3bffcd
--- /dev/null
+++ b/providers/bgp/route/pom.xml
@@ -0,0 +1,50 @@
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-bgp-providers</artifactId>
+ <version>1.11.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>onos-bgp-provider-route</artifactId>
+ <packaging>bundle</packaging>
+ <description>BGP route provider</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-bgp-api</artifactId>
+ </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.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-bgp-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/BgpRouteProvider.java b/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/BgpRouteProvider.java
new file mode 100755
index 0000000..81bd1d5
--- /dev/null
+++ b/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/BgpRouteProvider.java
@@ -0,0 +1,394 @@
+/*
+ * 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.provider.bgp.route.impl;
+
+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.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpPeer.FlowSpecOperation;
+import org.onosproject.bgp.controller.BgpRouteListener;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
+import org.onosproject.bgpio.protocol.BgpUpdateMsg;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
+import org.onosproject.bgpio.types.BgpEvpnEsi;
+import org.onosproject.bgpio.types.BgpEvpnLabel;
+import org.onosproject.bgpio.types.BgpExtendedCommunity;
+import org.onosproject.bgpio.types.BgpNlriType;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.MpReachNlri;
+import org.onosproject.bgpio.types.MpUnReachNlri;
+import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.types.RouteTarget;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.incubator.net.routing.EvpnRoute.Source;
+import org.onosproject.incubator.net.routing.EvpnRouteAdminService;
+import org.onosproject.incubator.net.routing.EvpnRouteEvent;
+import org.onosproject.incubator.net.routing.EvpnRouteListener;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Provider which uses an BGP controller to update/delete route.
+ */
+@Component(immediate = true)
+public class BgpRouteProvider extends AbstractProvider {
+
+ /**
+ * Creates an instance of BGP route provider.
+ */
+ public BgpRouteProvider() {
+ super(new ProviderId("route",
+ "org.onosproject.provider.bgp.route.impl"));
+ }
+
+ private static final Logger log = LoggerFactory
+ .getLogger(BgpRouteProvider.class);
+
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected BgpController controller;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected EvpnRouteAdminService evpnRouteAdminService;
+
+ private final InternalEvpnRouteListener routeListener = new
+ InternalEvpnRouteListener();
+ private final InternalBgpRouteListener bgpRouteListener = new
+ InternalBgpRouteListener();
+
+
+ @Activate
+ public void activate() {
+ controller.addRouteListener(bgpRouteListener);
+ evpnRouteAdminService.addListener(routeListener);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ controller.removeRouteListener(bgpRouteListener);
+ evpnRouteAdminService.removeListener(routeListener);
+ log.info("Stopped");
+ }
+
+ /**
+ * Handles the bgp route update message.
+ *
+ * @param operationType operationType
+ * @param rdString rd
+ * @param exportRtList rt export
+ * @param nextHop next hop
+ * @param macAddress mac address
+ * @param ipAddress ip address
+ * @param labelInt label
+ */
+ private void sendUpdateMessage(FlowSpecOperation operationType,
+ String rdString,
+ List<VpnRouteTarget> exportRtList,
+ IpAddress nextHop,
+ MacAddress macAddress,
+ InetAddress ipAddress,
+ int labelInt) {
+ log.info("sendUpdateMessage 1");
+
+ List<BgpEvpnNlri> eVpnNlri = new ArrayList<BgpEvpnNlri>();
+ RouteDistinguisher rd = stringToRD(rdString);
+ BgpEvpnEsi esi = new BgpEvpnEsi(new byte[10]);
+ int ethernetTagID = 0;
+ BgpEvpnLabel mplsLabel1 = intToLabel(labelInt);
+ BgpEvpnLabel mplsLabel2 = null;
+
+ List<BgpValueType> extCom = new ArrayList<BgpValueType>();
+ if ((operationType == FlowSpecOperation.UPDATE)
+ && (!exportRtList.isEmpty())) {
+ for (VpnRouteTarget rt : exportRtList) {
+ RouteTarget rTarget = stringToRT(rt.getRouteTarget());
+ extCom.add(rTarget);
+ }
+ }
+ BgpEvpnRouteType2Nlri routeTypeSpec =
+ new BgpEvpnRouteType2Nlri(rd,
+ esi,
+ ethernetTagID,
+ macAddress,
+ ipAddress,
+ mplsLabel1,
+ mplsLabel2);
+ BgpEvpnNlri nlri = new BgpEvpnNlriImpl(BgpEvpnRouteType
+ .MAC_IP_ADVERTISEMENT
+ .getType(),
+ routeTypeSpec);
+ eVpnNlri.add(nlri);
+ log.info("sendUpdateMessage 2");
+ controller.getPeers().forEach(peer -> {
+ log.info("Send route update eVpnComponents {} to peer {}",
+ eVpnNlri, peer);
+ peer.updateEvpnNlri(operationType, nextHop, extCom, eVpnNlri);
+ });
+
+ }
+
+ private static RouteDistinguisher stringToRD(String rdString) {
+ if (rdString.contains(":")) {
+ if ((rdString.indexOf(":") != 0)
+ && (rdString.indexOf(":") != rdString.length() - 1)) {
+ String[] tem = rdString.split(":");
+ short as = (short) Integer.parseInt(tem[0]);
+ int assignednum = Integer.parseInt(tem[1]);
+ long rd = ((long) assignednum & 0xFFFFFFFFL)
+ | (((long) as << 32) & 0xFFFFFFFF00000000L);
+ return new RouteDistinguisher(rd);
+ }
+ }
+ return null;
+
+ }
+
+ private static String rdToString(RouteDistinguisher rd) {
+ long rdLong = rd.getRouteDistinguisher();
+ int as = (int) ((rdLong & 0xFFFFFFFF00000000L) >> 32);
+ int assignednum = (int) (rdLong & 0xFFFFFFFFL);
+ String result = as + ":" + assignednum;
+ return result;
+ }
+
+ private static RouteTarget stringToRT(String rdString) {
+ if (rdString.contains(":")) {
+ if ((rdString.indexOf(":") != 0)
+ && (rdString.indexOf(":") != rdString.length() - 1)) {
+ String[] tem = rdString.split(":");
+ short as = Short.parseShort(tem[0]);
+ int assignednum = Integer.parseInt(tem[1]);
+
+ byte[] rt = new byte[]{(byte) ((as >> 8) & 0xFF),
+ (byte) (as & 0xFF),
+ (byte) ((assignednum >> 24) & 0xFF),
+ (byte) ((assignednum >> 16) & 0xFF),
+ (byte) ((assignednum >> 8) & 0xFF),
+ (byte) (assignednum & 0xFF)};
+ short type = 0x02;
+ return new RouteTarget(type, rt);
+ }
+ }
+ return null;
+
+ }
+
+ private static String rtToString(RouteTarget rt) {
+ byte[] b = rt.getRouteTarget();
+
+ int assignednum = b[5] & 0xFF | (b[4] & 0xFF) << 8 | (b[3] & 0xFF) << 16
+ | (b[2] & 0xFF) << 24;
+ short as = (short) (b[1] & 0xFF | (b[0] & 0xFF) << 8);
+ String result = as + ":" + assignednum;
+ return result;
+ }
+
+ private static BgpEvpnLabel intToLabel(int labelInt) {
+ byte[] label = new byte[]{(byte) ((labelInt >> 16) & 0xFF),
+ (byte) ((labelInt >> 8) & 0xFF),
+ (byte) (labelInt & 0xFF)};
+
+ return new BgpEvpnLabel(label);
+ }
+
+ private static int labelToInt(BgpEvpnLabel label) {
+ byte[] b = label.getMplsLabel();
+ return b[2] & 0xFF | (b[1] & 0xFF) << 8 | (b[0] & 0xFF) << 16;
+
+ }
+
+ private class InternalBgpRouteListener implements BgpRouteListener {
+
+ @Override
+ public void processRoute(BgpId bgpId, BgpUpdateMsg updateMsg) {
+ log.info("Evpn route event received from BGP protocol");
+ List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes()
+ .pathAttributes();
+ Iterator<BgpValueType> iterator = pathAttr.iterator();
+ RouteTarget rt = null;
+ List<VpnRouteTarget> exportRt = new LinkedList<>();
+ List<BgpEvpnNlri> evpnReachNlri = new LinkedList<>();
+ List<BgpEvpnNlri> evpnUnreachNlri = new LinkedList<>();
+
+ Ip4Address ipNextHop = null;
+ while (iterator.hasNext()) {
+ BgpValueType attr = iterator.next();
+ if (attr instanceof MpReachNlri) {
+ MpReachNlri mpReachNlri = (MpReachNlri) attr;
+ ipNextHop = mpReachNlri.nexthop4();
+ if (mpReachNlri
+ .getNlriDetailsType() == BgpNlriType.EVPN) {
+ evpnReachNlri.addAll(mpReachNlri.bgpEvpnNlri());
+ }
+
+ }
+ if (attr instanceof MpUnReachNlri) {
+ MpUnReachNlri mpUnReachNlri = (MpUnReachNlri) attr;
+ if (mpUnReachNlri
+ .getNlriDetailsType() == BgpNlriType.EVPN) {
+ evpnUnreachNlri.addAll(mpUnReachNlri.bgpEvpnNlri());
+ }
+ }
+
+ if (attr instanceof BgpExtendedCommunity) {
+ BgpExtendedCommunity extCom = (BgpExtendedCommunity) attr;
+ Iterator<BgpValueType> extIte = extCom.fsActionTlv()
+ .iterator();
+ while (extIte.hasNext()) {
+ BgpValueType extAttr = extIte.next();
+ if (extAttr instanceof RouteTarget) {
+ rt = (RouteTarget) extAttr;
+ exportRt.add(VpnRouteTarget
+ .routeTarget(rtToString(rt)));
+ break;
+ }
+ }
+ }
+ }
+
+ if ((!exportRt.isEmpty()) && (!evpnReachNlri.isEmpty())) {
+ for (BgpEvpnNlri nlri : evpnReachNlri) {
+ if (nlri.getRouteType() == BgpEvpnRouteType
+ .MAC_IP_ADVERTISEMENT) {
+ BgpEvpnRouteType2Nlri macIpAdvNlri
+ = (BgpEvpnRouteType2Nlri) nlri
+ .getNlri();
+ MacAddress macAddress = macIpAdvNlri.getMacAddress();
+ Ip4Address ipAddress = Ip4Address
+ .valueOf(macIpAdvNlri.getIpAddress());
+ RouteDistinguisher rd = macIpAdvNlri
+ .getRouteDistinguisher();
+ BgpEvpnLabel label = macIpAdvNlri.getMplsLable1();
+ log.info("Route Provider received bgp packet {} " +
+ "to route system.",
+ macIpAdvNlri.toString());
+ // Add route to route system
+ Source source = Source.REMOTE;
+ EvpnRoute evpnRoute = new EvpnRoute(source,
+ macAddress,
+ IpPrefix.valueOf(ipAddress, 32),
+ ipNextHop,
+ rdToString(rd),
+ null, //empty rt
+ exportRt,
+ labelToInt(label));
+
+ evpnRouteAdminService.update(Collections
+ .singleton(evpnRoute));
+ }
+ }
+ }
+
+ if (!evpnUnreachNlri.isEmpty()) {
+ for (BgpEvpnNlri nlri : evpnUnreachNlri) {
+ if (nlri.getRouteType() == BgpEvpnRouteType
+ .MAC_IP_ADVERTISEMENT) {
+ BgpEvpnRouteType2Nlri macIpAdvNlri
+ = (BgpEvpnRouteType2Nlri) nlri
+ .getNlri();
+ MacAddress macAddress = macIpAdvNlri.getMacAddress();
+ Ip4Address ipAddress = Ip4Address
+ .valueOf(macIpAdvNlri.getIpAddress());
+ RouteDistinguisher rd = macIpAdvNlri
+ .getRouteDistinguisher();
+ BgpEvpnLabel label = macIpAdvNlri.getMplsLable1();
+ log.info("Route Provider received bgp packet {} " +
+ "and remove from route system.",
+ macIpAdvNlri.toString());
+ // Delete route from route system
+ Source source = Source.REMOTE;
+ // For mpUnreachNlri, nexthop and rt is null
+ EvpnRoute evpnRoute = new EvpnRoute(source,
+ macAddress,
+ IpPrefix.valueOf(ipAddress, 32),
+ null,
+ rdToString(rd),
+ null,
+ null,
+ labelToInt(label));
+
+ evpnRouteAdminService.withdraw(Collections
+ .singleton(evpnRoute));
+ }
+ }
+ }
+ }
+ }
+
+ private class InternalEvpnRouteListener implements EvpnRouteListener {
+
+ @Override
+ public void event(EvpnRouteEvent event) {
+ log.info("evpnroute event is received from evpn route manager");
+ FlowSpecOperation operationType = null;
+ EvpnRoute route = event.subject();
+ EvpnRoute evpnRoute = route;
+ log.info("Event received for public route {}", evpnRoute);
+ if (evpnRoute.source().equals(Source.REMOTE)) {
+ return;
+ }
+ switch (event.type()) {
+ case ROUTE_ADDED:
+ case ROUTE_UPDATED:
+ log.info("route added");
+ operationType = FlowSpecOperation.UPDATE;
+ break;
+ case ROUTE_REMOVED:
+ log.info("route deleted");
+ operationType = FlowSpecOperation.DELETE;
+ break;
+ default:
+ break;
+ }
+
+ String rdString = evpnRoute.routeDistinguisher()
+ .getRouteDistinguisher();
+ MacAddress macAddress = evpnRoute.prefixMac();
+ InetAddress inetAddress = evpnRoute.prefixIp().address().toInetAddress();
+ IpAddress nextHop = evpnRoute.ipNextHop();
+ List<VpnRouteTarget> exportRtList = evpnRoute
+ .exportRouteTarget();
+ int labelInt = evpnRoute.label().getLabel();
+
+ sendUpdateMessage(operationType,
+ rdString,
+ exportRtList,
+ nextHop,
+ macAddress,
+ inetAddress,
+ labelInt);
+ }
+ }
+}
\ No newline at end of file
diff --git a/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/package-info.java b/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/package-info.java
new file mode 100755
index 0000000..97f14ab
--- /dev/null
+++ b/providers/bgp/route/src/main/java/org/onosproject/provider/bgp/route/impl/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * Provider that uses BGP controller as a means of infrastructure route exchange.
+ */
+package org.onosproject.provider.bgp.route.impl;
\ No newline at end of file
diff --git a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpControllerAdapter.java b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpControllerAdapter.java
index d8673cd..8102f17 100644
--- a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpControllerAdapter.java
+++ b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpControllerAdapter.java
@@ -23,6 +23,7 @@
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpPeerManager;
+import org.onosproject.bgp.controller.BgpRouteListener;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpMessage;
@@ -130,6 +131,21 @@
}
@Override
+ public void addRouteListener(BgpRouteListener listener) {
+
+ }
+
+ @Override
+ public void removeRouteListener(BgpRouteListener listener) {
+
+ }
+
+ @Override
+ public Set<BgpRouteListener> routeListener() {
+ return null;
+ }
+
+ @Override
public void addListener(BgpNodeListener listener) {
// TODO Auto-generated method stub
}