aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java')
-rw-r--r--framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java242
1 files changed, 242 insertions, 0 deletions
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java
new file mode 100644
index 00000000..d3065f43
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp.controller.impl;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib;
+import org.onosproject.bgpio.types.AsPath;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.LocalPref;
+import org.onosproject.bgpio.types.Med;
+import org.onosproject.bgpio.types.Origin;
+import org.onosproject.bgpio.types.Origin.ORIGINTYPE;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of BGP best path Selection process.
+ */
+public final class BgpSelectionAlgo implements Comparator<PathAttrNlriDetailsLocalRib> {
+ private static final Logger log = LoggerFactory.getLogger(BgpSelectionAlgo.class);
+ LocalPref obj1LocPref = null;
+ AsPath obj1Aspath = null;
+ Origin obj1Origin = null;
+ Med obj1Med = null;
+ LocalPref obj2LocPref = null;
+ AsPath obj2Aspath = null;
+ Origin obj2Origin = null;
+ Med obj2Med = null;
+
+ @Override
+ public int compare(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
+ if (pathNlriDetails1 == null) {
+ return -1;
+ }
+ if (pathNlriDetails2 == null) {
+ return 1;
+ }
+ if (pathNlriDetails1.equals(pathNlriDetails2)) {
+ return 0;
+ }
+
+ List<BgpValueType> o1 = pathNlriDetails1.localRibNlridetails().pathAttributes();
+ List<BgpValueType> o2 = pathNlriDetails2.localRibNlridetails().pathAttributes();
+ ListIterator<BgpValueType> listIteratorObj1 = o1.listIterator();
+ ListIterator<BgpValueType> listIteratorObj2 = o2.listIterator();
+ storeAttr(listIteratorObj1, listIteratorObj2);
+
+ // prefer attribute with higher local preference
+ if (obj1LocPref != null || obj2LocPref != null && (obj1LocPref != null && !obj1LocPref.equals(obj2LocPref))) {
+ return compareLocalPref(obj1LocPref, obj2LocPref);
+ }
+
+ // prefer attribute with shortest Aspath
+ if (!obj1Aspath.equals(obj2Aspath)) {
+ Integer obj1Size = countASSize(obj1Aspath);
+ Integer obj2Size = countASSize(obj2Aspath);
+ if (obj1Size != obj2Size) {
+ return compareAsPath(obj1Size, obj2Size);
+ }
+ }
+
+ // prefer attribute with lowest origin type
+ if (!obj1Origin.equals(obj2Origin)) {
+ return compareOrigin(obj1Origin, obj2Origin);
+ }
+
+ // prefer attribute with lowest MED
+ if (obj1Med != null || obj2Med != null && (obj1Med != null && !obj1Med.equals(obj2Med))) {
+ return compareMed(obj1Med, obj2Med);
+ }
+
+ if ((pathNlriDetails1 != null || pathNlriDetails2 != null) && (pathNlriDetails1 != null && !pathNlriDetails1
+ .equals(pathNlriDetails2))) {
+ return comparePeerDetails(pathNlriDetails1, pathNlriDetails2);
+ }
+ return 0;
+ }
+
+ /**
+ * Compares local preference of two objects and returns object with higher preference.
+ *
+ * @param obj1LocPref local preference object1
+ * @param obj2LocPref local preference object2
+ * @return object with higher preference
+ */
+ int compareLocalPref(LocalPref obj1LocPref, LocalPref obj2LocPref) {
+ return ((Integer) (obj1LocPref.localPref())).compareTo((Integer) (obj2LocPref.localPref()));
+ }
+
+ /**
+ * Compares AsPath of two objects and returns object with shortest AsPath.
+ *
+ * @param obj1Size object1 AS count
+ * @param obj2Size object2 AS count
+ * @return
+ */
+ int compareAsPath(Integer obj1Size, Integer obj2Size) {
+ return obj1Size.compareTo(obj2Size);
+ }
+
+ /**
+ * Compare Origin of two objects and returns object with lowest origin value.
+ *
+ * @param obj1Origin Origin object1
+ * @param obj2Origin Origin object1
+ * @return object with lowest origin value
+ */
+ int compareOrigin(Origin obj1Origin, Origin obj2Origin) {
+ if (obj1Origin.origin() == ORIGINTYPE.IGP) {
+ return 1;
+ }
+ if (obj2Origin.origin() == ORIGINTYPE.IGP) {
+ return -1;
+ }
+ if (obj1Origin.origin() == ORIGINTYPE.EGP) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Compare Med of two objects and returns object with lowestMed value.
+ *
+ * @param obj1Med Med object1
+ * @param obj2Med Med object2
+ * @return returns object with lowestMed value
+ */
+ int compareMed(Med obj1Med, Med obj2Med) {
+ return ((Integer) (obj2Med.med())).compareTo((Integer) (obj1Med.med()));
+ }
+
+ /**
+ * Compares EBGP over IBGP, BGP identifier value and peer address.
+ *
+ * @param pathNlriDetails1 PathAttrNlriDetailsLocalRib object1
+ * @param pathNlriDetails2 PathAttrNlriDetailsLocalRib object2
+ * @return object which as EBGP over IBGP, lowest BGP identifier value and lowest peer address
+ */
+ int comparePeerDetails(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
+ // consider EBGP over IBGP
+ if (pathNlriDetails1.isLocalRibIbgpSession() != pathNlriDetails2.isLocalRibIbgpSession()) {
+ if (pathNlriDetails1 == null || pathNlriDetails1.isLocalRibIbgpSession()) {
+ return -1;
+ }
+ if (pathNlriDetails2 == null || pathNlriDetails2.isLocalRibIbgpSession()) {
+ return 1;
+ }
+ }
+ // prefer lowest BGP identifier value.
+ if (pathNlriDetails1.localRibIdentifier() != pathNlriDetails2.localRibIdentifier()) {
+ return ((Integer) pathNlriDetails2.localRibIdentifier())
+ .compareTo(pathNlriDetails1.localRibIdentifier());
+ }
+ //prefer lowest peer address
+ if (pathNlriDetails1.localRibIpAddress() != pathNlriDetails2.localRibIpAddress()) {
+ return pathNlriDetails2.localRibIpAddress().compareTo(pathNlriDetails1.localRibIpAddress());
+ }
+ return 0;
+ }
+
+ /**
+ * Returns ASes count of AsPath attribute , if AS_SET is present then count as 1.
+ *
+ * @param aspath object of AsPath
+ * @return count of ASes
+ */
+ Integer countASSize(AsPath aspath) {
+ boolean isASSet = false;
+ int count = 0;
+ if (!aspath.asPathSet().isEmpty()) {
+ isASSet = true;
+ }
+ if (!aspath.asPathSeq().isEmpty()) {
+ count = aspath.asPathSeq().size();
+ }
+ return isASSet ? ++count : count;
+ }
+
+ /**
+ * Stores BGP basic attributes of two objects.
+ *
+ * @param listIteratorObj1 list iterator of object1
+ * @param listIteratorObj2 list iterator of object2
+ */
+ void storeAttr(ListIterator<BgpValueType> listIteratorObj1, ListIterator<BgpValueType> listIteratorObj2) {
+ while (listIteratorObj1.hasNext()) {
+ BgpValueType pathAttributeObj1 = listIteratorObj1.next();
+ switch (pathAttributeObj1.getType()) {
+ case LocalPref.LOCAL_PREF_TYPE:
+ obj1LocPref = (LocalPref) pathAttributeObj1;
+ break;
+ case AsPath.ASPATH_TYPE:
+ obj1Aspath = (AsPath) pathAttributeObj1;
+ break;
+ case Origin.ORIGIN_TYPE:
+ obj1Origin = (Origin) pathAttributeObj1;
+ break;
+ case Med.MED_TYPE:
+ obj1Med = (Med) pathAttributeObj1;
+ break;
+ default:
+ log.debug("Got other type, Not required: " + pathAttributeObj1.getType());
+ }
+ }
+ while (listIteratorObj2.hasNext()) {
+ BgpValueType pathAttributeObj2 = listIteratorObj2.next();
+ switch (pathAttributeObj2.getType()) {
+ case LocalPref.LOCAL_PREF_TYPE:
+ obj2LocPref = (LocalPref) pathAttributeObj2;
+ break;
+ case AsPath.ASPATH_TYPE:
+ obj2Aspath = (AsPath) pathAttributeObj2;
+ break;
+ case Origin.ORIGIN_TYPE:
+ obj2Origin = (Origin) pathAttributeObj2;
+ break;
+ case Med.MED_TYPE:
+ obj2Med = (Med) pathAttributeObj2;
+ break;
+ default:
+ log.debug("Got other type, Not required: " + pathAttributeObj2.getType());
+ }
+ }
+ }
+} \ No newline at end of file