enviar un mensaje desde Controller1 a controller2

Helen:

Tengo una topología en MiniNet que consta de 2 controladores de lámpara de alta intensidad (C1 y C2), un interruptor (S1) que está conectado a C1 y 2 anfitriones (H1 y H2) que están conectados a este conmutador. Estoy escribiendo un programa en el que cuando c1 recibe un paquete ICMP de S1, se enviará un mensaje Hola a c2.

Estoy usando este tutorial para este fin, que dice:

Los mensajes pueden ser enviados desde un controlador a otro utilizando la función de envío, y los mensajes tienen que ser etiquetados con una 'm' “m”. Se va a enviar este mensaje a un controlador en particular por lo que la dirección de A se compone de dos partes IP: puerto. El IP es la dirección IP del equipo del otro controlador (HAServer está escuchando en todas las ips), y el puerto es el correspondiente puerto de escucha de HAServer en esa máquina.

Por defecto, HAServer en el controlador 1 está escuchando en el 4242, en el controlador 2 en 4243, el controlador 3 de 4244 ... y así sucesivamente.

recv () es similar a la función de envío y se le da la dirección FROM volver a escuchar de un controlador particular. La dirección también comprende a partir de dos partes, IP: puerto. El IP es la dirección IP del equipo del otro controlador (HAServer está escuchando en todas las ips), y el puerto es el correspondiente puerto de escucha de HAServer en esa máquina.

Idealmente, esta función se llama después de llamar a una función correspondiente send (), de lo contrario, podría no haberse establecido una conexión, y que sólo se devolverá un error.

Aquí está el código completo de mi módulo:

package net.floodlightcontroller.mactracker;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.hasupport.IHAControllerService;
import net.floodlightcontroller.hasupport.NetworkNode;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.ICMP;
import net.floodlightcontroller.packet.IPv4;

import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IpProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Mactracker implements IFloodlightModule, IOFMessageListener {

    protected static IHAControllerService hacontroller;
    protected static Logger logger = LoggerFactory.getLogger(Mactracker.class);
    protected IFloodlightProviderService floodlightProvider;
    protected Set<Long> macAddresses;
    private static NetworkNode network;

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
        // TODO Auto-generated method stubs
        return null;
    }

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
        // TODO Auto-generated method stub
        Collection<Class<? extends IFloodlightService>> l =
                new ArrayList<Class<? extends IFloodlightService>>();
            l.add(IFloodlightProviderService.class);
            l.add(IHAControllerService.class);
        return l;
    }

    @Override
    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
        // TODO Auto-generated method stub
        hacontroller = context.getServiceImpl(IHAControllerService.class);
        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
        macAddresses = new ConcurrentSkipListSet<Long>();
    }

    @Override
    public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
        // TODO Auto-generated method stub
        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
        // After more than 51% of configured controllers are started, this function will return,
        // or when a timeout of 60s is reached, whichever is earlier.
        hacontroller.pollForLeader();       
    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return Mactracker.class.getSimpleName();
    }

    @Override
    public boolean isCallbackOrderingPrereq(OFType type, String name) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isCallbackOrderingPostreq(OFType type, String name) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg,
            FloodlightContext cntx) {
        // TODO Auto-generated method stub
        Ethernet eth =
                IFloodlightProviderService.bcStore.get(cntx,
                                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
        if (eth.getEtherType() == EthType.IPv4) {
            IPv4 ipv4 = (IPv4) eth.getPayload();

            if ( ipv4.getProtocol().equals(IpProtocol.ICMP)){
                logger.warn ("ICMP Packet Received!:-)");
                ICMP icmp = (ICMP) ipv4.getPayload();
                logger.warn ("icmp.getIcmpType: "+icmp.getIcmpType());

                hacontroller.send("127.0.0.1:4243", "mHelloWorld");
                hacontroller.recv("127.0.0.1:4242");
            }
        }

        Long sourceMACHash = eth.getSourceMACAddress().getLong();
        if (!macAddresses.contains(sourceMACHash)) {
            macAddresses.add(sourceMACHash);
            logger.info("MAC Address: {} seen on switch: {}",
                    eth.getSourceMACAddress().toString(),
                    sw.getId().toString());
        }
        return Command.CONTINUE;
    }
}

Sin embargo, después de ejecutar este código, cuando c1 recibe un paquete ICMP, me encuentro con varios errores:

2018-09-13 00:39:56.716 WARN  [n.f.m.Mactracker] ICMP Packet Received!:-)
2018-09-13 00:39:56.716 WARN  [n.f.m.Mactracker] icmp.getIcmpType: 0
2018-09-13 00:39:56.716 INFO  [n.f.h.NetworkNode] [NetworkNode] Sending: mHelloWorld sent through port: 127.0.0.1:4243
2018-09-13 00:39:56.720 WARN  [i.n.c.DefaultChannelPipeline] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.NullPointerException: null
    at net.floodlightcontroller.hasupport.NetworkNode.recv(NetworkNode.java:535) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.hasupport.HAController.recv(HAController.java:190) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.mactracker.Mactracker.receive(Mactracker.java:121) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.Controller.handleMessage(Controller.java:411) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchManager.handleMessage(OFSwitchManager.java:487) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler.dispatchMessage(OFSwitchHandshakeHandler.java:1752) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler.access$24(OFSwitchHandshakeHandler.java:1751) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler$MasterState.processOFPacketIn(OFSwitchHandshakeHandler.java:1488) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler$OFSwitchHandshakeState.processOFMessage(OFSwitchHandshakeHandler.java:839) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler.processOFMessage(OFSwitchHandshakeHandler.java:1790) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler.messageReceived(OFSwitchHandshakeHandler.java:1964) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFConnection.messageReceived(OFConnection.java:414) ~[floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFChannelHandler.sendMessageToConnection(OFChannelHandler.java:579) [floodlight.jar:1.2-SNAPSHOT]
    at net.floodlightcontroller.core.internal.OFChannelHandler.access$9(OFChannelHandler.java:578) [floodlight.jar:1.2-SNAPSHOT]

¿Cuál es el problema? Parece que hay algo mal con la función recv (). Aquí está el código de funciones incorporado send () y recibir.

enviar():

/**
 * Sends a message to a specified client IP:port, if possible.
 *
 * @return boolean value that indicates success or failure.
 */

@Override
public Boolean send(String clientPort, String message) {
    if (message.equals(null)) {
        return Boolean.FALSE;
    }

    clientSock = socketDict.get(clientPort);
    try {
        logger.info("[NetworkNode] Sending: "+message+" sent through port: "+clientPort.toString());
        clientSock.send(message);
        return Boolean.TRUE;

    } catch (Exception e) {
        if (clientSock.getSocketChannel() != null) {
            clientSock.deleteConnection();
        }
        logger.debug("[NetworkNode] Send Failed: " + message + " not sent through port: " + clientPort.toString());
        return Boolean.FALSE;
    }
}

recv ():

/**
 * Receives a message from the specified IP:port, if possible.
 *
 * @return String containing the received message.
 */

@Override
public String recv(String receivingPort) {
    clientSock = socketDict.get(receivingPort);
    try {
        response = clientSock.recv();
        response.trim();
        logger.info("[NetworkNode] Recv on port:"+receivingPort.toString()+response);
        return response;
    } catch (Exception e) {
        if (clientSock.getSocketChannel() != null) {
            clientSock.deleteConnection();
        }
        logger.debug("[NetworkNode] Recv Failed on port: " + receivingPort.toString());
        return "";
    }

}

El código completo del módulo de NetworkNode donde se encuentran este send () y la función recv (), es aquí y el paquete completo de soporte de alta disponibilidad está aquí (En caso de que sea necesario)

Helen:

El problema con este código es que el método receive () se llama o (digamos de LET) se activa cuando el conmutador envía un nuevo paquete al controlador.

Aquí, cuando el primer controlador recibe un paquete ICMP, envía un mensaje de saludo al segundo controlador a través de esta pieza del código:

 hacontroller.send("127.0.0.1:4243", "mHelloWorld");

Pero desde el segundo controlador no ha recibido ningún mensaje desde el interruptor, no está llevando a cabo esta parte del código (receive ()) en el momento y no ve:

hacontroller.recv("127.0.0.1:4242");

Y por lo que puedo entender, esta es la razón por la cual clientSockno se ha inicializado y por lo que estoy recibiendo este error.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=176323&siteId=1
Recomendado
Clasificación