Skip to content

Commit

Permalink
Fixed ALTO maps update issue
Browse files Browse the repository at this point in the history
Signed-off-by: jensenzhang <jingxuan.n.zhang@gmail.com>
  • Loading branch information
fno2010 committed Mar 3, 2020
1 parent 9107163 commit 88ff08a
Show file tree
Hide file tree
Showing 9 changed files with 460 additions and 82 deletions.
8 changes: 8 additions & 0 deletions alto-basic/auto-maps/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
<version>0.6.4</version>
<name>ODL :: alto :: ${project.artifactId}</name>
<packaging>bundle</packaging>
<properties>
<bgpcep.version>0.9.4</bgpcep.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.alto.core</groupId>
Expand All @@ -35,5 +38,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-topology</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.bgpcep</groupId>
<artifactId>bgp-rib-api</artifactId>
<version>${bgpcep.version}</version>
</dependency>
</dependencies>
</project>
29 changes: 27 additions & 2 deletions alto-basic/auto-maps/api/src/main/yang/alto-auto-maps.yang
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ module alto-auto-maps {
prefix "topology";
}

import "bgp-rib" {
prefix "rib";
}

import "alto-basic-types" {
prefix "alto-types";
}
Expand Down Expand Up @@ -71,13 +75,34 @@ module alto-auto-maps {
}
case bgp-simple-as-cluster {
container bgp-simple-as-params {
// FIXME: identityref is better
leaf bgp-rib {
type string;
type rib:rib-id;
}
}
}
}
}

list resource-cost-map {
key "resource-id";

leaf "resource-id" {
mandatory true;
type alto-types:resource-id;
}

leaf "dependent-network-map" {
mandatory true;
type alto-types:resource-id;
}

choice cost-algorithm {
case bgp-routes {
leaf-list alternative-bgp-ribs {
type rib:rib-id;
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions alto-basic/auto-maps/impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html

<dependency>
<groupId>org.opendaylight.bgpcep</groupId>
<artifactId>bgp-rib-api</artifactId>
<artifactId>bgp-inet</artifactId>
<version>${bgpcep.version}</version>
</dependency>

<dependency>
<groupId>org.opendaylight.bgpcep</groupId>
<artifactId>bgp-inet</artifactId>
<artifactId>bgp-linkstate</artifactId>
<version>${bgpcep.version}</version>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import com.google.common.base.Optional;
import org.opendaylight.alto.basic.manual.maps.ManualMapsUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
Expand All @@ -35,117 +38,141 @@
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class AltoAutoMapsBgpIpv4Updater implements AutoCloseable {
public class AltoAutoMapsBgpIpv4Updater implements DataTreeChangeListener<Tables>, AutoCloseable {

private static final Logger LOG = LoggerFactory.getLogger(AltoAutoMapsBgpIpv4Updater.class);

private final DataBroker dataBroker;
// private ListenerRegistration<?> registration;
private ListenerRegistration<?> registration;
private String contextId;
private ResourceNetworkMap networkMapConfig;
private InstanceIdentifier<Tables> tableIID;

public AltoAutoMapsBgpIpv4Updater(String contextId, ResourceNetworkMap networkMapConfig, final DataBroker dataBroker) {
this.dataBroker = dataBroker;
this.contextId = contextId;
this.networkMapConfig = networkMapConfig;
this.tableIID = getConfiguredIpv4Table(networkMapConfig);
registerBGPListener();
}

private void registerBGPListener() {
final ReadWriteTransaction wrx = dataBroker.newReadWriteTransaction();
try {
List<Map> networkMap = computeNetworkMapByBgpIpv4(networkMapConfig);
LOG.info("Putting auto generated network-map to manual map config...");
ManualMapsUtils.createResourceNetworkMap(contextId, networkMapConfig.getResourceId().getValue(),
networkMap, wrx);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
if (tableIID != null) {
registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
LogicalDatastoreType.OPERATIONAL, tableIID), this);
LOG.info("Listening on BGP Ipv4 Routing Table:", tableIID);
}
LOG.info("No routing table to listen");
}

private void updateNetworkMap() {
final ReadWriteTransaction wrx = dataBroker.newReadWriteTransaction();
List<Map> networkMap = computeNetworkMapByBgpIpv4(networkMapConfig);
LOG.info("Putting auto generated network-map to manual map config...");
ManualMapsUtils.createResourceNetworkMap(contextId, networkMapConfig.getResourceId().getValue(),
networkMap, wrx);
wrx.submit();
}

private List<Map> computeNetworkMapByBgpIpv4(ResourceNetworkMap networkMapConfig) throws InterruptedException, ExecutionException {
final ReadTransaction rx = dataBroker.newReadOnlyTransaction();
List<Map> networkMap = new LinkedList<>();
private InstanceIdentifier<Tables> getConfiguredIpv4Table(ResourceNetworkMap networkMapConfig) {
if (networkMapConfig.getAlgorithm() instanceof BgpSimpleAsCluster) {
BgpSimpleAsCluster algorithm = (BgpSimpleAsCluster) networkMapConfig.getAlgorithm();
String ribId = algorithm.getBgpSimpleAsParams().getBgpRib();
InstanceIdentifier<Tables> ribIID = InstanceIdentifier.builder(BgpRib.class)
.child(Rib.class, new RibKey(new RibId(ribId)))
RibId ribId = algorithm.getBgpSimpleAsParams().getBgpRib();
return InstanceIdentifier.builder(BgpRib.class)
.child(Rib.class, new RibKey(ribId))
.child(LocRib.class)
.child(Tables.class, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))
.build();
try {
Optional<Tables> optional = rx.read(LogicalDatastoreType.OPERATIONAL, ribIID).get();
if (optional.isPresent()) {
Tables table = optional.get();
if (table.getRoutes() instanceof Ipv4RoutesCase) {
Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
java.util.Map<String, List<IpPrefix>> pids = new LinkedHashMap<>();
for (Ipv4Route route : routesCase.getIpv4Routes().getIpv4Route()) {
List<Segments> segments = route.getAttributes().getAsPath().getSegments();
String pidName = "PID0";
if (segments != null && !segments.isEmpty()) {
List<AsNumber> asSequence = segments.get(segments.size() - 1).getAsSequence();
if (asSequence != null && !asSequence.isEmpty()) {
pidName = "PID" + asSequence.get(asSequence.size() - 1).getValue().toString();
} else {
List<AsNumber> asSet = segments.get(segments.size() - 1).getAsSet();
if (asSet != null && !asSet.isEmpty()) {
pidName = "PID" + String.join("-",
(String[]) Arrays.stream((AsNumber[]) asSet.toArray())
.map(s -> s.getValue().toString())
.toArray());
}
}
}
if (!pids.containsKey(pidName)) {
pids.put(pidName, new LinkedList<>());
}
pids.get(pidName).add(new IpPrefix(route.getPrefix()));
}
for (java.util.Map.Entry<String, List<IpPrefix>> entry : pids.entrySet()) {
String pidName = entry.getKey();
List<IpPrefix> prefixList = entry.getValue();
networkMap.add(new MapBuilder()
.setPid(new PidName(pidName))
.setEndpointAddressGroup(Arrays.asList(new EndpointAddressGroup[]{
new EndpointAddressGroupBuilder()
.setAddressType(new EndpointAddressType(EndpointAddressType.Enumeration.Ipv4))
.setEndpointPrefix(prefixList)
.build()
}))
.build());
}
} else {
throw new ExecutionException("Unsupported route type", null);
} else {
LOG.error("Unsupported algorithm for bgp topology");
}
return null;
}

@Override
public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Tables>> changes) {
updateNetworkMap();
}

private List<Map> computeNetworkMapByBgpIpv4(ResourceNetworkMap networkMapConfig) {
final ReadTransaction rx = dataBroker.newReadOnlyTransaction();
List<Map> networkMap = new LinkedList<>();
try {
Optional<Tables> optional = rx.read(LogicalDatastoreType.OPERATIONAL, tableIID).get();
if (optional.isPresent()) {
Tables table = optional.get();
if (table.getRoutes() instanceof Ipv4RoutesCase) {
java.util.Map<String, List<IpPrefix>> pids = getPIDClusters((Ipv4RoutesCase) table.getRoutes());
for (java.util.Map.Entry<String, List<IpPrefix>> entry : pids.entrySet()) {
String pidName = entry.getKey();
List<IpPrefix> prefixList = entry.getValue();
networkMap.add(new MapBuilder()
.setPid(new PidName(pidName))
.setEndpointAddressGroup(Arrays.asList(new EndpointAddressGroup[]{
new EndpointAddressGroupBuilder()
.setAddressType(new EndpointAddressType(EndpointAddressType.Enumeration.Ipv4))
.setEndpointPrefix(prefixList)
.build()
}))
.build());
}
} else {
throw new InterruptedException("BGP Local RIB not found");
LOG.error("Unsupported route type");
}
} catch (InterruptedException | ExecutionException e) {
throw e;
} else {
LOG.error("BGP Local RIB not found");
}
} else {
throw new InterruptedException("Unsupported algorithm for bgp topology");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return networkMap;
}

private java.util.Map<String, List<IpPrefix>> getPIDClusters(Ipv4RoutesCase routesCase) {
java.util.Map<String, List<IpPrefix>> pids = new LinkedHashMap<>();
for (Ipv4Route route : routesCase.getIpv4Routes().getIpv4Route()) {
List<Segments> segments = route.getAttributes().getAsPath().getSegments();
String pidName = "PID0";
if (segments != null && !segments.isEmpty()) {
List<AsNumber> asSequence = segments.get(segments.size() - 1).getAsSequence();
if (asSequence != null && !asSequence.isEmpty()) {
pidName = "PID" + asSequence.get(asSequence.size() - 1).getValue().toString();
} else {
List<AsNumber> asSet = segments.get(segments.size() - 1).getAsSet();
if (asSet != null && !asSet.isEmpty()) {
pidName = "PID" + String.join("-",
(String[]) Arrays.stream((AsNumber[]) asSet.toArray())
.map(s -> s.getValue().toString())
.toArray());
}
}
}
if (!pids.containsKey(pidName)) {
pids.put(pidName, new LinkedList<>());
}
pids.get(pidName).add(new IpPrefix(route.getPrefix()));
}
return pids;
}

@Override
public void close() throws Exception {
if (registration != null) {
registration.close();
}
LOG.info("BGP IPv4 updater closed");
}
}
Loading

0 comments on commit 88ff08a

Please sign in to comment.