49e1bc1c5ae33781e0a2c4d508ceaae384257616
[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 static com.google.common.base.Preconditions.checkNotNull;
20
21 import io.fd.hc2vpp.common.translate.util.NamingContext;
22 import io.fd.hc2vpp.routing.write.factory.base.BasicHopRequestFactory;
23 import io.fd.hc2vpp.routing.write.trait.RouteRequestProducer;
24 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
25 import io.fd.honeycomb.translate.MappingContext;
26 import io.fd.vpp.jvpp.core.dto.IpAddDelRoute;
27 import java.util.Optional;
28 import javax.annotation.Nonnull;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.SpecialNextHopGrouping;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VppRouteAttributes;
34
35 public class SpecialNextHopRequestFactory extends BasicHopRequestFactory
36         implements RouteRequestProducer {
37
38     private SpecialNextHopRequestFactory(final VppClassifierContextManager classifierContextManager,
39                                          final NamingContext interfaceContext,
40                                          final NamingContext routingProtocolContext) {
41         super(classifierContextManager,interfaceContext,routingProtocolContext);
42     }
43
44     public static SpecialNextHopRequestFactory forContexts(
45             @Nonnull final VppClassifierContextManager classifierContextManager,
46             @Nonnull final NamingContext interfaceContext,
47             @Nonnull final NamingContext routingProtocolContext) {
48         return new SpecialNextHopRequestFactory(classifierContextManager, interfaceContext, routingProtocolContext);
49     }
50
51     public IpAddDelRoute createIpv4SpecialHopRequest(final boolean add,
52                                                      @Nonnull final String parentProtocolName,
53                                                      @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,
54                                                      @Nonnull final MappingContext mappingContext,
55                                                      @Nonnull final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
56         checkNotNull(route, "Route cannot be null");
57         checkNotNull(mappingContext, "Mapping Context cannot be null");
58         checkNotNull(flagsVariant, "Flags variant cannot be null");
59
60         final int parentProtocolTableId = getRoutingProtocolContext().getIndex(parentProtocolName,mappingContext);
61         final byte secondaryTableId = Optional.ofNullable(route.getVppIpv4Route())
62                 .map(VppRouteAttributes::getSecondaryVrf)
63                 .map(VniReference::getValue)
64                 .map(Long::byteValue)
65                 .orElse(DEFAULT_VNI);
66
67         return resolveFlags(getSpecialHopRequest(add, route.getDestinationPrefix(), (byte) parentProtocolTableId, secondaryTableId), flagsVariant);
68     }
69
70     public IpAddDelRoute createIpv6SpecialHopRequest(final boolean add,
71                                                      @Nonnull final String parentProtocolName,
72                                                      @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,
73                                                      @Nonnull final MappingContext mappingContext,
74                                                      @Nonnull final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
75
76         checkNotNull(route, "Route cannot be null");
77         checkNotNull(mappingContext, "Mapping Context cannot be null");
78         checkNotNull(flagsVariant, "Flags variant cannot be null");
79
80         final int parentProtocolTableId = getRoutingProtocolContext().getIndex(parentProtocolName,mappingContext);
81         final byte secondaryTableId = Optional.ofNullable(route.getVppIpv6Route())
82                 .map(VppRouteAttributes::getSecondaryVrf)
83                 .map(VniReference::getValue)
84                 .map(Long::byteValue)
85                 .orElse(DEFAULT_VNI);
86
87         return resolveFlags(getSpecialHopRequest(add, route.getDestinationPrefix(), (byte) parentProtocolTableId, secondaryTableId), flagsVariant);
88     }
89
90     private IpAddDelRoute getSpecialHopRequest(final boolean isAdd, @Nonnull final Ipv6Prefix destinationAddress,
91                                                final byte primaryTableId, final byte secondaryTableId) {
92
93         return flaglessAddDelRouteRequest(booleanToByte(isAdd), 0, null, DEFAULT_HOP_WEIGHT, BYTE_TRUE,
94                 ipv6AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), BYTE_FALSE,
95                 primaryTableId, secondaryTableId, DEFAULT_CLASSIFY_TABLE_INDEX, BYTE_FALSE);
96     }
97
98     private IpAddDelRoute getSpecialHopRequest(final boolean isAdd, @Nonnull final Ipv4Prefix destinationAddress,
99                                                final byte primaryTableId, final byte secondaryTableId) {
100         return flaglessAddDelRouteRequest(booleanToByte(isAdd), 0, null, DEFAULT_HOP_WEIGHT, BYTE_FALSE,
101                 ipv4AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), BYTE_FALSE,
102                 primaryTableId, secondaryTableId, DEFAULT_CLASSIFY_TABLE_INDEX, BYTE_FALSE);
103     }
104
105     private IpAddDelRoute resolveFlags(IpAddDelRoute request,
106                                        final SpecialNextHopGrouping.SpecialNextHop flagsVariant) {
107         switch (flagsVariant) {
108             case Blackhole:
109                 return resolveAsBlackholeVariant(request);
110             case Unreachable:
111                 return resolveAsUnreachableVariant(request);
112             case Prohibit:
113                 return resolveAsProhibitedVariant(request);
114             case Receive:
115                 return resolveAsReceiveVariant(request);
116             default:
117                 throw new IllegalArgumentException("Unsupported type");
118         }
119     }
120
121     private IpAddDelRoute resolveAsBlackholeVariant(IpAddDelRoute request) {
122         return bindFlags(request, true, false, false, false);
123     }
124
125     private IpAddDelRoute resolveAsReceiveVariant(IpAddDelRoute request) {
126         return bindFlags(request, false, true, false, false);
127     }
128
129     private IpAddDelRoute resolveAsUnreachableVariant(IpAddDelRoute request) {
130         return bindFlags(request, false, false, true, false);
131     }
132
133     private IpAddDelRoute resolveAsProhibitedVariant(IpAddDelRoute request) {
134         return bindFlags(request, false, false, false, true);
135     }
136
137     private IpAddDelRoute bindFlags(IpAddDelRoute request, final boolean isDrop, final boolean isReceive,
138                                     final boolean isUnreachable, final boolean isProhibited) {
139         request.isDrop = booleanToByte(isDrop);
140         request.isLocal = booleanToByte(isReceive);
141         request.isUnreach = booleanToByte(isUnreachable);
142         request.isProhibit = booleanToByte(isProhibited);
143
144         return request;
145     }
146 }