Search in sources :

Example 1 with MsgType

use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.

the class Dhcp6HandlerImpl method timeTick.

/**
 * Find lease-expired ipaddresses and pd prefixes.
 * Removing host/route/fpm entries.
 */
public void timeTick() {
    long currentTime = System.currentTimeMillis();
    Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
    log.debug("timeTick called currenttime {} records num {} ", currentTime, records.size());
    records.forEach(record -> {
        boolean addrOrPdRemoved = false;
        DHCP6.MsgType ip6Status = record.ip6Status().orElse(null);
        if (ip6Status == null) {
            log.debug("record is not valid v6 record.");
            return;
        }
        if ((currentTime - record.getLastIp6Update()) > ((record.addrPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
            // remove ipaddress from host/route table
            IpAddress ip = record.ip6Address().orElse(null);
            if (ip != null) {
                if (record.directlyConnected()) {
                    providerService.removeIpFromHost(HostId.hostId(record.macAddress(), record.vlanId()), ip);
                } else {
                    MacAddress gwMac = record.nextHop().orElse(null);
                    if (gwMac == null) {
                        log.warn("Can't find gateway mac address from record {} for ip6Addr", record);
                        return;
                    }
                    IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(), gwMac, record.vlanId());
                    Route route = new Route(Route.Source.DHCP, ip.toIpPrefix(), nextHopIp);
                    routeStore.removeRoute(route);
                }
                record.updateAddrPrefTime(0);
                record.ip6Address(null);
                addrOrPdRemoved = true;
                dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
                log.warn("IP6 address is set to null. delta {} lastUpdate {} addrPrefTime {}", (currentTime - record.getLastIp6Update()), record.getLastIp6Update(), record.addrPrefTime());
            }
        }
        if ((currentTime - record.getLastPdUpdate()) > ((record.pdPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
            // remove PD from route/fpm table
            IpPrefix pdIpPrefix = record.pdPrefix().orElse(null);
            if (pdIpPrefix != null) {
                if (record.directlyConnected()) {
                    providerService.removeIpFromHost(HostId.hostId(record.macAddress(), record.vlanId()), pdIpPrefix.address().getIp6Address());
                } else {
                    MacAddress gwMac = record.nextHop().orElse(null);
                    if (gwMac == null) {
                        log.warn("Can't find gateway mac address from record {} for PD prefix", record);
                        return;
                    }
                    IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(), gwMac, record.vlanId());
                    Route route = new Route(Route.Source.DHCP, pdIpPrefix, nextHopIp);
                    routeStore.removeRoute(route);
                    if (this.dhcpFpmEnabled) {
                        dhcpFpmPrefixStore.removeFpmRecord(pdIpPrefix);
                    }
                }
                record.updatePdPrefTime(0);
                record.pdPrefix(null);
                addrOrPdRemoved = true;
                dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
                log.warn("PD prefix is set to null.delta {} pdPrefTime {}", (currentTime - record.getLastPdUpdate()), record.pdPrefTime());
            }
        }
        if (addrOrPdRemoved && !record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
            log.warn("ip6Status {} IP6 address and IP6 PD both are null. Remove record.", ip6Status);
            dhcpRelayStore.removeDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()));
        }
    });
}
Also used : IpPrefix(org.onlab.packet.IpPrefix) DhcpRecord(org.onosproject.dhcprelay.store.DhcpRecord) MsgType(org.onlab.packet.DHCP6.MsgType) DHCP6(org.onlab.packet.DHCP6) IpAddress(org.onlab.packet.IpAddress) MacAddress(org.onlab.packet.MacAddress) Route(org.onosproject.routeservice.Route)

Example 2 with MsgType

use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.

the class Dhcp6HandlerUtil method isDhcp6Reply.

/**
 * check if DHCP6 relay-reply is reply.
 *
 * @param relayPacket dhcp6 relay-reply
 * @return boolean relay-reply contains ack
 */
public static boolean isDhcp6Reply(DHCP6 relayPacket) {
    DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
    if (leafDhcp6 != null) {
        if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
            log.debug("isDhcp6Reply  true.");
            // must be directly connected
            return true;
        } else {
            log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
        }
    } else {
        log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
    }
    log.debug("isDhcp6Reply  false.");
    return false;
}
Also used : DHCP6(org.onlab.packet.DHCP6)

Example 3 with MsgType

use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.

the class Dhcp6HandlerUtil method directlyConnected.

/**
 * Check if the host is directly connected to the network or not.
 *
 * @param dhcp6Payload the dhcp6 payload
 * @return true if the host is directly connected to the network; false otherwise
 */
public static boolean directlyConnected(DHCP6 dhcp6Payload) {
    log.debug("directlyConnected enters");
    if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() || dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
        log.debug("directlyConnected false. MsgType {}", dhcp6Payload.getMsgType());
        return false;
    }
    if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() && dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
        log.debug("directlyConnected true. MsgType {}", dhcp6Payload.getMsgType());
        return true;
    }
    // Regardless of relay-forward or relay-replay, check if we see another relay message
    DHCP6 dhcp6Payload2 = dhcp6PacketFromRelayPacket(dhcp6Payload);
    if (dhcp6Payload2 != null) {
        if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELAY_FORW.value()) {
            log.debug("directlyConnected  false. 1st relay-forward, 2nd MsgType {}", dhcp6Payload2.getMsgType());
            return false;
        } else {
            // relay-reply
            if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value() && dhcp6Payload2.getMsgType() != MsgType.LEASEQUERY_REPLY.value()) {
                log.debug("directlyConnected  true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
                // must be directly connected
                return true;
            } else {
                log.debug("directlyConnected  false. 1st relay-reply, 2nd relay-reply MsgType {}", dhcp6Payload2.getMsgType());
                // must be indirectly connected
                return false;
            }
        }
    } else {
        log.debug("directlyConnected  true.");
        return true;
    }
}
Also used : DHCP6(org.onlab.packet.DHCP6)

Example 4 with MsgType

use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.

the class Dhcp6HandlerImpl method addHostOrRoute.

/**
 * add host or route and update dhcp relay record.
 *
 * @param directConnFlag  flag to show that packet is from directly connected client
 * @param location  client side connect point
 * @param dhcp6Relay the dhcp6 payload
 * @param embeddedDhcp6 the dhcp6 payload within relay
 * @param srcMac client gw/host macAddress
 * @param clientInterface client interface
 * @param vlanIdInUse vlanid encoded in the interface id Option
 */
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay, DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface, VlanId vlanIdInUse) {
    log.debug("addHostOrRoute entered.");
    VlanId vlanId;
    if (clientInterface.vlanTagged().isEmpty()) {
        vlanId = clientInterface.vlan();
    } else {
        // might be multiple vlan in same interface
        vlanId = vlanIdInUse;
    }
    if (vlanId == null) {
        vlanId = VlanId.NONE;
    }
    Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
    MacAddress leafClientMac;
    Byte leafMsgType;
    Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, embeddedDhcp6);
    if (clientIdOption != null) {
        log.debug("CLIENTID option found {}", clientIdOption);
        if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) || (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
            leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
        } else {
            log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
            // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
            return;
        }
    } else {
        log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
        // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
        return;
    }
    HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
    DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
    if (record == null) {
        record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
    } else {
        record = record.clone();
    }
    IpAddressInfo ipInfo;
    PdPrefixInfo pdInfo = null;
    if (directConnFlag) {
        // Add to host store if it connect to network directly
        ipInfo = extractIpAddress(embeddedDhcp6);
        if (ipInfo != null) {
            if (isMsgReply) {
                Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
                HostId hostId = HostId.hostId(srcMac, vlanId);
                Host host = hostService.getHost(hostId);
                HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(), System.currentTimeMillis());
                Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
                if (host != null) {
                    // Dual homing support:
                    // if host exists, use old locations and new location
                    hostLocations.addAll(host.locations());
                }
                HostDescription desc = new DefaultHostDescription(srcMac, vlanId, hostLocations, ips, false);
                log.debug("adding Host for directly connected.");
                log.debug("client mac {} client vlan {} hostlocation {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
                // Replace the ip when dhcp server give the host new ip address
                providerService.hostDetected(hostId, desc, false);
            }
        } else {
            log.warn("ipAddress not found. Do not add Host {} for directly connected.", HostId.hostId(srcMac, vlanId).toString());
        }
        leafMsgType = embeddedDhcp6.getMsgType();
    } else {
        // Add to route store if it does not connect to network directly
        // pick out the first link-local ip address
        IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
        if (nextHopIp == null) {
            log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
            // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
            return;
        }
        DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
        ipInfo = extractIpAddress(leafDhcp);
        if (ipInfo == null) {
            log.debug("ip is null");
        } else {
            if (isMsgReply) {
                Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
                log.debug("adding Route of 128 address for indirectly connected.");
                routeStore.replaceRoute(routeForIP);
            }
        }
        pdInfo = extractPrefix(leafDhcp);
        if (pdInfo == null) {
            log.debug("ipPrefix is null ");
        } else {
            if (isMsgReply) {
                Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
                log.debug("adding Route of PD for indirectly connected.");
                routeStore.replaceRoute(routeForPrefix);
                if (this.dhcpFpmEnabled) {
                    FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
                    dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
                }
            }
        }
        leafMsgType = leafDhcp.getMsgType();
    }
    if (leafMsgType == DHCP6.MsgType.RELEASE.value() || (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
        log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
    // return;
    }
    record.addLocation(new HostLocation(location, System.currentTimeMillis()));
    if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
        if (ipInfo != null) {
            log.debug("IP6 address is being stored into dhcp-relay store.");
            log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
            record.ip6Address(ipInfo.ip6Address);
            record.updateAddrPrefTime(ipInfo.prefTime);
            record.updateLastIp6Update();
        } else {
            log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
        }
        if (pdInfo != null) {
            log.debug("IP6 PD address {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
            record.pdPrefix(pdInfo.pdPrefix);
            record.updatePdPrefTime(pdInfo.prefTime);
            record.updateLastPdUpdate();
        } else {
            log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
        }
    }
    record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
    record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
    record.setDirectlyConnected(directConnFlag);
    record.updateLastSeen();
    dhcpRelayStore.updateDhcpRecord(leafHostId, record);
/*
        // TODO Use AtomicInteger for the counters
        try {
            recordSemaphore.acquire();
            try {
                dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
            } finally {
                // calling release() after a successful acquire()
                recordSemaphore.release();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        */
}
Also used : DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) DhcpRecord(org.onosproject.dhcprelay.store.DhcpRecord) Host(org.onosproject.net.Host) MacAddress(org.onlab.packet.MacAddress) HostId(org.onosproject.net.HostId) HostDescription(org.onosproject.net.host.HostDescription) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) HostLocation(org.onosproject.net.HostLocation) FpmRecord(org.onosproject.routing.fpm.api.FpmRecord) IpAddress(org.onlab.packet.IpAddress) DHCP6(org.onlab.packet.DHCP6) VlanId(org.onlab.packet.VlanId) Route(org.onosproject.routeservice.Route) Dhcp6ClientIdOption(org.onlab.packet.dhcp.Dhcp6ClientIdOption)

Example 5 with MsgType

use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.

the class Dhcp6HandlerImpl method processDhcpPacket.

@Override
public void processDhcpPacket(PacketContext context, BasePacket payload) {
    checkNotNull(payload, "DHCP6 payload can't be null");
    checkState(payload instanceof DHCP6, "Payload is not a DHCP6");
    DHCP6 dhcp6Payload = (DHCP6) payload;
    Ethernet receivedPacket = context.inPacket().parsed();
    if (!configured()) {
        log.warn("Missing DHCP6 relay server config. " + "Abort packet processing dhcp6 payload {}", dhcp6Payload);
        return;
    }
    byte msgTypeVal = dhcp6Payload.getMsgType();
    MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
    log.debug("msgType is {}", msgType);
    ConnectPoint inPort = context.inPacket().receivedFrom();
    if (inPort == null) {
        log.warn("incoming ConnectPoint is null");
    }
    Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
    // ignore the packets if dhcp client interface is not configured on onos.
    if (receivingInterfaces.isEmpty()) {
        log.warn("Virtual interface is not configured on {}", inPort);
        return;
    }
    if (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
        List<InternalPacket> ethernetClientPackets = learnRouteFromLeasequery ? processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload) : processDhcp6ForwardOnly(context, receivedPacket, receivingInterfaces, dhcp6Payload);
        for (InternalPacket internalPacket : ethernetClientPackets) {
            forwardPacket(internalPacket);
        }
    } else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value() && learnRouteFromLeasequery) {
        IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
        UDP clientUdp = (UDP) clientIpv6.getPayload();
        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
        Interface serverInterface = Dhcp6HandlerUtil.directlyConnected(clientDhcp6) ? getServerInterface() : getIndirectServerInterface();
        InternalPacket ethernetPacketReply = Dhcp6HandlerUtil.processLQ6PacketFromServer(defaultServerInfoList, indirectServerInfoList, serverInterface, interfaceService, hostService, context, receivedPacket, receivingInterfaces);
        if (ethernetPacketReply != null) {
            forwardPacket(ethernetPacketReply);
        }
        handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
    } else if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
        List<InternalPacket> ethernetClientPacket = processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
        for (InternalPacket internalPacket : ethernetClientPacket) {
            forwardPacket(internalPacket);
        }
    } else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
        log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}, {}", receivedPacket, dhcp6Payload);
        InternalPacket ethernetPacketReply = processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
        if (ethernetPacketReply != null) {
            forwardPacket(ethernetPacketReply);
        }
    } else {
        log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
    }
}
Also used : UDP(org.onlab.packet.UDP) IPv6(org.onlab.packet.IPv6) Ethernet(org.onlab.packet.Ethernet) DHCP6(org.onlab.packet.DHCP6) MsgType(org.onlab.packet.DHCP6.MsgType) ConnectPoint(org.onosproject.net.ConnectPoint) Interface(org.onosproject.net.intf.Interface)

Aggregations

DHCP6 (org.onlab.packet.DHCP6)6 MsgType (org.onlab.packet.DHCP6.MsgType)2 IpAddress (org.onlab.packet.IpAddress)2 MacAddress (org.onlab.packet.MacAddress)2 DhcpRecord (org.onosproject.dhcprelay.store.DhcpRecord)2 Route (org.onosproject.routeservice.Route)2 Ethernet (org.onlab.packet.Ethernet)1 IPv6 (org.onlab.packet.IPv6)1 IpPrefix (org.onlab.packet.IpPrefix)1 UDP (org.onlab.packet.UDP)1 VlanId (org.onlab.packet.VlanId)1 Dhcp6ClientIdOption (org.onlab.packet.dhcp.Dhcp6ClientIdOption)1 ConnectPoint (org.onosproject.net.ConnectPoint)1 Host (org.onosproject.net.Host)1 HostId (org.onosproject.net.HostId)1 HostLocation (org.onosproject.net.HostLocation)1 DefaultHostDescription (org.onosproject.net.host.DefaultHostDescription)1 HostDescription (org.onosproject.net.host.HostDescription)1 Interface (org.onosproject.net.intf.Interface)1 FpmRecord (org.onosproject.routing.fpm.api.FpmRecord)1