ONOS源码笔记--实现

来源:互联网 发布:西门子plc伺服编程案例 编辑:程序博客网 时间:2024/06/03 16:39

app生命周期

@Activatepublic void activate(ComponentContext context ) {    cfgService.registerProperties(getClass());    appId = coreService .registerApplication("org.onosproject.fwd");    packetService.addProcessor(processor , PacketProcessor.director(2));    topologyService.addListener(topologyListener );    readComponentConfiguration( context);    requestIntercepts();    log.info("Started" , appId .id());}@Deactivatepublic void deactivate() {    cfgService.unregisterProperties(getClass(), false);    withdrawIntercepts();    flowRuleService.removeFlowRulesById(appId );    packetService.removeProcessor(processor );    topologyService.removeListener(topologyListener );    processor = null ;    log.info("Stopped" );}@Modifiedpublic void modified(ComponentContext context ) {    readComponentConfiguration( context);    requestIntercepts();}

常见功能函数

// Indicates whether this is a control packet, e.g. LLDP, BDDP// 判断是否为控制数据包private boolean isControlPacket(Ethernet eth ) {    short type = eth.getEtherType();    return type == Ethernet.TYPE_LLDP || type == Ethernet.TYPE_BSN;}// Indicated whether this is an IPv6 multicast packet.// 判断是否为ipv6多播包private boolean isIpv6Multicast(Ethernet eth ) {    return eth .getEtherType() == Ethernet.TYPE_IPV6 && eth.isMulticast();}// Selects a path from the given set that does not lead back to the// specified port if possible.// 在一个给定的path集合中选择一条不通过指定端口的路径private Path pickForwardPathIfPossible(Set<Path> paths, PortNumber notToPort) {    Path lastPath = null ;    for (Path path : paths) {        lastPath = path ;        if (!path .src().port().equals(notToPort)) {            return path ;        }    }    return lastPath ;}// Floods the specified packet if permissible.// 看看数据包从哪儿来,要是广播,泛洪出去private void flood(PacketContext context ) {    if (topologyService.isBroadcastPoint(topologyService .currentTopology(),                                         context.inPacket().receivedFrom())) {        packetOut( context, PortNumber.FLOOD);    } else {        context.block();    }}// Sends a packet out the specified port.// 把数据包从指定端口发出,一般映射为交换机的某个网卡,其实这是两个过程,可以分开private void packetOut(PacketContext context , PortNumber portNumber) {    context.treatmentBuilder().setOutput(portNumber );    context.send();}// Install a rule forwarding the packet to the specified port.// 按需制定流表规则,并发出,很自动化,其实可以分开实现private void installRule(PacketContext context , PortNumber portNumber) {    //    // We don't support (yet) buffer IDs in the Flow Service so    // packet out first.    //    Ethernet inPkt = context .inPacket().parsed();    TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();    // If PacketOutOnly or ARP packet than forward directly to output port    if (packetOutOnly || inPkt.getEtherType() == Ethernet. TYPE_ARP) {        packetOut( context, portNumber );        return;    }    //    // If matchDstMacOnly    //    Create flows matching dstMac only    // Else    //    Create flows with default matching and include configured fields    //    if (matchDstMacOnly ) {        selectorBuilder.matchEthDst(inPkt .getDestinationMAC());    } else {        selectorBuilder.matchInPort(context .inPacket().receivedFrom().port())                .matchEthSrc( inPkt.getSourceMAC())                .matchEthDst( inPkt.getDestinationMAC());        // If configured Match Vlan ID        if (matchVlanId && inPkt.getVlanID() != Ethernet.VLAN_UNTAGGED ) {            selectorBuilder.matchVlanId(VlanId.vlanId( inPkt.getVlanID()));        }        //        // If configured and EtherType is IPv4 - Match IPv4 and        // TCP/UDP/ICMP fields        //        if (matchIpv4Address && inPkt.getEtherType() == Ethernet.TYPE_IPV4 ) {            IPv4 ipv4Packet = (IPv4) inPkt .getPayload();            byte ipv4Protocol = ipv4Packet.getProtocol();            Ip4Prefix matchIp4SrcPrefix =                    Ip4Prefix. valueOf(ipv4Packet.getSourceAddress(),                                      Ip4Prefix. MAX_MASK_LENGTH);            Ip4Prefix matchIp4DstPrefix =                    Ip4Prefix.valueOf(ipv4Packet.getDestinationAddress(),                                      Ip4Prefix. MAX_MASK_LENGTH);            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)                    .matchIPSrc( matchIp4SrcPrefix)                    .matchIPDst( matchIp4DstPrefix);            if (matchIpv4Dscp ) {                byte dscp = ipv4Packet.getDscp();                byte ecn = ipv4Packet.getEcn();                selectorBuilder.matchIPDscp(dscp ).matchIPEcn(ecn);            }            if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_TCP ) {                TCP tcpPacket = (TCP) ipv4Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv4Protocol )                        .matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort()))                        .matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));            }            if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_UDP ) {                UDP udpPacket = (UDP) ipv4Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv4Protocol )                        .matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort()))                        .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));            }            if (matchIcmpFields && ipv4Protocol == IPv4.PROTOCOL_ICMP ) {                ICMP icmpPacket = (ICMP) ipv4Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv4Protocol )                        .matchIcmpType( icmpPacket.getIcmpType())                        .matchIcmpCode( icmpPacket.getIcmpCode());            }        }        //        // If configured and EtherType is IPv6 - Match IPv6 and        // TCP/UDP/ICMP fields        //        if (matchIpv6Address && inPkt.getEtherType() == Ethernet.TYPE_IPV6 ) {            IPv6 ipv6Packet = (IPv6) inPkt .getPayload();            byte ipv6NextHeader = ipv6Packet.getNextHeader();            Ip6Prefix matchIp6SrcPrefix =                    Ip6Prefix. valueOf(ipv6Packet.getSourceAddress(),                                      Ip6Prefix. MAX_MASK_LENGTH);            Ip6Prefix matchIp6DstPrefix =                    Ip6Prefix.valueOf(ipv6Packet.getDestinationAddress(),                                      Ip6Prefix. MAX_MASK_LENGTH);            selectorBuilder.matchEthType(Ethernet.TYPE_IPV6)                    .matchIPv6Src( matchIp6SrcPrefix)                    .matchIPv6Dst( matchIp6DstPrefix);            if (matchIpv6FlowLabel ) {                selectorBuilder.matchIPv6FlowLabel(ipv6Packet .getFlowLabel());            }            if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_TCP ) {                TCP tcpPacket = (TCP) ipv6Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv6NextHeader )                        .matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort()))                        .matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));            }            if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_UDP ) {                UDP udpPacket = (UDP) ipv6Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv6NextHeader )                        .matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort()))                        .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));            }            if (matchIcmpFields && ipv6NextHeader == IPv6.PROTOCOL_ICMP6 ) {                ICMP6 icmp6Packet = (ICMP6) ipv6Packet .getPayload();                selectorBuilder.matchIPProtocol(ipv6NextHeader )                        .matchIcmpv6Type( icmp6Packet.getIcmpType())                        .matchIcmpv6Code( icmp6Packet.getIcmpCode());            }        }    }    TrafficTreatment treatment = DefaultTrafficTreatment.builder()            .setOutput( portNumber)            .build();    ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()            .withSelector( selectorBuilder.build())            .withTreatment( treatment)            .withPriority( flowPriority)            .withFlag(ForwardingObjective.Flag. VERSATILE)            .fromApp( appId)            .makeTemporary( flowTimeout)            .add();    flowObjectiveService.forward(context .inPacket().receivedFrom().deviceId(),                                 forwardingObjective);    //    // If packetOutOfppTable    //  Send packet back to the OpenFlow pipeline to match installed flow    // Else    //  Send packet direction on the appropriate port    //    if (packetOutOfppTable ) {        packetOut( context, PortNumber.TABLE);    } else {        packetOut( context, portNumber );    }}
0 0
原创粉丝点击