Adding BGP provider code to support EVPN

Change-Id: Ic5508749b64a47a70f1aabd9324e9f89e85fa39f
This commit is contained in:
Mohammad Shahid 2017-08-09 11:49:40 +05:30 committed by Jonathan Hart
parent e1e968e055
commit 30fedc50be
36 changed files with 2297 additions and 69 deletions

View File

@ -345,4 +345,18 @@ public interface BgpCfg {
* @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();
}

View File

@ -179,5 +179,25 @@ public interface BgpController {
* @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();
}

View File

@ -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 @@ public interface BgpPeer {
* @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);
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -148,6 +148,16 @@ public interface BgpOpenMsg extends BgpMessage {
*/
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);
}

View File

@ -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);
}

View File

@ -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;
}
}

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.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;
}
}

View File

@ -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();
}
}

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.
*/
/**
* BGP Protocol evpn components.
*/
package org.onosproject.bgpio.protocol.evpn;

View File

@ -322,6 +322,7 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg {
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 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg {
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 @@ public class BgpOpenMsgVer4 implements BgpOpenMsg {
this.isFlowSpecRpdCapabilityTlvSet = isFlowSpecRpdCapabilityTlvSet;
return this;
}
@Override
public Builder setEvpnCapabilityTlv(boolean isEvpnCapabilitySet) {
this.isEvpnCapabilityTlvSet = isEvpnCapabilitySet;
return this;
}
}
@Override

View File

@ -246,11 +246,17 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
}
}
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) {

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -90,6 +90,11 @@ public class BgpExtendedCommunity implements BgpValueType {
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 @@ public class BgpExtendedCommunity implements BgpValueType {
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 @@ public class BgpExtendedCommunity implements BgpValueType {
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) {

View File

@ -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;
}

View File

@ -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 @@ public class MpReachNlri implements BgpValueType {
private final byte safi;
private final Ip4Address ipNextHop;
private BgpFlowSpecNlri bgpFlowSpecNlri;
private List<BgpEvpnNlri> evpnNlri;
/**
* Constructor to initialize parameters.
@ -71,6 +74,13 @@ public class MpReachNlri implements BgpValueType {
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;
@ -81,6 +91,24 @@ public class MpReachNlri implements BgpValueType {
this.safi = safi;
}
/**
* 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.
*
@ -117,6 +145,60 @@ public class MpReachNlri implements BgpValueType {
return this.bgpFlowSpecNlri;
}
/**
* 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.
*
@ -272,6 +354,29 @@ public class MpReachNlri implements BgpValueType {
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 @@ public class MpReachNlri implements BgpValueType {
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;

View File

@ -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 @@ public class MpUnReachNlri implements BgpValueType {
private final List<BgpLSNlri> mpUnReachNlri;
private final int length;
private BgpFlowSpecNlri bgpFlowSpecNlri;
private List<BgpEvpnNlri> evpnNlri;
/**
* Constructor to initialize parameters.
@ -67,6 +70,13 @@ public class MpUnReachNlri implements BgpValueType {
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;
@ -76,6 +86,22 @@ public class MpUnReachNlri implements BgpValueType {
this.safi = safi;
}
/**
* 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.
*
@ -85,6 +111,60 @@ public class MpUnReachNlri implements BgpValueType {
return this.bgpFlowSpecNlri;
}
/**
* 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.
*
@ -226,6 +306,17 @@ public class MpUnReachNlri implements BgpValueType {
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 @@ public class MpUnReachNlri implements BgpValueType {
}
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;

View File

@ -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;
}
}

View File

@ -46,6 +46,9 @@ public final class Constants {
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 final class Constants {
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;

View File

@ -24,6 +24,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
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 @@ public class Validation {
}
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.
*

View File

@ -677,6 +677,8 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler {
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 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler {
.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 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler {
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 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler {
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 @@ class BgpChannelHandler extends IdleStateAwareChannelHandler {
}
}
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,

View File

@ -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.onosproject.bgp.controller.impl.BgpControllerImpl.BgpPeerManagerImpl;
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 @@ public class BgpConfig implements BgpCfg {
private BgpPeerManagerImpl peerManager;
private BgpController bgpController;
private boolean rpdCapability;
private boolean evpnCapability;
/*
* Constructor to initialize the values.
@ -141,6 +142,16 @@ public class BgpConfig implements BgpCfg {
this.rpdCapability = rpdCapability;
}
@Override
public boolean getEvpnCapability() {
return this.evpnCapability;
}
@Override
public void setEvpnCapability(boolean evpnCapability) {
this.evpnCapability = evpnCapability;
}
@Override
public String getRouterId() {
if (this.routerId != null) {

View File

@ -28,6 +28,7 @@ import org.onosproject.bgp.controller.BgpLocalRib;
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 @@ public class BgpControllerImpl implements BgpController {
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 @@ public class BgpControllerImpl implements BgpController {
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 @@ public class BgpControllerImpl implements BgpController {
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;
}
}

View File

@ -26,6 +26,7 @@ import org.onosproject.bgp.controller.BgpLocalRib;
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.BgpLinkLsNlriVer4;
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.MpReachNlri;
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;
@ -255,6 +256,69 @@ public class BgpPeerImpl implements BgpPeer {
sendFlowSpecUpdateMessageToPeer(operType, routeKey, flowSpec, wideCommunity);
}
@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();

View File

@ -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',

View File

@ -30,9 +30,9 @@ import org.slf4j.LoggerFactory;
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 class BgpAppConfig extends Config<ApplicationId> {
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 @@ public class BgpAppConfig extends Config<ApplicationId> {
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;
@ -181,6 +184,15 @@ public class BgpAppConfig extends Config<ApplicationId> {
return true;
}
/**
* 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.
*

View File

@ -127,6 +127,7 @@ public class BgpCfgProvider extends AbstractProvider {
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);

View File

@ -28,7 +28,8 @@
<module>cfg</module>
<module>app</module>
<module>cli</module>
</modules>
<module>route</module>
</modules>
<dependencies>
<dependency>

16
providers/bgp/route/BUCK Executable file
View File

@ -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,
)

50
providers/bgp/route/pom.xml Executable file
View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -23,6 +23,7 @@ import org.onosproject.bgp.controller.BgpLocalRib;
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;
@ -129,6 +130,21 @@ public class BgpControllerAdapter implements BgpController {
return null;
}
@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