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.impl;
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 public 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);
50 public synchronized AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi,
51 final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser) {
52 final BgpTableType key = createKey(afi, safi);
53 final NlriParser prev = handlers.get(key);
54 Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
56 handlers.put(key, parser);
57 final Object lock = this;
58 return new AbstractRegistration() {
60 protected void removeRegistration() {
68 private Class<? extends AddressFamily> getAfi(final byte[] header) throws BGPParsingException {
69 final int afiVal = UnsignedBytes.toInt(header[0]) * 256 + UnsignedBytes.toInt(header[1]);
70 final Class<? extends AddressFamily> afi = afiReg.classForFamily(afiVal);
72 throw new BGPParsingException("Address Family Identifier: '" + afiVal + "' not supported.");
78 private Class<? extends SubsequentAddressFamily> getSafi(final byte[] header) throws BGPParsingException {
79 final int safiVal = UnsignedBytes.toInt(header[2]);
80 final Class<? extends SubsequentAddressFamily> safi = safiReg.classForFamily(safiVal);
82 throw new BGPParsingException("Subsequent Address Family Identifier: '" + safiVal + "' not supported.");
89 public MpUnreachNlri parseMpUnreach(final byte[] bytes) throws BGPParsingException {
90 final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder();
91 builder.setAfi(getAfi(bytes));
92 builder.setSafi(getSafi(bytes));
94 final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
95 parser.parseNlri(ByteArray.subByte(bytes, 3, bytes.length - 3), builder);
97 return builder.build();
101 public MpReachNlri parseMpReach(final byte[] bytes) throws BGPParsingException {
102 final MpReachNlriBuilder builder = new MpReachNlriBuilder();
103 builder.setAfi(getAfi(bytes));
104 builder.setSafi(getSafi(bytes));
106 final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
108 final int nextHopLength = UnsignedBytes.toInt(bytes[3]);
111 final byte[] nextHop = ByteArray.subByte(bytes, byteOffset, nextHopLength);
112 byteOffset += nextHopLength + 1;
114 final byte[] nlri = ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset);
115 parser.parseNlri(nlri, nextHop, builder);
117 return builder.build();