org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnNlriParser Maven / Gradle / Ivy
/*
* Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.protocol.bgp.flowspec.l3vpn;
import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.extractRouteDistinguisher;
import com.google.common.annotations.VisibleForTesting;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecNlriParser;
import org.opendaylight.protocol.bgp.flowspec.FlowspecTypeRegistry;
import org.opendaylight.protocol.bgp.parser.BGPParsingException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.Flowspec;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.FlowspecBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNlriParser {
private static final Logger LOG = LoggerFactory.getLogger(AbstractFlowspecL3vpnNlriParser.class);
public static final NodeIdentifier RD_NID =
new NodeIdentifier(QName.create(Flowspec.QNAME, "route-distinguisher").intern());
protected AbstractFlowspecL3vpnNlriParser(final FlowspecTypeRegistry flowspecTypeRegistry) {
super(flowspecTypeRegistry);
}
@Override
public final String stringNlri(final DataContainerNode flowspec) {
final StringBuilder buffer = new StringBuilder();
final RouteDistinguisher rd = extractRouteDistinguisher(flowspec, RD_NID);
if (rd != null) {
buffer.append("[l3vpn with route-distinguisher ").append(rd.stringValue()).append("] ");
}
buffer.append(super.stringNlri(flowspec));
return buffer.toString();
}
/**
* For flowspec-l3vpn, there is a route distinguisher field at the beginning of NLRI (8 bytes).
*/
private static @NonNull RouteDistinguisher readRouteDistinguisher(final ByteBuf nlri) {
final var rd = RouteDistinguisherUtil.parseRouteDistinguisher(nlri);
LOG.trace("Route Distinguisher read from NLRI: {}", rd);
return rd;
}
@VisibleForTesting
public final void serializeNlri(final @NonNull RouteDistinguisher rd, final List flowspecList,
final @Nullable PathId pathId, final @NonNull ByteBuf buffer) {
final var nlri = Unpooled.buffer();
RouteDistinguisherUtil.serializeRouteDistinquisher(rd, nlri);
serializeNlri(flowspecList, nlri);
appendNlri(pathId, nlri, buffer);
}
@Override
protected final DestinationType parseAdvertizedNlri(final ByteBuf nlri, final PathId pathId)
throws BGPParsingException {
readNlriLength(nlri);
return createAdvertizedRoutesDestinationType(readRouteDistinguisher(nlri),
parseL3vpnNlriFlowspecList(nlri), pathId);
}
/**
* Create advertized destination type.
*
* @param rd the RouteDistinguisher
* @param flowspecList a list of {@link Flowspec}s
* @param pathId associated path id with given destination
* @return created destination type
*/
protected abstract @NonNull DestinationType createAdvertizedRoutesDestinationType(RouteDistinguisher rd,
@Nullable List flowspecList, @Nullable PathId pathId);
@Override
protected final DestinationType parseWithdrawnNlri(final ByteBuf nlri, final PathId pathId)
throws BGPParsingException {
readNlriLength(nlri);
return createWithdrawnDestinationType(readRouteDistinguisher(nlri), parseL3vpnNlriFlowspecList(nlri), pathId);
}
/**
* Create withdrawn destination type.
*
* @param rd the RouteDistinguisher
* @param flowspecList a list of {@link Flowspec}s
* @param pathId associated path id with given destination
* @return created destination type
*/
protected abstract @NonNull DestinationType createWithdrawnDestinationType(RouteDistinguisher rd,
@Nullable List flowspecList, @Nullable PathId pathId);
private @Nullable List parseL3vpnNlriFlowspecList(final ByteBuf nlri) {
if (!nlri.isReadable()) {
return null;
}
final var fss = new ArrayList();
while (nlri.isReadable()) {
fss.add(new FlowspecBuilder().setFlowspecType(flowspecTypeRegistry.parseFlowspecType(nlri)).build());
}
return fss;
}
}