use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder in project bgpcep by opendaylight.
the class BGPUpdateMessageParser method parseMessageBody.
/**
* Parse Update message from buffer. Calls {@link #checkMandatoryAttributesPresence(Update, RevisedErrorHandling)}
* to check for presence of mandatory attributes.
*
* @param buffer Encoded BGP message in ByteBuf
* @param messageLength Length of the BGP message
* @param constraint Peer specific constraints
* @return Parsed Update message body
*/
@Override
public Update parseMessageBody(final ByteBuf buffer, final int messageLength, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException {
checkArgument(buffer != null && buffer.isReadable(), "Buffer cannot be null or empty.");
final UpdateBuilder builder = new UpdateBuilder();
final boolean isMultiPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
final RevisedErrorHandling errorHandling = RevisedErrorHandling.from(constraint);
final int withdrawnRoutesLength = buffer.readUnsignedShort();
if (withdrawnRoutesLength > 0) {
final List<WithdrawnRoutes> withdrawnRoutes = new ArrayList<>();
final ByteBuf withdrawnRoutesBuffer = buffer.readSlice(withdrawnRoutesLength);
while (withdrawnRoutesBuffer.isReadable()) {
final WithdrawnRoutesBuilder withdrawnRoutesBuilder = new WithdrawnRoutesBuilder();
if (isMultiPathSupported) {
withdrawnRoutesBuilder.setPathId(PathIdUtil.readPathId(withdrawnRoutesBuffer));
}
withdrawnRoutesBuilder.setPrefix(readPrefix(withdrawnRoutesBuffer, errorHandling, "Withdrawn Routes"));
withdrawnRoutes.add(withdrawnRoutesBuilder.build());
}
builder.setWithdrawnRoutes(withdrawnRoutes);
}
final int totalPathAttrLength = buffer.readUnsignedShort();
if (withdrawnRoutesLength == 0 && totalPathAttrLength == 0) {
return builder.build();
}
Optional<BGPTreatAsWithdrawException> withdrawCauseOpt;
if (totalPathAttrLength > 0) {
final ParsedAttributes attributes = parseAttributes(buffer, totalPathAttrLength, constraint);
builder.setAttributes(attributes.getAttributes());
withdrawCauseOpt = attributes.getWithdrawCause();
} else {
withdrawCauseOpt = Optional.empty();
}
final List<Nlri> nlri = new ArrayList<>();
while (buffer.isReadable()) {
final NlriBuilder nlriBuilder = new NlriBuilder();
if (isMultiPathSupported) {
nlriBuilder.setPathId(PathIdUtil.readPathId(buffer));
}
nlriBuilder.setPrefix(readPrefix(buffer, errorHandling, "NLRI"));
nlri.add(nlriBuilder.build());
}
if (!nlri.isEmpty()) {
builder.setNlri(nlri);
}
try {
checkMandatoryAttributesPresence(builder.build(), errorHandling);
} catch (BGPTreatAsWithdrawException e) {
LOG.debug("Well-known mandatory attributes missing", e);
if (withdrawCauseOpt.isPresent()) {
final BGPTreatAsWithdrawException exception = withdrawCauseOpt.get();
exception.addSuppressed(e);
withdrawCauseOpt = Optional.of(exception);
} else {
withdrawCauseOpt = Optional.of(e);
}
}
Update msg = builder.build();
if (withdrawCauseOpt.isPresent()) {
// Attempt to apply treat-as-withdraw
msg = withdrawUpdate(msg, errorHandling, withdrawCauseOpt.get());
}
LOG.debug("BGP Update message was parsed {}.", msg);
return msg;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder in project bgpcep by opendaylight.
the class BGPUpdateMessageParser method withdrawUpdate.
private Update withdrawUpdate(final Update parsed, final RevisedErrorHandling errorHandling, final BGPTreatAsWithdrawException withdrawCause) throws BGPDocumentedException {
if (errorHandling == RevisedErrorHandling.NONE) {
throw new BGPDocumentedException(withdrawCause);
}
// TODO: additional checks as per RFC7606 section 5.2
LOG.debug("Converting BGP Update message {} to withdraw", parsed, withdrawCause);
final UpdateBuilder builder = new UpdateBuilder();
final List<Nlri> nlris = parsed.getNlri();
final List<WithdrawnRoutes> withdrawn;
if (nlris != null && !nlris.isEmpty()) {
withdrawn = Streams.concat(parsed.nonnullWithdrawnRoutes().stream(), nlris.stream().map(nlri -> new WithdrawnRoutesBuilder(nlri).build())).collect(ImmutableList.toImmutableList());
} else {
withdrawn = parsed.getWithdrawnRoutes();
}
builder.setWithdrawnRoutes(withdrawn);
final Attributes attributes = parsed.getAttributes();
if (attributes != null) {
builder.setAttributes(withdrawAttributes(attributes, withdrawCause));
}
return builder.build();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder in project bgpcep by opendaylight.
the class BGPParserTest method testUpdateMessageWithdrawAddPath.
/*
* Tests withdrawn routes with multiple paths.
*
* ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff <- marker
* 00 29 <- length (41) - including header
* 02 <- message type
* 00 12 <- withdrawn routes length (18)
* 00 00 00 01 <- path-id (1)
* 1e ac 10 00 04 <- route (172.16.0.4)
* 00 00 00 02 <- path-id (2)
* 1e ac 10 00 04 <- route (172.16.0.4)
* 00 00 <- total path attribute length
*
*/
@Test
public void testUpdateMessageWithdrawAddPath() throws Exception {
final byte[] body = ByteArray.cutBytes(updatesWithMultiplePath.get(1), MessageUtil.COMMON_HEADER_LENGTH);
final int messageLength = ByteArray.bytesToInt(ByteArray.subByte(updatesWithMultiplePath.get(1), MessageUtil.MARKER_LENGTH, LENGTH_FIELD_LENGTH));
final Update message = BGPParserTest.updateParser.parseMessageBody(Unpooled.copiedBuffer(body), messageLength, mpConstraint);
// attributes
final List<WithdrawnRoutes> withdrawnRoutes = new ArrayList<>();
withdrawnRoutes.add(new WithdrawnRoutesBuilder().setPrefix(new Ipv4Prefix("172.16.0.4/30")).setPathId(new PathId(Uint32.ONE)).build());
withdrawnRoutes.add(new WithdrawnRoutesBuilder().setPrefix(new Ipv4Prefix("172.16.0.4/30")).setPathId(new PathId(Uint32.TWO)).build());
// check API message
final Update expectedMessage = new UpdateBuilder().setWithdrawnRoutes(withdrawnRoutes).build();
assertEquals(expectedMessage.getWithdrawnRoutes(), message.getWithdrawnRoutes());
final ByteBuf buffer = Unpooled.buffer();
BGPParserTest.updateParser.serializeMessage(message, buffer);
assertArrayEquals(updatesWithMultiplePath.get(1), ByteArray.readAllBytes(buffer));
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder in project bgpcep by opendaylight.
the class MvpnIpv6NlriHandler method parseNlri.
@Override
public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder, final PeerSpecificParserConstraint constraint) throws BGPParsingException {
if (!nlri.isReadable()) {
return;
}
final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(Ipv6NlriHandler.parseIpv6UnreachNlri(nlri, mPathSupported)).build());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder in project bgpcep by opendaylight.
the class MvpnIpv4NlriHandler method parseNlri.
@Override
public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder, final PeerSpecificParserConstraint constraint) throws BGPParsingException {
if (!nlri.isReadable()) {
return;
}
final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(Ipv4NlriHandler.parseIpv4UnreachNlri(nlri, mPathSupported)).build());
}
Aggregations