BUG-4692: Migrate TCP-MD5 support in bgp package to netty's native-epoll
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / nlri / TeLspNlriSerializer.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, 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.protocol.bgp.linkstate.nlri;
9
10 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv4Address;
11 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv6Address;
12 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeShort;
13 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedShort;
14
15 import com.google.common.annotations.VisibleForTesting;
16 import com.google.common.base.Preconditions;
17 import io.netty.buffer.ByteBuf;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.AddressFamily;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4Case;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4CaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6Case;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6CaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.TunnelId;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
34
35 @VisibleForTesting
36 public final class TeLspNlriSerializer implements NlriTypeCaseSerializer {
37
38     @VisibleForTesting
39     public static final YangInstanceIdentifier.NodeIdentifier LSP_ID = new YangInstanceIdentifier.NodeIdentifier(
40         QName.create(CLinkstateDestination.QNAME, "lsp-id").intern());
41     @VisibleForTesting
42     public static final YangInstanceIdentifier.NodeIdentifier TUNNEL_ID = new YangInstanceIdentifier.NodeIdentifier(
43         QName.create(CLinkstateDestination.QNAME, "tunnel-id").intern());
44     @VisibleForTesting
45     public static final YangInstanceIdentifier.NodeIdentifier IPV4_TUNNEL_SENDER_ADDRESS = new YangInstanceIdentifier.NodeIdentifier(
46         QName.create(CLinkstateDestination.QNAME, "ipv4-tunnel-sender-address").intern());
47     @VisibleForTesting
48     public static final YangInstanceIdentifier.NodeIdentifier IPV4_TUNNEL_ENDPOINT_ADDRESS = new YangInstanceIdentifier
49         .NodeIdentifier(QName.create(CLinkstateDestination.QNAME, "ipv4-tunnel-endpoint-address").intern());
50     @VisibleForTesting
51     public static final YangInstanceIdentifier.NodeIdentifier IPV6_TUNNEL_SENDER_ADDRESS = new YangInstanceIdentifier
52         .NodeIdentifier( QName.create(CLinkstateDestination.QNAME, "ipv6-tunnel-sender-address").intern());
53     @VisibleForTesting
54     public static final YangInstanceIdentifier.NodeIdentifier IPV6_TUNNEL_ENDPOINT_ADDRESS = new YangInstanceIdentifier
55         .NodeIdentifier(QName.create(CLinkstateDestination.QNAME, "ipv6-tunnel-endpoint-address").intern());
56
57     @VisibleForTesting
58     public static final YangInstanceIdentifier.NodeIdentifier ADDRESS_FAMILY = new YangInstanceIdentifier.NodeIdentifier(AddressFamily.QNAME);
59
60     public static NlriType serializeIpvTSA(final AddressFamily addressFamily, final ByteBuf body) {
61         if (addressFamily.equals(Ipv6Case.class)) {
62             final Ipv6Address ipv6 = ((Ipv6Case) addressFamily).getIpv6TunnelSenderAddress();
63             Preconditions.checkArgument(ipv6 != null, "Ipv6TunnelSenderAddress is mandatory.");
64             writeIpv6Address(ipv6, body);
65             return NlriType.Ipv6TeLsp;
66         }
67
68         final Ipv4Address ipv4 = ((Ipv4Case) addressFamily).getIpv4TunnelSenderAddress();
69         Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelSenderAddress is mandatory.");
70         writeIpv4Address(ipv4, body);
71
72         return NlriType.Ipv4TeLsp;
73     }
74
75     public static void serializeTunnelID(final TunnelId tunnelID, final ByteBuf body) {
76         Preconditions.checkArgument(tunnelID != null, "TunnelId is mandatory.");
77         writeUnsignedShort(tunnelID.getValue(), body);
78     }
79
80     public static void serializeLspID(final LspId lspId, final ByteBuf body) {
81         Preconditions.checkArgument(lspId != null, "LspId is mandatory.");
82         writeShort(lspId.getValue().shortValue(), body);
83     }
84
85     public static void serializeTEA(final AddressFamily addressFamily, final ByteBuf body) {
86         if (addressFamily.equals(Ipv6Case.class)) {
87             final Ipv6Address ipv6 = ((Ipv6Case) addressFamily).getIpv6TunnelEndpointAddress();
88             Preconditions.checkArgument(ipv6 != null, "Ipv6TunnelEndpointAddress is mandatory.");
89             writeIpv6Address(ipv6, body);
90             return;
91         }
92
93         final Ipv4Address ipv4 = ((Ipv4Case) addressFamily).getIpv4TunnelEndpointAddress();
94         Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelEndpointAddress is mandatory.");
95         Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelEndpointAddress is mandatory.");
96         writeIpv4Address(ipv4, body);
97     }
98
99     public static boolean isTeLsp(final ChoiceNode objectType) {
100         return objectType.getChild(ADDRESS_FAMILY).isPresent();
101     }
102
103     public static TeLspCase serializeTeLsp(final ChoiceNode objectType) {
104         final TeLspCaseBuilder teLsp = new TeLspCaseBuilder();
105         teLsp.setLspId(new LspId((Long) objectType.getChild(LSP_ID).get().getValue()));
106         teLsp.setTunnelId(new TunnelId((Integer) objectType.getChild(TUNNEL_ID).get().getValue()));
107         final ChoiceNode addressFamily = (ChoiceNode) objectType.getChild(ADDRESS_FAMILY).get();
108         teLsp.setAddressFamily(serializeAddressFamily(addressFamily, addressFamily.getChild(IPV4_TUNNEL_SENDER_ADDRESS).isPresent()));
109
110         return teLsp.build();
111     }
112
113     private static AddressFamily serializeAddressFamily(final ChoiceNode addressFamily, final boolean ipv4Case) {
114         if(ipv4Case) {
115             return new Ipv4CaseBuilder()
116                 .setIpv4TunnelSenderAddress(new Ipv4Address((String) addressFamily.getChild(IPV4_TUNNEL_SENDER_ADDRESS).get().getValue()))
117                 .setIpv4TunnelEndpointAddress(new Ipv4Address((String) addressFamily.getChild(IPV4_TUNNEL_ENDPOINT_ADDRESS).get().getValue()))
118                 .build();
119         }
120
121         return new Ipv6CaseBuilder()
122             .setIpv6TunnelSenderAddress(new Ipv6Address((String) addressFamily.getChild(IPV6_TUNNEL_SENDER_ADDRESS).get().getValue()))
123             .setIpv6TunnelEndpointAddress(new Ipv6Address((String) addressFamily.getChild(IPV6_TUNNEL_ENDPOINT_ADDRESS).get().getValue()))
124             .build();
125     }
126
127     @Override
128     public NlriType serializeTypeNlri(final CLinkstateDestination destination, final ByteBuf localdescs, final ByteBuf byteAggregator) {
129         final TeLspCase teLSP = ((TeLspCase) destination.getObjectType());
130         final AddressFamily afi = teLSP.getAddressFamily();
131         NlriType nlriType = serializeIpvTSA(afi, localdescs);
132         serializeTunnelID(teLSP.getTunnelId(), localdescs);
133         serializeLspID(teLSP.getLspId(), localdescs);
134         serializeTEA(afi, localdescs);
135         return nlriType;
136     }
137
138 }