ONOS core changes for RIP support
Change-Id: I5aa22ed6509d99af22d7cb80944bc3a4c26b5257
diff --git a/apps/routing/fpm/app/src/main/java/org/onosproject/routing/fpm/FpmManager.java b/apps/routing/fpm/app/src/main/java/org/onosproject/routing/fpm/FpmManager.java
index abb8ddd..42ce4e2 100644
--- a/apps/routing/fpm/app/src/main/java/org/onosproject/routing/fpm/FpmManager.java
+++ b/apps/routing/fpm/app/src/main/java/org/onosproject/routing/fpm/FpmManager.java
@@ -86,6 +86,8 @@
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -166,11 +168,11 @@
@Property(name = "pdPushNextHopIPv4", value = "",
label = "IPv4 next-hop address for PD Pushing.")
- private Ip4Address pdPushNextHopIPv4 = null;
+ private List<Ip4Address> pdPushNextHopIPv4 = null;
@Property(name = "pdPushNextHopIPv6", value = "",
label = "IPv6 next-hop address for PD Pushing.")
- private Ip6Address pdPushNextHopIPv6 = null;
+ private List<Ip6Address> pdPushNextHopIPv6 = null;
protected void bindRipStore(FpmPrefixStore store) {
if ((ripStore == null) && (store != null)) {
@@ -253,6 +255,8 @@
@Modified
protected void modified(ComponentContext context) {
+ Ip4Address rurIPv4Address;
+ Ip6Address rurIPv6Address;
Dictionary<?, ?> properties = context.getProperties();
if (properties == null) {
return;
@@ -269,20 +273,28 @@
pdPushEnabled = Boolean.parseBoolean(strPdPushEnabled);
if (pdPushEnabled) {
- pdPushNextHopIPv4 = null;
- pdPushNextHopIPv6 = null;
+ pdPushNextHopIPv4 = new ArrayList<Ip4Address>();
+ pdPushNextHopIPv6 = new ArrayList<Ip6Address>();
String strPdPushNextHopIPv4 = Tools.get(properties, "pdPushNextHopIPv4");
if (strPdPushNextHopIPv4 != null) {
- pdPushNextHopIPv4 = Ip4Address.valueOf(strPdPushNextHopIPv4);
+ List<String> strPdPushNextHopIPv4List = Arrays.asList(strPdPushNextHopIPv4.split(","));
+ for (String nextHop : strPdPushNextHopIPv4List) {
+ log.debug("IPv4 next hop added is:" + nextHop);
+ pdPushNextHopIPv4.add(Ip4Address.valueOf(nextHop));
+ }
}
String strPdPushNextHopIPv6 = Tools.get(properties, "pdPushNextHopIPv6");
if (strPdPushNextHopIPv6 != null) {
- pdPushNextHopIPv6 = Ip6Address.valueOf(strPdPushNextHopIPv6);
+ List<String> strPdPushNextHopIPv6List = Arrays.asList(strPdPushNextHopIPv6.split(","));
+ for (String nextHop : strPdPushNextHopIPv6List) {
+ log.debug("IPv6 next hop added is:" + nextHop);
+ pdPushNextHopIPv6.add(Ip6Address.valueOf(nextHop));
+ }
}
- if (pdPushNextHopIPv4 == null) {
- pdPushNextHopIPv4 = interfaceService.getInterfaces()
+ if (pdPushNextHopIPv4 == null || pdPushNextHopIPv4.size() == 0) {
+ rurIPv4Address = interfaceService.getInterfaces()
.stream()
.filter(iface -> iface.name().contains("RUR"))
.map(Interface::ipAddressesList)
@@ -292,10 +304,14 @@
.map(IpAddress::getIp4Address)
.findFirst()
.orElse(null);
+ if (rurIPv4Address != null) {
+ pdPushNextHopIPv4.add(rurIPv4Address);
+ }
+
}
if (pdPushNextHopIPv6 == null) {
- pdPushNextHopIPv6 = interfaceService.getInterfaces()
+ rurIPv6Address = interfaceService.getInterfaces()
.stream()
.filter(iface -> iface.name().contains("RUR"))
.map(Interface::ipAddressesList)
@@ -305,22 +321,24 @@
.map(IpAddress::getIp6Address)
.findFirst()
.orElse(null);
+ if (rurIPv6Address != null) {
+ pdPushNextHopIPv6.add(rurIPv6Address);
+ }
}
log.info("PD pushing is enabled.");
- if (pdPushNextHopIPv4 != null) {
- log.info("ipv4 next-hop {}", pdPushNextHopIPv4.toString());
+ if (pdPushNextHopIPv4 != null || pdPushNextHopIPv4.size() != 0) {
+ log.info("ipv4 next-hop {} with {} items", pdPushNextHopIPv4.toString(), pdPushNextHopIPv4.size());
+
} else {
log.info("ipv4 next-hop is null");
}
- if (pdPushNextHopIPv6 != null) {
- log.info("ipv6 next-hop={}", pdPushNextHopIPv6.toString());
+ if (pdPushNextHopIPv6 != null || pdPushNextHopIPv6.size() != 0) {
+ log.info("ipv6 next-hop={} with {} items", pdPushNextHopIPv6.toString(), pdPushNextHopIPv6.size());
} else {
log.info("ipv6 next-hop is null");
}
- if (!oldValue) {
- processStaticRoutes();
- }
+ processStaticRoutes();
} else {
log.info("PD pushing is disabled.");
}
@@ -497,6 +515,7 @@
}
public void processStaticRoutes() {
+ log.debug("processStaticRoutes function is called");
for (Channel ch : allChannels) {
processStaticRoutes(ch);
}
@@ -531,74 +550,47 @@
}
}
- private void sendRouteUpdateToChannel(boolean isAdd, IpPrefix prefix, Channel ch) {
-
- if (!pdPushEnabled) {
- return;
- }
-
+ private void updateRoute(IpAddress pdPushNextHop, boolean isAdd, IpPrefix prefix,
+ Channel ch, int raLength, short addrFamily) {
try {
- int raLength;
- short addrFamily;
- IpAddress pdPushNextHop;
-
- // Build route attributes.
- if (prefix.isIp4()) {
- if (pdPushNextHopIPv4 == null) {
- log.info("Prefix not pushed because ipv4 next-hop is null.");
- return;
- }
- pdPushNextHop = pdPushNextHopIPv4;
- raLength = Ip4Address.BYTE_LENGTH + RouteAttribute.ROUTE_ATTRIBUTE_HEADER_LENGTH;
- addrFamily = RtNetlink.RT_ADDRESS_FAMILY_INET;
- } else {
- if (pdPushNextHopIPv6 == null) {
- log.info("Prefix not pushed because ipv6 next-hop is null.");
- return;
- }
- pdPushNextHop = pdPushNextHopIPv6;
- raLength = Ip6Address.BYTE_LENGTH + RouteAttribute.ROUTE_ATTRIBUTE_HEADER_LENGTH;
- addrFamily = RtNetlink.RT_ADDRESS_FAMILY_INET6;
- }
-
- RouteAttributeDst raDst = RouteAttributeDst.builder()
- .length(raLength)
- .type(RouteAttribute.RTA_DST)
- .dstAddress(prefix.address())
- .build();
+ RouteAttributeDst raDst = RouteAttributeDst.builder()
+ .length(raLength)
+ .type(RouteAttribute.RTA_DST)
+ .dstAddress(prefix.address())
+ .build();
RouteAttributeGateway raGateway = RouteAttributeGateway.builder()
- .length(raLength)
- .type(RouteAttribute.RTA_GATEWAY)
- .gateway(pdPushNextHop)
- .build();
+ .length(raLength)
+ .type(RouteAttribute.RTA_GATEWAY)
+ .gateway(pdPushNextHop)
+ .build();
// Build RtNetlink.
RtNetlink rtNetlink = RtNetlink.builder()
- .addressFamily(addrFamily)
- .dstLength(prefix.prefixLength())
- .routeAttribute(raDst)
- .routeAttribute(raGateway)
- .build();
+ .addressFamily(addrFamily)
+ .dstLength(prefix.prefixLength())
+ .routeAttribute(raDst)
+ .routeAttribute(raGateway)
+ .build();
// Build Netlink.
int messageLength = raDst.length() + raGateway.length() +
- RtNetlink.RT_NETLINK_LENGTH + Netlink.NETLINK_HEADER_LENGTH;
+ RtNetlink.RT_NETLINK_LENGTH + Netlink.NETLINK_HEADER_LENGTH;
Netlink netLink = Netlink.builder()
- .length(messageLength)
- .type(isAdd ? NetlinkMessageType.RTM_NEWROUTE : NetlinkMessageType.RTM_DELROUTE)
- .flags(Netlink.NETLINK_REQUEST | Netlink.NETLINK_CREATE)
- .rtNetlink(rtNetlink)
- .build();
+ .length(messageLength)
+ .type(isAdd ? NetlinkMessageType.RTM_NEWROUTE : NetlinkMessageType.RTM_DELROUTE)
+ .flags(Netlink.NETLINK_REQUEST | Netlink.NETLINK_CREATE)
+ .rtNetlink(rtNetlink)
+ .build();
// Build FpmHeader.
messageLength += FpmHeader.FPM_HEADER_LENGTH;
FpmHeader fpmMessage = FpmHeader.builder()
- .version(FpmHeader.FPM_VERSION_1)
- .type(FpmHeader.FPM_TYPE_NETLINK)
- .length(messageLength)
- .netlink(netLink)
- .build();
+ .version(FpmHeader.FPM_VERSION_1)
+ .type(FpmHeader.FPM_TYPE_NETLINK)
+ .length(messageLength)
+ .netlink(netLink)
+ .build();
// Encode message in a channel buffer and transmit.
ch.write(fpmMessage.encode());
@@ -608,6 +600,44 @@
}
}
+ private void sendRouteUpdateToChannel(boolean isAdd, IpPrefix prefix, Channel ch) {
+
+ if (!pdPushEnabled) {
+ return;
+ }
+ int raLength;
+ short addrFamily;
+
+ // Build route attributes.
+ if (prefix.isIp4()) {
+ List<Ip4Address> pdPushNextHopList;
+ if (pdPushNextHopIPv4 == null || pdPushNextHopIPv4.size() == 0) {
+ log.info("Prefix not pushed because ipv4 next-hop is null.");
+ return;
+ }
+ pdPushNextHopList = pdPushNextHopIPv4;
+ raLength = Ip4Address.BYTE_LENGTH + RouteAttribute.ROUTE_ATTRIBUTE_HEADER_LENGTH;
+ addrFamily = RtNetlink.RT_ADDRESS_FAMILY_INET;
+ for (Ip4Address pdPushNextHop: pdPushNextHopList) {
+ log.debug("IPv4 next hop is:" + pdPushNextHop);
+ updateRoute(pdPushNextHop, isAdd, prefix, ch, raLength, addrFamily);
+ }
+ } else {
+ List<Ip6Address> pdPushNextHopList;
+ if (pdPushNextHopIPv6 == null || pdPushNextHopIPv6.size() == 0) {
+ log.info("Prefix not pushed because ipv6 next-hop is null.");
+ return;
+ }
+ pdPushNextHopList = pdPushNextHopIPv6;
+ raLength = Ip6Address.BYTE_LENGTH + RouteAttribute.ROUTE_ATTRIBUTE_HEADER_LENGTH;
+ addrFamily = RtNetlink.RT_ADDRESS_FAMILY_INET6;
+ for (Ip6Address pdPushNextHop: pdPushNextHopList) {
+ log.debug("IPv6 next hop is:" + pdPushNextHop);
+ updateRoute(pdPushNextHop, isAdd, prefix, ch, raLength, addrFamily);
+ }
+ }
+ }
+
private void sendRouteUpdate(boolean isAdd, IpPrefix prefix) {
for (Channel ch : allChannels) {
diff --git a/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java b/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java
index ecddc3a..085ecfc 100644
--- a/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java
+++ b/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java
@@ -45,6 +45,12 @@
Ip6Address.valueOf("ff05::1:3");
/**
+ * All RIP routers multicast group. (RFC 2080)
+ */
+ public static final Ip6Address ALL_RIP_ROUTERS =
+ Ip6Address.valueOf("ff02::9");
+
+ /**
* All-zero unspecified IPv6 address.
*/
public static final Ip6Address ZERO = Ip6Address.valueOf("::");