use of org.onosproject.routing.fpm.protocol.Netlink in project onos by opennetworkinglab.
the class FpmManager method fpmMessage.
private void fpmMessage(FpmPeer peer, FpmHeader fpmMessage) {
if (fpmMessage.type() == FpmHeader.FPM_TYPE_KEEPALIVE) {
return;
}
Netlink netlink = fpmMessage.netlink();
RtNetlink rtNetlink = netlink.rtNetlink();
if (log.isTraceEnabled()) {
log.trace("Received FPM message: {}", fpmMessage);
}
if (!(rtNetlink.protocol() == RtProtocol.ZEBRA || rtNetlink.protocol() == RtProtocol.UNSPEC)) {
log.trace("Ignoring non-zebra route");
return;
}
IpAddress dstAddress = null;
IpAddress gateway = null;
for (RouteAttribute attribute : rtNetlink.attributes()) {
if (attribute.type() == RouteAttribute.RTA_DST) {
RouteAttributeDst raDst = (RouteAttributeDst) attribute;
dstAddress = raDst.dstAddress();
} else if (attribute.type() == RouteAttribute.RTA_GATEWAY) {
RouteAttributeGateway raGateway = (RouteAttributeGateway) attribute;
gateway = raGateway.gateway();
}
}
if (dstAddress == null) {
log.error("Dst address missing!");
return;
}
IpPrefix prefix = IpPrefix.valueOf(dstAddress, rtNetlink.dstLength());
// Ignore routes that we sent.
if (gateway != null && ((prefix.isIp4() && pdPushNextHopIPv4 != null && pdPushNextHopIPv4.contains(gateway.getIp4Address())) || (prefix.isIp6() && pdPushNextHopIPv6 != null && pdPushNextHopIPv6.contains(gateway.getIp6Address())))) {
if (routeInDhcpStore(prefix) || routeInRipStore(prefix)) {
return;
}
}
List<Route> updates = new LinkedList<>();
List<Route> withdraws = new LinkedList<>();
Route route;
switch(netlink.type()) {
case RTM_NEWROUTE:
if (gateway == null) {
// We ignore interface routes with no gateway for now.
return;
}
route = new Route(Route.Source.FPM, prefix, gateway, clusterService.getLocalNode().id());
Route oldRoute = fpmRoutes.get(peer).put(prefix, route);
if (oldRoute != null) {
log.trace("Swapping {} with {}", oldRoute, route);
withdraws.add(oldRoute);
}
updates.add(route);
break;
case RTM_DELROUTE:
Route existing = fpmRoutes.get(peer).remove(prefix);
if (existing == null) {
log.warn("Got delete for non-existent prefix");
return;
}
route = new Route(Route.Source.FPM, prefix, existing.nextHop(), clusterService.getLocalNode().id());
withdraws.add(route);
break;
case RTM_GETROUTE:
default:
break;
}
updateRouteStore(updates, withdraws);
}
use of org.onosproject.routing.fpm.protocol.Netlink in project onos by opennetworkinglab.
the class FpmManager method updateRoute.
private void updateRoute(IpAddress pdPushNextHop, boolean isAdd, IpPrefix prefix, Channel ch, int raLength, short addrFamily) {
try {
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();
// Build RtNetlink.
RtNetlink rtNetlink = RtNetlink.builder().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;
Netlink netLink = Netlink.builder().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();
// Encode message in a channel buffer and transmit.
ch.write(fpmMessage.encode());
log.debug("Fpm Message for updated route {}", fpmMessage.toString());
} catch (RuntimeException e) {
log.info("Route not sent over fpm connection.");
}
}
Aggregations