Updated SDN-IP to use Ip4Address and Ip4Prefix instead of IpAddress and
IpPrefix, because so far we haven't implemented IPv6.
Also, some of the BGP-related attributes (e.g., BGP Speaker ID)
are IPv4 by definition.

The following components are updated:
 * BGP implementation
 * Router component and relevant state (e.g., RouteEntry)

Other components (e.g., configuration) will continue to use
the more generic IpAddress and IpPrefix.

Change-Id: I1936ca9871fd5a9709cb4f2c2850d78ebc1472c4
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/RouteEntry.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/RouteEntry.java
index 95169bb..07dd691 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/RouteEntry.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/RouteEntry.java
@@ -19,8 +19,8 @@
 
 import java.util.Objects;
 
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 
 import com.google.common.base.MoreObjects;
 
@@ -28,8 +28,8 @@
  * Represents a route entry for an IP prefix.
  */
 public class RouteEntry {
-    private final IpPrefix prefix;             // The IP prefix
-    private final IpAddress nextHop;           // Next-hop IP address
+    private final Ip4Prefix prefix;             // The IP prefix
+    private final Ip4Address nextHop;           // Next-hop IP address
 
     /**
      * Class constructor.
@@ -37,7 +37,7 @@
      * @param prefix the IP prefix of the route
      * @param nextHop the next hop IP address for the route
      */
-    public RouteEntry(IpPrefix prefix, IpAddress nextHop) {
+    public RouteEntry(Ip4Prefix prefix, Ip4Address nextHop) {
         this.prefix = checkNotNull(prefix);
         this.nextHop = checkNotNull(nextHop);
     }
@@ -47,7 +47,7 @@
      *
      * @return the IP prefix of the route
      */
-    public IpPrefix prefix() {
+    public Ip4Prefix prefix() {
         return prefix;
     }
 
@@ -56,7 +56,7 @@
      *
      * @return the next hop IP address for the route
      */
-    public IpAddress nextHop() {
+    public Ip4Address nextHop() {
         return nextHop;
     }
 
@@ -67,7 +67,7 @@
      * @param ip4Prefix the IPv4 prefix to use
      * @return the binary string representation
      */
-    static String createBinaryString(IpPrefix ip4Prefix) {
+    static String createBinaryString(Ip4Prefix ip4Prefix) {
         if (ip4Prefix.prefixLength() == 0) {
             return "";
         }
@@ -75,7 +75,7 @@
         StringBuilder result = new StringBuilder(ip4Prefix.prefixLength());
         long value = ip4Prefix.address().toInt() & 0xffffffffL;
         for (int i = 0; i < ip4Prefix.prefixLength(); i++) {
-            long mask = 1 << (IpPrefix.MAX_INET_MASK_LENGTH - 1 - i);
+            long mask = 1 << (Ip4Prefix.MAX_MASK_LENGTH - 1 - i);
             result.append(((value & mask) == 0) ? "0" : "1");
         }
         return result.toString();
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
index f1a14e7..cffdc09 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/Router.java
@@ -53,7 +53,8 @@
 import org.onlab.onos.sdnip.config.SdnIpConfigService;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.MacAddress;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,9 +84,9 @@
     // Stores all incoming route updates in a queue.
     private BlockingQueue<RouteUpdate> routeUpdates;
 
-    // The IpAddress is the next hop address of each route update.
-    private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
-    private ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent> pushedRouteIntents;
+    // The Ip4Address is the next hop address of each route update.
+    private SetMultimap<Ip4Address, RouteEntry> routesWaitingOnArp;
+    private ConcurrentHashMap<Ip4Prefix, MultiPointToSinglePointIntent> pushedRouteIntents;
 
     private IntentService intentService;
     private HostService hostService;
@@ -106,7 +107,8 @@
 
     // For routes announced by local BGP daemon in SDN network,
     // the next hop will be 0.0.0.0.
-    public static final IpAddress LOCAL_NEXT_HOP = IpAddress.valueOf("0.0.0.0");
+    public static final Ip4Address LOCAL_NEXT_HOP =
+        Ip4Address.valueOf("0.0.0.0");
 
     /**
      * Class constructor.
@@ -130,7 +132,7 @@
                 new DefaultByteArrayNodeFactory());
         routeUpdates = new LinkedBlockingQueue<>();
         routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
-                HashMultimap.<IpAddress, RouteEntry>create());
+                HashMultimap.<Ip4Address, RouteEntry>create());
         pushedRouteIntents = new ConcurrentHashMap<>();
 
         bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
@@ -273,7 +275,7 @@
             }
             log.debug("Syncing SDN-IP Route Intents...");
 
-            Map<IpPrefix, MultiPointToSinglePointIntent> fetchedIntents =
+            Map<Ip4Prefix, MultiPointToSinglePointIntent> fetchedIntents =
                     new HashMap<>();
 
             //
@@ -292,7 +294,12 @@
                 Criterion c = mp2pIntent.selector().getCriterion(Type.IPV4_DST);
                 if (c != null && c instanceof IPCriterion) {
                     IPCriterion ipCriterion = (IPCriterion) c;
-                    fetchedIntents.put(ipCriterion.ip(), mp2pIntent);
+                    Ip4Prefix ip4Prefix = ipCriterion.ip().getIp4Prefix();
+                    if (ip4Prefix == null) {
+                        // TODO: For now we support only IPv4
+                        continue;
+                    }
+                    fetchedIntents.put(ip4Prefix, mp2pIntent);
                 } else {
                     log.warn("No IPV4_DST criterion found for intent {}",
                             mp2pIntent.id());
@@ -316,15 +323,15 @@
             //    Intent for same prefix, then delete/withdraw the FETCHED
             //    Intent.
             //
-            Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>>
+            Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>>
                     storeInMemoryIntents = new LinkedList<>();
-            Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>>
+            Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>>
                     addIntents = new LinkedList<>();
-            Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>>
+            Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>>
                     deleteIntents = new LinkedList<>();
-            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry :
+            for (Map.Entry<Ip4Prefix, MultiPointToSinglePointIntent> entry :
                     pushedRouteIntents.entrySet()) {
-                IpPrefix prefix = entry.getKey();
+                Ip4Prefix prefix = entry.getKey();
                 MultiPointToSinglePointIntent inMemoryIntent =
                         entry.getValue();
                 MultiPointToSinglePointIntent fetchedIntent =
@@ -369,9 +376,9 @@
             //
             // Any remaining FETCHED Intents have to be deleted/withdrawn
             //
-            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry :
+            for (Map.Entry<Ip4Prefix, MultiPointToSinglePointIntent> entry :
                     fetchedIntents.entrySet()) {
-                IpPrefix prefix = entry.getKey();
+                Ip4Prefix prefix = entry.getKey();
                 MultiPointToSinglePointIntent fetchedIntent = entry.getValue();
                 deleteIntents.add(Pair.of(prefix, fetchedIntent));
             }
@@ -383,9 +390,9 @@
             // 2. Delete intents: check if the leader before each operation
             // 3. Add intents: check if the leader before each operation
             //
-            for (Pair<IpPrefix, MultiPointToSinglePointIntent> pair :
+            for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair :
                     storeInMemoryIntents) {
-                IpPrefix prefix = pair.getLeft();
+                Ip4Prefix prefix = pair.getLeft();
                 MultiPointToSinglePointIntent intent = pair.getRight();
                 log.debug("Intent synchronization: updating in-memory " +
                                   "Intent for prefix: {}", prefix);
@@ -393,9 +400,9 @@
             }
             //
             isActivatedLeader = true;           // Allow push of Intents
-            for (Pair<IpPrefix, MultiPointToSinglePointIntent> pair :
+            for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair :
                     deleteIntents) {
-                IpPrefix prefix = pair.getLeft();
+                Ip4Prefix prefix = pair.getLeft();
                 MultiPointToSinglePointIntent intent = pair.getRight();
                 if (!isElectedLeader) {
                     isActivatedLeader = false;
@@ -406,9 +413,9 @@
                 intentService.withdraw(intent);
             }
             //
-            for (Pair<IpPrefix, MultiPointToSinglePointIntent> pair :
+            for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair :
                     addIntents) {
-                IpPrefix prefix = pair.getLeft();
+                Ip4Prefix prefix = pair.getLeft();
                 MultiPointToSinglePointIntent intent = pair.getRight();
                 if (!isElectedLeader) {
                     isActivatedLeader = false;
@@ -460,8 +467,8 @@
         synchronized (this) {
             log.debug("Processing route add: {}", routeEntry);
 
-            IpPrefix prefix = routeEntry.prefix();
-            IpAddress nextHop = null;
+            Ip4Prefix prefix = routeEntry.prefix();
+            Ip4Address nextHop = null;
             RouteEntry foundRouteEntry =
                     bgpRoutes.put(RouteEntry.createBinaryString(prefix),
                                   routeEntry);
@@ -535,8 +542,8 @@
      * @param nextHopIpAddress  IP address of the next hop
      * @param nextHopMacAddress MAC address of the next hop
      */
-    private void addRouteIntentToNextHop(IpPrefix prefix,
-                                         IpAddress nextHopIpAddress,
+    private void addRouteIntentToNextHop(Ip4Prefix prefix,
+                                         Ip4Address nextHopIpAddress,
                                          MacAddress nextHopMacAddress) {
 
         // Find the attachment point (egress interface) of the next hop
@@ -573,7 +580,7 @@
      * @param egressInterface   egress Interface connected to next hop router
      * @param nextHopMacAddress MAC address of next hop router
      */
-    private void doAddRouteIntent(IpPrefix prefix, Interface egressInterface,
+    private void doAddRouteIntent(Ip4Prefix prefix, Interface egressInterface,
                                   MacAddress nextHopMacAddress) {
         log.debug("Adding intent for prefix {}, next hop mac {}",
                   prefix, nextHopMacAddress);
@@ -634,7 +641,7 @@
     protected void processRouteDelete(RouteEntry routeEntry) {
         synchronized (this) {
             log.debug("Processing route delete: {}", routeEntry);
-            IpPrefix prefix = routeEntry.prefix();
+            Ip4Prefix prefix = routeEntry.prefix();
 
             if (bgpRoutes.remove(RouteEntry.createBinaryString(prefix))) {
                 //
@@ -659,7 +666,7 @@
     private void executeRouteDelete(RouteEntry routeEntry) {
         log.debug("Executing route delete: {}", routeEntry);
 
-        IpPrefix prefix = routeEntry.prefix();
+        Ip4Prefix prefix = routeEntry.prefix();
 
         MultiPointToSinglePointIntent intent =
                 pushedRouteIntents.remove(prefix);
@@ -685,11 +692,12 @@
      * @param ipAddress the IP address that an event was received for
      * @param macAddress the most recently known MAC address for the IP address
      */
-    private void updateMac(IpAddress ipAddress, MacAddress macAddress) {
+    private void updateMac(Ip4Address ipAddress, MacAddress macAddress) {
         log.debug("Received updated MAC info: {} => {}", ipAddress, macAddress);
 
         // TODO here we should check whether the next hop for any of our
-        // installed prefixes has changed, not just prefixes pending installation.
+        // installed prefixes has changed, not just prefixes pending
+        // installation.
 
         // We synchronize on this to prevent changes to the radix tree
         // while we're pushing intents. If the tree changes, the
@@ -701,7 +709,7 @@
 
             for (RouteEntry routeEntry : routesToPush) {
                 // These will always be adds
-                IpPrefix prefix = routeEntry.prefix();
+                Ip4Prefix prefix = routeEntry.prefix();
                 String binaryString = RouteEntry.createBinaryString(prefix);
                 RouteEntry foundRouteEntry =
                         bgpRoutes.getValueForExactKey(binaryString);
@@ -748,7 +756,7 @@
     public Collection<MultiPointToSinglePointIntent> getPushedRouteIntents() {
         List<MultiPointToSinglePointIntent> pushedIntents = new LinkedList<>();
 
-        for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry :
+        for (Map.Entry<Ip4Prefix, MultiPointToSinglePointIntent> entry :
             pushedRouteIntents.entrySet()) {
             pushedIntents.add(entry.getValue());
         }
@@ -765,7 +773,12 @@
                     event.type() == HostEvent.Type.HOST_UPDATED) {
                 Host host = event.subject();
                 for (IpAddress ip : host.ipAddresses()) {
-                    updateMac(ip, host.mac());
+                    Ip4Address ip4Address = ip.getIp4Address();
+                    if (ip4Address == null) {
+                        // TODO: For now we support only IPv4
+                        continue;
+                    }
+                    updateMac(ip4Address, host.mac());
                 }
             }
         }
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpRouteEntry.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpRouteEntry.java
index 8d48a27..cd36f72 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpRouteEntry.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpRouteEntry.java
@@ -21,8 +21,8 @@
 import java.util.Objects;
 
 import org.onlab.onos.sdnip.RouteEntry;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 
 import com.google.common.base.MoreObjects;
 
@@ -48,8 +48,8 @@
      * @param asPath the AS path
      * @param localPref the route local preference
      */
-    public BgpRouteEntry(BgpSession bgpSession, IpPrefix prefix,
-                         IpAddress nextHop, byte origin,
+    public BgpRouteEntry(BgpSession bgpSession, Ip4Prefix prefix,
+                         Ip4Address nextHop, byte origin,
                          BgpRouteEntry.AsPath asPath, long localPref) {
         super(prefix, nextHop);
         this.bgpSession = checkNotNull(bgpSession);
@@ -232,15 +232,15 @@
         }
 
         // Compare the peer BGP ID: lower is better
-        IpAddress peerBgpId = getBgpSession().getRemoteBgpId();
-        IpAddress otherPeerBgpId = other.getBgpSession().getRemoteBgpId();
+        Ip4Address peerBgpId = getBgpSession().getRemoteBgpId();
+        Ip4Address otherPeerBgpId = other.getBgpSession().getRemoteBgpId();
         if (!peerBgpId.equals(otherPeerBgpId)) {
             return (peerBgpId.compareTo(otherPeerBgpId) < 0);
         }
 
         // Compare the peer BGP address: lower is better
-        IpAddress peerAddress = getBgpSession().getRemoteIp4Address();
-        IpAddress otherPeerAddress =
+        Ip4Address peerAddress = getBgpSession().getRemoteIp4Address();
+        Ip4Address otherPeerAddress =
             other.getBgpSession().getRemoteIp4Address();
         if (!peerAddress.equals(otherPeerAddress)) {
             return (peerAddress.compareTo(otherPeerAddress) < 0);
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSession.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSession.java
index 901ac90..98477ae 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSession.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSession.java
@@ -42,8 +42,8 @@
 import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
 import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.OpenMessageError;
 import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,18 +62,18 @@
     private boolean isClosed = false;
 
     private SocketAddress remoteAddress;        // Peer IP addr/port
-    private IpAddress remoteIp4Address;        // Peer IPv4 address
+    private Ip4Address remoteIp4Address;        // Peer IPv4 address
     private int remoteBgpVersion;               // 1 octet
     private long remoteAs;                      // 2 octets
     private long remoteHoldtime;                // 2 octets
-    private IpAddress remoteBgpId;             // 4 octets -> IPv4 address
+    private Ip4Address remoteBgpId;             // 4 octets -> IPv4 address
     //
     private SocketAddress localAddress;         // Local IP addr/port
-    private IpAddress localIp4Address;         // Local IPv4 address
+    private Ip4Address localIp4Address;         // Local IPv4 address
     private int localBgpVersion;                // 1 octet
     private long localAs;                       // 2 octets
     private long localHoldtime;                 // 2 octets
-    private IpAddress localBgpId;              // 4 octets -> IPv4 address
+    private Ip4Address localBgpId;              // 4 octets -> IPv4 address
     //
     private long localKeepaliveInterval;        // Keepalive interval
 
@@ -83,7 +83,7 @@
     private volatile Timeout sessionTimeout;    // Session timeout
 
     // BGP RIB-IN routing entries from this peer
-    private ConcurrentMap<IpPrefix, BgpRouteEntry> bgpRibIn =
+    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn =
         new ConcurrentHashMap<>();
 
     /**
@@ -110,7 +110,7 @@
      * @param prefix the prefix of the route to search for
      * @return the BGP routing entry if found, otherwise null
      */
-    public BgpRouteEntry findBgpRouteEntry(IpPrefix prefix) {
+    public BgpRouteEntry findBgpRouteEntry(Ip4Prefix prefix) {
         return bgpRibIn.get(prefix);
     }
 
@@ -128,7 +128,7 @@
      *
      * @return the BGP session remote IPv4 address
      */
-    public IpAddress getRemoteIp4Address() {
+    public Ip4Address getRemoteIp4Address() {
         return remoteIp4Address;
     }
 
@@ -164,7 +164,7 @@
      *
      * @return the BGP session remote BGP Identifier as an IPv4 address
      */
-    public IpAddress getRemoteBgpId() {
+    public Ip4Address getRemoteBgpId() {
         return remoteBgpId;
     }
 
@@ -209,7 +209,7 @@
      *
      * @return the BGP session local BGP Identifier as an IPv4 address
      */
-    public IpAddress getLocalBgpId() {
+    public Ip4Address getLocalBgpId() {
         return localBgpId;
     }
 
@@ -246,13 +246,11 @@
         InetAddress inetAddr;
         if (localAddress instanceof InetSocketAddress) {
             inetAddr = ((InetSocketAddress) localAddress).getAddress();
-            localIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
-                                                inetAddr.getAddress());
+            localIp4Address = Ip4Address.valueOf(inetAddr.getAddress());
         }
         if (remoteAddress instanceof InetSocketAddress) {
             inetAddr = ((InetSocketAddress) remoteAddress).getAddress();
-            remoteIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
-                                                 inetAddr.getAddress());
+            remoteIp4Address = Ip4Address.valueOf(inetAddr.getAddress());
         }
 
         log.debug("BGP Session Connected from {} on {}",
@@ -388,7 +386,7 @@
         }
 
         // Remote BGP Identifier
-        remoteBgpId = IpAddress.valueOf((int) message.readUnsignedInt());
+        remoteBgpId = Ip4Address.valueOf((int) message.readUnsignedInt());
 
         // Optional Parameters
         int optParamLen = message.readUnsignedByte();
@@ -460,7 +458,7 @@
      */
     void processBgpUpdate(ChannelHandlerContext ctx, ChannelBuffer message) {
         Collection<BgpRouteEntry> addedRoutes = null;
-        Map<IpPrefix, BgpRouteEntry> deletedRoutes = new HashMap<>();
+        Map<Ip4Prefix, BgpRouteEntry> deletedRoutes = new HashMap<>();
 
         int minLength =
             BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
@@ -494,7 +492,7 @@
             actionsBgpUpdateMalformedAttributeList(ctx);
             return;
         }
-        Collection<IpPrefix> withdrawnPrefixes = null;
+        Collection<Ip4Prefix> withdrawnPrefixes = null;
         try {
             withdrawnPrefixes = parsePackedPrefixes(withdrawnRoutesLength,
                                                     message);
@@ -505,7 +503,7 @@
             actionsBgpUpdateInvalidNetworkField(ctx);
             return;
         }
-        for (IpPrefix prefix : withdrawnPrefixes) {
+        for (Ip4Prefix prefix : withdrawnPrefixes) {
             log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
                       remoteAddress, prefix);
             BgpRouteEntry bgpRouteEntry = bgpRibIn.get(prefix);
@@ -560,19 +558,19 @@
                                 ChannelHandlerContext ctx,
                                 ChannelBuffer message)
         throws BgpParseException {
-        Map<IpPrefix, BgpRouteEntry> addedRoutes = new HashMap<>();
+        Map<Ip4Prefix, BgpRouteEntry> addedRoutes = new HashMap<>();
 
         //
         // Parsed values
         //
         Short origin = -1;                      // Mandatory
         BgpRouteEntry.AsPath asPath = null;     // Mandatory
-        IpAddress nextHop = null;              // Mandatory
+        Ip4Address nextHop = null;              // Mandatory
         long multiExitDisc =                    // Optional
             BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
         Long localPref = null;                  // Mandatory
         Long aggregatorAsNumber = null;         // Optional: unused
-        IpAddress aggregatorIpAddress = null;  // Optional: unused
+        Ip4Address aggregatorIpAddress = null;  // Optional: unused
 
         //
         // Get and verify the Path Attributes Length
@@ -684,7 +682,7 @@
 
             case BgpConstants.Update.Aggregator.TYPE:
                 // Attribute Type Code AGGREGATOR
-                Pair<Long, IpAddress> aggregator =
+                Pair<Long, Ip4Address> aggregator =
                     parseAttributeTypeAggregator(ctx, attrTypeCode, attrLen,
                                                  attrFlags, message);
                 aggregatorAsNumber = aggregator.getLeft();
@@ -720,7 +718,7 @@
         //
         // Parse the NLRI (Network Layer Reachability Information)
         //
-        Collection<IpPrefix> addedPrefixes = null;
+        Collection<Ip4Prefix> addedPrefixes = null;
         int nlriLength = message.readableBytes();
         try {
             addedPrefixes = parsePackedPrefixes(nlriLength, message);
@@ -734,7 +732,7 @@
         }
 
         // Generate the added routes
-        for (IpPrefix prefix : addedPrefixes) {
+        for (Ip4Prefix prefix : addedPrefixes) {
             BgpRouteEntry bgpRouteEntry =
                 new BgpRouteEntry(this, prefix, nextHop,
                                   origin.byteValue(), asPath, localPref);
@@ -768,7 +766,7 @@
                         ChannelHandlerContext ctx,
                         Short origin,
                         BgpRouteEntry.AsPath asPath,
-                        IpAddress nextHop,
+                        Ip4Address nextHop,
                         Long localPref)
         throws BgpParseException {
         //
@@ -1025,7 +1023,7 @@
      * @return the parsed NEXT_HOP value
      * @throws BgpParseException
      */
-    private IpAddress parseAttributeTypeNextHop(
+    private Ip4Address parseAttributeTypeNextHop(
                         ChannelHandlerContext ctx,
                         int attrTypeCode,
                         int attrLen,
@@ -1043,8 +1041,8 @@
         }
 
         message.markReaderIndex();
-        long address = message.readUnsignedInt();
-        IpAddress nextHopAddress = IpAddress.valueOf((int) address);
+        Ip4Address nextHopAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
         //
         // Check whether the NEXT_HOP IP address is semantically correct.
         // As per RFC 4271, Section 6.3:
@@ -1173,7 +1171,7 @@
      * @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address>
      * @throws BgpParseException
      */
-    private Pair<Long, IpAddress> parseAttributeTypeAggregator(
+    private Pair<Long, Ip4Address> parseAttributeTypeAggregator(
                         ChannelHandlerContext ctx,
                         int attrTypeCode,
                         int attrLen,
@@ -1193,11 +1191,10 @@
         // The AGGREGATOR AS number
         long aggregatorAsNumber = message.readUnsignedShort();
         // The AGGREGATOR IP address
-        long aggregatorAddress = message.readUnsignedInt();
-        IpAddress aggregatorIpAddress =
-                IpAddress.valueOf((int) aggregatorAddress);
+        Ip4Address aggregatorIpAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
 
-        Pair<Long, IpAddress> aggregator = Pair.of(aggregatorAsNumber,
+        Pair<Long, Ip4Address> aggregator = Pair.of(aggregatorAsNumber,
                                                     aggregatorIpAddress);
         return aggregator;
     }
@@ -1215,10 +1212,10 @@
      * @return a collection of parsed IPv4 network prefixes
      * @throws BgpParseException
      */
-    private Collection<IpPrefix> parsePackedPrefixes(int totalLength,
+    private Collection<Ip4Prefix> parsePackedPrefixes(int totalLength,
                                                       ChannelBuffer message)
         throws BgpParseException {
-        Collection<IpPrefix> result = new ArrayList<>();
+        Collection<Ip4Prefix> result = new ArrayList<>();
 
         if (totalLength == 0) {
             return result;
@@ -1242,9 +1239,9 @@
                 prefixBytelen--;
             }
             address <<= extraShift;
-            IpPrefix prefix =
-                IpPrefix.valueOf(IpAddress.valueOf((int) address),
-                                 prefixBitlen);
+            Ip4Prefix prefix =
+                Ip4Prefix.valueOf(Ip4Address.valueOf((int) address),
+                                  prefixBitlen);
             result.add(prefix);
         }
 
@@ -1413,7 +1410,7 @@
                         int attrLen,
                         int attrFlags,
                         ChannelBuffer message,
-                        IpAddress nextHop) {
+                        Ip4Address nextHop) {
         log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}",
                   remoteAddress, nextHop);
 
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSessionManager.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSessionManager.java
index 247c95f..8b5ed41 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSessionManager.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/bgp/BgpSessionManager.java
@@ -35,8 +35,8 @@
 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
 import org.onlab.onos.sdnip.RouteListener;
 import org.onlab.onos.sdnip.RouteUpdate;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,10 +49,10 @@
     private Channel serverChannel;     // Listener for incoming BGP connections
     private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
         new ConcurrentHashMap<>();
-    private IpAddress myBgpId;         // Same BGP ID for all peers
+    private Ip4Address myBgpId;        // Same BGP ID for all peers
 
     private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector();
-    private ConcurrentMap<IpPrefix, BgpRouteEntry> bgpRoutes =
+    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes =
         new ConcurrentHashMap<>();
 
     private final RouteListener routeListener;
@@ -105,8 +105,7 @@
         if (bgpSession.getLocalAddress() instanceof InetSocketAddress) {
             InetAddress inetAddr =
                 ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress();
-            IpAddress ip4Address = IpAddress.valueOf(IpAddress.Version.INET,
-                                                     inetAddr.getAddress());
+            Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
             updateMyBgpId(ip4Address);
         }
         return true;
@@ -128,7 +127,7 @@
      *
      * @param ip4Address the IPv4 address to use as BGP ID
      */
-    private synchronized void updateMyBgpId(IpAddress ip4Address) {
+    private synchronized void updateMyBgpId(Ip4Address ip4Address) {
         if (myBgpId == null) {
             myBgpId = ip4Address;
             log.debug("BGP: My BGP ID is {}", myBgpId);
@@ -140,7 +139,7 @@
      *
      * @return the local BGP Identifier as an IPv4 address
      */
-    IpAddress getMyBgpId() {
+    Ip4Address getMyBgpId() {
         return myBgpId;
     }
 
@@ -352,7 +351,7 @@
          * @param prefix the prefix of the route
          * @return the best route if found, otherwise null
          */
-        private BgpRouteEntry findBestBgpRoute(IpPrefix prefix) {
+        private BgpRouteEntry findBestBgpRoute(Ip4Prefix prefix) {
             BgpRouteEntry bestRoute = null;
 
             // Iterate across all BGP Sessions and select the best route