Migrate lisp-proto implementation to IETF YANG model
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / address / LispAddressSerializer.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.lispflowmapping.lisp.serializer.address;
9
10 import java.nio.ByteBuffer;
11
12 import org.opendaylight.lispflowmapping.lisp.serializer.address.factory.LispAddressSerializerFactory;
13 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
14 import org.opendaylight.lispflowmapping.lisp.util.AddressTypeMap;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Lcaf;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddressFamily;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
24
25 public class LispAddressSerializer {
26
27     private static final LispAddressSerializer INSTANCE = new LispAddressSerializer();
28     public static final InstanceIdType DEFAULT_VNI = new InstanceIdType(0L);
29
30     // Private constructor prevents instantiation from other classes
31     protected LispAddressSerializer() {
32     }
33
34     public static LispAddressSerializer getInstance() {
35         return INSTANCE;
36     }
37
38     protected void serializeData(ByteBuffer buffer, LispAddress lispAddress) {
39         throw new RuntimeException("Unimplemented");
40     }
41
42     protected void serializeData(ByteBuffer buffer, SimpleAddress lispAddress) {
43         throw new RuntimeException("Unimplemented");
44     }
45
46     protected void serializeData(ByteBuffer buffer, IpPrefix lispAddress) {
47         throw new RuntimeException("Unimplemented");
48     }
49
50     protected Eid deserializeEidData(ByteBuffer buffer, LispAddressSerializerContext ctx) {
51         throw new RuntimeException("Unimplemented");
52     }
53
54     protected SimpleAddress deserializeSimpleAddressData(ByteBuffer buffer, LispAddressSerializerContext ctx) {
55         throw new RuntimeException("Unimplemented");
56     }
57
58     protected Eid deserializeLcafEidData(ByteBuffer buffer, byte res2, short length,
59             LispAddressSerializerContext ctx) {
60         throw new RuntimeException("Unimplemented");
61     }
62
63     protected Rloc deserializeRlocData(ByteBuffer buffer) {
64         throw new RuntimeException("Unimplemented");
65     }
66
67     protected Rloc deserializeLcafRlocData(ByteBuffer buffer, byte res2, short length,
68             LispAddressSerializerContext ctx) {
69         throw new RuntimeException("Unimplemented");
70     }
71
72     protected short getAfi() {
73         throw new RuntimeException("Unimplemented");
74     }
75
76     protected byte getLcafType() {
77         throw new RuntimeException("Unimplemented");
78     }
79
80     protected short getLcafLength(LispAddress lispAddress) {
81         throw new RuntimeException("Unimplemented");
82     }
83
84     protected int getAddressSize(SimpleAddress address) {
85         throw new RuntimeException("Unimplemented");
86     }
87
88     protected InstanceIdType getVni(LispAddressSerializerContext ctx) {
89         if (ctx != null) {
90             return ctx.getVni();
91         }
92         return null;
93     }
94
95     public void serialize(ByteBuffer buffer, LispAddress lispAddress) {
96         if (lispAddress.getVirtualNetworkId() != null) {
97             serializeInstanceIdExtra(buffer, lispAddress);
98         }
99         LispAddressSerializer serializer = LispAddressSerializerFactory.getSerializer(lispAddress.getAddressType());
100         if (serializer == null) {
101             throw new LispSerializationException("Unknown address type: "
102                     + lispAddress.getAddressType().getSimpleName());
103         }
104         short afi = serializer.getAfi();
105         if (afi == (short) AddressFamily.LispCanonicalAddressFormat.getIntValue()) {
106             serializer =  LispAddressSerializerFactory.getSerializer(Lcaf.class);
107         }
108         buffer.putShort(afi);
109         serializer.serializeData(buffer, lispAddress);
110     }
111
112     private void serializeInstanceIdExtra(ByteBuffer buffer, LispAddress lispAddress) {
113         buffer.putShort((short) AddressFamily.LispCanonicalAddressFormat.getIntValue());
114         LcafSerializer.getInstance().serializeLCAFAddressHeaderForInstanceId(buffer, lispAddress);
115         InstanceIdSerializer.getInstance().serializeNonLcafAddress(buffer, lispAddress);
116     }
117
118     public int getAddressSize(LispAddress lispAddress) {
119         int size = Length.AFI;
120         if (lispAddress.getVirtualNetworkId() != null) {
121             size += getInstanceIdExtraSize();
122         }
123         LispAddressSerializer serializer = LispAddressSerializerFactory.getSerializer(lispAddress.getAddressType());
124         if (serializer == null) {
125             throw new LispSerializationException("Unknown address type: "
126                     + lispAddress.getAddressType().getSimpleName());
127         }
128         return size + serializer.getAddressSize(lispAddress);
129     }
130
131     int getInstanceIdExtraSize() {
132         return LcafSerializer.getInstance().getLcafHeaderSize() +
133                 InstanceIdSerializer.getInstance().getInstanceIdSize() +
134                 Length.AFI;
135     }
136
137     public Eid deserializeEid(ByteBuffer buffer, LispAddressSerializerContext ctx) {
138         short afi = buffer.getShort();
139         // AddressTypeMap indexes IPv4 and IPv6 prefixes (vs simple addresses) with the negative AFI values -1 and -2
140         if ((afi == 1 || afi == 2) && ctx.getMaskLen() != LispAddressSerializerContext.MASK_LEN_MISSING) {
141             afi *= -1;
142         }
143         Class <? extends LispAddressFamily> addressType = AddressTypeMap.getAddressType(afi);
144         LispAddressSerializer serializer = LispAddressSerializerFactory.getSerializer(addressType);
145         if (serializer == null) {
146             throw new LispSerializationException("Unknown AFI: " + afi);
147         }
148         try {
149             return serializer.deserializeEidData(buffer, ctx);
150         } catch (RuntimeException e) {
151             throw new LispSerializationException("Problem deserializing AFI " + afi + " in EID context", e);
152         }
153     }
154
155     public Rloc deserializeRloc(ByteBuffer buffer) {
156         short afi = buffer.getShort();
157         Class <? extends LispAddressFamily> addressType = AddressTypeMap.getAddressType(afi);
158         LispAddressSerializer serializer = LispAddressSerializerFactory.getSerializer(addressType);
159         if (serializer == null) {
160             throw new LispSerializationException("Unknown AFI: " + afi);
161         }
162         try {
163             return serializer.deserializeRlocData(buffer);
164         } catch (RuntimeException e) {
165             throw new LispSerializationException("Problem deserializing AFI " + afi + " in RLOC context", e);
166         }
167     }
168
169     private interface Length {
170         int AFI = 2;
171     }
172 }