# Conflicts:
#	.classpath
#	src/org/kne/cloud/network/klalb/KLALBControllerConfigItem.java
This commit is contained in:
2026-08-30 21:42:29 +08:00
46 changed files with 4351 additions and 446 deletions
@@ -0,0 +1,52 @@
package org.kne.cloud.network.srv6;
import java.util.List;
import org.kne.cloud.network.MultiProtocolSocketAddress;
/**
* 节点信息(开放线路 + 设备名称 + 设备描述),由路由协议 JSON API 查询获得。
*/
public class KLALBNodeInformation {
private List<MultiProtocolSocketAddress> openLines;
private String deviceName;
private String deviceDescription;
public KLALBNodeInformation(List<MultiProtocolSocketAddress> openLines, String deviceName,
String deviceDescription) {
super();
this.openLines = openLines;
this.deviceName = deviceName;
this.deviceDescription = deviceDescription;
}
public List<MultiProtocolSocketAddress> getOpenLines() {
return openLines;
}
public void setOpenLines(List<MultiProtocolSocketAddress> openLines) {
this.openLines = openLines;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceDescription() {
return deviceDescription;
}
public void setDeviceDescription(String deviceDescription) {
this.deviceDescription = deviceDescription;
}
@Override
public String toString() {
return "KLALBNodeInformation [openLines=" + openLines + ", deviceName=" + deviceName
+ ", deviceDescription=" + deviceDescription + "]";
}
}
@@ -43,6 +43,10 @@ public class KLALBRoutingProtocol extends Thread{
private RouterInfo selfRouterInfo;
private Map<IPv6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
public Map<IPv6Address, RouterInfo> getNetmap() {
return netmap;
}
private volatile Map<IPv6Address,Long>addresses;
@@ -545,6 +549,7 @@ public class KLALBRoutingProtocol extends Thread{
List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
RouterInfo ri=new RouterInfo(System.currentTimeMillis(),router.getLocator(),router.getASN());
ri.setDeviceName(router.getDeviceName());
for(int i=0;i<nls.length;i++) {
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
if((!nl.isLoopBack())&&nl.isUp()) {
@@ -595,6 +600,19 @@ public class KLALBRoutingProtocol extends Thread{
public Map<IPv6Address, Long> getAddresses() {
return addresses;
}
/**
* 查询某地址广播的设备名称(未知返回null)
*/
public String getDeviceName(IPv6Address address) {
RouterInfo ri=netmap.get(address);
if(ri!=null) {
String dn=ri.getDeviceName();
if(dn!=null&&!dn.isEmpty())
return dn;
}
return null;
}
public Map<IPv6Address, List<LinkDirection>> getPaths() {
return paths;
}
@@ -29,20 +29,27 @@ public class KLALBRoutingProtocolAPIClient {
JsonDataPacket relate = null;
//System.out.println(ruid + " " + window.getSendmap());
switch (dataobj.getType()) {
case KLALBRoutingProtocolJsonData.OPEN_LINES_RESP:
case KLALBRoutingProtocolJsonData.NODE_INFO_FULL_RESP:
case KLALBRoutingProtocolJsonData.NODE_INFO_TINY_RESP:
if ((relate = window.ack(ruid)) != null) {
List<?> connects = (List<?>) dataobj.getData();
List<MultiProtocolSocketAddress> connectsm = new ArrayList<MultiProtocolSocketAddress>(connects.size());
for (Object open : connects) {
if (open instanceof MultiProtocolSocketAddress) {
connectsm.add((MultiProtocolSocketAddress) open);
} else {
connectsm.add(new MultiProtocolSocketAddress((String) open));
List<MultiProtocolSocketAddress> connectsm = new ArrayList<MultiProtocolSocketAddress>(
connects == null ? 0 : connects.size());
if (connects != null) {
for (Object open : connects) {
if (open instanceof MultiProtocolSocketAddress) {
connectsm.add((MultiProtocolSocketAddress) open);
} else {
connectsm.add(new MultiProtocolSocketAddress((String) open));
}
}
}
((Consumer<List<MultiProtocolSocketAddress>>) relate.getUserCallback()).accept(connectsm);
// 组装节点信息(线路 + 设备名称 + 设备描述,精简模式下线路与描述为 null)
KLALBNodeInformation info = new KLALBNodeInformation(connectsm, dataobj.getDeviceName(),
dataobj.getDeviceDescription());
((Consumer<KLALBNodeInformation>) relate.getUserCallback()).accept(info);
}
break;
}
@@ -56,11 +63,26 @@ public class KLALBRoutingProtocolAPIClient {
clr.register(this, releaser);
}
public void requestOpenLines(SocketAddress addr, Consumer<List<MultiProtocolSocketAddress>> callback)
/**
* 精简查询:仅获取对端设备名称(开销最小,适用于未查看节点详情的场景)。
*/
public void requestNodeInfoTiny(SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
sendNodeInfoRequest(KLALBRoutingProtocolJsonData.NODE_INFO_TINY_REQ, addr, callback);
}
/**
* 完整查询:获取对端开放线路 + 设备名称 + 设备描述(查看节点信息时使用)。
*/
public void requestNodeInfoFull(SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
sendNodeInfoRequest(KLALBRoutingProtocolJsonData.NODE_INFO_FULL_REQ, addr, callback);
}
private void sendNodeInfoRequest(String type, SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
UUID suid = UUID.randomUUID();
KLALBRoutingProtocolJsonData json = new KLALBRoutingProtocolJsonData(
KLALBRoutingProtocolJsonData.OPEN_LINES_REQ, suid, null);
KLALBRoutingProtocolJsonData json = new KLALBRoutingProtocolJsonData(type, suid, null);
JsonDataPacket packet = new JsonDataPacket(json);
packet.setUserCallback(callback);
window.put(suid, packet);
@@ -21,11 +21,21 @@ public class KLALBRoutingProtocolAPIServer {
KLALBRoutingProtocolJsonData dataobj= data.getDecodedData();
InetSocketAddress addrs=(InetSocketAddress) addr;
switch(dataobj.getType()){
case KLALBRoutingProtocolJsonData.OPEN_LINES_REQ:
if(controller.getConfigItem()==null||(!controller.getConfigItem().isDenyLineTableQuery())) {
KLALBRoutingProtocolJsonData json=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.OPEN_LINES_RESP,dataobj.getUuid(),controller.getSelflineTable());
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(json),addr);
case KLALBRoutingProtocolJsonData.NODE_INFO_TINY_REQ:
// 精简查询:仅返回设备名称(设备名称随路由信息广播公开,不受 denyExternalEndpointQuery 限制)
KLALBRoutingProtocolJsonData tinyjson=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.NODE_INFO_TINY_RESP,dataobj.getUuid(),null);
tinyjson.setDeviceName(controller.getIpv6Router().getDeviceName());
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(tinyjson),addr);
break;
case KLALBRoutingProtocolJsonData.NODE_INFO_FULL_REQ:
// 完整查询:设备名称与描述总是正常响应;denyExternalEndpointQuery 仅隐藏外部端点列表
boolean denyEndpoints=controller.getConfigItem()!=null&&controller.getConfigItem().isDenyExternalEndpointQuery();
KLALBRoutingProtocolJsonData json=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.NODE_INFO_FULL_RESP,dataobj.getUuid(),denyEndpoints?null:controller.getExternalEndpoints());
json.setDeviceName(controller.getIpv6Router().getDeviceName());// 附带本机设备名称
if(controller.getConfigItem()!=null) {
json.setDeviceDescription(controller.getConfigItem().getDeviceDescription());// 附带本机设备描述
}
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(json),addr);
break;
}
} catch (IOException e) {
@@ -3,11 +3,27 @@ package org.kne.cloud.network.srv6;
import java.util.UUID;
public class KLALBRoutingProtocolJsonData {
public static final String OPEN_LINES_REQ="openlinesreq";
public static final String OPEN_LINES_RESP="openlinesresp";
public static final String NODE_INFO_TINY_REQ="nodeinfotinyreq";// 精简查询:仅设备名称
public static final String NODE_INFO_TINY_RESP="nodeinfotinyresp";
public static final String NODE_INFO_FULL_REQ="nodeinfofullreq";// 完整查询:开放线路+设备名称+设备描述
public static final String NODE_INFO_FULL_RESP="nodeinfofullresp";
private String type;
private UUID uuid;
private Object data;
private String deviceName;// 对端设备名称
private String deviceDescription;// 对端设备描述
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceDescription() {
return deviceDescription;
}
public void setDeviceDescription(String deviceDescription) {
this.deviceDescription = deviceDescription;
}
public String getType() {
return type;
}
@@ -24,6 +40,8 @@ public class KLALBRoutingProtocolJsonData {
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
result = prime * result + ((deviceName == null) ? 0 : deviceName.hashCode());
result = prime * result + ((deviceDescription == null) ? 0 : deviceDescription.hashCode());
return result;
}
@Override
@@ -50,6 +68,16 @@ public class KLALBRoutingProtocolJsonData {
return false;
} else if (!uuid.equals(other.uuid))
return false;
if (deviceName == null) {
if (other.deviceName != null)
return false;
} else if (!deviceName.equals(other.deviceName))
return false;
if (deviceDescription == null) {
if (other.deviceDescription != null)
return false;
} else if (!deviceDescription.equals(other.deviceDescription))
return false;
return true;
}
public KLALBRoutingProtocolJsonData(String type, UUID uuid, Object data) {
@@ -60,7 +88,8 @@ public class KLALBRoutingProtocolJsonData {
}
@Override
public String toString() {
return "KLALBRoutingProtocolJsonData [type=" + type + ", uuid=" + uuid + ", data=" + data + "]";
return "KLALBRoutingProtocolJsonData [type=" + type + ", uuid=" + uuid + ", data=" + data + ", deviceName="
+ deviceName + ", deviceDescription=" + deviceDescription + "]";
}
}
@@ -60,6 +60,7 @@ public class RouterInfo implements Serializable{
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses);
}
private List<NeighborInfo> neighborAddresses=new ArrayList<>();
private String deviceName=""; // 设备名称(广播时携带,描述不广播)
private long createTime;
@@ -90,6 +91,14 @@ public class RouterInfo implements Serializable{
return neighborAddresses;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public RouterInfo( long createTime,IPv6AddressGroup locator,long asn) {
this.createTime = createTime;
this.locator=locator;
@@ -106,6 +115,7 @@ public class RouterInfo implements Serializable{
for( NeighborInfo neighborInfo :neighborAddresses) {
neighborInfo.writeToStream(out);
}
out.writeUTF(deviceName==null?"":deviceName);
}
protected void writeToChannel(WritableByteChannel dto) throws IOException {
@@ -126,6 +136,7 @@ public class RouterInfo implements Serializable{
neighborAddresses.add(nif);
}
deviceName=in.readUTF();
}
}
@@ -294,6 +294,15 @@ public class SRv6Router {
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;