<commit_before>/*
 * Copyright (c) 2013 Big Switch Networks, Inc.
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the
 * "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package org.sdnplatform.linkdiscovery;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;


import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
import org.openflow.util.HexString;
import org.sdnplatform.core.IInfoProvider;
import org.sdnplatform.core.IOFMessageListener;
import org.sdnplatform.core.IOFSwitch;
import org.sdnplatform.core.IOFSwitchListener;
import org.sdnplatform.core.module.ModuleContext;
import org.sdnplatform.core.module.IModule;
import org.sdnplatform.linkdiscovery.ILinkDiscovery.LDUpdate;
import org.sdnplatform.linkdiscovery.ILinkDiscovery.UpdateOperation;
import org.sdnplatform.linkdiscovery.internal.LinkDiscoveryManager;
import org.sdnplatform.packet.IPv4;
import org.sdnplatform.packet.LLDPTLV;
import org.sdnplatform.routing.Link;
import org.sdnplatform.storage.IStorageSourceListener;
import org.sdnplatform.tunnelmanager.ITunnelManagerService;
import org.sdnplatform.vendor.OFActionMirror;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class BetterLinkDiscoveryManager extends LinkDiscoveryManager
implements IOFMessageListener, IOFSwitchListener,
IStorageSourceListener, ILinkDiscoveryService,
IModule, IInfoProvider {
    protected static Logger log =
            LoggerFactory.getLogger(BetterLinkDiscoveryManager.class);

    ITunnelManagerService tunnelManager;

    @Override
    public void startUp(ModuleContext context) {
        super.startUp(context);
    }

    @Override
    public void init (ModuleContext context) {

        try {
            // set the default value to true.
            AUTOPORTFAST_DEFAULT = true;
            super.init(context);
            tunnelManager = context.getServiceImpl(ITunnelManagerService.class);
        } catch (Exception e) {
            log.warn("{}", e);
        }
    }

    /**
     * This method should ideally be in OFSwitchImpl that should be
     * overridden when sub-classing.  This way, every switch can
     * implement their own versions of identifying a tunnel port
     * if they are indeed different
     */
    @Override
    public boolean isTunnelPort(long sw, short port) {
        if (tunnelManager == null) return false;
        Short tunnelPort = tunnelManager.getTunnelPortNumber(sw);
        if (tunnelPort == null || tunnelPort.shortValue() != port)
            return false;
        return true;
    }

    @Override
    public ILinkDiscovery.LinkType getLinkType(Link lt, LinkInfo info) {

        if (lt == null)
            return ILinkDiscovery.LinkType.INVALID_LINK;

        IOFSwitch srcSw = controllerProvider.getSwitches().get(lt.getSrc());
        IOFSwitch dstSw = controllerProvider.getSwitches().get(lt.getDst());

        if (srcSw == null || dstSw == null)
            return ILinkDiscovery.LinkType.INVALID_LINK;

        if (isTunnelPort(lt.getSrc(), lt.getSrcPort()) ||
                isTunnelPort(lt.getDst(), lt.getDstPort())) {
            return ILinkDiscovery.LinkType.TUNNEL;
        }

        if (info == null) return ILinkDiscovery.LinkType.INVALID_LINK;

        if (info.getUnicastValidTime() != null) {
            return ILinkDiscovery.LinkType.DIRECT_LINK;
        } else if (info.getMulticastValidTime()  != null) {
            return ILinkDiscovery.LinkType.MULTIHOP_LINK;
        }
        return ILinkDiscovery.LinkType.INVALID_LINK;
    }

    @Override
    protected void setControllerTLV() {
        //Setting the controllerTLVValue based on current nano time,
        //controller's IP address, and the network interface object hash
        //the corresponding IP address.

        final int prime = 7867;
        InetAddress localIPAddress = null;
        NetworkInterface localInterface = null;

        byte[] controllerTLVValue = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};  // 8 byte value.
        ByteBuffer bb = ByteBuffer.allocate(10);

        try{
            localIPAddress = java.net.InetAddress.getLocalHost();
            localInterface = NetworkInterface.getByInetAddress(localIPAddress);
        } catch (Exception e) {
            e.printStackTrace();
        }

        long result = System.nanoTime();
        if (localIPAddress != null)
            result = result * prime + IPv4.toIPv4Address(localIPAddress.getHostAddress());
        if (localInterface != null)
            result = result * prime + localInterface.hashCode();
        // Set the first 4 bits to 0x7, so that SDN platform is higher than sdnplatform.
        result = result | (0x7000000000000000L);

        log.trace("Controller TLV: {}", result);

        bb.putLong(result);
        bb.rewind();
        bb.get(controllerTLVValue, 0, 8);

        this.controllerTLV = new LLDPTLV().setType((byte) 0x0c).setLength((short) 8).setValue(controllerTLVValue);
    }

    /**
     * This method overrides the one in LinkDiscovery to special-case
     * tunnel links.
     */
    @Override
    protected boolean isLinkAllowed(long src, short srcPort,
                                    long dst, short dstPort) {
        // tunnel manager doesn't exist.
        if (tunnelManager == null) return true;

        Short srcTunnelPort = tunnelManager.getTunnelPortNumber(src);
        Short dstTunnelPort = tunnelManager.getTunnelPortNumber(dst);

        boolean srcTunnelFlag = (srcTunnelPort != null &&
                srcTunnelPort.shortValue() == srcPort);
        boolean dstTunnelFlag = (dstTunnelPort != null &&
                dstTunnelPort.shortValue() == dstPort);

        if (srcTunnelFlag && dstTunnelFlag) {
            // Tunnel links are not allowed to be handled. However updates are
            // being sent for tunnel liveness detection
            updates.add(new LDUpdate(src, srcPort, dst, dstPort,
                                     ILinkDiscovery.LinkType.TUNNEL,
                                     UpdateOperation.LINK_UPDATED));
            return false;
        } else if (srcTunnelFlag || dstTunnelFlag) {
            // one of them is tunnel, so there's something wrong
            // in the network.
            log.warn("Detecting link between a tunnel and a non-tunnel port. {}",
                     new Link(src, srcPort, dst, dstPort));
            return false;
        }

        return true;
    }

    /**
     * This empty method is to ensure link information is not written to
     * the database on the SDN platform -- for scalability; while this
     * feature is available on the open-source side.  These methods are
     * currently in place for scalability. When we work on multi-master,
     * we need to sync the links through the database, then we will remove
     * and/or re-factor as necessary.
     * @param lt
     * @param linkInfo
     */
    @Override
    protected void writeLinkToStorage(Link lt, LinkInfo linkInfo) {
    }

    /**
     * Since we are not writing links to storage, we don't need to remove
     * links from storage.
     */
    @Override
    protected void removeLinkFromStorage(Link lt) {
    }


    @Override
    protected List<OFAction> getDiscoveryActions (IOFSwitch sw, OFPhysicalPort port){
        List<OFAction> actions = new ArrayList<OFAction>();

        // if overlay bind mode and port mirror is enabled, set the action to mirror
        if ((sw.getActions() == 0) && (port.getConfig() == 0x80000000)) {
            actions.add(new OFActionMirror(port.getPortNumber()));
        } else {
            actions.add(new OFActionOutput(port.getPortNumber(), (short) 0));
        }
        return actions;
    }

    /**
     * Check if outgoing discovery messages are enabled or not.
     * @param sw
     * @param port
     * @param isStandard
     * @param isReverse
     * @return
     */
    @Override
    protected boolean isOutgoingDiscoveryAllowed(long sw, short port,
                                                 boolean isStandard,
                                                 boolean isReverse) {

        if (isLinkDiscoverySuppressed(sw, port)) {
            /* Dont send LLDPs out of this port as suppressLLDP is set */
            return false;
        }

        IOFSwitch iofSwitch = controllerProvider.getSwitches().get(sw);
        if (iofSwitch == null) {
            return false;
        }

        if (port == OFPort.OFPP_LOCAL.getValue()) return false;

        OFPhysicalPort ofpPort = iofSwitch.getPort(port);
        if (ofpPort == null) {
            if (log.isTraceEnabled()) {
                log.trace("Null physical port. sw={}, port={}",
                          HexString.toHexString(sw), port);
            }
            return false;
        }

        // if it is a tunnel port, then do not send LLDPs.
        if (tunnelManager != null &&
                tunnelManager.getTunnelPortNumber(sw) != null &&
                tunnelManager.getTunnelPortNumber(sw).shortValue() == port)
            return false;

        // For fast ports, do not send forward LLDPs or BDDPs.
        if (!isReverse && isAutoPortFastFeature() && iofSwitch.isFastPort(port))
            return false;

        // if overlay bind mode and port mirror is not enabled, do not send LLDPs or BDDPs.
        if ((iofSwitch.getActions() == 0) && (ofpPort.getConfig() != 0x80000000)) {
            return false;
        }

        return true;
    }
}
<commit_msg>Mininet compatability fix Signed-off-by: <NAME> <<EMAIL>><commit_after>/*
 * Copyright (c) 2013 Big Switch Networks, Inc.
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the
 * "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package org.sdnplatform.linkdiscovery;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;


import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
import org.openflow.util.HexString;
import org.sdnplatform.core.IInfoProvider;
import org.sdnplatform.core.IOFMessageListener;
import org.sdnplatform.core.IOFSwitch;
import org.sdnplatform.core.IOFSwitchListener;
import org.sdnplatform.core.module.ModuleContext;
import org.sdnplatform.core.module.IModule;
import org.sdnplatform.linkdiscovery.ILinkDiscovery.LDUpdate;
import org.sdnplatform.linkdiscovery.ILinkDiscovery.UpdateOperation;
import org.sdnplatform.linkdiscovery.internal.LinkDiscoveryManager;
import org.sdnplatform.packet.IPv4;
import org.sdnplatform.packet.LLDPTLV;
import org.sdnplatform.routing.Link;
import org.sdnplatform.storage.IStorageSourceListener;
import org.sdnplatform.tunnelmanager.ITunnelManagerService;
import org.sdnplatform.vendor.OFActionMirror;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class BetterLinkDiscoveryManager extends LinkDiscoveryManager
implements IOFMessageListener, IOFSwitchListener,
IStorageSourceListener, ILinkDiscoveryService,
IModule, IInfoProvider {
    protected static Logger log =
            LoggerFactory.getLogger(BetterLinkDiscoveryManager.class);

    ITunnelManagerService tunnelManager;

    @Override
    public void startUp(ModuleContext context) {
        super.startUp(context);
    }

    @Override
    public void init (ModuleContext context) {

        try {
            super.init(context);
            tunnelManager = context.getServiceImpl(ITunnelManagerService.class);
        } catch (Exception e) {
            log.warn("{}", e);
        }
    }

    /**
     * This method should ideally be in OFSwitchImpl that should be
     * overridden when sub-classing.  This way, every switch can
     * implement their own versions of identifying a tunnel port
     * if they are indeed different
     */
    @Override
    public boolean isTunnelPort(long sw, short port) {
        if (tunnelManager == null) return false;
        Short tunnelPort = tunnelManager.getTunnelPortNumber(sw);
        if (tunnelPort == null || tunnelPort.shortValue() != port)
            return false;
        return true;
    }

    @Override
    public ILinkDiscovery.LinkType getLinkType(Link lt, LinkInfo info) {

        if (lt == null)
            return ILinkDiscovery.LinkType.INVALID_LINK;

        IOFSwitch srcSw = controllerProvider.getSwitches().get(lt.getSrc());
        IOFSwitch dstSw = controllerProvider.getSwitches().get(lt.getDst());

        if (srcSw == null || dstSw == null)
            return ILinkDiscovery.LinkType.INVALID_LINK;

        if (isTunnelPort(lt.getSrc(), lt.getSrcPort()) ||
                isTunnelPort(lt.getDst(), lt.getDstPort())) {
            return ILinkDiscovery.LinkType.TUNNEL;
        }

        if (info == null) return ILinkDiscovery.LinkType.INVALID_LINK;

        if (info.getUnicastValidTime() != null) {
            return ILinkDiscovery.LinkType.DIRECT_LINK;
        } else if (info.getMulticastValidTime()  != null) {
            return ILinkDiscovery.LinkType.MULTIHOP_LINK;
        }
        return ILinkDiscovery.LinkType.INVALID_LINK;
    }

    @Override
    protected void setControllerTLV() {
        //Setting the controllerTLVValue based on current nano time,
        //controller's IP address, and the network interface object hash
        //the corresponding IP address.

        final int prime = 7867;
        InetAddress localIPAddress = null;
        NetworkInterface localInterface = null;

        byte[] controllerTLVValue = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};  // 8 byte value.
        ByteBuffer bb = ByteBuffer.allocate(10);

        try{
            localIPAddress = java.net.InetAddress.getLocalHost();
            localInterface = NetworkInterface.getByInetAddress(localIPAddress);
        } catch (Exception e) {
            e.printStackTrace();
        }

        long result = System.nanoTime();
        if (localIPAddress != null)
            result = result * prime + IPv4.toIPv4Address(localIPAddress.getHostAddress());
        if (localInterface != null)
            result = result * prime + localInterface.hashCode();
        // Set the first 4 bits to 0x7, so that SDN platform is higher than sdnplatform.
        result = result | (0x7000000000000000L);

        log.trace("Controller TLV: {}", result);

        bb.putLong(result);
        bb.rewind();
        bb.get(controllerTLVValue, 0, 8);

        this.controllerTLV = new LLDPTLV().setType((byte) 0x0c).setLength((short) 8).setValue(controllerTLVValue);
    }

    /**
     * This method overrides the one in LinkDiscovery to special-case
     * tunnel links.
     */
    @Override
    protected boolean isLinkAllowed(long src, short srcPort,
                                    long dst, short dstPort) {
        // tunnel manager doesn't exist.
        if (tunnelManager == null) return true;

        Short srcTunnelPort = tunnelManager.getTunnelPortNumber(src);
        Short dstTunnelPort = tunnelManager.getTunnelPortNumber(dst);

        boolean srcTunnelFlag = (srcTunnelPort != null &&
                srcTunnelPort.shortValue() == srcPort);
        boolean dstTunnelFlag = (dstTunnelPort != null &&
                dstTunnelPort.shortValue() == dstPort);

        if (srcTunnelFlag && dstTunnelFlag) {
            // Tunnel links are not allowed to be handled. However updates are
            // being sent for tunnel liveness detection
            updates.add(new LDUpdate(src, srcPort, dst, dstPort,
                                     ILinkDiscovery.LinkType.TUNNEL,
                                     UpdateOperation.LINK_UPDATED));
            return false;
        } else if (srcTunnelFlag || dstTunnelFlag) {
            // one of them is tunnel, so there's something wrong
            // in the network.
            log.warn("Detecting link between a tunnel and a non-tunnel port. {}",
                     new Link(src, srcPort, dst, dstPort));
            return false;
        }

        return true;
    }

    /**
     * This empty method is to ensure link information is not written to
     * the database on the SDN platform -- for scalability; while this
     * feature is available on the open-source side.  These methods are
     * currently in place for scalability. When we work on multi-master,
     * we need to sync the links through the database, then we will remove
     * and/or re-factor as necessary.
     * @param lt
     * @param linkInfo
     */
    @Override
    protected void writeLinkToStorage(Link lt, LinkInfo linkInfo) {
    }

    /**
     * Since we are not writing links to storage, we don't need to remove
     * links from storage.
     */
    @Override
    protected void removeLinkFromStorage(Link lt) {
    }


    @Override
    protected List<OFAction> getDiscoveryActions (IOFSwitch sw, OFPhysicalPort port){
        List<OFAction> actions = new ArrayList<OFAction>();

        // if overlay bind mode and port mirror is enabled, set the action to mirror
        if ((sw.getActions() == 0) && (port.getConfig() == 0x80000000)) {
            actions.add(new OFActionMirror(port.getPortNumber()));
        } else {
            actions.add(new OFActionOutput(port.getPortNumber(), (short) 0));
        }
        return actions;
    }

    /**
     * Check if outgoing discovery messages are enabled or not.
     * @param sw
     * @param port
     * @param isStandard
     * @param isReverse
     * @return
     */
    @Override
    protected boolean isOutgoingDiscoveryAllowed(long sw, short port,
                                                 boolean isStandard,
                                                 boolean isReverse) {

        if (isLinkDiscoverySuppressed(sw, port)) {
            /* Dont send LLDPs out of this port as suppressLLDP is set */
            return false;
        }

        IOFSwitch iofSwitch = controllerProvider.getSwitches().get(sw);
        if (iofSwitch == null) {
            return false;
        }

        if (port == OFPort.OFPP_LOCAL.getValue()) return false;

        OFPhysicalPort ofpPort = iofSwitch.getPort(port);
        if (ofpPort == null) {
            if (log.isTraceEnabled()) {
                log.trace("Null physical port. sw={}, port={}",
                          HexString.toHexString(sw), port);
            }
            return false;
        }

        // if it is a tunnel port, then do not send LLDPs.
        if (tunnelManager != null &&
                tunnelManager.getTunnelPortNumber(sw) != null &&
                tunnelManager.getTunnelPortNumber(sw).shortValue() == port)
            return false;

        // For fast ports, do not send forward LLDPs or BDDPs.
        if (!isReverse && isAutoPortFastFeature() && iofSwitch.isFastPort(port))
            return false;

        // if overlay bind mode and port mirror is not enabled, do not send LLDPs or BDDPs.
        if ((iofSwitch.getActions() == 0) && (ofpPort.getConfig() != 0x80000000)) {
            return false;
        }

        return true;
    }
}

{'fraction_non_alphanumeric': 0.09082317831385228, 'fraction_numerical': 0.0073613528972892315, 'mean_word_length': 2.43751068558728, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3114262', 'n_tokens_mistral': 5725, 'n_tokens_neox': 5454, 'n_words': 1569}