e9c9c63ee148315a2e8e7bfef5a4f241bbee4ba3
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.hc2vpp.routing.write.factory;
18
19 import io.fd.hc2vpp.common.translate.util.NamingContext;
20 import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory;
21 import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer;
22 import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager;
23 import io.fd.honeycomb.translate.MappingContext;
24 import io.fd.vpp.jvpp.core.dto.IpAddDelRoute;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VppRouteAttributes;
30
31 import javax.annotation.Nonnull;
32 import java.util.Optional;
33
34 import static com.google.common.base.Preconditions.checkNotNull;
35
36 public class SpecialNextHopRequestFactory extends BasicHopRequestFactory
37         implements RouteRequestProducer {
38
39     private SpecialNextHopRequestFactory(final VppClassifierContextManager classifierContextManager,
40                                          final NamingContext interfaceContext,
41                                          final NamingContext routingProtocolContext) {
42         super(classifierContextManager,interfaceContext,routingProtocolContext);
43     }
44
45     public static SpecialNextHopRequestFactory forContexts(
46             @Nonnull final VppClassifierContextManager classifierContextManager,
47             @Nonnull final NamingContext interfaceContext,
48             @Nonnull final NamingContext routingProtocolContext) {
49         return new SpecialNextHopRequestFactory(classifierContextManager, interfaceContext, routingProtocolContext);
50     }
51
52     public IpAddDelRoute createIpv4SpecialHopRequest(final boolean add,
53                                                      @Nonnull final String parentProtocolName,
54                                                      @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route route,
55                                                      @Nonnull final MappingContext mappingContext,
56                                                      @Nonnull final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
57         checkNotNull(route, "Route cannot be null");
58         checkNotNull(mappingContext, "Mapping Context cannot be null");
59         checkNotNull(flagsVariant, "Flags variant cannot be null");
60
61         final int parentProtocolTableId = getRoutingProtocolContext().getIndex(parentProtocolName,mappingContext);
62         final byte secondaryTableId = Optional.ofNullable(route.getVppIpv4Route())
63                 .map(VppRouteAttributes::getSecondaryVrf)
64                 .map(VniReference::getValue)
65                 .map(Long::byteValue)
66                 .orElse(DEFAULT_VNI);
67
68         return resolveFlags(getSpecialHopRequest(add, route.getDestinationPrefix(), (byte) parentProtocolTableId, secondaryTableId), flagsVariant);
69     }
70
71     public IpAddDelRoute createIpv6SpecialHopRequest(final boolean add,
72                                                      @Nonnull final String parentProtocolName,
73                                                      @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv6.Route route,
74                                                      @Nonnull final MappingContext mappingContext,
75                                                      @Nonnull final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
76
77         checkNotNull(route, "Route cannot be null");
78         checkNotNull(mappingContext, "Mapping Context cannot be null");
79         checkNotNull(flagsVariant, "Flags variant cannot be null");
80
81         final int parentProtocolTableId = getRoutingProtocolContext().getIndex(parentProtocolName,mappingContext);
82         final byte secondaryTableId = Optional.ofNullable(route.getVppIpv6Route())
83                 .map(VppRouteAttributes::getSecondaryVrf)
84                 .map(VniReference::getValue)
85                 .map(Long::byteValue)
86                 .orElse(DEFAULT_VNI);
87
88         return resolveFlags(getSpecialHopRequest(add, route.getDestinationPrefix(), (byte) parentProtocolTableId, secondaryTableId), flagsVariant);
89     }
90
91     private IpAddDelRoute getSpecialHopRequest(final boolean isAdd, @Nonnull final Ipv6Prefix destinationAddress,
92                                                final byte primaryTableId, final byte secondaryTableId) {
93
94         return flaglessAddDelRouteRequest(booleanToByte(isAdd), 0, null, DEFAULT_HOP_WEIGHT, BYTE_TRUE,
95                 ipv6AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), BYTE_FALSE,
96                 primaryTableId, secondaryTableId, DEFAULT_CLASSIFY_TABLE_INDEX, BYTE_FALSE);
97     }
98
99     private IpAddDelRoute getSpecialHopRequest(final boolean isAdd, @Nonnull final Ipv4Prefix destinationAddress,
100                                                final byte primaryTableId, final byte secondaryTableId) {
101         return flaglessAddDelRouteRequest(booleanToByte(isAdd), 0, null, DEFAULT_HOP_WEIGHT, BYTE_FALSE,
102                 ipv4AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), BYTE_FALSE,
103                 primaryTableId, secondaryTableId, DEFAULT_CLASSIFY_TABLE_INDEX, BYTE_FALSE);
104     }
105
106     private IpAddDelRoute resolveFlags(IpAddDelRoute request,
107                                        final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
108         switch (flagsVariant) {
109             case Blackhole:
110                 return resolveAsBlackholeVariant(request);
111             case Unreachable:
112                 return resolveAsUnreachableVariant(request);
113             case Prohibit:
114                 return resolveAsProhibitedVariant(request);
115             case Receive:
116                 return resolveAsReceiveVariant(request);
117             default:
118                 throw new IllegalArgumentException("Unsupported type");
119         }
120     }
121
122     private IpAddDelRoute resolveAsBlackholeVariant(IpAddDelRoute request) {
123         return bindFlags(request, true, false, false, false);
124     }
125
126     private IpAddDelRoute resolveAsReceiveVariant(IpAddDelRoute request) {
127         return bindFlags(request, false, true, false, false);
128     }
129
130     private IpAddDelRoute resolveAsUnreachableVariant(IpAddDelRoute request) {
131         return bindFlags(request, false, false, true, false);
132     }
133
134     private IpAddDelRoute resolveAsProhibitedVariant(IpAddDelRoute request) {
135         return bindFlags(request, false, false, false, true);
136     }
137
138     private IpAddDelRoute bindFlags(IpAddDelRoute request, final boolean isDrop, final boolean isReceive,
139                                     final boolean isUnreachable, final boolean isProhibited) {
140         request.isDrop = booleanToByte(isDrop);
141         request.isLocal = booleanToByte(isReceive);
142         request.isUnreach = booleanToByte(isUnreachable);
143         request.isProhibit = booleanToByte(isProhibited);
144
145         return request;
146     }
147 }