Packet throttle support
Change-Id: I6f2da5ed25f794561349013bfcbf9afa85d5e190
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketInClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/PacketInClassifier.java
new file mode 100644
index 0000000..34c7502
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketInClassifier.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet;
+
+
+/**
+ * Abstraction of incoming packet classifier for filtering.
+ */
+public interface PacketInClassifier {
+
+ /**
+ * Returns true if the packet classifier matches else false.
+ * The matching criterion should be non overlapping with other
+ * implementation of the PacketInClassifier.
+ *
+ * @param packet PacketContext holding the packet information
+ * @return boolean checks whether packet matches classifier
+ */
+ boolean match(PacketContext packet);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketInFilter.java b/core/api/src/main/java/org/onosproject/net/packet/PacketInFilter.java
new file mode 100644
index 0000000..1338b05
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketInFilter.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet;
+
+/**
+ * Abstraction of incoming packet filter.
+ */
+public interface PacketInFilter {
+
+ /**
+ * Types of filter action applied to incoming packets.
+ */
+ enum FilterAction {
+ /**
+ * Signifies that the packet is allowed to be processed.
+ */
+ PACKET_ALLOW,
+ /**
+ * Signifies that the packet is denied from being processed
+ * as it crossed the maxCounter.
+ */
+ PACKET_DENY,
+ /**
+ * Signifies that filter applied is a valid filter.
+ */
+ FILTER_VALID,
+ /**
+ * Signifies that this filter is disabled.
+ */
+ FILTER_DISABLED,
+ /**
+ * Signifies that the current window for packet processing is full
+ * and the window is blocked for packet processing.
+ */
+ WINDOW_BLOCKED,
+ /**
+ * Signifies that the packet processing is blocked as the
+ * threshold has crossed.
+ */
+ PACKET_BLOCKED,
+ /**
+ * Signifies that the filter applied is invalid filter.
+ */
+ FILTER_INVALID
+ }
+
+ /**
+ * Returns FilterAction before processing the packet.
+ * Decides if the packet is allowed to be processed or not.
+ *
+ * @param packet PackerContext holding the packet information
+ * @return FilterAction
+ */
+ FilterAction preProcess(PacketContext packet);
+
+ /**
+ * Get the name of the counter.
+ *
+ * @return name of the counter
+ */
+ String name();
+
+ /**
+ * Get the current value of the count of packets for this particular
+ * filter type waiting to get processed.
+ *
+ * @return count of packets with current filter type waiting to get processed
+ */
+ int pendingPackets();
+
+ /**
+ * Get the count of the dropped packets for this filter type.
+ *
+ * @return count of dropped packets for this filter type
+ */
+ int droppedPackets();
+
+ /**
+ * Set the pps rate for the current filter type to calculate the max counter
+ * allowed with window size.
+ *
+ * @param pps Packet per second rate expected
+ */
+ void setPps(int pps);
+
+ /**
+ * Set the window size for rate limiting.
+ *
+ * @param winSize Window size in milli seconds
+ */
+ void setWinSize(int winSize);
+
+ /**
+ * Set the Guard time in case WinThres is crossed.
+ *
+ * @param guardTime Guard time in seconds
+ */
+ void setGuardTime(int guardTime);
+
+ /**
+ * Set the Window Threshold for dropping the packet.
+ *
+ * @param winThres Threshold count of the consecutive windows with packet drops
+ */
+ void setWinThres(int winThres);
+
+ /**
+ * Stop the threads running for this filter.
+ *
+ */
+ void stop();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
index 56889a5..21ecd49 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
@@ -19,6 +19,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.flow.TrafficSelector;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -52,6 +53,22 @@
void removeProcessor(PacketProcessor processor);
/**
+ * Adds the specified filter to the list of packet filters.
+ * It will be added into the list in the order in which it is added.
+ *
+ * @param filter filter to be added
+ */
+ default void addFilter(PacketInFilter filter) {}
+
+
+ /**
+ * Removes the specified filter from the filters list.
+ *
+ * @param filter filter to be removed
+ */
+ default void removeFilter(PacketInFilter filter) {}
+
+ /**
* Returns priority bindings of all registered packet processor entries.
*
* @return list of existing packet processor entries
@@ -123,4 +140,20 @@
*/
void emit(OutboundPacket packet);
+ /**
+ * Get the list of packet filters present in ONOS.
+ *
+ * @return List of packet filters
+ */
+ default List<PacketInFilter> getFilters() {
+ return new ArrayList<>();
+ }
+
+ /**
+ * Clear all packet filters in one shot.
+ *
+ */
+ default void clearFilters() {}
+
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/ArpPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/ArpPacketClassifier.java
new file mode 100644
index 0000000..5aed044
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/ArpPacketClassifier.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+
+public class ArpPacketClassifier implements PacketInClassifier {
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+ if (eth != null && (eth.getEtherType() == Ethernet.TYPE_ARP)) {
+ ARP arpPacket = (ARP) eth.getPayload();
+ if (arpPacket.getOpCode() == ARP.OP_REQUEST) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java
new file mode 100644
index 0000000..d628f80
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+import org.onosproject.net.packet.PacketInFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Default implementation of a packet-in filter.
+ */
+public class DefaultPacketInFilter implements PacketInFilter {
+
+ /**
+ * Tracks the count of specific packet types (eg ARP, ND, DHCP etc)
+ * to be limited in the packet queue. This count always reflects the
+ * number of packets in the queue at any point in time
+ */
+ private AtomicInteger currentCounter = new AtomicInteger(0);
+
+ /**
+ * Tracks the number of continuous windows where the drop packet happens.
+ */
+ private AtomicInteger windowBlockCounter = new AtomicInteger(0);
+
+ /**
+ * Tracks the counter of the packet which are dropped.
+ */
+ private AtomicInteger overFlowCounter = new AtomicInteger(0);
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * Max Allowed packet rate beyond which the packet will be dropped
+ * within given window size.
+ */
+ private int pps = 100;
+
+ /**
+ * Window size which will be used for number of packets acceptable
+ * based on the accepted pps.
+ */
+ private int winSize = 500;
+
+ /**
+ * Guard time in seconds which will be enabled if there are continuous
+ * windows crossing winThres where the packet rate crosses the acceptable
+ * packet count calculated based on accepted pps.
+ * Guard time should be always greater then the the window size.
+ */
+ private int guardTime = 10;
+
+ /**
+ * Threshold of continuous windows where the packet drop happens post which
+ * the guardTime will be triggered and no future packet processing happens
+ * till the expiry of this guard time.
+ */
+ private int winThres = 10;
+
+
+ private int maxCounter;
+
+ private ScheduledExecutorService timerExecutor;
+
+ private ScheduledExecutorService windowUnblockExecutor;
+
+ private boolean windowBlocked;
+
+ private boolean packetProcessingBlocked;
+
+
+ /**
+ * Name of the counter.
+ */
+ private String counterName;
+
+ /**
+ * PacketInclassifier associated with this filter object.
+ */
+ private final PacketInClassifier classifier;
+
+
+
+ /**
+ * Only one filter object per packet type to be associated.
+ * Multiple filter types will result in undefined behavior.
+ * @param pps Rate at which the packet is accepted in packets per second
+ * @param winSize Size of window in milli seconds within which
+ * the packet rate will be analyzed
+ * @param guardTime Time duration in seconds for which the packet processing
+ * will be on hold if there is a continuous window where
+ * cross of the rate happens and that window count crosses
+ * winThres
+ * @param winThres Continuous window threshold after which gaurdTime will be
+ * activated
+ * @param counterName Name of the counter
+ * @param classifier Packet classification
+ */
+ public DefaultPacketInFilter(int pps, int winSize, int guardTime, int winThres,
+ String counterName, PacketInClassifier classifier) {
+ this.pps = pps;
+ this.winSize = winSize;
+ this.guardTime = guardTime;
+ this.winThres = winThres;
+ this.counterName = counterName;
+ this.classifier = classifier;
+ this.maxCounter = (pps * winSize) / 1000;
+ timerExecutor = Executors.newScheduledThreadPool(1,
+ groupedThreads("packet/packetfilter",
+ "packet-filter-timer-%d", log));
+
+ windowUnblockExecutor = Executors.newScheduledThreadPool(1,
+ groupedThreads("packet/packetfilter",
+ "packet-filter-unblocker-%d", log));
+ timerExecutor.scheduleAtFixedRate(new ClearWindowBlock(),
+ 0,
+ winSize,
+ TimeUnit.MILLISECONDS);
+
+
+ windowBlocked = false;
+ packetProcessingBlocked = false;
+
+ }
+
+
+
+ @Override
+ public FilterAction preProcess(PacketContext packet) {
+
+
+ maxCounter = (pps * winSize) / 1000;
+
+ // If pps is set then min value for maxCounter is 1
+ if (maxCounter == 0 && pps != 0) {
+ log.trace("{}: maxCounter set to 1 as was coming as 0", counterName);
+ maxCounter = 1;
+ }
+
+
+
+ if (!classifier.match(packet)) {
+ return FilterAction.FILTER_INVALID;
+ }
+
+ if (pps == 0 && maxCounter == 0) {
+ log.trace("{}: Filter is disabled", counterName);
+ return FilterAction.FILTER_DISABLED;
+ }
+ log.trace("{}: Preprocess called", counterName);
+
+ // Packet block checking should be done before windowBlocked checking
+ // otherwise there will be windows with packets while packet processing is suspended
+ // and that may break the existing check logic
+ if (packetProcessingBlocked) {
+ log.trace("{}: Packet processing is blocked for sometime", counterName);
+ return FilterAction.PACKET_BLOCKED;
+ }
+
+ if (windowBlocked) {
+ log.trace("{}: Packet processing is blocked for the window number: {}",
+ counterName, windowBlockCounter.get());
+ return FilterAction.WINDOW_BLOCKED;
+ }
+
+ if (currentCounter.getAndIncrement() < maxCounter) {
+ log.trace("{}: Packet is picked for processing with currentCounter: {} and maxCounter: {}",
+ counterName, currentCounter.get(), maxCounter);
+ return FilterAction.PACKET_ALLOW;
+ }
+ //Need to decrement the currentCounter and increment overFlowCounter
+ //Need to block the window and increment the window block counter
+ windowBlocked = true;
+ //TODO: Review this and the complete state machine
+ // If windowBlock crosses threshold then block packet processing for guard time
+ if (windowBlockCounter.incrementAndGet() > winThres) {
+ log.trace("{}: Packet processing blocked as current window crossed threshold " +
+ "currentWindowNumber: {} maxWindowNumber: {}",
+ counterName, windowBlockCounter.get(), winThres);
+ packetProcessingBlocked = true;
+ windowUnblockExecutor.schedule(new ClearPacketProcessingBlock(),
+ guardTime,
+ TimeUnit.SECONDS);
+ } else {
+ log.trace("{}: WindowBlockCounter: {} winThres: {}", counterName, windowBlockCounter.get(),
+ winThres);
+ }
+ //MT: Temp change in logic to branch the code - Rolled back
+ currentCounter.decrementAndGet();
+ if (overFlowCounter.incrementAndGet() < 0) {
+ overFlowCounter.set(0);
+ }
+ log.trace("{}: Overflow counter is: {}", counterName, overFlowCounter.get());
+ return FilterAction.PACKET_DENY;
+
+ }
+
+ @Override
+ public String name() {
+ return counterName;
+ }
+
+ @Override
+ public int pendingPackets() {
+ return currentCounter.get();
+ }
+
+ @Override
+ public int droppedPackets() {
+ return overFlowCounter.get();
+ }
+
+
+
+ @Override
+ public void setPps(int pps) {
+ this.pps = pps;
+ }
+
+ @Override
+ public void setWinSize(int winSize) {
+ this.winSize = winSize;
+ }
+
+ @Override
+ public void setGuardTime(int guardTime) {
+ this.guardTime = guardTime;
+ }
+
+ @Override
+ public void setWinThres(int winThres) {
+ this.winThres = winThres;
+ }
+
+ @Override
+ public void stop() {
+ timerExecutor.shutdown();
+ windowUnblockExecutor.shutdown();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ DefaultPacketInFilter that = (DefaultPacketInFilter) o;
+ return pps == that.pps &&
+ winSize == that.winSize &&
+ guardTime == that.guardTime &&
+ winThres == that.winThres &&
+ counterName.equals(that.counterName) &&
+ classifier.equals(that.classifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(pps, winSize, guardTime, winThres, counterName, classifier);
+ }
+
+
+ private final class ClearWindowBlock implements Runnable {
+ @Override
+ public void run() {
+ // If window is not already blocked and there is at least one packet processed
+ // in that window then reset the window block counter:
+ if (!windowBlocked) {
+ log.trace("{}: WindowBlockCounter is reset as there was no blocking in current " +
+ "window with current windowBlockCounter: {}", counterName, windowBlockCounter.get());
+ windowBlockCounter.set(0);
+ }
+ if (currentCounter.get() == 0) {
+ //No packet processed in current window so do not change anything in the current state
+ log.trace("{}: No packets in the current window so not doing anything in ClearWindowBlock",
+ counterName);
+ return;
+ }
+
+ //Reset the counter and unblock the window
+ log.trace("{}: Current counter and windowBlocked is reset in ClearWindowBlock", counterName);
+ currentCounter.set(0);
+ windowBlocked = false;
+ }
+ }
+
+ private final class ClearPacketProcessingBlock implements Runnable {
+ @Override
+ public void run() {
+ //Reset the counter and unblock the window and packet processing
+ //CurrentCounter and windowBlocked counter setting is not required here
+ //Still setting to be on safer side
+ log.trace("{}: All blocks cleared in ClearPacketProcessingBlock", counterName);
+ currentCounter.set(0);
+ windowBlocked = false;
+ packetProcessingBlocked = false;
+ windowBlockCounter.set(0);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6DirectPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6DirectPacketClassifier.java
new file mode 100644
index 0000000..a320a44
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6DirectPacketClassifier.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.UDP;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class Dhcp6DirectPacketClassifier implements PacketInClassifier {
+ private final Logger log = getLogger(getClass());
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IPv6 ipv6Packet = (IPv6) eth.getPayload();
+
+ if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_UDP) {
+ UDP udpPacket = (UDP) ipv6Packet.getPayload();
+ //Directly connected host
+ if (udpPacket.getDestinationPort() == UDP.DHCP_V6_SERVER_PORT &&
+ udpPacket.getSourcePort() == UDP.DHCP_V6_CLIENT_PORT) {
+ DHCP6 dhcp6 = (DHCP6) udpPacket.getPayload();
+ if (dhcp6.getMsgType() == DHCP6.MsgType.SOLICIT.value()) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6IndirectPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6IndirectPacketClassifier.java
new file mode 100644
index 0000000..afb2c31
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Dhcp6IndirectPacketClassifier.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.UDP;
+import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+import org.slf4j.Logger;
+
+import java.util.Arrays;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class Dhcp6IndirectPacketClassifier implements PacketInClassifier {
+ private final Logger log = getLogger(getClass());
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IPv6 ipv6Packet = (IPv6) eth.getPayload();
+
+ if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_UDP) {
+ UDP udpPacket = (UDP) ipv6Packet.getPayload();
+ //Indirectly connected host
+ if (udpPacket.getDestinationPort() == UDP.DHCP_V6_SERVER_PORT &&
+ udpPacket.getSourcePort() == UDP.DHCP_V6_SERVER_PORT &&
+ Arrays.equals(ipv6Packet.getDestinationAddress(),
+ Ip6Address.valueOf("ff02::1:2").toOctets())) {
+ DHCP6 relayMessage = (DHCP6) udpPacket.getPayload();
+ DHCP6 dhcp6 = (DHCP6) relayMessage.getOptions().stream()
+ .filter(opt -> opt instanceof Dhcp6RelayOption)
+ .map(BasePacket::getPayload)
+ .map(pld -> (DHCP6) pld)
+ .findFirst()
+ .orElse(null);
+
+ if (dhcp6.getMsgType() == DHCP6.MsgType.SOLICIT.value()) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DhcpPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DhcpPacketClassifier.java
new file mode 100644
index 0000000..1389c8c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DhcpPacketClassifier.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.DHCP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.UDP;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+
+public class DhcpPacketClassifier implements PacketInClassifier {
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 ipv4Packet = (IPv4) eth.getPayload();
+
+ if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
+ UDP udpPacket = (UDP) ipv4Packet.getPayload();
+
+ if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT &&
+ udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) {
+ DHCP dhcp = (DHCP) udpPacket.getPayload();
+ if (dhcp.getPacketType() == DHCP.MsgType.DHCPDISCOVER) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Icmp6PacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Icmp6PacketClassifier.java
new file mode 100644
index 0000000..7dfa806
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/Icmp6PacketClassifier.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv6;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class Icmp6PacketClassifier implements PacketInClassifier {
+ private final Logger log = getLogger(getClass());
+ @Override
+ public boolean match(PacketContext packet) {
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IPv6 ipv6Packet = (IPv6) eth.getPayload();
+
+ if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
+ ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
+ if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/IcmpPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/IcmpPacketClassifier.java
new file mode 100644
index 0000000..501357c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/IcmpPacketClassifier.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.IPv4;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+
+public class IcmpPacketClassifier implements PacketInClassifier {
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 ipv4Packet = (IPv4) eth.getPayload();
+
+ if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
+ ICMP icmpPacket = (ICMP) ipv4Packet.getPayload();
+ if (icmpPacket.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NAPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NAPacketClassifier.java
new file mode 100644
index 0000000..2dc653c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NAPacketClassifier.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv6;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+
+public class NAPacketClassifier implements PacketInClassifier {
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IPv6 ipv6Packet = (IPv6) eth.getPayload();
+ if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
+ ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
+ if (icmp6.getIcmpType() == ICMP6.NEIGHBOR_ADVERTISEMENT) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NSPacketClassifier.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NSPacketClassifier.java
new file mode 100644
index 0000000..4d90ada
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/NSPacketClassifier.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.net.packet.packetfilter;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv6;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+
+public class NSPacketClassifier implements PacketInClassifier {
+
+ @Override
+ public boolean match(PacketContext packet) {
+
+ Ethernet eth = packet.inPacket().parsed();
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IPv6 ipv6Packet = (IPv6) eth.getPayload();
+ if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
+ ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
+ if (icmp6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/package-info.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/package-info.java
new file mode 100644
index 0000000..2918caf
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Packet filter classifier for various Packet types.
+ */
+package org.onosproject.net.packet.packetfilter;
\ No newline at end of file