- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直致力于使用在 SQL Server 2012 实例上运行的 T-SQL 从 IPv4 和 IPv6 地址范围生成 CIDR。通常我们的应用程序(在数据库之外)负责计算 CIDR,但我目前需要在数据库中进行 CIDR 计算。因为 IPv6 太大而无法存储在 bigint
中我们将 IP 地址存储为 binary(4)
的数据类型或 binary(16)
.
计算 IPv4 范围的路由前缀虽然有点难看,但相对简单:
declare @ipv4_begin binary(4)
,@ipv4_end binary(4)
set @ipv4_begin = 0xC0A80000 -- '192.168.000.000'
set @ipv4_end = 0xC0A8FFFF -- '192.168.255.255'
select 32 - LOG(
Cast(@ipv4_end As bigint)
- Cast(@ipv4_begin As bigint) + 1, 2
) as ipv4_route_prefix
遗憾的是,针对 IPv6 修改的相同查询不起作用。它不起作用的原因是因为 IPv6 地址大于可以存储在 bigint
中的地址。数据类型(我们使用 binary(4)
和 binary(16)
进行存储的原因):
declare @ipv6_begin binary(16)
,@ipv6_end binary(16)
set @ipv6_begin = 0xFC000000000000000000000000000000 -- fc00::
set @ipv6_end = 0xFC00000000000000FFFFFFFFFFFFFFFF -- fc00::ffff:ffff:ffff:ffff
-- This will cause error: 'An invalid floating point operation occurred.'
select 128 - LOG(
Cast(@ipv6_end As bigint)
- Cast(@ipv6_begin As bigint) + 1, 2
) as ipv6_route_prefix
除了不稳定的按位运算(最终不起作用)之外,我还没有想出任何可以在数据库中进行此计算的方法。
是否可以根据 T-SQL 中的 IPv6 地址范围计算 IPv6 CIDR 的路由前缀?
最佳答案
嗯,对于 IPv4,您已经有了一个巧妙的技巧——只需将值分成我们可以处理的最大块,然后重复这个技巧。
SELECT ISNULL(MIN(32 - B + N), 128)
FROM (VALUES
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 1, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 1, 4)
) + 1, 2), 0),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 5, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 5, 4)
) + 1, 2), 32),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 9, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 9, 4)
) + 1, 2), 64),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 13, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 13, 4)
) + 1, 2), 96)
) AS Bits(B, N)
WHERE B <> 0;
我们确定每个 block 中第一个设置位的位置,然后选择最低的这样的位——如果没有这样的位,则所有位都匹配(ISNULL
涵盖了这种情况)。如果您将“128”替换为“32”,这也适用于 IPv4,但显然您已经有了一个表达式。我们可以将它打包成一个对两者都适用的函数:
CREATE FUNCTION dbo.CidrPrefixFromRange(@ip_begin VARBINARY(16), @ip_end VARBINARY(16))
RETURNS TABLE AS
RETURN
SELECT ISNULL(MIN(32 - B + N), DATALENGTH(@ip_begin) * 8) AS Prefix
FROM (VALUES
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 1, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 1, 4)
) + 1, 2), 0),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 5, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 5, 4)
) + 1, 2), 32),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 9, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 9, 4)
) + 1, 2), 64),
(LOG(
CONVERT(BIGINT, SUBSTRING(@ip_end, 13, 4)) -
CONVERT(BIGINT, SUBSTRING(@ip_begin, 13, 4)
) + 1, 2), 96)
) AS Bits(B, N)
WHERE B <> 0;
示例用途:
-- 192.168.100.0 - 192.168.103.255
SELECT * FROM dbo.CidrPrefixFromRange(0xc0a86400, 0xc0a867ff) -- /22
-- 192.168.0.0 - 192.168.255.255
SELECT * FROM dbo.CidrPrefixFromRange(0xC0A80000, 0xC0A8FFFF) -- /16
-- fc00:: - fc00::ffff:ffff:ffff:ffff
SELECT * FROM dbo.CidrPrefixFromRange(
0xFC000000000000000000000000000000,
0xFC00000000000000FFFFFFFFFFFFFFFF
) -- /64
-- 127.0.0.1 - 127.0.0.1
SELECT * FROM dbo.CidrPrefixFromRange(0x7f000001, 0x7f000001) -- /32
没有关于这有多高效的 promise ......如果你想要效率,这不是你想要在 T-SQL 中做的事情。 :-)
附录:我使用表值函数而不是更简单的标量值函数(毕竟,我们只返回一个值)的原因是标量值函数 perform far worse inside a query .内联表值函数可以有效地CROSS APPLY
到一个表。出于这个原因,作为一种习惯,我将每个函数都写成内联 TVF,即使我没有预见到这样的用途——任何东西都比标量值函数好。
关于sql-server - 如何在 SQL 中计算 IPv6 CIDR 路由前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28595821/
目前部署在 Kubernetes 中的服务,通过 Calico BGP 将 Service 与集群外网络打通,并在外部的 nginx 中配置 Service 地址对外进行服务暴露。经过一段时间的观察
如发现here , 有一种新的 kube 服务是 IPVS 并且有很多负载均衡算法。 唯一的问题是我没有找到指定这些算法的位置。 我的理解: rr:循环法->循环调用后端pod lc:最少连接-> 将
我想尝试这种新的代理模式以及它为我们的一些应用程序提供的各种调度程序。到目前为止,我一直无法找到更改默认模式的方法 iptables至 ipvs在 GKE 节点上。 每个人都说通过--proxy-mo
我想在现有集群中为 IPVS 启用 Kube-proxy 模式。目前,它在 IPtables 上运行。如何在不影响现有工作负载的情况下将其更改为 IPVS? 我已经安装了所有必需的模块来启用它。另外,
我正在开发的应用程序作为 Kubernetes 集群中的部署运行。为此部署创建的 Pod 分布在集群中的各个节点上。我们的应用程序一次只能处理一个 TCP 连接,并且会拒绝进一步的连接。目前,我们使用
我是一名优秀的程序员,十分优秀!