如何创建和发送PacketOut?

时间:2017-10-25 13:50:38

标签: java sdn mininet opendaylight

我正在尝试基于OpenNetMon理念做一个延迟监控系统。我想要做的是将一个数据包注入交换机,这样该节点就会将数据包转发到另一个交换机,然后这个交换机将它发送回控制器。最后,控制器将测量延迟。

为了区分这种探测数据包进行测量,我将修改IPv4数据包中的DSCP字段。

我想到的是,当Opendaylight控制器接收到PacketIn时,将会复制这个,但会修改DSCP字段,然后复制的data_packet / probe_packet会将其发送到数据平面。

我可以从PacketChain中提取RawPacket,EthernetPacket,IPv4Packet:

    RawPacket rawPacket = null;
    EthernetPacket ethernetPacket = null;
    Ipv4Packet ipv4Packet = null;

    for (PacketChain packetChain : packetReceived.getPacketChain()) {
        if (packetChain.getPacket() instanceof RawPacket) {
            rawPacket = (RawPacket) packetChain.getPacket();
        } else if (packetChain.getPacket() instanceof EthernetPacket) {
            ethernetPacket = (EthernetPacket) packetChain.getPacket();
        } else if (packetChain.getPacket() instanceof Ipv4Packet) {
            ipv4Packet = (Ipv4Packet) packetChain.getPacket();
        }
    }

如何发送这些数据包?

1 个答案:

答案 0 :(得分:0)

使用PacketProcessingService:

,您需要以下内容
NodeConnectorId egress = TABLE_PORT;
TransmitPacketInput input = new TransmitPacketInputBuilder()
                                .setNode(nodeRef(linkDef.srcNodeId))
                                .setEgress(nodeConnectorRef(linkDef.srcNodeId, egress))
                                .setPayload(STUFF)
                                .build();
packetProcessingService.transmitPacket(input);

使用以下实用程序:

// reserved ports
public final static NodeConnectorId INGRESS_PORT = new NodeConnectorId("0xfffffff8");
public final static NodeConnectorId TABLE_PORT = new NodeConnectorId("0xfffffff9");
public final static NodeConnectorId NORMAL_PORT = new NodeConnectorId("0xfffffffa"); // optional functionality
public final static NodeConnectorId FLOOD_PORT = new NodeConnectorId("0xfffffffb"); // optional functionality
public final static NodeConnectorId ALL_PORT = new NodeConnectorId("0xfffffffc");
public final static NodeConnectorId CONTROLLER_PORT = new NodeConnectorId("0xfffffffd");
public final static NodeConnectorId LOCAL_PORT = new NodeConnectorId("0xfffffffe");
public final static NodeConnectorId ANY_PORT = new NodeConnectorId("0xffffffff");

public static final InstanceIdentifier<Nodes> NODES_IID = InstanceIdentifier.builder(Nodes.class).build();

public static InstanceIdentifier<Node> nodeIId(NodeId nodeId) {
    return NODES_IID.child(Node.class, new NodeKey(nodeId));
}

public static NodeRef nodeRef(NodeId nodeId) {
    return new NodeRef(nodeIId(nodeId));
}

public static InstanceIdentifier<NodeConnector> nodeConnectorIId(NodeId nodeId, NodeConnectorId ncId) {
    return NODES_IID.child(Node.class, new NodeKey(nodeId)).child(NodeConnector.class, new NodeConnectorKey(ncId));
}

public static NodeConnectorRef nodeConnectorRef(NodeId nodeId, NodeConnectorId ncId) {
    return new NodeConnectorRef(nodeConnectorIId(nodeId, ncId));
}

此外,您还可以设置Ingress,它是数据包'来自'的端口,由端口内匹配器使用。