From 0e11129c8a27a3ddbb42262844b08fb3de847d8b Mon Sep 17 00:00:00 2001 From: Iveta Halanova Date: Mon, 2 Nov 2015 12:26:19 +0100 Subject: [PATCH] BUG-4552: Enhance LS-SR - discern protocols Updated yang model and decoding methods. Corrected and extended unit tests. Change-Id: I4cb8e7ba18ebce2962d4a5155e910f1292d57174 Signed-off-by: Iveta Halanova --- .../attribute/LinkAttributesParser.java | 12 +- .../attribute/LinkstateAttributeParser.java | 23 +-- .../attribute/NodeAttributesParser.java | 6 +- .../attribute/PrefixAttributesParser.java | 14 +- .../attribute/sr/BindingSidLabelParser.java | 63 ++++++-- .../attribute/sr/RangeTlvParser.java | 11 +- .../attribute/sr/SidLabelIndexParser.java | 14 ++ .../attribute/sr/SrLinkAttributesParser.java | 83 +++++++++-- .../attribute/sr/SrNodeAttributesParser.java | 19 ++- .../sr/SrPrefixAttributesParser.java | 62 +++++++- .../src/main/yang/bgp-segment-routing.yang | 104 +++++++++++-- .../LinkstateAttributeParserTest.java | 12 +- .../bgp/linkstate/SrAttributeParserTest.java | 141 ++++++++++++++---- 13 files changed, 466 insertions(+), 98 deletions(-) diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkAttributesParser.java index 326f841489..457c4c7900 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkAttributesParser.java @@ -27,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv6RouterIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkProtectionType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.MplsProtocolMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.PeerSetSidBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.PeerSidBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrAdjIdBuilder; @@ -86,9 +87,10 @@ public final class LinkAttributesParser { * Parse Link Attributes. * * @param attributes key is the tlv type and value is the value of the tlv + * @param protocolId to differentiate parsing methods * @return {@link LinkStateAttribute} */ - static LinkStateAttribute parseLinkAttributes(final Multimap attributes) { + static LinkStateAttribute parseLinkAttributes(final Multimap attributes, final ProtocolId protocolId) { final LinkAttributesBuilder builder = new LinkAttributesBuilder(); for (final Entry entry : attributes.entries()) { LOG.trace("Link attribute TLV {}", entry.getKey()); @@ -155,19 +157,19 @@ public final class LinkAttributesParser { LOG.debug("Parsed Link Name : {}", builder.getLinkName()); break; case SR_ADJ_ID: - builder.setSrAdjId(new SrAdjIdBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value)).build()); + builder.setSrAdjId(new SrAdjIdBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value, protocolId)).build()); LOG.debug("Parsed Adjacency Segment Identifier :{}", builder.getSrAdjId()); break; case SR_LAN_ADJ_ID: - builder.setSrLanAdjId(SrLinkAttributesParser.parseLanAdjacencySegmentIdentifier(value)); + builder.setSrLanAdjId(SrLinkAttributesParser.parseLanAdjacencySegmentIdentifier(value, protocolId)); LOG.debug("Parsed Adjacency Segment Identifier :{}", builder.getSrLanAdjId()); break; case PEER_SID_CODE: - builder.setPeerSid(new PeerSidBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value)).build()); + builder.setPeerSid(new PeerSidBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value, protocolId)).build()); LOG.debug("Parsed Peer Segment Identifier :{}", builder.getPeerSid()); break; case PEER_SET_SID_CODE: - builder.setPeerSetSid(new PeerSetSidBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value)).build()); + builder.setPeerSetSid(new PeerSetSidBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(value, protocolId)).build()); LOG.debug("Parsed Peer Set Sid :{}", builder.getPeerSetSid()); break; default: diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkstateAttributeParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkstateAttributeParser.java index 8914998ce6..65e8401f6a 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkstateAttributeParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkstateAttributeParser.java @@ -19,6 +19,7 @@ import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil; import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase; @@ -81,22 +82,24 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria @Override public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder) throws BGPParsingException { - final ObjectType nlriType = getNlriType(builder); - if (nlriType == null) { + final CLinkstateDestination lsDestination = getNlriType(builder); + if (lsDestination == null) { LOG.warn("No Linkstate NLRI found, not parsing Linkstate attribute"); return; } - final Attributes1 a = new Attributes1Builder().setLinkStateAttribute(parseLinkState(nlriType, buffer)).build(); + final ObjectType nlriType = lsDestination.getObjectType(); + final ProtocolId protocolId = lsDestination.getProtocolId(); + final Attributes1 a = new Attributes1Builder().setLinkStateAttribute(parseLinkState(nlriType, protocolId, buffer)).build(); builder.addAugmentation(Attributes1.class, a); } - private ObjectType getNlriType(final AttributesBuilder pab) { + private CLinkstateDestination getNlriType(final AttributesBuilder pab) { final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1 mpr = pab.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1.class); if (mpr != null && mpr.getMpReachNlri() != null) { final DestinationType dt = mpr.getMpReachNlri().getAdvertizedRoutes().getDestinationType(); if (dt instanceof DestinationLinkstateCase) { for (final CLinkstateDestination d : ((DestinationLinkstateCase) dt).getDestinationLinkstate().getCLinkstateDestination()) { - return d.getObjectType(); + return d; } } } @@ -105,21 +108,21 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria final DestinationType dt = mpu.getMpUnreachNlri().getWithdrawnRoutes().getDestinationType(); if (dt instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) { for (final CLinkstateDestination d : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) dt).getDestinationLinkstate().getCLinkstateDestination()) { - return d.getObjectType(); + return d; } } } return null; } - private LinkStateAttribute parseLinkState(final ObjectType nlri, final ByteBuf buffer) throws BGPParsingException { + private LinkStateAttribute parseLinkState(final ObjectType nlri, final ProtocolId protocolId, final ByteBuf buffer) throws BGPParsingException { if (nlri instanceof PrefixCase) { - return PrefixAttributesParser.parsePrefixAttributes(getAttributesMap(buffer)); + return PrefixAttributesParser.parsePrefixAttributes(getAttributesMap(buffer), protocolId); } else if (nlri instanceof LinkCase) { - return LinkAttributesParser.parseLinkAttributes(getAttributesMap(buffer)); + return LinkAttributesParser.parseLinkAttributes(getAttributesMap(buffer), protocolId); } else if (nlri instanceof NodeCase) { - return NodeAttributesParser.parseNodeAttributes(getAttributesMap(buffer)); + return NodeAttributesParser.parseNodeAttributes(getAttributesMap(buffer), protocolId); } else if (nlri instanceof TeLspCase) { return TeLspAttributesParser.parseTeLspAttributes(this.rsvpTeObjectRegistry, getAttributesMap(buffer) .entries().iterator().next().getValue()); diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/NodeAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/NodeAttributesParser.java index 8d16acd7cc..3a0469e482 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/NodeAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/NodeAttributesParser.java @@ -26,6 +26,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv6RouterIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.IsisAreaIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeFlagBits; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.LinkStateAttribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.NodeAttributesCase; @@ -70,9 +71,10 @@ public final class NodeAttributesParser { * Parse Node Attributes. * * @param attributes key is the tlv type and value is the value of the tlv + * @param protocolId to differentiate parsing methods * @return {@link LinkStateAttribute} */ - static LinkStateAttribute parseNodeAttributes(final Multimap attributes) { + static LinkStateAttribute parseNodeAttributes(final Multimap attributes, final ProtocolId protocolId) { final List topologyMembership = new ArrayList<>(); final List areaMembership = new ArrayList<>(); final NodeAttributesBuilder builder = new NodeAttributesBuilder(); @@ -116,7 +118,7 @@ public final class NodeAttributesParser { LOG.debug("Parsed IPv6 Router Identifier {}", ip6); break; case SR_CAPABILITIES: - final SrCapabilities caps = SrNodeAttributesParser.parseSrCapabilities(value); + final SrCapabilities caps = SrNodeAttributesParser.parseSrCapabilities(value, protocolId); builder.setSrCapabilities(caps); LOG.debug("Parsed SR Capabilities {}", caps); break; diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/PrefixAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/PrefixAttributesParser.java index d9bcbd6138..791d3e8aca 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/PrefixAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/PrefixAttributesParser.java @@ -26,6 +26,7 @@ import org.opendaylight.protocol.util.Ipv6Util; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ExtendedRouteTag; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.IgpBits.UpDown; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.RouteTag; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.LinkStateAttribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase; @@ -72,9 +73,10 @@ public final class PrefixAttributesParser { * Parse prefix attributes. * * @param attributes key is the tlv type and value are the value bytes of the tlv + * @param protocolId to differentiate parsing methods * @return {@link LinkStateAttribute} */ - static LinkStateAttribute parsePrefixAttributes(final Multimap attributes) { + static LinkStateAttribute parsePrefixAttributes(final Multimap attributes, final ProtocolId protocolId) { final PrefixAttributesBuilder builder = new PrefixAttributesBuilder(); final List routeTags = new ArrayList<>(); final List exRouteTags = new ArrayList<>(); @@ -82,7 +84,7 @@ public final class PrefixAttributesParser { final int key = entry.getKey(); final ByteBuf value = entry.getValue(); LOG.trace("Prefix attribute TLV {}", key); - parseAttribute(key, value, builder, routeTags, exRouteTags); + parseAttribute(key, value, protocolId, builder, routeTags, exRouteTags); } LOG.trace("Finished parsing Prefix Attributes."); builder.setRouteTags(routeTags); @@ -90,7 +92,7 @@ public final class PrefixAttributesParser { return new PrefixAttributesCaseBuilder().setPrefixAttributes(builder.build()).build(); } - private static void parseAttribute(final int key, final ByteBuf value, final PrefixAttributesBuilder builder, final List routeTags, final List exRouteTags) { + private static void parseAttribute(final int key, final ByteBuf value, final ProtocolId protocolId, final PrefixAttributesBuilder builder, final List routeTags, final List exRouteTags) { switch (key) { case IGP_FLAGS: final BitArray flags = BitArray.valueOf(value, FLAGS_SIZE); @@ -120,17 +122,17 @@ public final class PrefixAttributesParser { } break; case PREFIX_SID: - final SrPrefix prefix = SrPrefixAttributesParser.parseSrPrefix(value); + final SrPrefix prefix = SrPrefixAttributesParser.parseSrPrefix(value, protocolId); builder.setSrPrefix(prefix); LOG.debug("Parsed SR Prefix: {}", prefix); break; case RANGE: - final SrRange range = RangeTlvParser.parseSrRange(value); + final SrRange range = RangeTlvParser.parseSrRange(value, protocolId); builder.setSrRange(range); LOG.debug("Parsed SR Range: {}", range); break; case BINDING_SID: - final SrBindingSidLabel label = BindingSidLabelParser.parseBindingSidLabel(value); + final SrBindingSidLabel label = BindingSidLabelParser.parseBindingSidLabel(value, protocolId); builder.setSrBindingSidLabel(label); LOG.debug("Parsed SR Binding SID {}", label); break; diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/BindingSidLabelParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/BindingSidLabelParser.java index f77dd7b15f..71f2c15a6e 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/BindingSidLabelParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/BindingSidLabelParser.java @@ -19,12 +19,18 @@ import org.opendaylight.protocol.util.Ipv4Util; import org.opendaylight.protocol.util.Ipv6Util; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrBindingSidLabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrBindingSidLabelBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrPrefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Weight; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.BindingSubTlvs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.BindingSubTlvsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.Flags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.IsisBindingFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.IsisBindingFlagsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.OspfBindingFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.OspfBindingFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.BindingSubTlv; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.EroMetricCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.EroMetricCaseBuilder; @@ -59,6 +65,12 @@ public final class BindingSidLabelParser { /* Flags */ private static final int FLAGS_SIZE = 8; + private static final int AFI = 0; + private static final int MIRROR_CONTEXT = 1; + private static final int MIRROR_CONTEXT_OSPF = 0; + private static final int SPREAD_TLV = 2; + private static final int LEAKED = 3; + private static final int ATTACHED = 4; private static final int LOOSE = 0; /* SID Label Tlv types */ @@ -73,29 +85,45 @@ public final class BindingSidLabelParser { private static final int RESERVED_BINDING_SID = 2; private static final int RESERVED_ERO = 3; - public static SrBindingSidLabel parseBindingSidLabel(final ByteBuf buffer) { + public static SrBindingSidLabel parseBindingSidLabel(final ByteBuf buffer, final ProtocolId protocolId) { final SrBindingSidLabelBuilder bindingSid = new SrBindingSidLabelBuilder(); bindingSid.setWeight(new Weight(buffer.readUnsignedByte())); - bindingSid.setFlags(new byte[] { (byte) buffer.readUnsignedByte() }); + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + bindingSid.setFlags(parseBindingSidFlags(flags, protocolId)); buffer.skipBytes(RESERVED_BINDING_SID); - bindingSid.setBindingSubTlvs(parseBindingSubTlvs(buffer)); + bindingSid.setBindingSubTlvs(parseBindingSubTlvs(buffer, protocolId)); return bindingSid.build(); } - private static List parseBindingSubTlvs(final ByteBuf buffer) { + private static Flags parseBindingSidFlags(final BitArray flags, final ProtocolId protocol) { + if (protocol.equals(ProtocolId.IsisLevel1) || protocol.equals(ProtocolId.IsisLevel2)) { + return new IsisBindingFlagsCaseBuilder() + .setAddressFamily(flags.get(AFI)) + .setMirrorContext(flags.get(MIRROR_CONTEXT)) + .setSpreadTlv(flags.get(SPREAD_TLV)) + .setLeakedFromLevel2(flags.get(LEAKED)) + .setAttachedFlag(flags.get(ATTACHED)).build(); + } else if (protocol.equals(ProtocolId.Ospf)) { + return new OspfBindingFlagsCaseBuilder() + .setMirroring(flags.get(MIRROR_CONTEXT_OSPF)).build(); + } + return null; + } + + private static List parseBindingSubTlvs(final ByteBuf buffer, final ProtocolId protocolId) { final List subTlvs = new ArrayList(); while (buffer.isReadable()) { final int type = buffer.readUnsignedShort(); final int length = buffer.readUnsignedShort(); final ByteBuf slice = buffer.readSlice(length); final BindingSubTlvsBuilder builder = new BindingSubTlvsBuilder(); - parseSubTlv(type, slice, builder); + parseSubTlv(type, slice, builder, protocolId); subTlvs.add(builder.build()); } return subTlvs; } - private static void parseSubTlv(final int type, final ByteBuf slice, final BindingSubTlvsBuilder builder) { + private static void parseSubTlv(final int type, final ByteBuf slice, final BindingSubTlvsBuilder builder, final ProtocolId protocolId) { switch (type) { case SidLabelIndexParser.SID_TYPE: final SidLabelIndex sid = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(slice.readableBytes()), slice); @@ -103,7 +131,7 @@ public final class BindingSidLabelParser { .setSidLabelIndex(sid).build()); break; case PrefixAttributesParser.PREFIX_SID: - final SrPrefix prefix = SrPrefixAttributesParser.parseSrPrefix(slice); + final SrPrefix prefix = SrPrefixAttributesParser.parseSrPrefix(slice, protocolId); builder.setBindingSubTlv(new PrefixSidCaseBuilder() .setAlgorithm(prefix.getAlgorithm()) .setFlags(prefix.getFlags()) @@ -189,13 +217,30 @@ public final class BindingSidLabelParser { serializeBindingSidAttributes(bindingSid.getWeight(), bindingSid.getFlags(), bindingSid.getBindingSubTlvs(), aggregator); } - public static void serializeBindingSidAttributes(final Weight weight, final byte[] flags, final List bindingSubTlvs, final ByteBuf aggregator) { + public static void serializeBindingSidAttributes(final Weight weight, final Flags flags, final List bindingSubTlvs, final ByteBuf aggregator) { aggregator.writeByte(weight.getValue()); - aggregator.writeBytes(flags); + final BitArray bitFlags = serializeBindingSidFlags(flags); + bitFlags.toByteBuf(aggregator); aggregator.writeZero(RESERVED_BINDING_SID); serializeBindingSubTlvs(bindingSubTlvs, aggregator); } + private static BitArray serializeBindingSidFlags(final Flags flags) { + final BitArray bitFlags = new BitArray(FLAGS_SIZE); + if (flags instanceof IsisBindingFlagsCase) { + final IsisBindingFlagsCase isisFlags = (IsisBindingFlagsCase) flags; + bitFlags.set(AFI, isisFlags.isAddressFamily()); + bitFlags.set(MIRROR_CONTEXT, isisFlags.isMirrorContext()); + bitFlags.set(SPREAD_TLV, isisFlags.isSpreadTlv()); + bitFlags.set(LEAKED, isisFlags.isLeakedFromLevel2()); + bitFlags.set(ATTACHED, isisFlags.isAttachedFlag()); + } else if (flags instanceof OspfBindingFlagsCase) { + final OspfBindingFlagsCase ospfFlags = (OspfBindingFlagsCase) flags; + bitFlags.set(MIRROR_CONTEXT_OSPF, ospfFlags.isMirroring()); + } + return bitFlags; + } + private static void serializeBindingSubTlvs(final List bindingSubTlvs, final ByteBuf aggregator) { for (final BindingSubTlvs subTlv : bindingSubTlvs) { ByteBuf buffer = Unpooled.buffer(); diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/RangeTlvParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/RangeTlvParser.java index 8684be49c6..5eb7699b54 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/RangeTlvParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/RangeTlvParser.java @@ -15,6 +15,7 @@ import org.opendaylight.protocol.bgp.linkstate.attribute.PrefixAttributesParser; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SidLabelIndexParser.Size; import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil; import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrRange; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrRangeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.range.sub.tlvs.RangeSubTlv; @@ -43,17 +44,17 @@ public final class RangeTlvParser { private static final int RESERVED = 1; - public static SrRange parseSrRange(final ByteBuf buffer) { + public static SrRange parseSrRange(final ByteBuf buffer, final ProtocolId protocolId) { final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); final SrRangeBuilder range = new SrRangeBuilder(); range.setInterArea(flags.get(INNER_AREA)); buffer.skipBytes(RESERVED); range.setRangeSize(buffer.readUnsignedShort()); - range.setSubTlvs(parseRangeSubTlvs(buffer)); + range.setSubTlvs(parseRangeSubTlvs(buffer, protocolId)); return range.build(); } - private static List parseRangeSubTlvs(final ByteBuf buffer) { + private static List parseRangeSubTlvs(final ByteBuf buffer, final ProtocolId protocolId) { final List subTlvs = new ArrayList<>(); while (buffer.isReadable()) { final SubTlvsBuilder subTlv = new SubTlvsBuilder(); @@ -62,10 +63,10 @@ public final class RangeTlvParser { final int length = buffer.readUnsignedShort(); switch (type) { case PrefixAttributesParser.PREFIX_SID: - subTlvCase = new PrefixSidTlvCaseBuilder(SrPrefixAttributesParser.parseSrPrefix(buffer.readSlice(length))).build(); + subTlvCase = new PrefixSidTlvCaseBuilder(SrPrefixAttributesParser.parseSrPrefix(buffer.readSlice(length), protocolId)).build(); break; case PrefixAttributesParser.BINDING_SID: - subTlvCase = new BindingSidTlvCaseBuilder(BindingSidLabelParser.parseBindingSidLabel(buffer.readSlice(length))).build(); + subTlvCase = new BindingSidTlvCaseBuilder(BindingSidLabelParser.parseBindingSidLabel(buffer.readSlice(length), protocolId)).build(); break; case SidLabelIndexParser.SID_TYPE: subTlvCase = new SidLabelTlvCaseBuilder().setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(Size.forValue(length), buffer.readSlice(length))).build(); diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SidLabelIndexParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SidLabelIndexParser.java index 7ac53d663b..9c76788cfb 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SidLabelIndexParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SidLabelIndexParser.java @@ -11,6 +11,7 @@ import com.google.common.collect.ImmutableMap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.util.Map; +import org.opendaylight.protocol.util.BitArray; import org.opendaylight.protocol.util.Ipv6Util; import org.opendaylight.protocol.util.MplsLabelUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.SidLabelIndex; @@ -86,4 +87,17 @@ public final class SidLabelIndexParser { } } + static void setFlags(final SidLabelIndex tlv, final BitArray flags, final int value, final int local) { + if (tlv instanceof LocalLabelCase) { + flags.set(value, Boolean.TRUE); + flags.set(local, Boolean.TRUE); + } else if (tlv instanceof SidCase) { + flags.set(value, Boolean.FALSE); + flags.set(local, Boolean.FALSE); + } else if (tlv instanceof Ipv6AddressCase) { + flags.set(value, Boolean.TRUE); + flags.set(local, Boolean.FALSE); + } + } + } diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrLinkAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrLinkAttributesParser.java index 9ae9d738ee..16b7fb46c2 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrLinkAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrLinkAttributesParser.java @@ -10,11 +10,19 @@ package org.opendaylight.protocol.bgp.linkstate.attribute.sr; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SidLabelIndexParser.Size; +import org.opendaylight.protocol.util.BitArray; import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.protocol.util.Ipv4Util; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.AdjSidTlv; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Weight; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.Flags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.SidLabelIndex; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier; import org.opendaylight.yangtools.yang.binding.DataContainer; @@ -24,6 +32,18 @@ public final class SrLinkAttributesParser { private static final int ISO_SYSTEM_ID_SIZE = 6; private static final int RESERVED = 2; + /* Adj-SID flags */ + private static final int ADDRESS_FAMILY_FLAG = 0; + private static final int BACKUP_ISIS = 1; + private static final int BACKUP_OSPF = 0; + private static final int VALUE_ISIS = 2; + private static final int VALUE_OSPF = 1; + private static final int LOCAL_ISIS = 3; + private static final int LOCAL_OSPF = 2; + private static final int SET_ISIS = 4; + private static final int SET_OSPF = 3; + private static final int FLAGS_SIZE = 8; + /** OSPF flags 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ @@ -41,12 +61,13 @@ public final class SrLinkAttributesParser { throw new UnsupportedOperationException(); } - public static AdjSidTlv parseAdjacencySegmentIdentifier(final ByteBuf buffer) { - final byte[] adjFlags; + public static AdjSidTlv parseAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) { + final Flags adjFlags; final Weight weight; final SidLabelIndex sidValue; if (buffer.isReadable()) { - adjFlags = new byte[] { (byte) buffer.readUnsignedByte() }; + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + adjFlags = parseFlags(flags, protocolId); weight = new Weight(buffer.readUnsignedByte()); buffer.skipBytes(RESERVED); sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer); @@ -69,29 +90,49 @@ public final class SrLinkAttributesParser { return sidValue; } @Override - public byte[] getFlags() { + public Flags getFlags() { return adjFlags; } }; } - public static SrLanAdjId parseLanAdjacencySegmentIdentifier(final ByteBuf buffer) { + public static SrLanAdjId parseLanAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) { if (!buffer.isReadable()) { return new SrLanAdjIdBuilder().build(); } final SrLanAdjIdBuilder srLanAdjIdBuilder = new SrLanAdjIdBuilder(); - srLanAdjIdBuilder.setFlags(new byte[] { (byte) buffer.readUnsignedByte() }); + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + srLanAdjIdBuilder.setFlags(parseFlags(flags, protocolId)); srLanAdjIdBuilder.setWeight(new Weight(buffer.readUnsignedByte())); buffer.skipBytes(RESERVED); - srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE))); + if (protocolId.equals(ProtocolId.IsisLevel1) || protocolId.equals(ProtocolId.IsisLevel2)) { + srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE))); + } else if (protocolId.equals(ProtocolId.Ospf)) { + srLanAdjIdBuilder.setNeighborId(Ipv4Util.addressForByteBuf(buffer)); + } // length determines a type of next field, which is used for parsing srLanAdjIdBuilder.setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer)); return srLanAdjIdBuilder.build(); } + private static Flags parseFlags(final BitArray flags, final ProtocolId protocol) { + if (protocol.equals(ProtocolId.IsisLevel1) || protocol.equals(ProtocolId.IsisLevel2)) { + return new IsisAdjFlagsCaseBuilder() + .setAddressFamily(flags.get(ADDRESS_FAMILY_FLAG)) + .setBackup(flags.get(BACKUP_ISIS)) + .setSet(flags.get(SET_ISIS)).build(); + } else if (protocol.equals(ProtocolId.Ospf)) { + return new OspfAdjFlagsCaseBuilder() + .setBackup(flags.get(BACKUP_OSPF)) + .setSet(flags.get(SET_OSPF)).build(); + } + return null; + } + public static ByteBuf serializeAdjacencySegmentIdentifier(final AdjSidTlv adjSid) { final ByteBuf value = Unpooled.buffer(); - value.writeBytes(adjSid.getFlags()); + final BitArray flags = serializeAdjFlags(adjSid.getFlags(), adjSid.getSidLabelIndex()); + flags.toByteBuf(value); value.writeByte(adjSid.getWeight().getValue()); value.writeZero(RESERVED); value.writeBytes(SidLabelIndexParser.serializeSidValue(adjSid.getSidLabelIndex())); @@ -100,12 +141,34 @@ public final class SrLinkAttributesParser { public static ByteBuf serializeLanAdjacencySegmentIdentifier(final SrLanAdjId srLanAdjId) { final ByteBuf value = Unpooled.buffer(); - value.writeBytes(srLanAdjId.getFlags()); + final BitArray flags = serializeAdjFlags(srLanAdjId.getFlags(), srLanAdjId.getSidLabelIndex()); + flags.toByteBuf(value); value.writeByte(srLanAdjId.getWeight().getValue()); value.writeZero(RESERVED); - value.writeBytes(srLanAdjId.getIsoSystemId().getValue()); + if (srLanAdjId.getIsoSystemId() != null) { + value.writeBytes(srLanAdjId.getIsoSystemId().getValue()); + } else if (srLanAdjId.getNeighborId() != null) { + value.writeBytes(Ipv4Util.byteBufForAddress(srLanAdjId.getNeighborId())); + } value.writeBytes(SidLabelIndexParser.serializeSidValue(srLanAdjId.getSidLabelIndex())); return value; } + private static BitArray serializeAdjFlags(final Flags flags, final SidLabelIndex sidLabelIndex) { + final BitArray bitFlags = new BitArray(FLAGS_SIZE); + if (flags instanceof OspfAdjFlagsCase) { + final OspfAdjFlagsCase ospfFlags = (OspfAdjFlagsCase) flags; + bitFlags.set(BACKUP_OSPF, ospfFlags.isBackup()); + bitFlags.set(SET_OSPF, ospfFlags.isSet()); + SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_OSPF, LOCAL_OSPF); + } else if (flags instanceof IsisAdjFlagsCase) { + final IsisAdjFlagsCase isisFlags = (IsisAdjFlagsCase) flags; + bitFlags.set(ADDRESS_FAMILY_FLAG, isisFlags.isAddressFamily()); + bitFlags.set(BACKUP_ISIS, isisFlags.isBackup()); + bitFlags.set(SET_ISIS, isisFlags.isSet()); + SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_ISIS, LOCAL_ISIS); + } + return bitFlags; + } + } diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrNodeAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrNodeAttributesParser.java index 0484b9ebf0..e2463b2385 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrNodeAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrNodeAttributesParser.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil; import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.state.SrAlgorithm; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.state.SrAlgorithmBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.state.SrCapabilities; @@ -33,18 +34,28 @@ public final class SrNodeAttributesParser { private static final int RESERVERED = 1; - public static SrCapabilities parseSrCapabilities(final ByteBuf buffer) { + public static SrCapabilities parseSrCapabilities(final ByteBuf buffer, final ProtocolId protocol) { final SrCapabilitiesBuilder builder = new SrCapabilitiesBuilder(); final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); - builder.setMplsIpv4(flags.get(MPLS_IPV4)); - builder.setMplsIpv6(flags.get(MPLS_IPV6)); - builder.setSrIpv6(flags.get(SR_IPV6)); + setFlags(flags, protocol, builder); buffer.skipBytes(RESERVERED); builder.setRangeSize((long)buffer.readUnsignedMedium()); builder.setSidLabelIndex(SidLabelIndexParser.parseSidSubTlv(buffer)); return builder.build(); } + private static void setFlags(final BitArray flags, final ProtocolId protocol, final SrCapabilitiesBuilder builder) { + if (protocol.equals(ProtocolId.IsisLevel1) || protocol.equals(ProtocolId.IsisLevel2)) { + builder.setMplsIpv4(flags.get(MPLS_IPV4)); + builder.setMplsIpv6(flags.get(MPLS_IPV6)); + builder.setSrIpv6(flags.get(SR_IPV6)); + } else { + builder.setMplsIpv4(Boolean.FALSE); + builder.setMplsIpv6(Boolean.FALSE); + builder.setSrIpv6(Boolean.FALSE); + } + } + public static void serializeSrCapabilities(final SrCapabilities caps, final ByteBuf buffer) { final BitArray bs = new BitArray(FLAGS_SIZE); bs.set(MPLS_IPV4, caps.isMplsIpv4()); diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrPrefixAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrPrefixAttributesParser.java index 69cd3495e2..fd0eb10b8e 100644 --- a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrPrefixAttributesParser.java +++ b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/sr/SrPrefixAttributesParser.java @@ -9,9 +9,16 @@ package org.opendaylight.protocol.bgp.linkstate.attribute.sr; import io.netty.buffer.ByteBuf; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SidLabelIndexParser.Size; +import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrPrefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrPrefixBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Algorithm; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.Flags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.IsisPrefixFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.IsisPrefixFlagsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.OspfPrefixFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.OspfPrefixFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.SidLabelIndex; public final class SrPrefixAttributesParser { @@ -20,26 +27,73 @@ public final class SrPrefixAttributesParser { throw new UnsupportedOperationException(); } + /* Flags */ + private static final int RE_ADVERTISEMENT = 0; + private static final int NODE_SID = 1; + private static final int NO_PHP_OSPF = 1; + private static final int NO_PHP = 2; + private static final int MAPPING_SERVER = 2; + private static final int EXPLICIT_NULL = 3; + private static final int VALUE = 4; + private static final int LOCAL = 5; + private static final int FLAGS_SIZE = 8; + private static final int RESERVED_PREFIX = 2; - public static SrPrefix parseSrPrefix(final ByteBuf buffer) { + public static SrPrefix parseSrPrefix(final ByteBuf buffer, final ProtocolId protocol) { final SrPrefixBuilder builder = new SrPrefixBuilder(); - builder.setFlags(new byte[] { (byte) buffer.readUnsignedByte() }); + builder.setFlags(parsePrefixFlags(BitArray.valueOf(buffer, FLAGS_SIZE), protocol)); builder.setAlgorithm(Algorithm.forValue(buffer.readUnsignedByte())); buffer.skipBytes(RESERVED_PREFIX); builder.setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer)); return builder.build(); } + private static Flags parsePrefixFlags(final BitArray flags, final ProtocolId protocol) { + if (protocol.equals(ProtocolId.IsisLevel1) || protocol.equals(ProtocolId.IsisLevel2)) { + return new IsisPrefixFlagsCaseBuilder() + .setReadvertisement(flags.get(RE_ADVERTISEMENT)) + .setNodeSid(flags.get(NODE_SID)) + .setNoPhp(flags.get(NO_PHP)) + .setExplicitNull(flags.get(EXPLICIT_NULL)).build(); + } + if (protocol.equals(ProtocolId.Ospf)) { + return new OspfPrefixFlagsCaseBuilder() + .setExplicitNull(flags.get(EXPLICIT_NULL)) + .setMappingServer(flags.get(MAPPING_SERVER)) + .setNoPhp(flags.get(NO_PHP_OSPF)).build(); + } + return null; + } + public static void serializeSrPrefix(final SrPrefix srPrefix, final ByteBuf aggregator) { serializePrefixAttributes(srPrefix.getFlags(), srPrefix.getAlgorithm(), srPrefix.getSidLabelIndex(), aggregator); } - public static void serializePrefixAttributes(final byte[] flags, final Algorithm algorithm, final SidLabelIndex sidLabelIndex, final ByteBuf buffer) { - buffer.writeByte(flags[0]); + public static void serializePrefixAttributes(final Flags flags, final Algorithm algorithm, final SidLabelIndex sidLabelIndex, final ByteBuf buffer) { + final BitArray bitFlags = serializePrefixFlags(flags, sidLabelIndex); + bitFlags.toByteBuf(buffer); buffer.writeByte(algorithm.getIntValue()); buffer.writeZero(RESERVED_PREFIX); buffer.writeBytes(SidLabelIndexParser.serializeSidValue(sidLabelIndex)); } + private static BitArray serializePrefixFlags(final Flags flags, final SidLabelIndex sidLabelIndex) { + final BitArray bitFlags = new BitArray(FLAGS_SIZE); + SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE, LOCAL); + if (flags instanceof OspfPrefixFlagsCase) { + final OspfPrefixFlagsCase ospfFlags = (OspfPrefixFlagsCase) flags; + bitFlags.set(NO_PHP_OSPF, ospfFlags.isNoPhp()); + bitFlags.set(MAPPING_SERVER, ospfFlags.isMappingServer()); + bitFlags.set(EXPLICIT_NULL, ospfFlags.isExplicitNull()); + } else if (flags instanceof IsisPrefixFlagsCase) { + final IsisPrefixFlagsCase isisFlags = (IsisPrefixFlagsCase) flags; + bitFlags.set(RE_ADVERTISEMENT, isisFlags.isReadvertisement()); + bitFlags.set(NODE_SID, isisFlags.isNodeSid()); + bitFlags.set(NO_PHP, isisFlags.isNoPhp()); + bitFlags.set(EXPLICIT_NULL, isisFlags.isExplicitNull()); + } + return bitFlags; + } + } diff --git a/bgp/linkstate/src/main/yang/bgp-segment-routing.yang b/bgp/linkstate/src/main/yang/bgp-segment-routing.yang index b214430a2e..ef9d8bfe4b 100644 --- a/bgp/linkstate/src/main/yang/bgp-segment-routing.yang +++ b/bgp/linkstate/src/main/yang/bgp-segment-routing.yang @@ -42,14 +42,6 @@ module bgp-segment-routing { type uint8; } - grouping general-flags { - leaf flags { - type binary { - length "1"; - } - } - } - grouping sid-label-index { reference "https://tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.3.4.2"; choice sid-label-index { @@ -96,9 +88,34 @@ module bgp-segment-routing { } } + grouping ospf-adj-flags { + reference "https://tools.ietf.org/html/draft-ietf-ospf-segment-routing-extensions-05#section-7.1"; + leaf backup { + type boolean; + } + leaf set { + type boolean; + } + } + + grouping adj-flags { + choice flags { + case ospf-adj-flags-case { + uses ospf-adj-flags; + } + case isis-adj-flags-case { + reference "https://tools.ietf.org/html/draft-ietf-isis-segment-routing-extensions-05#section-2.2.1"; + uses ospf-adj-flags; + leaf address-family { + type boolean; + } + } + } + } + grouping adj-sid-tlv { reference "https://tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.2.1"; - uses general-flags; + uses adj-flags; leaf weight { type weight; } @@ -107,19 +124,49 @@ module bgp-segment-routing { grouping lan-adj-sid-tlv { reference "https://tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.2.2"; - uses general-flags; + uses adj-flags; leaf weight { type weight; } leaf iso-system-id { type netc:iso-system-identifier; } + leaf neighbor-id { + type inet:ipv4-address; + } uses sid-label-index; } + grouping prefix-flags { + leaf no-php { + type boolean; + } + leaf explicit-null { + type boolean; + } + } + grouping prefix-sid-tlv { reference "https://tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.3.1"; - uses general-flags; + choice flags { + case isis-prefix-flags-case { + reference "https://tools.ietf.org/html/draft-ietf-ospf-segment-routing-extensions-05#section-5"; + uses prefix-flags; + leaf readvertisement { + type boolean; + } + leaf node-sid { + type boolean; + } + } + case ospf-prefix-flags-case { + reference "https://tools.ietf.org/html/draft-ietf-ospf-segment-routing-extensions-05#section-5"; + uses prefix-flags; + leaf mapping-server { + type boolean; + } + } + } leaf algorithm { type algorithm; } @@ -193,12 +240,45 @@ module bgp-segment-routing { } } + grouping isis-binding-flags { + reference "https://tools.ietf.org/html/draft-ietf-isis-segment-routing-extensions-05#section-2.4"; + leaf address-family { + type boolean; + } + leaf mirror-context { + type boolean; + } + leaf spread-tlv { + type boolean; + } + leaf leaked-from-level-2 { + type boolean; + } + leaf attached-flag { + type boolean; + } + } + + grouping ospf-binding-flags { + reference "https://tools.ietf.org/html/draft-ietf-ospf-segment-routing-extensions-05#section-6"; + leaf mirroring { + type boolean; + } + } + grouping binding-sid-tlv { reference "https://tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.3.3"; leaf weight { type weight; } - uses general-flags; + choice flags { + case isis-binding-flags-case { + uses isis-binding-flags; + } + case ospf-binding-flags-case { + uses ospf-binding-flags; + } + } list binding-sub-tlvs { uses binding-sub-tlvs; } diff --git a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java index 9d33c8e763..af062e14f9 100644 --- a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java +++ b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java @@ -38,6 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkProtectionType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestinationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCaseBuilder; @@ -63,6 +64,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.sid.label.index.SidCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.AssociationType; @@ -138,7 +141,7 @@ public class LinkstateAttributeParserTest { new AdvertizedRoutesBuilder().setDestinationType( new DestinationLinkstateCaseBuilder().setDestinationLinkstate( new DestinationLinkstateBuilder().setCLinkstateDestination( - Lists.newArrayList(new CLinkstateDestinationBuilder().setObjectType(type).build())).build()).build()).build()).build()).build()); + Lists.newArrayList(new CLinkstateDestinationBuilder().setObjectType(type).setProtocolId(ProtocolId.IsisLevel1).build())).build()).build()).build()).build()).build()); } private static AttributesBuilder createUnreachBuilder(final ObjectType type) { @@ -149,7 +152,7 @@ public class LinkstateAttributeParserTest { new WithdrawnRoutesBuilder().setDestinationType( new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCaseBuilder().setDestinationLinkstate( new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder().setCLinkstateDestination( - Lists.newArrayList(new CLinkstateDestinationBuilder().setObjectType(type).build())).build()).build()).build()).build()).build()); + Lists.newArrayList(new CLinkstateDestinationBuilder().setObjectType(type).setProtocolId(ProtocolId.IsisLevel1).build())).build()).build()).build()).build()).build()); } @Test @@ -206,8 +209,9 @@ public class LinkstateAttributeParserTest { assertEquals(2, ls.getSharedRiskLinkGroups().size()); assertEquals(305419896, ls.getSharedRiskLinkGroups().get(0).getValue().intValue()); assertEquals("12K-2", ls.getLinkName()); - assertEquals((byte) 0x80, ls.getPeerSid().getFlags()[0]); - assertEquals((byte) 0x80, ls.getPeerSetSid().getFlags()[0]); + final IsisAdjFlagsCase flags = new IsisAdjFlagsCaseBuilder().setAddressFamily(Boolean.TRUE).setBackup(Boolean.FALSE).setSet(Boolean.FALSE).build(); + assertEquals(flags, ls.getPeerSid().getFlags()); + assertEquals(flags, ls.getPeerSetSid().getFlags()); assertEquals(new Long(168496141L), ((SidCase) ls.getPeerSid().getSidLabelIndex()).getSid()); assertEquals(new Short("5"), ls.getPeerSid().getWeight().getValue()); assertEquals(new Long(168496142L), ((SidCase) ls.getPeerSetSid().getSidLabelIndex()).getSid()); diff --git a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/SrAttributeParserTest.java b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/SrAttributeParserTest.java index 4f8055b45e..c74933be90 100644 --- a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/SrAttributeParserTest.java +++ b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/SrAttributeParserTest.java @@ -19,7 +19,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Test; +import org.opendaylight.protocol.bgp.linkstate.attribute.sr.BindingSidLabelParser; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.RangeTlvParser; +import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SidLabelIndexParser; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SrLinkAttributesParser; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SrNodeAttributesParser; import org.opendaylight.protocol.bgp.linkstate.attribute.sr.SrPrefixAttributesParser; @@ -27,6 +29,7 @@ import org.opendaylight.protocol.util.ByteArray; import org.opendaylight.protocol.util.Ipv6Util; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrAdjId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrAdjIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjId; @@ -41,8 +44,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.SrRangeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Algorithm; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Weight; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.BindingSubTlvs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.BindingSubTlvsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.IsisBindingFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sid.tlv.flags.IsisBindingFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.EroMetricCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.Ipv4EroBackupCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.Ipv4EroCaseBuilder; @@ -52,6 +61,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segm import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.SidLabelCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.UnnumberedInterfaceIdBackupEroCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.binding.sub.tlvs.binding.sub.tlv.UnnumberedInterfaceIdEroCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.IsisPrefixFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.IsisPrefixFlagsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.OspfPrefixFlagsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.prefix.sid.tlv.flags.OspfPrefixFlagsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.range.sub.tlvs.range.sub.tlv.BindingSidTlvCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.range.sub.tlvs.range.sub.tlv.PrefixSidTlvCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.range.sub.tlvs.range.sub.tlv.SidLabelTlvCaseBuilder; @@ -71,6 +84,24 @@ public class SrAttributeParserTest { private static final byte[] IPV6_B_BYTES = { 0x20, 1, 0x0d, (byte) 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }; private static final Ipv6Address IPV6_B = new Ipv6Address("2001:db8::2"); + private static final IsisPrefixFlagsCase ISIS_PREFIX_FLAGS = new IsisPrefixFlagsCaseBuilder().setReadvertisement(Boolean.TRUE).setNodeSid(Boolean.FALSE).setNoPhp(Boolean.TRUE).setExplicitNull(Boolean.FALSE).build(); + private static final OspfPrefixFlagsCase OSPF_PREFIX_FLAGS = new OspfPrefixFlagsCaseBuilder().setNoPhp(Boolean.FALSE).setMappingServer(Boolean.TRUE).setExplicitNull(Boolean.FALSE).build(); + + private static final IsisBindingFlagsCase BINDING_FLAGS = new IsisBindingFlagsCaseBuilder() + .setAddressFamily(Boolean.FALSE) + .setMirrorContext(Boolean.TRUE) + .setSpreadTlv(Boolean.FALSE) + .setLeakedFromLevel2(Boolean.FALSE) + .setAttachedFlag(Boolean.TRUE).build(); + + private static final IsisAdjFlagsCase ISIS_ADJ_FLAGS = new IsisAdjFlagsCaseBuilder() + .setAddressFamily(Boolean.FALSE) + .setBackup(Boolean.TRUE) + .setSet(Boolean.FALSE).build(); + private static final OspfAdjFlagsCase OSPF_ADJ_FLAGS = new OspfAdjFlagsCaseBuilder() + .setBackup(Boolean.TRUE) + .setSet(Boolean.FALSE).build(); + @Test public void testSrAlgorithm() { final byte[] bytes = { 0 }; @@ -89,25 +120,39 @@ public class SrAttributeParserTest { // tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.1.1 @Test public void testSrCapabilities() { - final byte[] bytes = { (byte)0xC0, 0, 0, 0, 10, 4, (byte)0x89, 0, 4, 1, 2, 3, 4 }; - final SrCapabilities caps = new SrCapabilitiesBuilder().setMplsIpv4(Boolean.TRUE).setMplsIpv6(Boolean.TRUE).setSrIpv6(Boolean.FALSE).setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).setRangeSize((long) 10).build(); - assertEquals(caps, SrNodeAttributesParser.parseSrCapabilities(Unpooled.wrappedBuffer(bytes))); - final ByteBuf b = Unpooled.buffer(); - SrNodeAttributesParser.serializeSrCapabilities(caps, b); - assertArrayEquals(bytes, ByteArray.readAllBytes(b)); + final byte[] bytesIsis = { (byte)0xC0, 0, 0, 0, 10, 4, (byte)0x89, 0, 4, 1, 2, 3, 4 }; + final byte[] bytesOspf = { 0, 0, 0, 0, 10, 4, (byte)0x89, 0, 4, 1, 2, 3, 4 }; + final SrCapabilities capsIsis = new SrCapabilitiesBuilder().setMplsIpv4(Boolean.TRUE).setMplsIpv6(Boolean.TRUE).setSrIpv6(Boolean.FALSE).setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).setRangeSize((long) 10).build(); + final SrCapabilities capsOspf = new SrCapabilitiesBuilder().setMplsIpv4(Boolean.FALSE).setMplsIpv6(Boolean.FALSE).setSrIpv6(Boolean.FALSE).setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).setRangeSize((long) 10).build(); + assertEquals(capsIsis, SrNodeAttributesParser.parseSrCapabilities(Unpooled.wrappedBuffer(bytesIsis), ProtocolId.IsisLevel1)); + assertEquals(capsOspf, SrNodeAttributesParser.parseSrCapabilities(Unpooled.wrappedBuffer(bytesIsis), ProtocolId.Ospf)); + final ByteBuf encodedIsis = Unpooled.buffer(); + final ByteBuf encodedOspf = Unpooled.buffer(); + SrNodeAttributesParser.serializeSrCapabilities(capsIsis, encodedIsis); + SrNodeAttributesParser.serializeSrCapabilities(capsOspf, encodedOspf); + assertArrayEquals(bytesIsis, ByteArray.readAllBytes(encodedIsis)); + assertArrayEquals(bytesOspf, ByteArray.readAllBytes(encodedOspf)); } // tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.3.1 @Test public void testSrPrefix() { - final byte[] bytes = { (byte)0xFC, 0, 0, 0, 1, 2, 3, 4 }; - final SrPrefix prefix = new SrPrefixBuilder() - .setFlags(new byte[] {(byte)0xfc}) + final byte[] bytes = { (byte)0xA0, 0, 0, 0, 1, 2, 3, 4 }; + final byte[] bytesOspf = { (byte)0x20, 0, 0, 0, 1, 2, 3, 4 }; + final SrPrefix prefixIsis = new SrPrefixBuilder() + .setFlags(ISIS_PREFIX_FLAGS) .setAlgorithm(Algorithm.ShortestPathFirst).setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).build(); - assertEquals(prefix, SrPrefixAttributesParser.parseSrPrefix(Unpooled.wrappedBuffer(bytes))); + final SrPrefix prefixOspf = new SrPrefixBuilder() + .setFlags(OSPF_PREFIX_FLAGS) + .setAlgorithm(Algorithm.ShortestPathFirst).setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).build(); + assertEquals(prefixIsis, SrPrefixAttributesParser.parseSrPrefix(Unpooled.wrappedBuffer(bytes), ProtocolId.IsisLevel1)); + assertEquals(prefixOspf, SrPrefixAttributesParser.parseSrPrefix(Unpooled.wrappedBuffer(bytes), ProtocolId.Ospf)); final ByteBuf serializedPrefix = Unpooled.buffer(); - SrPrefixAttributesParser.serializeSrPrefix(prefix, serializedPrefix); + final ByteBuf serializedPrefixOspf = Unpooled.buffer(); + SrPrefixAttributesParser.serializeSrPrefix(prefixIsis, serializedPrefix); + SrPrefixAttributesParser.serializeSrPrefix(prefixOspf, serializedPrefixOspf); assertArrayEquals(bytes, ByteArray.readAllBytes(serializedPrefix)); + assertArrayEquals(bytesOspf, ByteArray.readAllBytes(serializedPrefixOspf)); } // tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.3.2 @@ -116,10 +161,10 @@ public class SrAttributeParserTest { final byte[] tested = { 0, 0, 0, 5, 4, (byte)0x89, 0, 4, 1, 2, 3, 4, // sid - 4, (byte)0x86, 0, 7, 0, 1, 0, 0, 1, 2, 0, // prefix - 4, (byte)0x88, 0, 0x58, 5, 0, 0, 0, // binding sid + 4, (byte)0x86, 0, 7, (byte)0xac, 1, 0, 0, 1, 2, 0, // prefix + 4, (byte)0x88, 0, 0x58, 5, 0x48, 0, 0, // binding sid // binding sub-tlvs - 4, (byte)0x86, 0, 8, 0, 1, 0, 0, 1, 2, 3, 4, // prefix + 4, (byte)0x86, 0, 8, (byte)0xa0, 1, 0, 0, 1, 2, 3, 4, // prefix 4, (byte)0x89, 0, 4, 1, 2, 3, 4, // sid 4, (byte)0x8a, 0, 4, 0, 0, 0, 6, // ero metric 4, (byte)0x8b, 0, 8, 0, 0, 0, 0, 9, 8, 7, 6, // IPv4 ERO @@ -127,7 +172,7 @@ public class SrAttributeParserTest { 4, (byte)0x8e, 0, 8, 0, 0, 0, 0, 3, 4, 5, 6, // IPv4 ERO backup 4, (byte)0x90, 0, 0x0c, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, // Unnumbered Interface ID ERO Sub-TLV Backup }; - final SrRange parsedRange = RangeTlvParser.parseSrRange(Unpooled.wrappedBuffer(tested)); + final SrRange parsedRange = RangeTlvParser.parseSrRange(Unpooled.wrappedBuffer(tested), ProtocolId.IsisLevel1); final List rangeSubTlvs = new ArrayList(); addSubTlvs(rangeSubTlvs); @@ -146,7 +191,7 @@ public class SrAttributeParserTest { .setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()).build()).build()); rangeSubTlvs.add(new SubTlvsBuilder().setRangeSubTlv( new PrefixSidTlvCaseBuilder() - .setFlags(new byte[] {0}) + .setFlags(ISIS_PREFIX_FLAGS) .setAlgorithm(Algorithm.StrictShortestPathFirst) .setSidLabelIndex(new LocalLabelCaseBuilder().setLocalLabel(new MplsLabel(4128L)).build()).build()).build()); final List bindingSubTlvs = new ArrayList(); @@ -154,14 +199,14 @@ public class SrAttributeParserTest { rangeSubTlvs.add(new SubTlvsBuilder().setRangeSubTlv( new BindingSidTlvCaseBuilder() .setWeight(new Weight((short) 5)) - .setFlags(new byte[] {0}) + .setFlags(BINDING_FLAGS) .setBindingSubTlvs(bindingSubTlvs).build()).build()); } private void addBindingSubTlvs(final List bindingSubTlvs) { bindingSubTlvs.add(new BindingSubTlvsBuilder().setBindingSubTlv( new PrefixSidCaseBuilder() - .setFlags(new byte[] {0}) + .setFlags(ISIS_PREFIX_FLAGS) .setAlgorithm(Algorithm.StrictShortestPathFirst) .setSidLabelIndex(new SidCaseBuilder().setSid(16909060L).build()) .build()).build()); @@ -184,12 +229,12 @@ public class SrAttributeParserTest { final byte[] tested = Bytes.concat( new byte[] { 0, 0, 0, 5, - 4, (byte)0x88, 0, 0x34, 5, 0, 0, 0, // binding sid + 4, (byte)0x88, 0, 0x34, 5, 0x48, 0, 0, // binding sid // binding sub-tlvs 4, (byte)0x8c, 0, 0x14, 0, 0, 0, 0 }, IPV6_A_BYTES, // IPv6 ERO new byte[] { 4, (byte)0x8f, 0, 0x14, 0, 0, 0, 0 }, IPV6_B_BYTES // IPv6 ERO backup ); - final SrRange parsedRange = RangeTlvParser.parseSrRange(Unpooled.wrappedBuffer(tested)); + final SrRange parsedRange = RangeTlvParser.parseSrRange(Unpooled.wrappedBuffer(tested), ProtocolId.IsisLevel1); final List rangeSubTlvs = new ArrayList(); final List bindingSubTlvs = new ArrayList(); @@ -200,7 +245,7 @@ public class SrAttributeParserTest { rangeSubTlvs.add(new SubTlvsBuilder().setRangeSubTlv( new BindingSidTlvCaseBuilder() .setWeight(new Weight((short) 5)) - .setFlags(new byte[] {0}) + .setFlags(BINDING_FLAGS) .setBindingSubTlvs(bindingSubTlvs).build()).build()); final SrRange expected = new SrRangeBuilder().setInterArea(Boolean.FALSE).setRangeSize(5).setSubTlvs(rangeSubTlvs).build(); @@ -214,29 +259,38 @@ public class SrAttributeParserTest { // tools.ietf.org/html/draft-gredler-idr-bgp-ls-segment-routing-ext-00#section-2.2.1 @Test public void testSrAdjId() { - final byte[] tested = { (byte)-80, 10, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + final byte[] tested = { (byte)0x60, 10, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + final byte[] testedOspf = { (byte)0xc0, 10, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; final byte[] sidLabel = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; final SrAdjId srAdjId = new SrAdjIdBuilder() - .setFlags(new byte[] { (byte)-80 }) + .setFlags(ISIS_ADJ_FLAGS) + .setWeight(new Weight((short) 10)) + .setSidLabelIndex(new Ipv6AddressCaseBuilder().setIpv6Address(Ipv6Util.addressForByteBuf(Unpooled.copiedBuffer(sidLabel))).build()).build(); + final SrAdjId ospfAdj = new SrAdjIdBuilder() + .setFlags(OSPF_ADJ_FLAGS) .setWeight(new Weight((short) 10)) .setSidLabelIndex(new Ipv6AddressCaseBuilder().setIpv6Address(Ipv6Util.addressForByteBuf(Unpooled.copiedBuffer(sidLabel))).build()).build(); + + assertEquals(srAdjId, new SrAdjIdBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(Unpooled.wrappedBuffer(tested), ProtocolId.IsisLevel1)).build()); + assertEquals(ospfAdj, new SrAdjIdBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(Unpooled.wrappedBuffer(testedOspf), ProtocolId.Ospf)).build()); final ByteBuf serializedData = SrLinkAttributesParser.serializeAdjacencySegmentIdentifier(srAdjId); - assertEquals(srAdjId, new SrAdjIdBuilder(SrLinkAttributesParser.parseAdjacencySegmentIdentifier(Unpooled.wrappedBuffer(tested))).build()); + final ByteBuf serializedOspf = SrLinkAttributesParser.serializeAdjacencySegmentIdentifier(ospfAdj); assertArrayEquals(tested, ByteArray.readAllBytes(serializedData)); + assertArrayEquals(testedOspf, ByteArray.readAllBytes(serializedOspf)); } @Test public void testSrLanAdjId() { - final byte[] tested = { (byte)-80, 10, 0, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + final byte[] tested = { (byte)0x60, 10, 0, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; final byte[] sidLabel = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; final byte[] systemId = { 1, 2, 3, 4, 5, 6 }; final SrLanAdjId srLanAdjId = new SrLanAdjIdBuilder() - .setFlags(new byte[] { (byte) -80 }) + .setFlags(ISIS_ADJ_FLAGS) .setWeight(new Weight((short)10)) .setIsoSystemId(new IsoSystemIdentifier(systemId)) .setSidLabelIndex(new Ipv6AddressCaseBuilder().setIpv6Address(Ipv6Util.addressForByteBuf(Unpooled.copiedBuffer(sidLabel))).build()).build(); + assertEquals(srLanAdjId, SrLinkAttributesParser.parseLanAdjacencySegmentIdentifier(Unpooled.wrappedBuffer(tested), ProtocolId.IsisLevel1)); final ByteBuf serializedData = SrLinkAttributesParser.serializeLanAdjacencySegmentIdentifier(srLanAdjId); - assertEquals(srLanAdjId, SrLinkAttributesParser.parseLanAdjacencySegmentIdentifier(Unpooled.wrappedBuffer(tested))); assertArrayEquals(tested, ByteArray.readAllBytes(serializedData)); } @@ -272,4 +326,37 @@ public class SrAttributeParserTest { throw e.getCause(); } } + + @Test(expected=UnsupportedOperationException.class) + public void testBindingParserPrivateConstructor() throws Throwable { + final Constructor c = BindingSidLabelParser.class.getDeclaredConstructor(); + c.setAccessible(true); + try { + c.newInstance(); + } catch (final InvocationTargetException e) { + throw e.getCause(); + } + } + + @Test(expected=UnsupportedOperationException.class) + public void testRangeTlvParserPrivateConstructor() throws Throwable { + final Constructor c = RangeTlvParser.class.getDeclaredConstructor(); + c.setAccessible(true); + try { + c.newInstance(); + } catch (final InvocationTargetException e) { + throw e.getCause(); + } + } + + @Test(expected=UnsupportedOperationException.class) + public void testSidLabelIndexParserPrivateConstructor() throws Throwable { + final Constructor c = SidLabelIndexParser.class.getDeclaredConstructor(); + c.setAccessible(true); + try { + c.newInstance(); + } catch (final InvocationTargetException e) { + throw e.getCause(); + } + } } -- 2.36.6