您的位置:首页 > 其它

ONOS源码笔记--实现

2016-04-26 16:02 267 查看
app生命周期

@Activate
public 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());
}

@Deactivate
public void deactivate() {
cfgService.unregisterProperties(getClass(), false);
withdrawIntercepts();
flowRuleService.removeFlowRulesById(appId );
packetService.removeProcessor(processor );
topologyService.removeListener(topologyListener );
processor = null ;
log.info("Stopped" );
}

@Modified
public 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 );
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: