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
8 package org.opendaylight.protocol.bgp.parser.spi.pojo;
10 import java.util.concurrent.ConcurrentHashMap;
11 import java.util.concurrent.ConcurrentMap;
13 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
14 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
15 import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
16 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
17 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
18 import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
19 import org.opendaylight.protocol.concepts.AbstractRegistration;
20 import org.opendaylight.protocol.util.ByteArray;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.BgpTableType;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlri;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlri;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
29 import com.google.common.base.Preconditions;
30 import com.google.common.primitives.UnsignedBytes;
32 final class SimpleNlriRegistry implements NlriRegistry {
33 private final ConcurrentMap<BgpTableType, NlriParser> handlers = new ConcurrentHashMap<>();
34 private final SubsequentAddressFamilyRegistry safiReg;
35 private final AddressFamilyRegistry afiReg;
37 public SimpleNlriRegistry(final AddressFamilyRegistry afiReg, final SubsequentAddressFamilyRegistry safiReg) {
38 this.afiReg = Preconditions.checkNotNull(afiReg);
39 this.safiReg = Preconditions.checkNotNull(safiReg);
42 private static BgpTableType createKey(final Class<? extends AddressFamily> afi,
43 final Class<? extends SubsequentAddressFamily> safi) {
44 Preconditions.checkNotNull(afi);
45 Preconditions.checkNotNull(safi);
46 return new BgpTableTypeImpl(afi, safi);
49 synchronized AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi,
50 final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser) {
51 final BgpTableType key = createKey(afi, safi);
52 final NlriParser prev = handlers.get(key);
53 Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
55 handlers.put(key, parser);
56 final Object lock = this;
57 return new AbstractRegistration() {
59 protected void removeRegistration() {
67 private Class<? extends AddressFamily> getAfi(final byte[] header) throws BGPParsingException {
68 final int afiVal = UnsignedBytes.toInt(header[0]) * 256 + UnsignedBytes.toInt(header[1]);
69 final Class<? extends AddressFamily> afi = afiReg.classForFamily(afiVal);
71 throw new BGPParsingException("Address Family Identifier: '" + afiVal + "' not supported.");
77 private Class<? extends SubsequentAddressFamily> getSafi(final byte[] header) throws BGPParsingException {
78 final int safiVal = UnsignedBytes.toInt(header[2]);
79 final Class<? extends SubsequentAddressFamily> safi = safiReg.classForFamily(safiVal);
81 throw new BGPParsingException("Subsequent Address Family Identifier: '" + safiVal + "' not supported.");
88 public MpUnreachNlri parseMpUnreach(final byte[] bytes) throws BGPParsingException {
89 final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder();
90 builder.setAfi(getAfi(bytes));
91 builder.setSafi(getSafi(bytes));
93 final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
94 parser.parseNlri(ByteArray.subByte(bytes, 3, bytes.length - 3), builder);
96 return builder.build();
100 public MpReachNlri parseMpReach(final byte[] bytes) throws BGPParsingException {
101 final MpReachNlriBuilder builder = new MpReachNlriBuilder();
102 builder.setAfi(getAfi(bytes));
103 builder.setSafi(getSafi(bytes));
105 final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
107 final int nextHopLength = UnsignedBytes.toInt(bytes[3]);
110 final byte[] nextHop = ByteArray.subByte(bytes, byteOffset, nextHopLength);
111 byteOffset += nextHopLength + 1;
113 final byte[] nlri = ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset);
114 parser.parseNlri(nlri, nextHop, builder);
116 return builder.build();