import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
if (pathAttributes1 != null) {
final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes();
- if (routes != null &&
- routes.getDestinationType()
- instanceof
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase
- flowspecCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) routes.getDestinationType();
+ if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) {
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase flowspecCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) routes.getDestinationType();
serializeNlri(flowspecCase.getDestinationFlowspec().getFlowspec(), byteAggregator);
}
} else if (pathAttributes2 != null) {
final FlowspecType value = flow.getFlowspecType();
switch (flow.getComponentType()) {
case DestinationPrefix:
- nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((DestinationPrefixCase)value).getDestinationPrefix()));
+ nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((DestinationPrefixCase) value).getDestinationPrefix()));
break;
case SourcePrefix:
- nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((SourcePrefixCase)value).getSourcePrefix()));
+ nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((SourcePrefixCase) value).getSourcePrefix()));
break;
case ProtocolIp:
- serializeNumericTwoByteValue(((ProtocolIpCase)value).getProtocolIps(), nlriByteBuf);
+ serializeNumericTwoByteValue(((ProtocolIpCase) value).getProtocolIps(), nlriByteBuf);
break;
case Port:
- serializeNumericTwoByteValue(((PortCase)value).getPorts(), nlriByteBuf);
+ serializeNumericTwoByteValue(((PortCase) value).getPorts(), nlriByteBuf);
break;
case DestinationPort:
- serializeNumericTwoByteValue(((DestinationPortCase)value).getDestinationPorts(), nlriByteBuf);
+ serializeNumericTwoByteValue(((DestinationPortCase) value).getDestinationPorts(), nlriByteBuf);
break;
case SourcePort:
- serializeNumericTwoByteValue(((SourcePortCase)value).getSourcePorts(), nlriByteBuf);
+ serializeNumericTwoByteValue(((SourcePortCase) value).getSourcePorts(), nlriByteBuf);
break;
case IcmpType:
- serializeNumericOneByteValue(((IcmpTypeCase)value).getTypes(), nlriByteBuf);
+ serializeNumericOneByteValue(((IcmpTypeCase) value).getTypes(), nlriByteBuf);
break;
case IcmpCode:
- serializeNumericOneByteValue(((IcmpCodeCase)value).getCodes(), nlriByteBuf);
+ serializeNumericOneByteValue(((IcmpCodeCase) value).getCodes(), nlriByteBuf);
break;
case TcpFlags:
- final List<TcpFlags> flags = ((TcpFlagsCase)value).getTcpFlags();
+ final List<TcpFlags> flags = ((TcpFlagsCase) value).getTcpFlags();
for (final TcpFlags flag : flags) {
final ByteBuf flagsBuf = Unpooled.buffer();
writeShortest(flag.getValue(), flagsBuf);
}
break;
case PacketLength:
- serializeNumericTwoByteValue(((PacketLengthCase)value).getPacketLengths(), nlriByteBuf);
+ serializeNumericTwoByteValue(((PacketLengthCase) value).getPacketLengths(), nlriByteBuf);
break;
case Dscp:
- final List<Dscps> dscps = ((DscpCase)value).getDscps();
+ final List<Dscps> dscps = ((DscpCase) value).getDscps();
for (final Dscps dscp : dscps) {
serializeNumericOperand(dscp.getOp(), 1, nlriByteBuf);
writeShortest(dscp.getValue().getValue(), nlriByteBuf);
}
break;
case Fragment:
- final List<Fragments> fragments = ((FragmentCase)value).getFragments();
+ final List<Fragments> fragments = ((FragmentCase) value).getFragments();
for (final Fragments fragment : fragments) {
serializeBitmaskOperand(fragment.getOp(), 1, nlriByteBuf);
nlriByteBuf.writeByte(serializeFragment(fragment.getValue()));
builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
- .setDestinationFlowspec(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.flowspec._case.DestinationFlowspecBuilder().setFlowspec(dst).build()).build()).build());
+ .setDestinationFlowspec(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.flowspec._case.DestinationFlowspecBuilder()
+ .setFlowspec(dst).build()).build()).build());
}
/**
final int length = nlri.readableBytes();
nlri.skipBytes(length > MAX_NLRI_LENGTH_ONE_BYTE ? NLRI_LENGTH_EXTENDED : NLRI_LENGTH);
- while(nlri.isReadable()) {
+ while (nlri.isReadable()) {
final FlowspecBuilder builder = new FlowspecBuilder();
// read type
final ComponentType type = ComponentType.forValue(nlri.readUnsignedByte());
return bs.toByte();
}
- public static String stringNlri(final UnkeyedListEntryNode linkstate) {
- // FIXME: BUG-2571 : create human-readable route key, e.g : "all packets to 10.0.1/24 from 192/8 and port {range [137, 139] or 8080}"
- return "";
+ public static String stringNlri(final DataContainerNode<?> flowspec) {
+ return stringNlri(extractFlowspec((MapEntryNode) flowspec));
}
public static Flowspec extractFlowspec(final MapEntryNode route) {
return null;
}
}
+
+ @VisibleForTesting
+ static final String stringNlri(final Flowspec flow) {
+ final StringBuilder buffer = new StringBuilder("all packets ");
+ final FlowspecType value = flow.getFlowspecType();
+ switch (flow.getComponentType()) {
+ case DestinationPrefix:
+ buffer.append("to ");
+ buffer.append(((DestinationPrefixCase) value).getDestinationPrefix().getValue());
+ break;
+ case SourcePrefix:
+ buffer.append("from ");
+ buffer.append(((SourcePrefixCase) value).getSourcePrefix().getValue());
+ break;
+ case ProtocolIp:
+ buffer.append("where protocol ");
+ buffer.append(stringNumericTwo(((ProtocolIpCase) value).getProtocolIps()));
+ break;
+ case Port:
+ buffer.append("where port ");
+ buffer.append(stringNumericTwo(((PortCase) value).getPorts()));
+ break;
+ case DestinationPort:
+ buffer.append("where destination port ");
+ buffer.append(stringNumericTwo(((DestinationPortCase) value).getDestinationPorts()));
+ break;
+ case SourcePort:
+ buffer.append("where source port ");
+ buffer.append(stringNumericTwo(((SourcePortCase) value).getSourcePorts()));
+ break;
+ case IcmpType:
+ buffer.append("where ICMP type ");
+ buffer.append(stringNumericOne(((IcmpTypeCase) value).getTypes()));
+ break;
+ case IcmpCode:
+ buffer.append("where ICMP code ");
+ buffer.append(stringNumericOne(((IcmpCodeCase) value).getCodes()));
+ break;
+ case TcpFlags:
+ buffer.append(stringTcpFlags(((TcpFlagsCase) value).getTcpFlags()));
+ break;
+ case PacketLength:
+ buffer.append("where packet length ");
+ buffer.append(stringNumericTwo(((PacketLengthCase) value).getPacketLengths()));
+ break;
+ case Dscp:
+ buffer.append(stringDscp(((DscpCase) value).getDscps()));
+ break;
+ case Fragment:
+ buffer.append(stringFragment(((FragmentCase) value).getFragments()));
+ break;
+ default:
+ LOG.warn("Skipping unhandled component type {}" , flow.getComponentType());
+ break;
+ }
+ return buffer.toString();
+ }
+
+ private static <T extends NumericTwoByteValue> String stringNumericTwo(final List<T> list) {
+ final StringBuilder buffer = new StringBuilder();
+ boolean isFirst = true;
+ for (final T item : list) {
+ buffer.append(stringNumericOperand(item.getOp(), isFirst));
+ buffer.append(item.getValue());
+ buffer.append(' ');
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ return buffer.toString();
+ }
+
+ private static <T extends NumericOneByteValue> String stringNumericOne(final List<T> list) {
+ final StringBuilder buffer = new StringBuilder();
+ boolean isFirst = true;
+ for (final T item : list) {
+ buffer.append(stringNumericOperand(item.getOp(), isFirst));
+ buffer.append(item.getValue());
+ buffer.append(' ');
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ return buffer.toString();
+ }
+
+ private static String stringNumericOperand(final NumericOperand op, final boolean isFirst) {
+ final StringBuilder buffer = new StringBuilder();
+ if (!op.isAndBit() && !isFirst) {
+ buffer.append("or ");
+ }
+ if (op.isAndBit()) {
+ buffer.append("and ");
+ }
+ if (op.isLessThan() && op.isEquals()) {
+ buffer.append("is less than or equal to ");
+ return buffer.toString();
+ } else if (op.isGreaterThan() && op.isEquals()) {
+ buffer.append("is greater than or equal to ");
+ return buffer.toString();
+ }
+ if (op.isEquals()) {
+ buffer.append("equals to ");
+ }
+ if (op.isLessThan()) {
+ buffer.append("is less than ");
+ }
+ if (op.isGreaterThan()) {
+ buffer.append("is greater than ");
+ }
+ return buffer.toString();
+ }
+
+ private static String stringTcpFlags(final List<TcpFlags> flags) {
+ final StringBuilder buffer = new StringBuilder("where TCP flags ");
+ boolean isFirst = true;
+ for (final TcpFlags item : flags) {
+ buffer.append(stringBitmaskOperand(item.getOp(), isFirst));
+ buffer.append(item.getValue());
+ buffer.append(' ');
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ return buffer.toString();
+ }
+
+ private static String stringBitmaskOperand(final BitmaskOperand op, final boolean isFirst) {
+ final StringBuilder buffer = new StringBuilder();
+ if (!op.isAndBit() && !isFirst) {
+ buffer.append("or ");
+ }
+ if (op.isAndBit()) {
+ buffer.append("and ");
+ }
+ if (op.isMatch()) {
+ buffer.append("does ");
+ if (op.isNot()) {
+ buffer.append("not ");
+ }
+ buffer.append("match ");
+ } else if (op.isNot()) {
+ buffer.append("is not ");
+ }
+ return buffer.toString();
+ }
+
+ private static String stringDscp(final List<Dscps> dscps) {
+ final StringBuilder buffer = new StringBuilder("where DSCP ");
+ boolean isFirst = true;
+ for (final Dscps item : dscps) {
+ buffer.append(stringNumericOperand(item.getOp(), isFirst));
+ buffer.append(item.getValue().getValue());
+ buffer.append(' ');
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ return buffer.toString();
+ }
+
+ private static String stringFragment(final List<Fragments> fragments) {
+ final StringBuilder buffer = new StringBuilder("where fragment ");
+ boolean isFirst = true;
+ for (final Fragments item : fragments) {
+ buffer.append(stringBitmaskOperand(item.getOp(), isFirst));
+ buffer.append(stringFragment(item.getValue()));
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ return buffer.toString();
+ }
+
+ private static String stringFragment(final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.Fragment fragment) {
+ final StringBuilder buffer = new StringBuilder();
+ if (fragment.isDoNot()) {
+ buffer.append("'DO NOT' ");
+ }
+ if (fragment.isFirst()) {
+ buffer.append("'IS FIRST' ");
+ }
+ if (fragment.isLast()) {
+ buffer.append("'IS LAST' ");
+ }
+ if (fragment.isIsA()) {
+ buffer.append("'IS A' ");
+ }
+ return buffer.toString();
+ }
}
private static final byte[] nlri = new byte[] { 0x1D, 01, 0x18, 0x0a, 00, 01, 02, 0x08, (byte) 0xc0,
03, (byte) 0x81, 06, 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
- 05, 0x12, 0x0f, (byte)0xf9, (byte)0x81, (byte)0xb3,
- 06, (byte) 0x91, 0x1f, (byte)0x90};
+ 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
+ 06, (byte) 0x91, 0x1f, (byte) 0x90 };
- private static final byte[] unnlri = new byte[] { 0x1B, 07, 4, 2, (byte)0x84, 3,
- 0x08, 06, 04, (byte)0x80, 05,
- 0x09, 0x12, 04, 01, (byte)0x91, 0x56, (byte) 0xb1,
- 0x0a, (byte)0x96, (byte) 0xde, (byte) 0xad,
- 0x0b, (byte)0x86, 0x2a,
- 0x0c, (byte)0x81, (byte)0x0f};
+ private static final byte[] unnlri = new byte[] { 0x1B, 07, 4, 2, (byte) 0x84, 3,
+ 0x08, 06, 04, (byte) 0x80, 05,
+ 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
+ 0x0a, (byte) 0x96, (byte) 0xde, (byte) 0xad,
+ 0x0b, (byte) 0x86, 0x2a,
+ 0x0c, (byte) 0x81, (byte) 0x0f };
@Test
public void testParseLength() {
// 00-00-0000 = 1
- assertEquals(1, FSNlriParser.parseLength((byte)0x00));
+ assertEquals(1, FSNlriParser.parseLength((byte) 0x00));
// 00-01-0000 = 2
- assertEquals(2, FSNlriParser.parseLength((byte)16));
+ assertEquals(2, FSNlriParser.parseLength((byte) 16));
// 00-10-0000 = 4
- assertEquals(4, FSNlriParser.parseLength((byte)32));
+ assertEquals(4, FSNlriParser.parseLength((byte) 32));
// 00-11-0000 = 8
- assertEquals(8, FSNlriParser.parseLength((byte)48));
+ assertEquals(8, FSNlriParser.parseLength((byte) 48));
}
-
@Test
public void testParseMpReachNlri() throws BGPParsingException {
final List<Flowspec> fs = new ArrayList<>();
final MpReachNlriBuilder result = new MpReachNlriBuilder();
parser.parseNlri(Unpooled.wrappedBuffer(nlri), result);
- final List<Flowspec> flows = ((DestinationFlowspecCase)(result.getAdvertizedRoutes().getDestinationType())).getDestinationFlowspec().getFlowspec();
+ final List<Flowspec> flows = ((DestinationFlowspecCase) (result.getAdvertizedRoutes().getDestinationType())).getDestinationFlowspec().getFlowspec();
assertEquals(6, flows.size());
assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
final ByteBuf buffer = Unpooled.buffer();
parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.build()).build()).build(), buffer);
assertArrayEquals(nlri, ByteArray.readAllBytes(buffer));
+
+ assertEquals("all packets to 10.0.1.0/24", FSNlriParser.stringNlri(flows.get(0)));
+ assertEquals("all packets from 192.0.0.0/8", FSNlriParser.stringNlri(flows.get(1)));
+ assertEquals("all packets where protocol equals to 6 ", FSNlriParser.stringNlri(flows.get(2)));
+ assertEquals("all packets where port is greater than or equal to 137 and is less than or equal to 139 or equals to 8080 ", FSNlriParser.stringNlri(flows.get(3)));
+ assertEquals("all packets where destination port is greater than 4089 or equals to 179 ", FSNlriParser.stringNlri(flows.get(4)));
+ assertEquals("all packets where source port equals to 8080 ", FSNlriParser.stringNlri(flows.get(5)));
}
@Test
final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
parser.parseNlri(Unpooled.wrappedBuffer(unnlri), result);
- final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)(result.getWithdrawnRoutes().getDestinationType())).getDestinationFlowspec().getFlowspec();
+ final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) (result.getWithdrawnRoutes().getDestinationType())).getDestinationFlowspec().getFlowspec();
assertEquals(6, flows.size());
assertEquals(icmpType, flows.get(0).getFlowspecType());
assertEquals(icmpCode, flows.get(1).getFlowspecType());
final ByteBuf buffer = Unpooled.buffer();
parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
assertArrayEquals(unnlri, ByteArray.readAllBytes(buffer));
+
+ assertEquals("all packets where ICMP type is less than 2 or is less than 3 ", FSNlriParser.stringNlri(flows.get(0)));
+ assertEquals("all packets where ICMP code is less than is greater than 4 or 5 ", FSNlriParser.stringNlri(flows.get(1)));
+ assertEquals("all packets where TCP flags is not 1025 or does match 22193 ", FSNlriParser.stringNlri(flows.get(2)));
+ assertEquals("all packets where packet length is less than is greater than 57005 ", FSNlriParser.stringNlri(flows.get(3)));
+ assertEquals("all packets where DSCP is less than is greater than 42 ", FSNlriParser.stringNlri(flows.get(4)));
+ assertEquals("all packets where fragment does match 'DO NOT' 'IS FIRST' 'IS LAST' 'IS A' ", FSNlriParser.stringNlri(flows.get(5)));
}
@Test