2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.protocol.bgp.parser.impl.message.update;
11 import java.util.Arrays;
13 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
14 import org.opendaylight.protocol.bgp.parser.BGPError;
15 import org.opendaylight.protocol.bgp.parser.impl.CommunityUtil;
16 import org.opendaylight.protocol.concepts.Ipv4Util;
17 import org.opendaylight.protocol.util.ByteArray;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Community;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.ExtendedCommunity;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.CAsSpecificExtendedCommunityBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.CInet4SpecificExtendedCommunityBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.COpaqueExtendedCommunityBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.CRouteOriginExtendedCommunityBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.CRouteTargetExtendedCommunityBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.c.as.specific.extended.community.AsSpecificExtendedCommunityBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.c.inet4.specific.extended.community.Inet4SpecificExtendedCommunityBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.c.opaque.extended.community.OpaqueExtendedCommunityBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.c.route.origin.extended.community.RouteOriginExtendedCommunityBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.c.route.target.extended.community.RouteTargetExtendedCommunityBuilder;
32 import com.google.common.annotations.VisibleForTesting;
33 import com.google.common.primitives.UnsignedBytes;
36 * Parser for Extended Communities Path Attribute.
38 public class CommunitiesParser {
40 public static final int EXTENDED_COMMUNITY_LENGTH = 8; // bytes
42 public static final int COMMUNITY_LENGTH = 4; // bytes
44 private static final int TYPE_LENGTH = 2; // bytes
46 private static final int AS_NUMBER_LENGTH = 2; // bytes
48 private static final int AS_LOCAL_ADMIN_LENGTH = 4; // bytes
50 private CommunitiesParser() {
55 * Parse known Community, if unknown, a new one will be created.
57 * @param bytes byte array to be parsed
58 * @return new Community
59 * @throws BGPDocumentedException
61 static Community parseCommunity(final byte[] bytes) throws BGPDocumentedException {
62 if (bytes.length != COMMUNITY_LENGTH)
63 throw new BGPDocumentedException("Community with wrong length: " + bytes.length, BGPError.OPT_ATTR_ERROR);
64 if (Arrays.equals(bytes, new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x01 })) {
65 return CommunityUtil.NO_EXPORT;
66 } else if (Arrays.equals(bytes, new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x02 })) {
67 return CommunityUtil.NO_ADVERTISE;
68 } else if (Arrays.equals(bytes, new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x03 })) {
69 return CommunityUtil.NO_EXPORT_SUBCONFED;
71 return CommunityUtil.create((ByteArray.bytesToLong(Arrays.copyOfRange(bytes, 0, AS_NUMBER_LENGTH))),
72 ByteArray.bytesToInt(Arrays.copyOfRange(bytes, AS_NUMBER_LENGTH, AS_NUMBER_LENGTH + AS_NUMBER_LENGTH)));
76 * Parse Extended Community according to their type.
78 * @param bytes byte array to be parsed
79 * @return new Specific Extended Community
80 * @throws BGPDocumentedException if the type is not recognized
83 public static ExtendedCommunity parseExtendedCommunity(final byte[] bytes) throws BGPDocumentedException {
84 final int type = UnsignedBytes.toInt(bytes[0]);
85 final int subType = UnsignedBytes.toInt(bytes[1]);
86 final byte[] value = ByteArray.subByte(bytes, TYPE_LENGTH, bytes.length - TYPE_LENGTH);
91 return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
92 new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
93 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
94 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
95 } else if (subType == 3) {
96 return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
97 new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
98 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
99 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
101 return new CAsSpecificExtendedCommunityBuilder().setAsSpecificExtendedCommunity(
102 new AsSpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
103 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
104 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
106 return new CAsSpecificExtendedCommunityBuilder().setAsSpecificExtendedCommunity(
107 new AsSpecificExtendedCommunityBuilder().setTransitive(true).setGlobalAdministrator(
108 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
109 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
112 return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
113 new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
114 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
115 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
116 } else if (subType == 3) {
117 return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
118 new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
119 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
120 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
122 throw new BGPDocumentedException("Could not parse Extended Community subtype: " + subType, BGPError.OPT_ATTR_ERROR);
125 return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
126 new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
127 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
128 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
129 } else if (subType == 3) {
130 return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
131 new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
132 new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
133 ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
135 return new CInet4SpecificExtendedCommunityBuilder().setInet4SpecificExtendedCommunity(
136 new Inet4SpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
137 Ipv4Util.addressForBytes(ByteArray.subByte(value, 0, 4))).setLocalAdministrator(
138 ByteArray.subByte(value, 4, 2)).build()).build();
140 return new CInet4SpecificExtendedCommunityBuilder().setInet4SpecificExtendedCommunity(
141 new Inet4SpecificExtendedCommunityBuilder().setTransitive(true).setGlobalAdministrator(
142 Ipv4Util.addressForBytes(ByteArray.subByte(value, 0, 4))).setLocalAdministrator(ByteArray.subByte(value, 4, 2)).build()).build();
144 return new COpaqueExtendedCommunityBuilder().setOpaqueExtendedCommunity(
145 new OpaqueExtendedCommunityBuilder().setTransitive(false).setValue(value).build()).build();
147 return new COpaqueExtendedCommunityBuilder().setOpaqueExtendedCommunity(
148 new OpaqueExtendedCommunityBuilder().setTransitive(true).setValue(value).build()).build();
150 throw new BGPDocumentedException("Could not parse Extended Community type: " + type, BGPError.OPT_ATTR_ERROR);