Reject bad ip addresses on IP packets and count punts.  Also added
Override as needed on appropriate members.

Change-Id: I49203ad57afe7fd7026d2d5ae9ff326d421ed9a3
diff --git a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
index 68f3b45..905e760 100644
--- a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
+++ b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
@@ -51,6 +51,7 @@
 public class McastForwarding {
 
     private final Logger log = getLogger(getClass());
+    private final IpPrefix mcast = IpPrefix.valueOf("224.0.0.0/4");
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected PacketService packetService;
@@ -74,9 +75,8 @@
         // Build a traffic selector for all multicast traffic
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(mcast);
         packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
-        //selector.matchIPDst(IpPrefix.valueOf("224/4"));
-        //packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
 
         mrib = McastRouteTable.getInstance();
         log.info("Started");
@@ -138,11 +138,22 @@
             IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
             IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
 
+            log.debug("Packet (" + saddr.toString() + ", " + gaddr.toString() +
+                    "\tingress port: " + context.inPacket().receivedFrom().toString());
 
-            // TODO: Add isMulticast to the Ip4Address checks
-            // if ( !gaddr.isMulticast() ) {
-            //    return;
-            // }
+            IpPrefix mcast = IpPrefix.valueOf("224.0.0.0/4");
+            if (!mcast.contains(gaddr)) {
+
+                // The IP destination is not a multicast address
+                return;
+            }
+
+            if (mcast.contains(saddr)) {
+
+                // The IP source is a multicast address.
+                return;
+            }
+
             IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
             IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
 
@@ -189,6 +200,8 @@
             McastIntentManager im = McastIntentManager.getInstance();
             im.setIntent(entry);
 
+            entry.incrementPuntCount();
+
             // Send the pack out each of the egress devices & port
             forwardPacketToDst(context, entry);
         }
diff --git a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
index 397ce35..06073a3 100644
--- a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
+++ b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
@@ -18,6 +18,7 @@
 import org.onlab.packet.IpPrefix;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
 
 import java.util.Set;
 
@@ -40,13 +41,18 @@
     public IpPrefix getSaddr();
 
     /**
-     * Check for IPv4 or IPv6 as well as (S, G) or (*, G).
-     *
-     * @return true if IP v4
+     * Is this an IPv4 multicast route.
+     * @return true if it is an IPv4 route
      */
     public boolean isIp4();
 
     /**
+     * Is this an IPv4 multicast route.
+     * @return true if it is an IPv4 route
+     */
+    public boolean isIp6();
+
+    /**
      * Add the ingress ConnectPoint with a ConnectPoint.
      *
      * @param ingress ingress point
@@ -86,12 +92,29 @@
     public Set<ConnectPoint> getEgressPoints();
 
     /**
+     * Increment the punt count.
+     */
+    public void incrementPuntCount();
+
+    /**
+     * Get the punt count.
+     * @return the punt count
+     */
+    public Integer getPuntCount();
+
+    /**
      * Have the McastIntentManager create an intent, attempt to
      * install the intent and then save the key.
      */
     public void setIntent();
 
     /**
+     * Set the Intent key.
+     * @param intent intent
+     */
+    public void setIntent(SinglePointToMultiPointIntent intent);
+
+    /**
      * Withdraw the intent if it has been installed.
      */
     public void withdrawIntent();
diff --git a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
index d6b86b8..cbe9904 100644
--- a/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
+++ b/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
@@ -40,6 +40,11 @@
     protected boolean isGroup = false;
 
     /**
+     * How may times has this packet been punted.
+     */
+    private int puntCount = 0;
+
+    /**
      * If the intentKey is null that means no intent has
      * been installed.
      */
@@ -100,6 +105,7 @@
      * Get the multicast group address.
      * @return the multicast group address
      */
+    @Override
     public IpPrefix getGaddr() {
         return gaddr;
     }
@@ -108,6 +114,7 @@
      * Get the multicast source address.
      * @return the multicast source address
      */
+    @Override
     public IpPrefix getSaddr() {
         return saddr;
     }
@@ -116,6 +123,7 @@
      * Is this an IPv4 multicast route.
      * @return true if it is an IPv4 route
      */
+    @Override
     public boolean isIp4() {
         return gaddr.isIp4();
     }
@@ -124,6 +132,7 @@
      * Is this an IPv6 multicast route.
      * @return true if it is an IPv6 route
      */
+    @Override
     public boolean isIp6() {
         return gaddr.isIp6();
     }
@@ -148,6 +157,7 @@
      *
      * @param ingress incoming connect point
      */
+    @Override
     public void addIngressPoint(ConnectPoint ingress) {
         ingressPoint = checkNotNull(ingress);
     }
@@ -157,6 +167,7 @@
      * @param deviceId the switch device Id
      * @param portNum the ingress port number
      */
+    @Override
     public void addIngressPoint(String deviceId, long portNum) {
         ingressPoint = new ConnectPoint(
                 DeviceId.deviceId(deviceId),
@@ -167,6 +178,7 @@
      * Get the ingress ConnectPoint.
      * @return the ingress ConnectPoint
      */
+    @Override
     public ConnectPoint getIngressPoint() {
         return this.ingressPoint;
     }
@@ -176,6 +188,7 @@
      *
      * @param member member egress connect point
      */
+    @Override
     public void addEgressPoint(ConnectPoint member) {
         egressPoints.add(checkNotNull(member));
     }
@@ -186,6 +199,7 @@
      * @param deviceId deviceId of the connect point
      * @param portNum portNum of the connect point
      */
+    @Override
     public void addEgressPoint(String deviceId, long portNum) {
         ConnectPoint cp = new ConnectPoint(DeviceId.deviceId(deviceId), PortNumber.portNumber(portNum));
         this.egressPoints.add(cp);
@@ -195,24 +209,28 @@
      * Get egress connect points for the route.
      * @return Set of egress connect points
      */
+    @Override
     public Set<ConnectPoint> getEgressPoints() {
         return egressPoints;
     }
 
     /**
-     * Set the Intent key.
-     * @param intent intent
+     * Get the number of times the packet has been punted.
+     * @return the punt count
      */
-    public void setIntent(SinglePointToMultiPointIntent intent) {
-        intentKey = intent.key();
+    @Override
+    public Integer getPuntCount() {
+        return puntCount;
     }
 
     /**
-     * Get the intent key represented by this route.
-     * @return intentKey
+     * Increment the punt count.
+     *
+     * TODO: we need to handle wrapping.
      */
-    public Key getIntentKey() {
-        return this.intentKey;
+    @Override
+    public void incrementPuntCount() {
+        puntCount++;
     }
 
     /**
@@ -222,6 +240,7 @@
      * replace it with a new one.  This will support the case where the ingress connectPoint
      * or group of egress connectPoints change.
      */
+    @Override
     public void setIntent() {
         if (this.intentKey != null) {
             this.withdrawIntent();
@@ -232,8 +251,28 @@
     }
 
     /**
+     * Set the Intent key.
+     * @param intent intent
+     */
+    @Override
+    public void setIntent(SinglePointToMultiPointIntent intent) {
+        intentKey = intent.key();
+    }
+
+    /**
+     * Get the intent key represented by this route.
+     * @return intentKey
+     */
+    @Override
+    public Key getIntentKey() {
+        return this.intentKey;
+    }
+
+
+    /**
      * Withdraw the intent and set the key to null.
      */
+    @Override
     public void withdrawIntent() {
         if (intentKey == null) {
             // nothing to withdraw
@@ -248,6 +287,7 @@
      * Pretty Print this Multicast Route.  Works for McastRouteSource and McastRouteGroup.
      * @return pretty string of the multicast route
      */
+    @Override
     public String toString() {
         String out = String.format("(%s, %s)\n\t",
                 saddr.toString(), gaddr.toString());
@@ -263,6 +303,7 @@
             }
         }
         out += ("\t}\n");
+        out += ("\tpunted: " + this.getPuntCount() + "\n");
         return out;
     }
 }