use of org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException in project bgpcep by opendaylight.
the class CommunitiesAttributeParser method parseAttribute.
@Override
public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder, final RevisedErrorHandling errorHandling, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException, BGPTreatAsWithdrawException {
final int readable = buffer.readableBytes();
if (readable == 0 && errorHandling != RevisedErrorHandling.NONE) {
throw new BGPTreatAsWithdrawException(BGPError.ATTR_LENGTH_ERROR, "Empty Community attribute");
}
if (readable % COMMUNITY_LENGTH != 0) {
throw errorHandling.reportError(BGPError.ATTR_LENGTH_ERROR, "Community attribute length must be a multiple of %s, have %s", COMMUNITY_LENGTH, readable);
}
final int count = readable / COMMUNITY_LENGTH;
final List<Communities> set = new ArrayList<>(count);
for (int i = 0; i < count; ++i) {
set.add((Communities) parseCommunity(this.refCache, buffer.readSlice(COMMUNITY_LENGTH)));
}
builder.setCommunities(set);
}
use of org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException in project bgpcep by opendaylight.
the class ExtendedCommunitiesAttributeParser method parseAttribute.
@Override
public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder, final RevisedErrorHandling errorHandling, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException, BGPTreatAsWithdrawException {
final int readable = buffer.readableBytes();
if (errorHandling != RevisedErrorHandling.NONE) {
if (readable == 0) {
throw new BGPTreatAsWithdrawException(BGPError.ATTR_LENGTH_ERROR, "Empty Extended Community attribute");
}
}
if (readable % 8 != 0) {
throw errorHandling.reportError(BGPError.ATTR_LENGTH_ERROR, "Extended Community attribute length must be a multiple of 8, have %s", readable);
}
final List<ExtendedCommunities> set = new ArrayList<>(readable / 8);
while (buffer.isReadable()) {
final ExtendedCommunities exComm;
try {
// FIXME: BGPCEP-359: revise API contract here
exComm = this.ecReg.parseExtendedCommunity(buffer);
} catch (BGPParsingException e) {
throw errorHandling.reportError(BGPError.MALFORMED_ATTR_LIST, e, "Failed to parse extended community");
}
if (exComm != null) {
set.add(exComm);
}
}
builder.setExtendedCommunities(set);
}
use of org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException in project bgpcep by opendaylight.
the class AsPathAttributeParser method parseAsPath.
/**
* Parses AS_PATH from bytes.
*
* @param refCache ReferenceCache shared reference of object
* @param buffer bytes to be parsed
* @return new ASPath object
* @throws BGPDocumentedException if there is no AS_SEQUENCE present (mandatory)
*/
private static AsPath parseAsPath(final ReferenceCache refCache, final ByteBuf buffer, final RevisedErrorHandling errorHandling) throws BGPDocumentedException, BGPTreatAsWithdrawException {
if (!buffer.isReadable()) {
return EMPTY;
}
final List<Segments> ases = new ArrayList<>();
boolean isSequence = false;
for (int readable = buffer.readableBytes(); readable != 0; readable = buffer.readableBytes()) {
if (readable < 2) {
throw errorHandling.reportError(BGPError.AS_PATH_MALFORMED, "Insufficient AS PATH segment header length %s", readable);
}
final int type = buffer.readUnsignedByte();
final SegmentType segmentType = AsPathSegmentParser.parseType(type);
if (segmentType == null) {
throw errorHandling.reportError(BGPError.AS_PATH_MALFORMED, "Unknown AS PATH segment type %s", type);
}
final int count = buffer.readUnsignedByte();
if (count == 0 && errorHandling != RevisedErrorHandling.NONE) {
throw new BGPTreatAsWithdrawException(BGPError.AS_PATH_MALFORMED, "Empty AS_PATH segment");
}
// We read 2 bytes of header at this point
readable -= 2;
final int segmentLength = count * AsPathSegmentParser.AS_NUMBER_LENGTH;
if (segmentLength > readable) {
throw errorHandling.reportError(BGPError.AS_PATH_MALFORMED, "Calculated segment length %s would overflow available buffer %s", segmentLength, readable);
}
final List<AsNumber> asList = AsPathSegmentParser.parseAsSegment(refCache, count, buffer.readSlice(segmentLength));
if (segmentType == SegmentType.AS_SEQUENCE) {
ases.add(new SegmentsBuilder().setAsSequence(asList).build());
isSequence = true;
} else {
ases.add(new SegmentsBuilder().setAsSet(asList).build());
}
}
if (!isSequence) {
throw errorHandling.reportError(BGPError.AS_PATH_MALFORMED, "AS_SEQUENCE must be present in AS_PATH attribute.");
}
return new AsPathBuilder().setSegments(ImmutableList.copyOf(ases)).build();
}
use of org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException in project bgpcep by opendaylight.
the class SimpleAttributeRegistry method parseAttributes.
@Override
public ParsedAttributes parseAttributes(final ByteBuf buffer, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException, BGPParsingException {
final RevisedErrorHandling errorHandling = RevisedErrorHandling.from(constraint);
final Map<Integer, RawAttribute> attributes = new TreeMap<>();
BGPTreatAsWithdrawException withdrawCause = null;
while (buffer.isReadable()) {
try {
addAttribute(buffer, errorHandling, attributes);
} catch (BGPTreatAsWithdrawException e) {
LOG.info("Failed to completely parse attributes list.");
withdrawCause = e;
break;
}
}
/*
* TreeMap guarantees that we will be invoking the parser in the order
* of increasing attribute type.
*/
// We may have multiple attribute errors, each specifying a withdraw. We need to finish parsing the message
// all attributes before we can decide whether we can discard attributes, or whether we need to terminate
// the session.
final AttributesBuilder builder = new AttributesBuilder();
for (final Entry<Integer, RawAttribute> entry : attributes.entrySet()) {
LOG.debug("Parsing attribute type {}", entry.getKey());
final RawAttribute a = entry.getValue();
try {
a.parser.parseAttribute(a.buffer, builder, errorHandling, constraint);
} catch (BGPTreatAsWithdrawException e) {
LOG.info("Attribute {} indicated treat-as-withdraw", entry.getKey(), e);
if (withdrawCause == null) {
withdrawCause = e;
} else {
withdrawCause.addSuppressed(e);
}
}
}
builder.setUnrecognizedAttributes(BindingMap.ordered(this.unrecognizedAttributes));
return new ParsedAttributes(builder.build(), withdrawCause);
}
use of org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException in project bgpcep by opendaylight.
the class PEDistinguisherLabelsAttributeHandler method parseAttribute.
@Override
public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder, final RevisedErrorHandling errorHandling, final PeerSpecificParserConstraint constraint) throws BGPTreatAsWithdrawException {
final int readable = buffer.readableBytes();
if (readable == 0) {
return;
}
final boolean isIpv4;
final int count;
if (readable % 7 == 0) {
count = readable / 7;
isIpv4 = true;
} else if (readable % 19 == 0) {
count = readable / 19;
isIpv4 = false;
} else {
// as though all the routes contained in this Update had been withdrawn.
throw new BGPTreatAsWithdrawException(BGPError.MALFORMED_ATTR_LIST, "PE Distinguisher Labels has incorrect length %s", readable);
}
final List<PeDistinguisherLabelAttribute> list = new ArrayList<>(count);
for (int i = 0; i < count; ++i) {
final PeDistinguisherLabelAttributeBuilder attribute = new PeDistinguisherLabelAttributeBuilder();
if (isIpv4) {
attribute.setPeAddress(new IpAddressNoZone(Ipv4Util.addressForByteBuf(buffer)));
} else {
attribute.setPeAddress(new IpAddressNoZone(Ipv6Util.addressForByteBuf(buffer)));
}
attribute.setMplsLabel(MplsLabelUtil.mplsLabelForByteBuf(buffer));
list.add(attribute.build());
}
builder.addAugmentation(new PeDistinguisherLabelsAttributeAugmentationBuilder().setPeDistinguisherLabelsAttribute(new PeDistinguisherLabelsAttributeBuilder().setPeDistinguisherLabelAttribute(list).build()).build());
}
Aggregations