All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onosproject.acl.AclRule Maven / Gradle / Ivy

There is a newer version: 1.6.0
Show newest version
/*
 * Copyright 2015 Open Networking Laboratory
 * Originally created by Pengfei Lu, Network and Cloud Computing Laboratory, Dalian University of Technology, China
 * Advisers: Keqiu Li, Heng Qi and Haisheng Yu
 * This work is supported by the State Key Program of National Natural Science of China(Grant No. 61432002)
 * and Prospective Research Project on Future Networks in Jiangsu Future Networks Innovation Institute.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.acl;

import com.google.common.base.MoreObjects;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Prefix;
import org.onosproject.core.IdGenerator;

import java.util.Objects;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * ACL rule class.
 */
public final class AclRule {

    private final RuleId id;

    private final Ip4Prefix srcIp;
    private final Ip4Prefix dstIp;
    private final byte ipProto;
    private final short dstTpPort;
    private final Action action;

    private static IdGenerator idGenerator;

    /**
     * Enum type for ACL rule's action.
     */
    public enum Action {
        DENY, ALLOW
    }

    /**
     * Constructor for serializer.
     */
    private AclRule() {
        this.id = null;
        this.srcIp = null;
        this.dstIp = null;
        this.ipProto = 0;
        this.dstTpPort = 0;
        this.action = null;
    }

    /**
     * Create a new ACL rule.
     *
     * @param srcIp     source IP address
     * @param dstIp     destination IP address
     * @param ipProto   IP protocol
     * @param dstTpPort destination transport layer port
     * @param action    ACL rule's action
     */
    private AclRule(Ip4Prefix srcIp, Ip4Prefix dstIp, byte ipProto,
                    short dstTpPort, Action action) {
        checkState(idGenerator != null, "Id generator is not bound.");
        this.id = RuleId.valueOf(idGenerator.getNewId());
        this.srcIp = srcIp;
        this.dstIp = dstIp;
        this.ipProto = ipProto;
        this.dstTpPort = dstTpPort;
        this.action = action;
    }

    /**
     * Check if the first CIDR address is in (or the same as) the second CIDR address.
     */
    private boolean checkCidrInCidr(Ip4Prefix cidrAddr1, Ip4Prefix cidrAddr2) {
        if (cidrAddr2 == null) {
            return true;
        } else if (cidrAddr1 == null) {
            return false;
        }
        if (cidrAddr1.prefixLength() < cidrAddr2.prefixLength()) {
            return false;
        }
        int offset = 32 - cidrAddr2.prefixLength();

        int cidr1Prefix = cidrAddr1.address().toInt();
        int cidr2Prefix = cidrAddr2.address().toInt();
        cidr1Prefix = cidr1Prefix >> offset;
        cidr2Prefix = cidr2Prefix >> offset;
        cidr1Prefix = cidr1Prefix << offset;
        cidr2Prefix = cidr2Prefix << offset;

        return (cidr1Prefix == cidr2Prefix);
    }

    /**
     * Check if this ACL rule match the given ACL rule.
     *
     * @param r ACL rule to check against
     * @return true if this ACL rule matches the given ACL ruleule.
     */
    public boolean checkMatch(AclRule r) {
        return (this.dstTpPort == r.dstTpPort || r.dstTpPort == 0)
                && (this.ipProto == r.ipProto || r.ipProto == 0)
                && (checkCidrInCidr(this.srcIp(), r.srcIp()))
                && (checkCidrInCidr(this.dstIp(), r.dstIp()));
    }

    /**
     * Returns a new ACL rule builder.
     *
     * @return ACL rule builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder of an ACL rule.
     */
    public static final class Builder {

        private Ip4Prefix srcIp = null;
        private Ip4Prefix dstIp = null;
        private byte ipProto = 0;
        private short dstTpPort = 0;
        private Action action = Action.DENY;

        private Builder() {
            // Hide constructor
        }

        /**
         * Sets the source IP address for the ACL rule that will be built.
         *
         * @param srcIp source IP address to use for built ACL rule
         * @return this builder
         */
        public Builder srcIp(Ip4Prefix srcIp) {
            this.srcIp = srcIp;
            return this;
        }

        /**
         * Sets the destination IP address for the ACL rule that will be built.
         *
         * @param dstIp destination IP address to use for built ACL rule
         * @return this builder
         */
        public Builder dstIp(Ip4Prefix dstIp) {
            this.dstIp = dstIp;
            return this;
        }

        /**
         * Sets the IP protocol for the ACL rule that will be built.
         *
         * @param ipProto IP protocol to use for built ACL rule
         * @return this builder
         */
        public Builder ipProto(byte ipProto) {
            this.ipProto = ipProto;
            return this;
        }

        /**
         * Sets the destination transport layer port for the ACL rule that will be built.
         *
         * @param dstTpPort destination transport layer port to use for built ACL rule
         * @return this builder
         */
        public Builder dstTpPort(short dstTpPort) {
            if ((ipProto == IPv4.PROTOCOL_TCP || ipProto == IPv4.PROTOCOL_UDP)) {
                this.dstTpPort = dstTpPort;
            }
            return this;
        }

        /**
         * Sets the action for the ACL rule that will be built.
         *
         * @param action action to use for built ACL rule
         * @return this builder
         */
        public Builder action(Action action) {
            this.action = action;
            return this;
        }

        /**
         * Builds an ACL rule from the accumulated parameters.
         *
         * @return ACL rule instance
         */
        public AclRule build() {
            checkState(srcIp != null && dstIp != null, "Either srcIp or dstIp must be assigned.");
            checkState(ipProto == 0 || ipProto == IPv4.PROTOCOL_ICMP
                               || ipProto == IPv4.PROTOCOL_TCP || ipProto == IPv4.PROTOCOL_UDP,
                       "ipProto must be assigned to TCP, UDP, or ICMP.");
            return new AclRule(srcIp, dstIp, ipProto, dstTpPort, action);
        }

    }

    /**
     * Binds an id generator for unique ACL rule id generation.
     * 

* Note: A generator cannot be bound if there is already a generator bound. * * @param newIdGenerator id generator */ public static void bindIdGenerator(IdGenerator newIdGenerator) { checkState(idGenerator == null, "Id generator is already bound."); idGenerator = checkNotNull(newIdGenerator); } public RuleId id() { return id; } public Ip4Prefix srcIp() { return srcIp; } public Ip4Prefix dstIp() { return this.dstIp; } public byte ipProto() { return ipProto; } public short dstTpPort() { return dstTpPort; } public Action action() { return action; } @Override public int hashCode() { return Objects.hash(action, id.fingerprint(), ipProto, srcIp, dstIp, dstTpPort); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof AclRule) { AclRule that = (AclRule) obj; return Objects.equals(id, that.id) && Objects.equals(srcIp, that.srcIp) && Objects.equals(dstIp, that.dstIp) && Objects.equals(ipProto, that.ipProto) && Objects.equals(dstTpPort, that.dstTpPort) && Objects.equals(action, that.action); } return false; } @Override public String toString() { return MoreObjects.toStringHelper(this) .omitNullValues() .add("id", id) .add("srcIp", srcIp) .add("dstIp", dstIp) .add("ipProto", ipProto) .add("dstTpPort", dstTpPort) .add("action", action) .toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy