1
2
3
4
5
6
7
8 package org.opendaylight.lispflowmapping.lisp.serializer;
9
10 import java.net.Inet4Address;
11 import java.net.InetAddress;
12 import java.nio.ByteBuffer;
13 import java.util.ArrayList;
14 import java.util.List;
15
16 import org.apache.commons.lang3.BooleanUtils;
17 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
18 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
19 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
29
30
31
32
33 public final class MapRegisterSerializer {
34
35 private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
36
37
38 private MapRegisterSerializer() {
39 }
40
41 public static MapRegisterSerializer getInstance() {
42 return INSTANCE;
43 }
44
45 public ByteBuffer serialize(MapRegister mapRegister) {
46 int size = Length.HEADER_SIZE;
47 if (mapRegister.getAuthenticationData() != null) {
48 size += mapRegister.getAuthenticationData().length;
49 }
50 if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
51 size += Length.XTRID_SIZE + Length.SITEID_SIZE;
52 }
53 for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
54 size += MappingRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord.getMappingRecord());
55 }
56
57 ByteBuffer registerBuffer = ByteBuffer.allocate(size);
58 registerBuffer.put((byte) ((byte) (MessageType.MapRegister.getIntValue() << 4) |
59 ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY) |
60 ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
61 registerBuffer.position(registerBuffer.position() + Length.RES);
62 registerBuffer.put((byte)
63 (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isMergeEnabled()), Flags.MERGE_ENABLED) |
64 ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_NOTIFY)));
65 registerBuffer.put((byte) mapRegister.getMappingRecordItem().size());
66 registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
67 registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
68
69 if (mapRegister.getAuthenticationData() != null) {
70 registerBuffer.putShort((short) mapRegister.getAuthenticationData().length);
71 registerBuffer.put(mapRegister.getAuthenticationData());
72 } else {
73 registerBuffer.putShort((short) 0);
74 }
75 for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
76 MappingRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord.getMappingRecord());
77 }
78
79 if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
80 registerBuffer.put(mapRegister.getXtrId());
81 registerBuffer.put(mapRegister.getSiteId());
82 }
83 registerBuffer.clear();
84 return registerBuffer;
85 }
86
87 public MapRegister deserialize(ByteBuffer registerBuffer, InetAddress sourceRloc) {
88 try {
89 MapRegisterBuilder builder = new MapRegisterBuilder();
90 builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
91
92 byte typeAndFlags = registerBuffer.get();
93 boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
94 builder.setProxyMapReply(ByteUtil.extractBit(typeAndFlags, Flags.PROXY));
95 builder.setXtrSiteIdPresent(xtrSiteIdPresent);
96
97 registerBuffer.position(registerBuffer.position() + Length.RES);
98 byte mergeAndMapReply = registerBuffer.get();
99 builder.setWantMapNotify(ByteUtil.extractBit(mergeAndMapReply, Flags.WANT_MAP_NOTIFY));
100 builder.setMergeEnabled(ByteUtil.extractBit(mergeAndMapReply, Flags.MERGE_ENABLED));
101 byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
102 builder.setNonce(registerBuffer.getLong());
103 builder.setKeyId(registerBuffer.getShort());
104 short authenticationLength = registerBuffer.getShort();
105 byte[] authenticationData = new byte[authenticationLength];
106 registerBuffer.get(authenticationData);
107 builder.setAuthenticationData(authenticationData);
108
109 if (xtrSiteIdPresent) {
110 List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
111 for (int i = 0; i < recordCount; i++) {
112 mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(registerBuffer));
113 }
114 byte[] xtrId = new byte[Length.XTRID_SIZE];
115 registerBuffer.get(xtrId);
116 byte[] siteId = new byte[Length.SITEID_SIZE];
117 registerBuffer.get(siteId);
118 builder.setXtrId(xtrId);
119 builder.setSiteId(siteId);
120 for (MappingRecordBuilder mrb : mrbs) {
121 mrb.setXtrId(xtrId);
122 mrb.setSiteId(siteId);
123 mrb.setSourceRloc(getSourceRloc(sourceRloc));
124 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
125 mrb.build()).build());
126 }
127 } else {
128 for (int i = 0; i < recordCount; i++) {
129 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
130 MappingRecordSerializer.getInstance().deserialize(registerBuffer)).build());
131 }
132 }
133
134 registerBuffer.limit(registerBuffer.position());
135 byte[] mapRegisterBytes = new byte[registerBuffer.position()];
136 registerBuffer.position(0);
137 registerBuffer.get(mapRegisterBytes);
138 return builder.build();
139 } catch (RuntimeException re) {
140 throw new LispSerializationException("Couldn't deserialize Map-Register (len=" + registerBuffer.capacity() + ")", re);
141 }
142
143 }
144
145 private static IpAddress getSourceRloc(InetAddress sourceRloc) {
146 if (sourceRloc == null) {
147 sourceRloc = InetAddress.getLoopbackAddress();
148 }
149
150 if (sourceRloc instanceof Inet4Address) {
151 return new IpAddress(new Ipv4Address(sourceRloc.getHostAddress()));
152 } else {
153 return new IpAddress(new Ipv6Address(sourceRloc.getHostAddress()));
154 }
155 }
156
157 private interface Flags {
158 byte PROXY = 0x08;
159 byte XTRSITEID = 0x02;
160 byte MERGE_ENABLED = 0x04;
161 byte WANT_MAP_NOTIFY = 0x01;
162 }
163
164 public interface Length {
165 int HEADER_SIZE = 16;
166 int XTRID_SIZE = 16;
167 int SITEID_SIZE = 8;
168 int RES = 1;
169 }
170 }