package org.kne.cloud.network.srv6; import java.io.IOException; import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.ArrayList; 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.Timer; import java.util.TimerTask; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import org.jctools.counters.FixedSizeStripedLongCounter; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.network.congestion.MessageBatcher; import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink; import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket; import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6HopByHopTLV; import org.kne.cloud.network.ipv6.IPv6LinkStateListener; import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.ipv6.IPv6Packet; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; import org.kne.cloud.network.ipv6.IPv6AddressGroup; import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV; import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV; import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink; import org.kne.cloud.network.ipv6.Neighbor; import org.kne.cloud.network.ipv6.PadNHopByHopTLV; import org.kne.cloud.network.ipv6.PostcardEntry; import org.kne.cloud.network.ipv6.RouteItem; import org.kne.cloud.network.klalb.KLALBRemoteLink; import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.klalb.PerformanceStrategy; import org.kne.cloud.network.klalb.ui.PerformanceStrategyItem; import org.kne.concurrent.HighPerformanceExecutor2; import org.kne.concurrent.TimeoutConcurrentHashMap; import org.pcap4j.packet.IllegalRawDataException; import com.google.gson.internal.Pair; // SRv6路由器主类,实现IPv6段路由功能 public class SRv6Router { private static final boolean debug = false; // 调试模式开关 // public static final int MTU = 16384; public static final int MTU = 16384; // 最大传输单元 public static final int MAX_REROUTE_COUNT = 2;// 1 // 最大重路由次数 private static final int IPv6_BITS = 128; // IPv6地址位数 private PerformanceStrategy performanceStrategy=PerformanceStrategy.MULTI_FILL; /*private TimeoutConcurrentHashMap flowIDmap = new TimeoutConcurrentHashMap( 60000000000L); */ private Set unduplicateSet = Collections .newSetFromMap(new TimeoutConcurrentHashMap(3000000000L, 1024, 0.5f)); private HighAccuracyClock clock; // 获取环回地址 ::1 private static Inet6Address getLoopbackAddress() { try { return (Inet6Address) Inet6Address.getByName("::1"); } catch (UnknownHostException e) { e.printStackTrace(); } return null; } // 获取任意本地地址 ::0 private static Inet6Address getAnyLocalAddress() { try { return (Inet6Address) Inet6Address.getByName("::0"); } catch (UnknownHostException e) { e.printStackTrace(); } return null; } private List routeTabel = new ArrayList<>(); // 路由表 private List linkTabel = new CopyOnWriteArrayList<>(); // 网络链路表,线程安全 public List getLinkTabel() { return linkTabel; } // 环回网络链路 private final LoopbackIPv6NetworkLink inLoopBack; // 获取路由表 public List getRouteTabel() { return routeTabel; } // 获取当前路由表 public List getCurrentRouteTabel() { return routeTable0; } // 默认重路由处理器 private Consumer defaultReroute = new Consumer() { @Override public void accept(IPv6Packet t) { // HighPerformanceExecutor.defaultExecutor.execute(() -> { routePacket(null, t, true); // 执行重路由 // }); } }; private boolean unduplicate(IPv6Packet pack) { IPv6HopByHopHeader hbh = pack.getHopByHopHeader(); KLALBOAMHopByHopTLV oamtlv = null; if (hbh != null) { List tlvs = hbh.getTlvs(); for (IPv6HopByHopTLV tlv : tlvs) { if (tlv instanceof KLALBOAMHopByHopTLV) { oamtlv = (KLALBOAMHopByHopTLV) tlv; break; } } } if (oamtlv == null) return true; boolean bool = unduplicateSet.add(oamtlv.getUUID()); // System.out.println(bool); return bool; } // 默认接收处理器 /* * private BiConsumer defaultReceive = new * BiConsumer() { * * @Override public void accept(IPv6NetworkLink link,IPv6Packet t) { // * HighPerformanceExecutor.defaultExecutor.execute(() -> { if(unduplicate(t)) { * routePacket(t); // 执行路由 t.putTimePassport("routed"); // 标记路由时间点 } // }); } }; */ // SRH接收处理器 private BiConsumer> srhReceive = new BiConsumer>() { @Override public void accept(IPv6NetworkLink link, Supplier pack) { enqueuePacketReceiveTask(link, pack); } }; public void setPerformanceStrategy(PerformanceStrategy performanceStrategy) { this.performanceStrategy=performanceStrategy; } public PerformanceStrategy getPerformanceStrategy(){ return performanceStrategy; } // 链路状态监听器实现 private class LinkListener implements IPv6LinkStateListener { @Override public void onOnlineStateUpdate(IPv6NetworkLink link) { srListeners.forEach((v) -> { v.onLinkChanged(SRv6Router.this, link); }); // 通知所有监听器链路状态变化 } @Override public void onAddressUpdate(IPv6NetworkLink link) { srListeners.forEach((v) -> { v.onLinkChanged(SRv6Router.this, link); }); // 通知所有监听器地址更新 } @Override public void onLocatorUpdate(IPv6NetworkLink link) { srListeners.forEach((v) -> { v.onLinkChanged(SRv6Router.this, link); }); // 通知所有监听器定位器更新 } } private IPv6LinkStateListener listener = new LinkListener(); // 链路状态监听器实例 private Set srListeners = new CopyOnWriteArraySet(); // SRv6路由器监听器集合 // 添加SRv6路由器监听器 public void addSRv6RouterListener(SRv6RouterListener listener) { srListeners.add(listener); } // 移除SRv6路由器监听器 public void removeSRv6RouterListener(SRv6RouterListener listener) { srListeners.remove(listener); } public void sortRouteTabel() { // 构建前缀长度索引的路由表 List>> routeTabel1x = new ArrayList>>( IPv6_BITS + 1); for (int i = 0; i < IPv6_BITS + 1; i++) { routeTabel1x.add(new HashMap>(1024, 0.5f)); } List routeTabel0x=routeTable0; // 按前缀长度组织路由表 for (RouteItem item : routeTabel0x) { IPv6AddressGroup iag = item.getDestination(); Map> map = routeTabel1x.get(iag.getPrefixLength()); List newlist = new ArrayList(); List oldlist = map.putIfAbsent(iag.getAddress(), newlist); if (oldlist == null) { oldlist = newlist; } oldlist.add(item); } for(Map> map:routeTabel1x) { for(Listv:map.values()) { Collections.sort(v); } } // System.out.println(routeTabel1x); routeTabel1 = routeTabel1x; // 更新索引路由表 } // 更新路由表 public void updateRouteTabel() { List routeTabel0x = new ArrayList<>(); // 遍历所有网络链路,收集路由信息 for (Iterator iterator = linkTabel.iterator(); iterator.hasNext();) { IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next(); List routes = nlink.getRouteItems(); // 获取链路的路由项 routeTabel0x.addAll(routes); // 添加到路由表 nlink.setSRv6Router(this); nlink.addIPv6LinkStateListener(listener); // 添加链路状态监听器 nlink.setReceiveConsumer(srhReceive); // 设置接收处理器 if (nlink instanceof ControlledIPv6NetworkLink) { ((ControlledIPv6NetworkLink) nlink).setRerouteConsumer(defaultReroute); // 设置重路由处理器 ((ControlledIPv6NetworkLink) nlink).setCongressCondition(congressLock, congressCondition); // 设置拥塞条件 } } // 预处理和排序路由项 for (Iterator iterator = routeTabel0x.iterator(); iterator.hasNext();) { RouteItem routeItem = (RouteItem) iterator.next(); routeItem.updateCost(); // 预排序 } Collections.sort(routeTabel0x); // 排序路由表 // 构建前缀长度索引的路由表 ArrayList>> routeTabel1x = new ArrayList>>( IPv6_BITS + 1); for (int i = 0; i < IPv6_BITS + 1; i++) { routeTabel1x.add(new HashMap>(1024, 0.5f)); } // 按前缀长度组织路由表 for (RouteItem item : routeTabel0x) { IPv6AddressGroup iag = item.getDestination(); Map> map = routeTabel1x.get(iag.getPrefixLength()); List newlist = new ArrayList(); List oldlist = map.putIfAbsent(iag.getAddress(), newlist); if (oldlist == null) { oldlist = newlist; } oldlist.add(item); } // System.out.println(routeTabel1x); routeTable0 = routeTabel0x; // 更新平面路由表 routeTabel1 = routeTabel1x; // 更新索引路由表 } private IPv6AddressGroup locator; // SRv6定位器 private long asn = new SecureRandom().nextLong(1, Long.MAX_VALUE); // 自治系统号 private volatile String deviceName; // 设备名称(随路由信息广播) public String getDeviceName() { return deviceName; } public void setDeviceName(String deviceName) { this.deviceName = deviceName; } public IPv6AddressGroup getLocator() { return locator; } public long getASN() { return asn; } public void setASN(long asn) { this.asn = asn; } // 设置定位器并更新路由表 public void setLocator(IPv6AddressGroup locator) { this.locator = locator; updateRouteTabel(); } // 插入SRH并路由数据包 public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) { insertHopByHopHeader(ipp); insertSRHeader(ipp); // 插入段路由头 routePacket(link, ipp); // 路由数据包 } private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4); // 插入逐跳路由头 public boolean insertHopByHopHeader(IPv6Packet ipp) { if (ipp.getHopByHopHeader() != null) { return false; } IPv6HopByHopHeader hbh = new IPv6HopByHopHeader(); hbh.getTlvs().add(pad4); UUID pid = KLALBUtils.createGlobalUUID(); hbh.getTlvs().add(new KLALBOAMHopByHopTLV(0, ipp.getHopLimit(), true, false, true, pid, clock.getCurrentTimeNTP64().longValue())); ipp.getHeaders().add(0, hbh); // 添加Hop头 ipp.setHopByHopHeader(hbh); return true; } // 插入段路由头 public boolean insertSRHeader(IPv6Packet ipp) { // 如果已有SRH,返回false if (ipp.getSegmentRoutingHeader() != null) { return false; } // 如果KLALB路由协议可用,创建段列表 if (klalbRouteProtol != null) { IPv6SegmentRoutingHeader segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress()); // System.out.println(segs); if (segs != null && (!segs.getAddresses().isEmpty())) { // 创建SRH头 ipp.getHeaders().add(segs); // 添加SRH头 ipp.setRoutingHeader(segs); ipp.setDestinationAddress(segs.getAddresses().get(segs.getAddresses().size() - 1)); // 更新目的地址为最后一个段 return true; } } return false; } private volatile List routeTable0 = new ArrayList<>(); // 当前路由表 // 前缀长度索引的路由表 private volatile List>> routeTabel1 = new ArrayList>>( IPv6_BITS + 1); { // 初始化索引路由表 for (int i = 0; i < IPv6_BITS + 1; i++) { routeTabel1.add(new HashMap>(1024, 0.5f)); } } private void routePacket(IPv6Packet iPv6Packet) { routePacket(null, iPv6Packet, false); } // 路由数据包(默认非重路由) private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet) { routePacket(linkfrom, iPv6Packet, false); } // 路由数据包主方法 private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute) { StringBuilder dbg = null; if (debug) { dbg = new StringBuilder(); // 调试信息 } try { int hop = iPv6Packet.getHopLimit(); // 获取跳数限制 if (hop > 0) { // 检查TTL值,只有大于0才会被转发 // 搜索匹配的路由表项 IPv6Address dest=iPv6Packet.getDestinationAddress(); List searchResult = getTabelByAddress(dest); if (searchResult!=null&&(!searchResult.isEmpty())) { // 匹配到路由表,执行负载均衡路由 routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult); return; } if (debug) dbg.append("noroute\n"); // 未找到路由,尝试FRR(快速重路由)保护 IPv6SegmentRoutingHeader srh = iPv6Packet.getSegmentRoutingHeader(); if (srh != null) { System.out.println("原SRH:" + srh); int segmentsLeft = srh.getSegmentsLeft(); if (segmentsLeft > 0) { srh.getAddresses().remove(segmentsLeft); // 移除当前故障段 segmentsLeft--; } // 创建修复段列表 IPv6SegmentRoutingHeader repairSegments = klalbRouteProtol .createSegmentList(srh.getAddresses().get(segmentsLeft)); if (repairSegments == null ||repairSegments.getAddresses().isEmpty()) { System.out.println("FRR保护失败"); return; } repairSegments.getAddresses().remove(0); // 移除第一个段(当前节点) srh.getAddresses().addAll(segmentsLeft + 1, repairSegments.getAddresses()); // 添加修复段 segmentsLeft += repairSegments.getAddresses().size(); // 更新剩余段数 srh.setSegmentsLeft(segmentsLeft); iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址 } else { return; } System.out.println("FRR修复SRH:" + srh); // 重新搜索路由表 List searchResult2 = getTabelByAddress(dest); if (searchResult2!=null&&(!searchResult2.isEmpty())) { routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2); return; } } else { // TTL超时,发送ICMP超时消息 sendTTLExceedPacket(iPv6Packet); } } catch (Exception e) { e.printStackTrace(); } finally { if (debug) { System.out.println(dbg.toString()); // 输出调试信息 } } } // 搜索路由表找到匹配的路由项 /*private List searchTable(IPv6Packet iPv6Packet, StringBuilder dbg) throws IllegalRawDataException, IOException { if (debug) { dbg.append("----------------------------------------\n"); dbg.append("packet:" + iPv6Packet.getSourceAddress() + " -> " + iPv6Packet.getDestinationAddress() + "\n"); } IPv6Address rk6 = iPv6Packet.getDestinationAddress(); List table = getTabelByAddress(rk6); RouteItem prevr = null; List routes = new ArrayList<>(); if (table == null) { return routes; // 无匹配路由 } // 遍历路由表,筛选可用路由 for (RouteItem tri : table) { // 检查ECMP(等价多路径)条件 if (prevr != null) { if (!tri.ECMPequals(prevr)) { return routes; // 非ECMP路由,返回当前结果 } } routes.add(tri); // 添加到可用路由列表 prevr = tri; } return routes; }*/ private List getTabelByAddress(IPv6Address rk6) { List table = null; // 最长前缀匹配搜索 for (int i = 128; i >= 0; i--) { rk6 = rk6.maskWith(IPv6Address.createMask(i)); // 应用掩码 table = routeTabel1.get(i).get(rk6); // 查找匹配的路由表 if (table != null) { break; // 找到匹配 } } return table; } private ReentrantLock congressLock = new ReentrantLock(); // 拥塞锁 private Condition congressCondition = congressLock.newCondition(); // 拥塞条件 // 负载均衡路由 private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, List routes) throws IllegalRawDataException, IOException { if(routes==null||routes.isEmpty()) { //System.out.println("Route not found:" + iPv6Packet); return false; } for (double i = 1; i < 100; i += 0.1) { if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, i)) { return true; } iPv6Packet.markCE(); // 标记拥塞 if (debug) { dbg.append("ECN enabled.\n"); } } //System.out.println("Send failed:" + iPv6Packet); LosscountAdder.inc(1); if (debug) { dbg.append("miss.\n"); // 路由失败 } return false; // 路由失败 } private boolean loadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, List routes, double cscale) throws IllegalRawDataException, IOException { // 遍历可用路由进行负载均衡 for (RouteItem tri : routes) { IPv6NetworkLink link = tri.getDestlink(); if (!link.isUp()) { // 检查链路状态 if (debug) { dbg.append(tri + "\n"); dbg.append("linkdown.\n"); } continue; // 跳过断开链路 } if (link instanceof ControlledIPv6NetworkLink) { if (((ControlledIPv6NetworkLink) link).isCongestion(iPv6Packet, cscale)) { // 检查拥塞 if (debug) { dbg.append(tri + "\n"); dbg.append("congress.\n"); } continue; // 跳过拥塞链路 } } if (debug) { dbg.append(tri + "\n"); dbg.append("matched.\n"); } // 找到可用链路,处理数据包 processPacket(linkfrom, iPv6Packet, tri, reroute); return true; } return false; } // 处理数据包转发 private void processPacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri, boolean reroute) throws IllegalRawDataException, IOException { int hop = iPv6Packet.getHopLimit(); if (ri.getDestlink().isLoopBack()) { // 环回链路处理 IPv6SegmentRoutingHeader srhh = iPv6Packet.getSegmentRoutingHeader(); if (srhh != null) { processSRv6Packet(linkfrom, iPv6Packet, ri, srhh, iPv6Packet.getHopByHopHeader(), reroute); // SRv6特殊处理 } else { sendPacketToRouteItem(iPv6Packet, ri); } } else { // 普通链路处理 // 检查重路由计数 if (iPv6Packet.getRerouteCounter().getAndIncrement() >= MAX_REROUTE_COUNT) { return; // 超过最大重路由次数,丢弃 } if (!reroute) { hop--; // 减少TTL(非重路由时) } if (hop > 0) { // TTL有效 iPv6Packet.setHopLimit(hop); // 更新TTL sendPacketToRouteItem(iPv6Packet, ri); // 发送数据包 } else { sendTTLExceedPacket(iPv6Packet); // TTL超时 } } } private void sendPacketToRouteItem(IPv6Packet iPv6Packet, RouteItem ri) throws IOException { if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) { onPostcardReceive(iPv6Packet); } else { ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop()); } } private void onPostcardReceive(IPv6Packet postcards) { ICMPv6PostcardPacket postcardsi = (ICMPv6PostcardPacket) postcards.getPayload(); for (PostcardEntry postcard : postcardsi.getPostcards()) { IPv6Address sid = postcard.getSID(); List ris = getTabelByAddress(sid); if (ris != null) { for (RouteItem ri : ris) { if (ri.getNexthop().equals(sid)) { if (ri.getDestlink() instanceof KLALBRemoteLink) { KLALBRemoteLink rem = (KLALBRemoteLink) ri.getDestlink(); rem.onPostcardReceive(postcard); } } } } } } // 发送ICMP TTL超时消息 private void sendTTLExceedPacket(IPv6Packet iPv6Packet) throws IOException, IllegalRawDataException { enqueuePacketSendTask(() -> { // 构建IPv6数据包封装ICMP消息 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); // ICMP消息TTL设为最大值 ICMPv6TimeExceededPacket ipl = ICMPv6TimeExceededPacket.createHopLimitExceeded(iPv6Packet); ipl.setParent(icmpv); ipl.updateChecksum(); icmpv.setPayload(ipl); return icmpv; }); } // 处理SRv6数据包 private void processSRv6Packet(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh, IPv6HopByHopHeader iPv6HopByHopHeader, boolean reroute) throws IllegalRawDataException, IOException { if (srhh.getSegmentsLeft() <= 0) { // 所有段已处理完毕 if (iPv6HopByHopHeader != null) { int sl = srhh.getSegmentsLeft(); // IPv6Address prevSID // =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1); if (linkfrom instanceof KLALBRemoteLink) { processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(), ((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); } } // System.out.println(iPv6HopByHopHeader); sendPacketToRouteItem(iPv6Packet, ri); } else { if (reroute) { // 重路由处理 } else { int oldSL = srhh.getSegmentsLeft(); if (iPv6HopByHopHeader != null) { // IPv6Address prevSID // =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1); if (linkfrom instanceof KLALBRemoteLink) { processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(), ((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); } } // 正常SRv6处理:移动到下一个段 int newSL = oldSL - 1; srhh.setSegmentsLeft(newSL); // 更新剩余段数 iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL)); // 更新目的地址 } // 记录热点地址(用于流量工程) if (iPv6Packet.getPayload().getProtocolNumber() != KLALBRoutingProtocol.DEFAULT_PROTOCOL_NUMBER) klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress()); routePacket(linkfrom, iPv6Packet, reroute); // 继续路由 } } private void processKLALBOAM(IPv6Packet iPv6Packet, IPv6Address sourceSID, IPv6Address prevSID, IPv6HopByHopHeader iPv6HopByHopHeader) { KLALBOAMHopByHopTLV oam = null; List tlvs = iPv6HopByHopHeader.getTlvs(); KLALBPassportHopByHopTLV prevEndPassport = null; for (IPv6HopByHopTLV tlv : tlvs) { if (tlv instanceof KLALBOAMHopByHopTLV) { oam = (KLALBOAMHopByHopTLV) tlv; } else if (tlv instanceof KLALBPassportHopByHopTLV) { prevEndPassport = (KLALBPassportHopByHopTLV) tlv; } } if (oam != null) { long timentp = clock.getCurrentTimeNTP64().longValue(); int packetLength = (int) iPv6Packet.getTotalLength(); long oamt = oam.getTimestamp(); long delta = timentp - oamt; long prevhop = oamt; if (prevEndPassport != null) { prevhop += prevEndPassport.getTimestampOffsetLong(); } if (oam.isRecordPassport()) { tlvs.add(new KLALBPassportHopByHopTLV(packetLength, (int) (delta >> 4))); } if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket) { } else { boolean phop = oam.isPostcardToPreviousHop(); boolean psrc = oam.isPostcardToSource(); // System.out.println(iPv6Packet.getPayload()); if (phop) { putPostcard(locator.getAddress(), prevSID, sourceSID, oam.getUUID(), prevhop, timentp - prevhop, packetLength); } if (psrc) { putPostcard(locator.getAddress(), iPv6Packet.getSourceAddress(), sourceSID, oam.getUUID(), oamt, delta, packetLength); } } } } private TimeoutConcurrentHashMap, MessageBatcher> postcardBatch = new TimeoutConcurrentHashMap<>( 1000000000L); private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp, long delta, int packetLength) { PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength); /*Pair addressPair = new Pair(src, dst); MessageBatcher batch = postcardBatch.computeIfAbsent(addressPair, (k) -> { MessageBatcher mb = new ArrayListMessageBatcher(30, 2000000L); mb.setConsumer((list) -> { enqueuePacketSendTask(() -> { IPv6Packet icmpv = new IPv6Packet(); icmpv.setSourceAddress(k.first); icmpv.setDestinationAddress(k.second); icmpv.setTrafficClass(0); icmpv.setVersion(6); icmpv.setFlowLabel(0); icmpv.setHopLimit(255); // ICMP消息TTL设为最大值 ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket(); ipl.getPostcards().addAll(list); ipl.setParent(icmpv); ipl.updateChecksum(); icmpv.setPayload(ipl); return icmpv; }); }); return mb; }); postcardBatch.refresh(addressPair); batch.putMessage(pn);*/ enqueuePacketSendTask(() -> { IPv6Packet icmpv = new IPv6Packet(); icmpv.setSourceAddress(src); icmpv.setDestinationAddress(dst); icmpv.setTrafficClass(0); icmpv.setVersion(6); icmpv.setFlowLabel(0); icmpv.setHopLimit(255); // ICMP消息TTL设为最大值 ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket(); ipl.getPostcards().addAll(List.of(pn)); ipl.setParent(icmpv); ipl.updateChecksum(); icmpv.setPayload(ipl); return icmpv; }); } private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2( (int) (Runtime.getRuntime().availableProcessors()), Thread.ofVirtual().name("SRv6 Routing").factory()); //private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(4, Thread.ofVirtual().name("SRv6 Routing").factory()); /*public static HighPerformanceExecutor2 getDefaultExecutor() { return defaultExecutor; }*/ // private ArrayBlockingQueue> packetQueue=new // ArrayBlockingQueue<>(10000); public void enqueuePacketSendTask(Supplier sendTask) { // packetQueue.add(object); switch(performanceStrategy) { case SINGLE_CORE: runPacketSendTask0(sendTask, false); break; case MULTI_FILL: case MULTI_SCATTER: defaultExecutor.executeWithCongestionReport((state) -> { runPacketSendTask0(sendTask, state); }, 20,performanceStrategy); break; } } public void runPacketSendTask0(Supplier sendTask,boolean ecn) { try { long start=System.nanoTime(); IPv6Packet packet=sendTask.get(); if(ecn) { packet.markCE(); } insertSRHandRoutePacket(null, packet); // 插入SRH并路由 long time=System.nanoTime()-start; backplaneCount(time,ecn); } catch (Exception e) { e.printStackTrace(); } } public void runPacketSendTask(Supplier sendTask) { runPacketSendTask0(sendTask,false); } public void onReceive(IPv6NetworkLink link,IPv6Packet t){ if (unduplicate(t)) { insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包 } } public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier pack) { defaultExecutor.executeWithCongestionReport((state) -> { try { long start=System.nanoTime(); IPv6Packet packet = pack.get(); if(state) { packet.markCE(); } onReceive(link ,packet); long time=System.nanoTime()-start; backplaneCount(time,state); } catch (Exception e) { e.printStackTrace(); } },20,performanceStrategy); } public void enqueuePacket(IPv6Packet packet) { enqueuePacketSendTask(() -> { return packet; }); } //private BandwidthSampler sampler=new BandwidthSampler(); private FixedSizeStripedLongCounter timeAdder=KLALBUtils.createCounter(); private FixedSizeStripedLongCounter countAdder=KLALBUtils.createCounter(); private FixedSizeStripedLongCounter ECNcountAdder=KLALBUtils.createCounter(); private FixedSizeStripedLongCounter LosscountAdder=KLALBUtils.createCounter(); private void backplaneCount(long time,boolean ECN) { timeAdder.inc(time); countAdder.inc(1); if(ECN) { ECNcountAdder.inc(1); } } private volatile long backplaneTime=0; private volatile double ECNRate=0; private volatile double LossRate=0; private volatile long backplanePPS=0; private volatile long backplanePPSMax=0; private volatile long prevTime=System.nanoTime(); private Timer backplaneTimer=new Timer(); private void updateBackplaneCounter() { long curr=System.nanoTime(); long totalTime=timeAdder.getAndReset(); long totalCount=countAdder.getAndReset(); long ECNCount=ECNcountAdder.getAndReset(); long LossCount=LosscountAdder.getAndReset(); if(totalCount!=0) { backplaneTime=totalTime/totalCount; ECNRate=((double)ECNCount)/totalCount; LossRate=((double)LossCount)/totalCount; } backplanePPS=totalCount*1000000000L/(curr-prevTime); if(backplanePPSMax{ * while(true) { try { SupplierpacketSup= packetQueue.take(); * insertSRHandRoutePacket(packetSup.get()); // 插入SRH并路由 }catch(Exception e) { * e.printStackTrace(); } } } ).start(); } } */ private KLALBRoutingProtocol klalbRouteProtol = null; // KLALB路由协议实例 // 启动KLALB路由协议 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; } public LoopbackIPv6NetworkLink getinLoopback() { return inLoopBack; } // 获取邻居信息 public List getNeighbors() { List result = new ArrayList<>(); List links = getLinkTabel(); Object[] nls = links.toArray(); for (int i = 0; i < nls.length; i++) { IPv6NetworkLink nl = (IPv6NetworkLink) nls[i]; if ((!nl.isLoopBack())&&nl.isUp()) { // 排除环回接口 List neis = nl.getNeighborsInfo(); for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); result.add(addresses); // 添加邻居信息 } } } return result; } // 获取所有SID public Set getLocators() { Set result = new HashSet<>(); List links = getLinkTabel(); Object[] nls = links.toArray(); for (int i = 0; i < nls.length; i++) { IPv6NetworkLink nl = (IPv6NetworkLink) nls[i]; if (!nl.isLoopBack()) { // 排除环回接口 List neis = nl.getNeighborsInfo(); for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); if (addresses.getLocator() != null) result.add(addresses.getLocator()); // 添加邻居SID } } } return result; } }