Adding Set Next Hop action 39/439/1
authorAlessandro Boch <aboch@cisco.com>
Thu, 6 Jun 2013 21:06:27 +0000 (14:06 -0700)
committerAlessandro Boch <aboch@cisco.com>
Thu, 6 Jun 2013 21:06:27 +0000 (14:06 -0700)
- It will be ignored by openflow plugin

Signed-off-by: Alessandro Boch <aboch@cisco.com>
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNextHop.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/action/ActionTest.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java

index f3429e62b181f155897ac7dc9034e355ac7d5d1f..77c1c859c601993a4c904099d4082a0d9ae4fa8d 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.controller.sal.action.Output;
 import org.opendaylight.controller.sal.action.PopVlan;
 import org.opendaylight.controller.sal.action.SetDlDst;
 import org.opendaylight.controller.sal.action.SetDlSrc;
+import org.opendaylight.controller.sal.action.SetNextHop;
 import org.opendaylight.controller.sal.action.SetNwDst;
 import org.opendaylight.controller.sal.action.SetNwSrc;
 import org.opendaylight.controller.sal.action.SetNwTos;
@@ -124,27 +125,6 @@ public class FlowConfig implements Serializable {
         ANY, V4, V6;
     };
 
-    private enum SetNextHopType {
-        CISCO_EXTENSION("Cisco NextHop Extension"), RESOLVE_L2RW(
-                "Resolve L2 Rewrite");
-
-        private SetNextHopType(String name) {
-            this.name = name;
-        }
-
-        private String name;
-
-        public String toString() {
-            return name;
-        }
-
-        public boolean equals(String type) {
-            if (type.trim().equalsIgnoreCase(name))
-                return true;
-            return false;
-        }
-    }
-
     public FlowConfig() {
     }
 
@@ -473,163 +453,160 @@ public class FlowConfig implements Serializable {
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         FlowConfig other = (FlowConfig) obj;
         if (actions == null) {
-            if (other.actions != null)
+            if (other.actions != null) {
                 return false;
-        } else if (!actions.equals(other.actions))
+            }
+        } else if (!actions.equals(other.actions)) {
             return false;
+        }
         if (cookie == null) {
-            if (other.cookie != null)
+            if (other.cookie != null) {
                 return false;
-        } else if (!cookie.equals(other.cookie))
+            }
+        } else if (!cookie.equals(other.cookie)) {
             return false;
+        }
         if (dlDst == null) {
-            if (other.dlDst != null)
+            if (other.dlDst != null) {
                 return false;
-        } else if (!dlDst.equals(other.dlDst))
+            }
+        } else if (!dlDst.equals(other.dlDst)) {
             return false;
+        }
         if (dlSrc == null) {
-            if (other.dlSrc != null)
+            if (other.dlSrc != null) {
                 return false;
-        } else if (!dlSrc.equals(other.dlSrc))
+            }
+        } else if (!dlSrc.equals(other.dlSrc)) {
             return false;
-        if (dynamic != other.dynamic)
+        }
+        if (dynamic != other.dynamic) {
             return false;
+        }
         if (etherType == null) {
-            if (other.etherType != null)
+            if (other.etherType != null) {
                 return false;
-        } else if (!etherType.equals(other.etherType))
+            }
+        } else if (!etherType.equals(other.etherType)) {
             return false;
+        }
         if (ingressPort == null) {
-            if (other.ingressPort != null)
+            if (other.ingressPort != null) {
                 return false;
-        } else if (!ingressPort.equals(other.ingressPort))
+            }
+        } else if (!ingressPort.equals(other.ingressPort)) {
             return false;
+        }
         if (name == null) {
-            if (other.name != null)
+            if (other.name != null) {
                 return false;
-        } else if (!name.equals(other.name))
+            }
+        } else if (!name.equals(other.name)) {
             return false;
+        }
         if (nwDst == null) {
-            if (other.nwDst != null)
+            if (other.nwDst != null) {
                 return false;
-        } else if (!nwDst.equals(other.nwDst))
+            }
+        } else if (!nwDst.equals(other.nwDst)) {
             return false;
+        }
         if (nwSrc == null) {
-            if (other.nwSrc != null)
+            if (other.nwSrc != null) {
                 return false;
-        } else if (!nwSrc.equals(other.nwSrc))
+            }
+        } else if (!nwSrc.equals(other.nwSrc)) {
             return false;
+        }
         if (portGroup == null) {
-            if (other.portGroup != null)
+            if (other.portGroup != null) {
                 return false;
-        } else if (!portGroup.equals(other.portGroup))
+            }
+        } else if (!portGroup.equals(other.portGroup)) {
             return false;
+        }
         if (priority == null) {
-            if (other.priority != null)
+            if (other.priority != null) {
                 return false;
-        } else if (!priority.equals(other.priority))
+            }
+        } else if (!priority.equals(other.priority)) {
             return false;
+        }
         if (protocol == null) {
-            if (other.protocol != null)
+            if (other.protocol != null) {
                 return false;
-        } else if (!protocol.equals(other.protocol))
+            }
+        } else if (!protocol.equals(other.protocol)) {
             return false;
+        }
         if (node == null) {
-            if (other.node != null)
+            if (other.node != null) {
                 return false;
-        } else if (!node.equals(other.node))
+            }
+        } else if (!node.equals(other.node)) {
             return false;
+        }
         if (tosBits == null) {
-            if (other.tosBits != null)
+            if (other.tosBits != null) {
                 return false;
-        } else if (!tosBits.equals(other.tosBits))
+            }
+        } else if (!tosBits.equals(other.tosBits)) {
             return false;
+        }
         if (tpDst == null) {
-            if (other.tpDst != null)
+            if (other.tpDst != null) {
                 return false;
-        } else if (!tpDst.equals(other.tpDst))
+            }
+        } else if (!tpDst.equals(other.tpDst)) {
             return false;
+        }
         if (tpSrc == null) {
-            if (other.tpSrc != null)
+            if (other.tpSrc != null) {
                 return false;
-        } else if (!tpSrc.equals(other.tpSrc))
+            }
+        } else if (!tpSrc.equals(other.tpSrc)) {
             return false;
+        }
         if (vlanId == null) {
-            if (other.vlanId != null)
+            if (other.vlanId != null) {
                 return false;
-        } else if (!vlanId.equals(other.vlanId))
+            }
+        } else if (!vlanId.equals(other.vlanId)) {
             return false;
+        }
         if (vlanPriority == null) {
-            if (other.vlanPriority != null)
+            if (other.vlanPriority != null) {
                 return false;
-        } else if (!vlanPriority.equals(other.vlanPriority))
+            }
+        } else if (!vlanPriority.equals(other.vlanPriority)) {
             return false;
+        }
         if (idleTimeout == null) {
-            if (other.idleTimeout != null)
+            if (other.idleTimeout != null) {
                 return false;
-        } else if (!idleTimeout.equals(other.idleTimeout))
+            }
+        } else if (!idleTimeout.equals(other.idleTimeout)) {
             return false;
+        }
         if (hardTimeout == null) {
-            if (other.hardTimeout != null)
+            if (other.hardTimeout != null) {
                 return false;
-        } else if (!hardTimeout.equals(other.hardTimeout))
-            return false;
-        return true;
-    }
-
-    public InetAddress getNextHopAddressForL2RWAction() {
-        if (actions != null) {
-            Matcher sstr;
-            for (String actiongrp : actions) {
-                sstr = Pattern.compile("SET_NEXT_HOP=(.*)").matcher(actiongrp);
-                if (sstr.matches()) {
-                    SetNextHopType setNHType = SetNextHopType.CISCO_EXTENSION;
-                    String nextHopInfo = sstr.group(1);
-                    String values[] = nextHopInfo.split("//");
-                    String address = values[0].trim();
-                    String type = null;
-                    if (values.length > 1) {
-                        type = values[1].trim();
-                    }
-
-                    if (type != null) {
-                        for (SetNextHopType nh : SetNextHopType.values()) {
-                            if (nh.equals(type))
-                                setNHType = nh;
-                        }
-                    }
-
-                    log.debug("Get Nexthop address = {} Type = {}", address,
-                            setNHType.toString());
-                    if (setNHType == SetNextHopType.RESOLVE_L2RW) {
-                        try {
-                            return InetAddress.getByName(address);
-                        } catch (Exception e) {
-                            log.debug(
-                                    "Exception during nextHopAddress resolution : ",
-                                    e);
-                        }
-                    }
-                }
             }
+        } else if (!hardTimeout.equals(other.hardTimeout)) {
+            return false;
         }
-        return null;
-    }
-
-    public String getNextHopL2RWUsageError() {
-        return "Could not resolve NextHop IP Address for the selected Switch.<br>"
-                + "Please Check the following configurations.<br>"
-                + "1. Is the NextHop IP address directly connected to the Selected Switch<br>"
-                + "2. If appropriate Subnet Configurations are done in the Switch Manager<br>"
-                + "3. If the Nexthop IP-Address is Correct";
+        return true;
     }
 
     public boolean isL2AddressValid(String mac) {
@@ -772,8 +749,9 @@ public class FlowConfig implements Serializable {
             }
 
             // make sure it's a valid number
-            if (cookie != null)
+            if (cookie != null) {
                 Long.decode(cookie);
+            }
 
             if (ingressPort != null) {
                 Short port = Short.decode(ingressPort);
@@ -812,10 +790,11 @@ public class FlowConfig implements Serializable {
                             "Ethernet type %s is not valid", etherType));
                     return false;
                 } else {
-                    if (type == 0x800)
+                    if (type == 0x800) {
                         etype = EtherIPType.V4;
-                    else if (type == 0x86dd)
+                    } else if (type == 0x86dd) {
                         etype = EtherIPType.V6;
+                    }
                 }
             }
 
@@ -1084,13 +1063,10 @@ public class FlowConfig implements Serializable {
                             ActionType.SET_NEXT_HOP.toString() + "=(.*)")
                             .matcher(actiongrp);
                     if (sstr.matches()) {
-                        String nextHopInfo = sstr.group(1);
-                        String values[] = nextHopInfo.split("//");
-                        String address = values[0].trim();
-
-                        if ((address == null) || !isOutputNextHopValid(address)) {
+                        if (!NetUtils.isIPAddressValid(sstr.group(1))) {
                             resultStr.append(String.format(
-                                    "next hop %s is not valid", sstr.group(1)));
+                                    "IP destination address %s is not valid",
+                                    sstr.group(1)));
                             return false;
                         }
                         continue;
@@ -1198,17 +1174,6 @@ public class FlowConfig implements Serializable {
         return flow;
     }
 
-    public boolean isOutputNextHopValid(String onh) {
-        if (onh == null) {
-            return false;
-        }
-        /*
-         * For now, only takes IPv4 or IPv6 address
-         */
-        return (NetUtils.isIPv4AddressValid(onh) || NetUtils
-                .isIPv6AddressValid(onh));
-    }
-
     public boolean isByNameAndNodeIdEqual(FlowConfig that) {
         return (this.name.equals(that.name) && this.node.equals(that.node));
     }
@@ -1221,14 +1186,6 @@ public class FlowConfig implements Serializable {
         return this.node.equals(node);
     }
 
-    public static List<String> getSupportedNextHopTypes() {
-        List<String> s = new ArrayList<String>();
-        for (SetNextHopType nh : SetNextHopType.values()) {
-            s.add(nh.toString());
-        }
-        return s;
-    }
-
     public void toggleStatus() {
         installInHw = (installInHw == null) ? "true" : (installInHw
                 .equals("true")) ? "false" : "true";
@@ -1393,7 +1350,8 @@ public class FlowConfig implements Serializable {
                         ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(
                         actiongrp);
                 if (sstr.matches()) {
-                    log.warn("We do not handle next hop action yet....");
+                    actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr
+                            .group(1))));
                     continue;
                 }
             }
index 0b11d13f3cdb582634e912d2a681f77298531b4b..34337ba42b625443b3a7587171325ee331dbe2be 100644 (file)
@@ -339,21 +339,6 @@ public class frmTest {
 
     }
 
-    @Test
-    public void testFlowConfigNextHopValidity() throws UnknownHostException {
-        FlowConfig fc = new FlowConfig();
-        Assert.assertFalse(fc.isOutputNextHopValid(null));
-        Assert.assertFalse(fc.isOutputNextHopValid("abc"));
-        Assert.assertFalse(fc.isOutputNextHopValid("1.1.1"));
-        Assert.assertFalse(fc.isOutputNextHopValid("1.1.1.1/49"));
-
-        Assert.assertTrue(fc.isOutputNextHopValid("1.1.1.1"));
-        Assert.assertTrue(fc.isOutputNextHopValid("1.1.1.1/32"));
-        Assert.assertTrue(fc
-                .isOutputNextHopValid("2001:420:281:1004:407a:57f4:4d15:c355"));
-
-    }
-
     @Test
     public void testFlowConfigEqualities() throws UnknownHostException {
         FlowConfig fc = new FlowConfig();
index 074774a25e2e8c295801c5ae9763f4661ba6a79c..8d3a1be20339b866b4165ad305f20aef2629d371 100644 (file)
@@ -100,7 +100,7 @@ public class FlowConverter {
     /**
      * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
      * form (V6Match)
-     * 
+     *
      * @return
      */
     public OFMatch getOFMatch() {
@@ -177,7 +177,7 @@ public class FlowConverter {
                  * actually the DSCP field followed by a zero ECN
                  */
                 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
-                byte dscp = (byte) ((int) tos << 2);
+                byte dscp = (byte) (tos << 2);
                 if (!isIPv6) {
                     ofMatch.setNetworkTypeOfService(dscp);
                     wildcards &= ~OFMatch.OFPFW_NW_TOS;
@@ -262,7 +262,7 @@ public class FlowConverter {
 
     /**
      * Returns the list of actions in OF 1.0 form
-     * 
+     *
      * @return
      */
     public List<OFAction> getOFActions() {
@@ -411,7 +411,7 @@ public class FlowConverter {
                     continue;
                 }
                 if (action.getType() == ActionType.SET_NEXT_HOP) {
-                    // TODO
+                    logger.info("Unsupported action: {}", action);
                     continue;
                 }
             }
@@ -424,7 +424,7 @@ public class FlowConverter {
     /**
      * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
      * IPv6 extension (V6FlowMod) Flow modifier Message
-     * 
+     *
      * @param sw
      * @param command
      * @param port
@@ -505,7 +505,7 @@ public class FlowConverter {
                     if (ofMatch.getInputPort() != 0) {
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createNodeConnector(
-                                        (Short) ofMatch.getInputPort(), node)));
+                                        ofMatch.getInputPort(), node)));
                     }
                     if (ofMatch.getDataLayerSource() != null
                             && !NetUtils
@@ -560,11 +560,11 @@ public class FlowConverter {
                     }
                     if (ofMatch.getTransportSource() != 0) {
                         salMatch.setField(MatchType.TP_SRC,
-                                ((Short) ofMatch.getTransportSource()));
+                                ofMatch.getTransportSource());
                     }
                     if (ofMatch.getTransportDestination() != 0) {
                         salMatch.setField(MatchType.TP_DST,
-                                ((Short) ofMatch.getTransportDestination()));
+                                ofMatch.getTransportDestination());
                     }
                 } else {
                     // Compute OF1.0 + IPv6 extensions Match
@@ -573,7 +573,7 @@ public class FlowConverter {
                         // Mask on input port is not defined
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createOFNodeConnector(
-                                        (Short) v6Match.getInputPort(), node)));
+                                        v6Match.getInputPort(), node)));
                     }
                     if (v6Match.getDataLayerSource() != null
                             && !NetUtils
@@ -623,11 +623,11 @@ public class FlowConverter {
                     }
                     if (v6Match.getTransportSource() != 0) {
                         salMatch.setField(MatchType.TP_SRC,
-                                ((Short) v6Match.getTransportSource()));
+                                (v6Match.getTransportSource()));
                     }
                     if (v6Match.getTransportDestination() != 0) {
                         salMatch.setField(MatchType.TP_DST,
-                                ((Short) v6Match.getTransportDestination()));
+                                (v6Match.getTransportDestination()));
                     }
                 }
             }
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNextHop.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/SetNextHop.java
new file mode 100644 (file)
index 0000000..33d9b93
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.action;
+
+import java.net.InetAddress;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class SetNextHop extends Action {
+    @XmlElement
+    private InetAddress address;
+
+    /* Dummy constructor for JAXB */
+    @SuppressWarnings("unused")
+    private SetNextHop() {
+    }
+
+    public SetNextHop(InetAddress address) {
+        type = ActionType.SET_NEXT_HOP;
+        this.address = address;
+    }
+
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((address == null) ? 0 : address.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        SetNextHop other = (SetNextHop) obj;
+        if (address == null) {
+            if (other.address != null) {
+                return false;
+            }
+        } else if (!address.equals(other.address)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return type + "[" + address.toString() + "]";
+    }
+}
index 691ddc93561bc0359858fa778b9e83d73b3cf2e3..2591d931e1d70e5084531c464f8c2b8c5209317f 100644 (file)
@@ -40,10 +40,11 @@ public abstract class NetUtils {
      * @return     the integer number
      */
     public static int byteArray4ToInt(byte[] ba) {
-        if (ba == null || ba.length != 4)
+        if (ba == null || ba.length != 4) {
             return 0;
-        return (int) ((0xff & ba[0]) << 24 | (0xff & ba[1]) << 16
-                | (0xff & ba[2]) << 8 | (0xff & ba[3]));
+        }
+        return (0xff & ba[0]) << 24 | (0xff & ba[1]) << 16
+                | (0xff & ba[2]) << 8 | (0xff & ba[3]);
     }
 
     /**
@@ -131,7 +132,7 @@ public abstract class NetUtils {
             int intMask = 0;
             int numBytes = prefixMask.length;
             for (int i = 0; i < numBytes; i++) {
-                intMask |= ((int) prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i));
+                intMask |= (prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i));
             }
 
             int bit = 1;
@@ -219,13 +220,13 @@ public abstract class NetUtils {
         if (isAny(testAddress) || isAny(filterAddress)) {
             return false;
         }
-        
+
         int testMaskLen = (testMask != null) ? NetUtils.getSubnetMaskLength(testMask.getAddress()) : 0;
         int filterMaskLen = (filterMask != null) ? NetUtils.getSubnetMaskLength(filterMask.getAddress()) : 0;
-        
+
         int testPrefixLen = (testAddress instanceof Inet6Address) ? (128 - testMaskLen) : (32 - testMaskLen);
         int filterPrefixLen = (filterAddress instanceof Inet6Address) ? (128 - filterMaskLen) : (32 - filterMaskLen);
-        
+
         // Mask length check. Test mask has to be more specific than filter one
         if (testPrefixLen < filterPrefixLen) {
             return true;
@@ -292,8 +293,9 @@ public abstract class NetUtils {
      * @return
      */
     public static boolean isIPv4AddressValid(String cidr) {
-        if (cidr == null)
+        if (cidr == null) {
             return false;
+        }
 
         String values[] = cidr.split("/");
         Pattern ipv4Pattern = Pattern
@@ -319,8 +321,9 @@ public abstract class NetUtils {
      * @return
      */
     public static boolean isIPv6AddressValid(String cidr) {
-        if (cidr == null)
+        if (cidr == null) {
             return false;
+        }
 
         String values[] = cidr.split("/");
         try {
@@ -341,29 +344,42 @@ public abstract class NetUtils {
         }
         return true;
     }
-    
+
+    /**
+     * Checks if the passed IP address in string form is a valid v4 or v6
+     * address. The address may specify a mask at the end as "/MMM"
+     *
+     * @param cidr
+     *            the v4 or v6 address as IP/MMM
+     * @return
+     */
+    public static boolean isIPAddressValid(String cidr) {
+        return NetUtils.isIPv4AddressValid(cidr)
+                || NetUtils.isIPv6AddressValid(cidr);
+    }
+
     /*
-     * Following utilities are useful when you need to 
+     * Following utilities are useful when you need to
      * compare or bit shift java primitive type variable
      * which are inerently signed
      */
     /**
      * Returns the unsigned value of the passed byte variable
-     * 
+     *
      * @param b        the byte value
      * @return the int variable containing the unsigned byte value
      */
     public static int getUnsignedByte(byte b) {
-               return (b > 0)? (int)b : ((int)b & 0x7F | 0x80);
+               return (b > 0)? (int)b : (b & 0x7F | 0x80);
        }
-       
+
     /**
      * Return the unsigned value of the passed short variable
-     * 
+     *
      * @param s the short value
      * @return the int variable containing the unsigned short value
      */
        public static int getUnsignedShort(short s) {
-               return (s > 0)? (int)s : ((int)s & 0x7FFF | 0x8000);
+               return (s > 0)? (int)s : (s & 0x7FFF | 0x8000);
        }
 }
index 6858494283a2ec6cf0ee0e56e57d88d5a3ce5960..4fd59790034d413034f7c4209e473c357f2aefa7 100644 (file)
@@ -156,7 +156,7 @@ public class ActionTest {
         try {
             ip = InetAddress.getByName("2001:420:281:1003:f2de:f1ff:fe71:728d");
         } catch (UnknownHostException e) {
-            logger.error("",e);
+            logger.error("", e);
         }
         action = new SetNwSrc(ip);
         Assert.assertTrue(action.isValid());
@@ -172,7 +172,7 @@ public class ActionTest {
 
         action = new SetNwTos(0x40);
         Assert.assertFalse(action.isValid());
-        
+
         action = new SetNwTos(0xff1);
         Assert.assertFalse(action.isValid());
 
@@ -206,6 +206,29 @@ public class ActionTest {
         Assert.assertFalse(action.isValid());
     }
 
+    @Test
+    public void testNextHopActionCreation() {
+        SetNextHop action = null;
+
+        InetAddress ip = null;
+        try {
+            ip = InetAddress.getByName("171.71.9.52");
+        } catch (UnknownHostException e) {
+            logger.error("", e);
+        }
+
+        action = new SetNextHop(ip);
+        Assert.assertTrue(action.getAddress().equals(ip));
+
+        try {
+            ip = InetAddress.getByName("2001:420:281:1003:f2de:f1ff:fe71:728d");
+        } catch (UnknownHostException e) {
+            logger.error("", e);
+        }
+        action = new SetNextHop(ip);
+        Assert.assertTrue(action.getAddress().equals(ip));
+    }
+
     @Test
     public void testActionList() {
         List<Action> actions = new ArrayList<Action>();
index 2d16afbd3d8fd6161922c092c212ae84722f9920..599f97448a4ce4e4d504542f9ae7df6347442789 100644 (file)
@@ -273,7 +273,7 @@ public class NetUtilsTest {
                 .isIPv6AddressValid("fe80:::0:0:0:204:61ff:fe9d/-1")); //not valid both
 
     }
-    
+
     @Test
     public void testInetAddressConflict() throws UnknownHostException {
 
@@ -318,4 +318,17 @@ public class NetUtilsTest {
                 InetAddress.getByName("255.255.0.0")));
 
     }
+
+    @Test
+    public void testIPAddressValidity() {
+        Assert.assertFalse(NetUtils.isIPAddressValid(null));
+        Assert.assertFalse(NetUtils.isIPAddressValid("abc"));
+        Assert.assertFalse(NetUtils.isIPAddressValid("1.1.1"));
+        Assert.assertFalse(NetUtils.isIPAddressValid("1.1.1.1/49"));
+
+        Assert.assertTrue(NetUtils.isIPAddressValid("1.1.1.1"));
+        Assert.assertTrue(NetUtils.isIPAddressValid("1.1.1.1/32"));
+        Assert.assertTrue(NetUtils
+                .isIPAddressValid("2001:420:281:1004:407a:57f4:4d15:c355"));
+    }
 }