package org.opendaylight.protocol.bgp.flowspec;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.primitives.UnsignedInts;
import org.opendaylight.protocol.util.ByteBufWriteUtil;
import org.opendaylight.protocol.util.Ipv4Util;
import org.opendaylight.protocol.util.Values;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.BitmaskOperand;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.ComponentType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.NumericOneByteValue;
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.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+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.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
import org.slf4j.Logger;
public class FSNlriParser implements NlriParser, NlriSerializer {
private static final Logger LOG = LoggerFactory.getLogger(FSNlriParser.class);
+ private static final NodeIdentifier FLOWSPEC_TYPE_NID = new NodeIdentifier(FlowspecType.QNAME);
+ @VisibleForTesting
+ static final NodeIdentifier COMPONENT_TYPE_NID = new NodeIdentifier(QName.cachedReference(QName.create(Flowspec.QNAME, "component-type")));
+ @VisibleForTesting
+ static final NodeIdentifier DEST_PREFIX_NID = new NodeIdentifier(QName.cachedReference(QName.create(DestinationPrefixCase.QNAME, "destination-prefix")));
+ private static final NodeIdentifier SOURCE_PREFIX_NID = new NodeIdentifier(QName.cachedReference(QName.create(SourcePrefixCase.QNAME, "source-prefix")));
+ private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
+ private static final NodeIdentifier PORTS_NID = new NodeIdentifier(Ports.QNAME);
+ private static final NodeIdentifier DEST_PORT_NID = new NodeIdentifier(DestinationPorts.QNAME);
+ private static final NodeIdentifier SOURCE_PORT_NID = new NodeIdentifier(SourcePorts.QNAME);
+ private static final NodeIdentifier ICMP_TYPE_NID = new NodeIdentifier(Types.QNAME);
+ private static final NodeIdentifier ICMP_CODE_NID = new NodeIdentifier(Codes.QNAME);
+ private static final NodeIdentifier TCP_FLAGS_NID = new NodeIdentifier(TcpFlags.QNAME);
+ private static final NodeIdentifier PACKET_LENGTHS_NID = new NodeIdentifier(PacketLengths.QNAME);
+ private static final NodeIdentifier DSCP_NID = new NodeIdentifier(Dscps.QNAME);
+ private static final NodeIdentifier FRAGMENT_NID = new NodeIdentifier(Fragments.QNAME);
+
private static final int NLRI_LENGTH = 1;
private static final int NLRI_LENGTH_EXTENDED = 2;
/**
}
public static Flowspec extractFlowspec(final MapEntryNode route) {
- // FIXME: BUG-2571 : finish this
- return new FlowspecBuilder().build();
+ final FlowspecBuilder fs = new FlowspecBuilder();
+ final Optional<DataContainerChild<? extends PathArgument, ?>> compType = route.getChild(COMPONENT_TYPE_NID);
+ if (compType.isPresent()) {
+ fs.setComponentType(componentTypeValue((String) compType.get().getValue()));
+ }
+ final ChoiceNode fsType = (ChoiceNode) route.getChild(FLOWSPEC_TYPE_NID).get();
+ if (fsType.getChild(DEST_PREFIX_NID).isPresent()) {
+ fs.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
+ new Ipv4Prefix((String) fsType.getChild(DEST_PREFIX_NID).get().getValue())).build());
+ } else if (fsType.getChild(SOURCE_PREFIX_NID).isPresent()) {
+ fs.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
+ .build());
+ } else if (fsType.getChild(PROTOCOL_IP_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new ProtocolIpCaseBuilder().build());
+ } else if (fsType.getChild(PORTS_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new PortCaseBuilder().build());
+ } else if (fsType.getChild(DEST_PORT_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new DestinationPortCaseBuilder().build());
+ } else if (fsType.getChild(SOURCE_PORT_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new SourcePortCaseBuilder().build());
+ } else if (fsType.getChild(ICMP_TYPE_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new IcmpTypeCaseBuilder().build());
+ } else if (fsType.getChild(ICMP_CODE_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new IcmpCodeCaseBuilder().build());
+ } else if (fsType.getChild(TCP_FLAGS_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new TcpFlagsCaseBuilder().build());
+ } else if (fsType.getChild(PACKET_LENGTHS_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new PacketLengthCaseBuilder().build());
+ } else if (fsType.getChild(DSCP_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new DscpCaseBuilder().build());
+ } else if (fsType.getChild(FRAGMENT_NID).isPresent()) {
+ // FIXME: BUG-3044
+ fs.setFlowspecType(new FragmentCaseBuilder().build());
+ }
+ return fs.build();
+ }
+
+ // FIXME: use codec
+ private static ComponentType componentTypeValue(final String compType) {
+ switch (compType) {
+ case "destination-prefix":
+ return ComponentType.DestinationPrefix;
+ case "source-prefix":
+ return ComponentType.SourcePrefix;
+ case "protocol-ip":
+ return ComponentType.ProtocolIp;
+ case "port":
+ return ComponentType.Port;
+ case "destination-port":
+ return ComponentType.DestinationPort;
+ case "source-port":
+ return ComponentType.SourcePort;
+ case "icmp-type":
+ return ComponentType.IcmpType;
+ case "icmp-code":
+ return ComponentType.IcmpCode;
+ case "tcp-flags":
+ return ComponentType.TcpFlags;
+ case "packet-length":
+ return ComponentType.PacketLength;
+ case "dscp":
+ return ComponentType.Dscp;
+ case "fragment":
+ return ComponentType.Fragment;
+ default:
+ return null;
+ }
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.NumericOperand;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.Flowspec;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.flowspec.FlowspecType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.flowspec.flowspec.type.DestinationPortCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.flowspec.destination.flowspec.flowspec.type.DestinationPrefixCase;
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.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
public class FSNlriParserTest {
parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
assertArrayEquals(unnlri, ByteArray.readAllBytes(buffer));
}
+
+ @Test
+ public void testExtractFlowspec() {
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+ entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+ entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("destination-prefix").build());
+ entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+ .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.DEST_PREFIX_NID).withValue("127.0.0.5/32").build()).build());
+ final FlowspecBuilder expected = new FlowspecBuilder();
+ expected.setComponentType(ComponentType.DestinationPrefix);
+ expected.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("127.0.0.5/32")).build());
+ assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+ }
}