Files
KLALB/src/org/kne/cloud/network/srv6/SRv6Router.java
T
2025-04-24 10:16:38 +08:00

768 lines
23 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package org.kne.cloud.network.srv6;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.FlowSession;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6DestinationHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6RoutingHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.ipv6.RouteItem;
import org.kne.cloud.network.klalb.BindableKLALBPacketConsumer;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.tun.TUNNetworkDevice;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
import org.pcap4j.packet.IcmpV6CommonPacket;
import org.pcap4j.packet.IcmpV6TimeExceededPacket;
import org.pcap4j.packet.IllegalRawDataException;
import org.pcap4j.packet.IpV6ExtRoutingPacket;
import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6ExtRoutingHeader;
import org.pcap4j.packet.IpV6Packet;
import org.pcap4j.packet.IpV6Packet.Builder;
import org.pcap4j.packet.IpV6RoutingSourceRouteData;
import org.pcap4j.packet.IpV6SimpleFlowLabel;
import org.pcap4j.packet.IpV6SimpleTrafficClass;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.Packet.Header;
import org.pcap4j.packet.TcpPacket;
import org.pcap4j.packet.TcpPacket.TcpHeader;
import org.pcap4j.packet.UnknownPacket;
import org.pcap4j.packet.namednumber.IcmpV6Code;
import org.pcap4j.packet.namednumber.IcmpV6Type;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpV6RoutingType;
import org.pcap4j.packet.namednumber.IpVersion;
import com.google.gson.internal.Pair;
public class SRv6Router {
private static final boolean debug = false;
public static final int MTU = 8192;
public static final int MAX_REROUTE_COUNT=2;//1
public static final IpV6RoutingType SRH_HEADER = new IpV6RoutingType((byte) 4, "SRH Header");
// private List<NetworkLink>links=new ArrayList<>();
private List<RouteItem> routeTabel = new ArrayList<>();
private List<IPv6NetworkLink> linkTabel = new CopyOnWriteArrayList<>();
public List<IPv6NetworkLink> getLinkTabel() {
return linkTabel;
}
// private ConcurrentHashMap<FlowSession,SlidingWindowInformation>swis=new
// ConcurrentHashMap<>();
private final LoopbackIPv6NetworkLink inLoopBack = new LoopbackIPv6NetworkLink();
//private final LoopbackIPv6NetworkLink inLoopBackSRv6;
private final LoopbackIPv6NetworkLink hostLoopBack ;
private class LoopbackIPv6NetworkLink implements IPv6NetworkLink {
private Inet6AddressGroup loopbackAddress;
public LoopbackIPv6NetworkLink() {
super();
try {
this.loopbackAddress=new Inet6AddressGroup( (Inet6Address) Inet6Address.getByName("::1"),128);
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public LoopbackIPv6NetworkLink(Inet6Address loopbackAddress) {
super();
this.loopbackAddress = new Inet6AddressGroup(loopbackAddress,128);
}
public Consumer<IPv6Packet> getReceiveConsumer() {
return receiveConsumer;
}
private Consumer<IPv6Packet> receiveConsumer;
@Override
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
PacketConsumer pcm;
if ((pcm = protocolNumberRegister.get(pack.getPayload().getProtocolNumber())) != null) {
pcm.accept(pack);
return;
}
}
@Override
public boolean isLoopBack() {
return true;
}
@Override
public List<Neighbor> getNeighborsInfo() {
List<Neighbor> hs = new ArrayList<>();
return hs;
}
@Override
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
return false;
}
@Override
public String getName() {
return "inLoopBack";
}
@Override
public boolean isUp() {
return true;
}
@Override
public boolean canSend(IPv6Packet iPv6Packet) {
//System.out.println(iPv6Packet.getPayload().getProtocolNumber());
return protocolNumberRegister.containsKey(iPv6Packet.getPayload().getProtocolNumber());
}
@Override
public void setReceiveConsumer(Consumer<IPv6Packet> con) {
this.receiveConsumer = con;
}
@Override
public Inet6AddressGroup getAddressGroup() {
return loopbackAddress;
}
@Override
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
// TODO 自动生成的方法存根
}
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist=new ArrayList<>();
rlist.add(new RouteItem(new Inet6AddressGroup(this.getAddressGroup().getAddress(), 128),
this.getAddressGroup().getAddress(), this, "Direct", 0, 0, null, "D",true));
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
rlist.add(ris);
}
return rlist;
}
@Override
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
return false;
}
};
public List<RouteItem> getRouteTabel() {
return routeTabel;
}
public List<RouteItem> getCurrentRouteTabel() {
return routeTabel0;
}
private Consumer<IPv6Packet> defaultReroute = new Consumer<IPv6Packet>() {
@Override
public void accept(IPv6Packet t) {
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
routePacket(t,true);
t.putTimePassport("rerouted");
//});
}
};
private Consumer<IPv6Packet> defaultReceive = new Consumer<IPv6Packet>() {
@Override
public void accept(IPv6Packet t) {
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
routePacket(t);
t.putTimePassport("routed");
//});
}
};
private Consumer<IPv6Packet> srhReceive = new Consumer<IPv6Packet>() {
@Override
public void accept(IPv6Packet t) {
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
insertSRHandRoutePacket(t);
//});
}
};
private volatile UUID suid=UUID.randomUUID();
public void updateRouteTabel() {
List<RouteItem> routeTabel0x = new ArrayList<>();
for (Iterator<IPv6NetworkLink> iterator = linkTabel.iterator(); iterator.hasNext();) {
IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next();
/*if (nlink.isLoopBack()) {
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 1, null, "D"));
} else {
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 0, null, "D"));
}
}
for (Iterator<Neighbor> iteratorx = nlink.getNeighborsInfo()
.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
nlink, "Direct", 0, 128, addresses.getMonitor(), "D");
routeTabel0x.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
nlink, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D");
routeTabel0x.add(ris);
}*/
List<RouteItem>routes=nlink.getRouteItems();
routeTabel0x.addAll(routes);
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
nlink.setReceiveConsumer(srhReceive);
} else {
nlink.setReceiveConsumer(defaultReceive);
}
nlink.setRerouteConsumer(defaultReroute);
}
/*List<RouteItem> routeTabel1x=new ArrayList<>(routeTabel0x.size());
routeTabel0x.addAll(routeTabel);
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
RouteItem routeItem = (RouteItem) iterator.next();
routeTabel1x.add((RouteItem) routeItem.clone());
}*/
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
RouteItem routeItem = (RouteItem) iterator.next();
routeItem.preSort();
}
Collections.sort(routeTabel0x);
routeTabel0 = routeTabel0x;
suid=UUID.randomUUID();
}
private Inet6AddressGroup locator;
private long asn=new SecureRandom().nextLong(1,Long.MAX_VALUE);
/*
* public List<NetworkLink> getLinks() { return links; }
*/
public Inet6AddressGroup getLocator() {
return locator;
}
public long getASN() {
return asn;
}
public void setASN(long asn) {
this.asn = asn;
}
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
updateRouteTabel();
}
//private ConcurrentHashMap<FlowSession, TCPTransimitAgent> swist = new ConcurrentHashMap<>();
public void insertSRHandRoutePacket(IPv6Packet ipp) {
insertSRH(ipp);
ipp.putTimePassport("SRH inserted");
routePacket(ipp);
ipp.putTimePassport("routed");
}
public void insertSRH(IPv6Packet ipp) {
if(ipp.getSRHHeader()!=null) {
throw new IllegalStateException("packet already has SRH!");
}
if (klalbRouteProtol != null) {
List<Inet6Address> segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
// System.out.println(segs);
if (segs != null && (!segs.isEmpty())) {
IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs);
//System.out.println(ipp.getFlowLabel());
ThreadLocalRandom tlr=ThreadLocalRandom.current();
//System.out.println(ipp.getFlowSeqMark());
irh.getTlvs().add(new SEQSSegmentRoutingTLV(ipp.getFlowSeqMark(),new UUID(suid.getMostSignificantBits()^tlr.nextLong(),suid.getMostSignificantBits()^tlr.nextLong()),ipp.isPromise(),ipp.getFlowSeqMark()!=-1));
ipp.getHeaders().add(irh);
ipp.setDestinationAddress(segs.get(segs.size() - 1));
}
}
}
private volatile List<RouteItem> routeTabel0 = new ArrayList<>();
// private ReentrantReadWriteLock routelock=new ReentrantReadWriteLock();
//路由数据包
public void routePacket(IPv6Packet iPv6Packet) {
routePacket(iPv6Packet ,false);
}
//路由数据包
public void routePacket(IPv6Packet iPv6Packet, boolean reroute) {
// routelock.readLock().lock();
// try {
// System.out.println("路由表:"+routeTabel0);
StringBuilder dbg=null;
if (debug) {
dbg=new StringBuilder();
}
try {
int hop = iPv6Packet.getHopLimit();//检查TTL值,只有大于0才会被转发,否则丢弃
if (hop > 0) {
// List<RouteItem> mached=new ArrayList<>();
// RouteItem pri=null;
//按延迟顺序从小到大匹配路由表
if(searchTableAndFoward(iPv6Packet, reroute, dbg)) {
//匹配到路由表,返回
return ;
}
if (debug)
dbg.append("noroute\n");
//System.out.println("找不到路由表:"+iPv6Packet.getSourceAddress().getHostAddress()+" -> "+iPv6Packet.getDestinationAddress().getHostAddress());
//未找到合适的路由表或路由表对应的链路down,使用FRR保护创建备用路由表
IPv6SegmentRoutingHeader srh=iPv6Packet.getSRHHeader();
if(srh!=null) {
System.out.println("原SRH"+srh);
int segmentsLeft=srh.getSegmentsLeft();
if(segmentsLeft>0) {
srh.getAddresses().remove(segmentsLeft);
segmentsLeft--;
}
List<Inet6Address> repairSegments= klalbRouteProtol.createSegmentList(srh.getAddresses().get(segmentsLeft));
if(repairSegments ==null) {
System.out.println("FRR保护失败");
return;
}
repairSegments.remove(0);
srh.getAddresses().addAll(segmentsLeft+1, repairSegments);
segmentsLeft+=repairSegments.size();
srh.setSegmentsLeft(segmentsLeft);
iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft));
}else {
return;
}
System.out.println("FRR修复SRH"+srh);
if(searchTableAndFoward(iPv6Packet, reroute, dbg)) {
return ;
}
} else {
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
ByteBuffer IPv6data = NetworkPacket.bufferAllocator.allocate(65535);
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
byte[] raw = new byte[IPv6data.remaining()];
IPv6data.get(0, raw);
icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length));
IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder();
icbd.type(IcmpV6Type.TIME_EXCEEDED);
icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED);
icbd.srcAddr(locator.getAddress());
icbd.dstAddr(iPv6Packet.getSourceAddress());
icbd.correctChecksumAtBuild(true);
icbd.payloadBuilder(icmpte);
IPv6Packet icmpv = new IPv6Packet();
icmpv.setSourceAddress(locator.getAddress());
icmpv.setDestinationAddress(iPv6Packet.getSourceAddress());
icmpv.setTrafficClass(iPv6Packet.getTrafficClass());
icmpv.setVersion(6);
icmpv.setFlowLabel(0);
icmpv.setHopLimit(255);
IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value());
ipl.getData().put(icbd.build().getRawData());
ipl.getData().flip();
icmpv.setPayload(ipl);
insertSRHandRoutePacket(icmpv);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(debug) {
System.out.println(dbg.toString());
}
}
// }finally {
// routelock.readLock().unlock();
// }
}
private boolean searchTableAndFoward(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg)
throws IllegalRawDataException, IOException {
byte[] ia = new byte[16];
iPv6Packet.getRawDestinationAddress(ia);
if (debug) {
dbg.append("----------------------------------------\n");
dbg.append("packet:" + iPv6Packet.getSourceAddress().getHostAddress() + " -> "
+ iPv6Packet.getDestinationAddress().getHostAddress()+"\n");
}
boolean routeFound=false;
RouteItem prevr=null;
List<RouteItem> routes=new ArrayList<>();
//遍历路由表
for (RouteItem tri: routeTabel0) {
if(!tri.checkMatch(ia)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("unmatched.\n");
}
//跳过前缀与掩码不符合要求的路由表条目
continue;
}
if (!tri.getDestlink().canSend(iPv6Packet)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkrefused.\n");
}
//跳过不能转发这种数据包的链路
continue;
}
if (!tri.getDestlink().isUp()) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkdown.\n");
}
//跳过断开连接的链路
continue;
}
routeFound=true;
if(prevr!=null) {
if(!tri.ECMPequals(prevr)) {
//执行流量整形负载均衡调度算法
if(routingLoadBalance(iPv6Packet, reroute, dbg, routes)) {
return routeFound;
}
routes.clear();
}
}
//将等价路由加入负载均衡列表
routes.add(tri);
prevr=tri;
}
routingLoadBalance(iPv6Packet, reroute, dbg, routes);
return routeFound;
}
private boolean routingLoadBalance(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, List<RouteItem> routes)
throws IllegalRawDataException, IOException {
double cscale=1.0;
if(iPv6Packet.getPayload().getProtocolNumber()==6) {
cscale=15.0;
}
boolean retry=false;
long start=System.nanoTime();
do {
retry=false;
//遍历可用于负载均衡调度的路由表
for (RouteItem tri: routes) {
if (!tri.getDestlink().isUp()) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkdown.\n");
}
//跳过断开的链路
continue;
}
if (tri.getDestlink().isCongress(iPv6Packet,cscale)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("congress.\n");
}
//跳过缓冲区拥塞的链路
continue;
}
if (tri.getDestlink().isReachSpeedLimit(iPv6Packet)) {
retry=true;
if (debug) {
dbg.append(tri+"\n");
dbg.append("reachspeedlimit.\n");
}
//跳过达到流量整形速度限制的链路(若仅超过流量整形速度限制,可多次重试)
continue;
}
if (debug) {
dbg.append(tri+"\n");
dbg.append("matched.\n");
}
//链路可用,处理并转发数据包
processPacket(iPv6Packet, tri,reroute);
return true;
}
if(retry) {
if(System.nanoTime()-start>200000000L) {
break;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Thread.yield();
//短暂挂起当前线程,待链路速度未超限时重试发送数据包
}
}while((!routes.isEmpty())&&retry);
if (debug) {
dbg.append("miss.\n");
}
//负载均衡未匹配成功,若数据包支持ECN,打上拥塞标记位
if(iPv6Packet.isEnableECN()) {
iPv6Packet.markCE();
if (debug) {
dbg.append("ECN enabled.\n");
}
}
for (RouteItem tri: routes) {
if (!tri.getDestlink().isUp()) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkdown.\n");
}
continue;
}
if (tri.getDestlink().isCongress(iPv6Packet,25.0)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("congress.\n");
}
//缓冲区留部分余量避免丢包
continue;
}
processPacket(iPv6Packet, tri,reroute);
return true;
}
//仍未成功发送,丢弃数据包
return false;
}
private void processPacket(IPv6Packet iPv6Packet, RouteItem ri, boolean reroute) throws IllegalRawDataException, IOException {
int hop = iPv6Packet.getHopLimit();
if (ri.getDestlink().isLoopBack()) {
IPv6SegmentRoutingHeader srhh =iPv6Packet. getSRHHeader();
if (srhh != null) {
processSRv6Packet(iPv6Packet, ri, srhh,reroute);
} else {
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
}
} else {
if(iPv6Packet.getRerouteCounter().getAndIncrement()>=MAX_REROUTE_COUNT) {
//System.out.println("reroute count >=2");
return;
}
if(!reroute) {
// if(!iPv6Packet.isTTLdecreased()) {
hop--;
/* iPv6Packet.setTTLdecreased(true);
}else {
System.out.print("ttl err");
}*/
}
// System.out.println(ipp.getHeader().getSrcAddr()+"->"+ipp.getHeader().getDstAddr()+"
// "+(hop+1)+"->"+hop);
if (hop > 0) {
iPv6Packet.setHopLimit(hop);
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
} else {
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
ByteBuffer IPv6data = NetworkPacket.bufferAllocator.allocate(65535);
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
byte[] raw = new byte[IPv6data.remaining()];
IPv6data.get(0, raw);
icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length));
IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder();
icbd.type(IcmpV6Type.TIME_EXCEEDED);
icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED);
icbd.srcAddr(locator.getAddress());
icbd.dstAddr(iPv6Packet.getSourceAddress());
icbd.correctChecksumAtBuild(true);
icbd.payloadBuilder(icmpte);
IPv6Packet icmpv = new IPv6Packet();
icmpv.setSourceAddress(locator.getAddress());
icmpv.setDestinationAddress(iPv6Packet.getSourceAddress());
icmpv.setTrafficClass(iPv6Packet.getTrafficClass());
icmpv.setVersion(6);
icmpv.setFlowLabel(0);
icmpv.setHopLimit(255);
IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value());
ipl.getData().put(icbd.build().getRawData());
ipl.getData().flip();
icmpv.setPayload(ipl);
insertSRHandRoutePacket(icmpv);
}
}
}
private void processSRv6Packet(IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh, boolean reroute)
throws IllegalRawDataException, IOException {
if (srhh.getSegmentsLeft() <= 0) {
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
} else {
if(reroute) {
}else {
int newSL = srhh.getSegmentsLeft() - 1;
srhh.setSegmentsLeft(newSL);
iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL));
}
klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress());
routePacket(iPv6Packet,reroute);
}
}
public SRv6Router(Inet6AddressGroup hostAddress) {
super();
this.locator = hostAddress;
//this.inLoopBackSRv6=new LoopbackIPv6NetworkLink(locator.getAddress());
this.hostLoopBack= new LoopbackIPv6NetworkLink(hostAddress.getAddress());
linkTabel.add(inLoopBack);
//linkTabel.add(inLoopBackSRv6);
linkTabel.add(hostLoopBack);
}
/*public SRv6Router() {
super();
linkTabel.add(inLoopBack);
}*/
private KLALBRoutingProtocol klalbRouteProtol = null;
public void runKLALBRouteProtocol() {
if (klalbRouteProtol != null)
throw new IllegalStateException("KLALB routing protocol is already running!");
klalbRouteProtol = new KLALBRoutingProtocol(this);
klalbRouteProtol.start();
}
public KLALBRoutingProtocol getKlalbRouteProtol() {
return klalbRouteProtol;
}
private Map<Integer, PacketConsumer> protocolNumberRegister = new ConcurrentHashMap<>(256*2);
public Map<Integer, PacketConsumer> getProtocolNumberRegister() {
return protocolNumberRegister;
}
/*public void putProtocolNumberPacketAndInsertSRHAsync(IPv6Packet pkt) {
// inLoopBack.getReceiveConsumer().accept(pkt);
srhReceive.accept(pkt);
}
public void putProtocolNumberPacketAsync(IPv6Packet pkt) {
// inLoopBack.getReceiveConsumer().accept(pkt);
defaultReceive.accept(pkt);
}*/
}