40a050a6d8f6cd48722bb90e4666954507759160
[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.honeycomb.translate.v3po.interfaces.acl.ingress;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20
21 import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession;
22 import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable;
23 import javax.annotation.Nonnull;
24 import javax.annotation.Nullable;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpAndEth;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.AceIpVersion;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv4;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.and.eth.ace.ip.version.AceIpv6;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 final class AceIpAndEthWriter
35     implements AceWriter<AceIpAndEth>, AclTranslator, L2AclTranslator, Ip4AclTranslator, Ip6AclTranslator {
36
37     private static final Logger LOG = LoggerFactory.getLogger(AceIpAndEthWriter.class);
38
39     private static int maskLength(@Nonnull final AceIpAndEth ace) {
40         if (ace.getAceIpVersion() != null) {
41             if (ace.getAceIpVersion() instanceof AceIpv4) {
42                 return 48;
43             } else {
44                 return 64;
45             }
46         }
47         return 16;
48     }
49
50     @Override
51     public ClassifyAddDelTable createTable(@Nonnull final AceIpAndEth ace, @Nullable final InterfaceMode mode,
52                                            final int nextTableIndex, final int vlanTags) {
53         final ClassifyAddDelTable request = createTable(nextTableIndex);
54         final int maskLength = maskLength(ace);
55         request.mask = new byte[maskLength];
56         request.skipNVectors = 0;
57         request.matchNVectors = maskLength / 16;
58
59         boolean aceIsEmpty =
60             destinationMacAddressMask(ace.getDestinationMacAddressMask(), ace.getDestinationMacAddress(), request);
61         aceIsEmpty &= sourceMacAddressMask(ace.getSourceMacAddressMask(), ace.getSourceMacAddress(), request);
62
63         // if we use classifier API, we need to know ip version (fields common for ip4 and ip6 have different offsets):
64         final AceIpVersion aceIpVersion = ace.getAceIpVersion();
65         checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion");
66
67         final int baseOffset = getVlanTagsLen(vlanTags);
68         if (aceIpVersion instanceof AceIpv4) {
69             final AceIpv4 ipVersion = (AceIpv4) aceIpVersion;
70             aceIsEmpty &= ip4Mask(baseOffset, mode, ace, ipVersion, request, LOG);
71         } else if (aceIpVersion instanceof AceIpv6) {
72             final AceIpv6 ipVersion = (AceIpv6) aceIpVersion;
73             aceIsEmpty &= ip6Mask(baseOffset, mode, ace, ipVersion, request, LOG);
74         } else {
75             throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion));
76         }
77
78         if (aceIsEmpty) {
79             throw new IllegalArgumentException(
80                 String.format("Ace %s does not define packet field match values", ace.toString()));
81         }
82
83         LOG.debug("ACE rule={} translated to table={}.", ace, request);
84         return request;
85     }
86
87     @Override
88     public ClassifyAddDelSession createSession(@Nonnull final PacketHandling action,
89                                                @Nonnull final AceIpAndEth ace,
90                                                @Nullable final InterfaceMode mode, final int tableIndex,
91                                                final int vlanTags) {
92         final ClassifyAddDelSession request = createSession(action, tableIndex);
93         request.match = new byte[maskLength(ace)];
94
95         boolean noMatch = destinationMacAddressMatch(ace.getDestinationMacAddress(), request);
96         noMatch &= sourceMacAddressMatch(ace.getSourceMacAddress(), request);
97
98         final AceIpVersion aceIpVersion = ace.getAceIpVersion();
99         checkArgument(aceIpVersion != null, "AceIpAndEth have to define IpVersion");
100
101         final int baseOffset = getVlanTagsLen(vlanTags);
102         if (aceIpVersion instanceof AceIpv4) {
103             final AceIpv4 ipVersion = (AceIpv4) aceIpVersion;
104             noMatch &= ip4Match(baseOffset, mode, ace, ipVersion, request, LOG);
105         } else if (aceIpVersion instanceof AceIpv6) {
106             final AceIpv6 ipVersion = (AceIpv6) aceIpVersion;
107             noMatch &= ip6Match(baseOffset, mode, ace, ipVersion, request, LOG);
108         } else {
109             throw new IllegalArgumentException(String.format("Unsupported IP version %s", aceIpVersion));
110         }
111
112         if (noMatch) {
113             throw new IllegalArgumentException(
114                 String.format("Ace %s does not define packet field match values", ace.toString()));
115         }
116
117         LOG.debug("ACE action={}, rule={} translated to session={}.", action, ace, request);
118         return request;
119     }
120 }