2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableList;
13 import java.util.Collection;
14 import java.util.List;
15 import javax.annotation.concurrent.NotThreadSafe;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPath;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.LocalPref;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.MultiExitDisc;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Origin;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.as.path.Segments;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.AListCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.ASetCase;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
28 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
32 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
36 final class BestPathState {
37 private static final Collection<PathArgument> AS_PATH = ImmutableList.<PathArgument>of(new NodeIdentifier(AsPath.QNAME), new NodeIdentifier(Segments.QNAME));
38 private static final Collection<PathArgument> LOCAL_PREF = ImmutableList.<PathArgument>of(new NodeIdentifier(LocalPref.QNAME), new NodeIdentifier(QName.create(LocalPref.QNAME, "pref")));
39 private static final Collection<PathArgument> MED = ImmutableList.<PathArgument>of(new NodeIdentifier(MultiExitDisc.QNAME), new NodeIdentifier(QName.create(MultiExitDisc.QNAME, "med")));
40 private static final Collection<PathArgument> ORIGIN = ImmutableList.<PathArgument>of(new NodeIdentifier(Origin.QNAME), new NodeIdentifier(QName.create(Origin.QNAME, "value")));
42 private final ContainerNode attributes;
43 private Long localPref;
44 private Long multiExitDisc;
45 private BgpOrigin origin;
46 private static final Long peerAs = 0L;
47 private static final int asPathLength = 0;
48 private boolean resolved;
50 BestPathState(final ContainerNode attributes) {
51 this.attributes = Preconditions.checkNotNull(attributes);
54 private static BgpOrigin fromString(final String originStr) {
61 return BgpOrigin.Incomplete;
63 throw new IllegalArgumentException("Unhandleed origin value " + originStr);
67 private void resolveValues() {
72 final Optional<NormalizedNode<?, ?>> maybeLocalPref = NormalizedNodes.findNode(this.attributes, LOCAL_PREF);
73 if (maybeLocalPref.isPresent()) {
74 this.localPref = (Long) ((LeafNode<?>)maybeLocalPref.get()).getValue();
76 this.localPref = null;
79 final Optional<NormalizedNode<?, ?>> maybeMultiExitDisc = NormalizedNodes.findNode(this.attributes, MED);
80 if (maybeMultiExitDisc.isPresent()) {
81 this.multiExitDisc = (Long) ((LeafNode<?>)maybeMultiExitDisc.get()).getValue();
83 this.multiExitDisc = null;
86 final Optional<NormalizedNode<?, ?>> maybeOrigin = NormalizedNodes.findNode(this.attributes, ORIGIN);
87 if (maybeOrigin.isPresent()) {
88 this.origin = fromString((String) ((LeafNode<?>)maybeOrigin.get()).getValue());
93 final Optional<NormalizedNode<?, ?>> maybeSegments = NormalizedNodes.findNode(this.attributes, AS_PATH);
94 if (maybeSegments.isPresent()) {
95 final UnkeyedListNode segments = (UnkeyedListNode) maybeSegments.get();
97 if (segments.getSize() != 0) {
98 // FIXME: peer AS number
100 // FIXME: asPathLength = countAsPath(this.bestState.getAsPath().getSegments());
101 final boolean haveSegment;
102 for (final UnkeyedListEntryNode s : segments.getValue()) {
108 this.resolved = true;
111 Long getLocalPref() {
113 return this.localPref;
116 Long getMultiExitDisc() {
118 return this.multiExitDisc;
121 BgpOrigin getOrigin() {
131 int getAsPathLength() {
136 private static int countAsPath(final List<Segments> segments) {
137 // an AS_SET counts as 1, no matter how many ASs are in the set.
139 boolean setPresent = false;
140 for (final Segments s : segments) {
141 if (s.getCSegment() instanceof ASetCase) {
144 final AListCase list = (AListCase) s.getCSegment();
145 count += list.getAList().getAsSequence().size();
148 return (setPresent) ? count + 1 : count;
151 private static AsNumber getPeerAs(final List<Segments> segments) {
152 if (segments.isEmpty()) {
156 final AListCase first = (AListCase) segments.get(0).getCSegment();
157 return first.getAList().getAsSequence().get(0).getAs();
160 ContainerNode getAttributes() {
161 return this.attributes;