@@ -30,7 +30,7 @@ import ovn
import lswitch
import lrouter
-function mAC_ADDR_SPACE(): bit<64> = 64'hffffff
+function mAC_ADDR_SPACE(): bit<48> = 48'hffffff
/*
* IPv4 dynamic address allocation.
@@ -112,10 +112,10 @@ SwitchIPv4ReservedAddress(.lswitch = ls._uuid,
Right{ranges} -> {
for (rng in ranges) {
(var ip_start, var ip_end) = rng;
- var start = iptohl(ip_start);
+ var start = ip_start.a;
var end = match (ip_end) {
None -> start,
- Some{ip} -> iptohl(ip)
+ Some{ip} -> ip.a
};
start = max(start_ipv4, start);
end = min(start_ipv4 + total_ipv4s - 1, end);
@@ -147,7 +147,7 @@ SwitchIPv4ReservedAddress(.lswitch = ls._uuid,
var addrs = {
var addrs = set_empty();
for (addr in lport_addrs.ipv4_addrs) {
- var addr_host_endian = iptohl(addr.addr);
+ var addr_host_endian = addr.addr.a;
if (addr_host_endian >= start_ipv4 and addr_host_endian < start_ipv4 + total_ipv4s) {
addrs.insert(addr_host_endian)
} else ()
@@ -166,7 +166,7 @@ SwitchIPv4ReservedAddress(.lswitch = ls._uuid,
var addrs = {
var addrs = set_empty();
for (addr in rport.networks.ipv4_addrs) {
- var addr_host_endian = iptohl(addr.addr);
+ var addr_host_endian = addr.addr.a;
if (addr_host_endian >= start_ipv4 and addr_host_endian < start_ipv4 + total_ipv4s) {
addrs.insert(addr_host_endian)
} else ()
@@ -177,7 +177,7 @@ SwitchIPv4ReservedAddress(.lswitch = ls._uuid,
/* Add reserved address group (5) */
SwitchIPv4ReservedAddress(.lswitch = sw.ls._uuid,
- .addr = iptohl(ip_addr)) :-
+ .addr = ip_addr.a) :-
&SwitchPort(.sw = &sw, .lsp = lsp, .static_dynamic_ipv4 = Some{ip_addr}).
/* Aggregate all reserved addresses for each switch. */
@@ -236,7 +236,7 @@ SwitchPortAllocatedIPv4DynAddress(lsport, dyn_addr) :-
need_addr.push(deref(port).lsp._uuid)
},
Some{addr} -> {
- var haddr = iptohl(addr.addr);
+ var haddr = addr.addr.a;
if (haddr < start_ipv4 or haddr >= start_ipv4 + total_ipv4s) {
need_addr.push(deref(port).lsp._uuid)
} else if (used_addrs.contains(haddr)) {
@@ -257,7 +257,7 @@ SwitchPortAllocatedIPv4DynAddress(lsport, dyn_addr) :-
},
var port_address = FlatMap(dyn_addresses),
(var lsport, var dyn_addr_bits) = port_address,
- var dyn_addr = dyn_addr_bits.map(hltoip).
+ var dyn_addr = dyn_addr_bits.map(|x| InAddr{x}).
/* Compute new dynamic IPv4 address assignment:
* - port does not need dynamic IP - use static_dynamic_ip if any
@@ -278,7 +278,7 @@ SwitchPortNewIPv4DynAddress(lsp._uuid, ip_addr) :-
match (sw.subnet) {
None -> { None },
Some{(_, _, start_ipv4, total_ipv4s)} -> {
- var haddr = iptohl(addr);
+ var haddr = addr.a;
if (haddr < start_ipv4 or haddr >= start_ipv4 + total_ipv4s) {
/* new static ip is not valid */
None
@@ -298,24 +298,20 @@ SwitchPortNewIPv4DynAddress(lsport, addr) :-
* Dynamic MAC address allocation.
*/
-function get_mac_prefix(options: Map<string,string>, uuid: uuid) : bit<64> =
+function get_mac_prefix(options: Map<string,string>, uuid: uuid) : bit<48> =
{
- var existing_prefix = match (map_get(options, "mac_prefix")) {
- Some{prefix} -> scan_eth_addr_prefix(prefix),
- None -> None
- };
- match (existing_prefix) {
- Some{prefix} -> prefix,
- None -> pseudorandom_mac(uuid, 16'h1234) & 64'hffffff000000
+ match (map_get(options, "mac_prefix").and_then(scan_eth_addr_prefix)) {
+ Some{prefix} -> prefix.ha,
+ None -> eth_addr_pseudorandom(uuid, 16'h1234).ha & 48'hffffff000000
}
}
-function put_mac_prefix(options: Map<string,string>, mac_prefix: bit<64>)
+function put_mac_prefix(options: Map<string,string>, mac_prefix: bit<48>)
: Map<string,string> =
{
map_insert_imm(options, "mac_prefix",
- string_substr(to_string(eth_addr_from_uint64(mac_prefix)), 0, 8))
+ string_substr(to_string(EthAddr{mac_prefix}), 0, 8))
}
-relation MacPrefix(mac_prefix: bit<64>)
+relation MacPrefix(mac_prefix: bit<48>)
MacPrefix(get_mac_prefix(options, uuid)) :-
nb::NB_Global(._uuid = uuid, .options = options).
@@ -324,24 +320,24 @@ MacPrefix(get_mac_prefix(options, uuid)) :-
* (2) static MAC component of "dynamic" `lsp.addresses`.
* (3) addresses associated with router ports peered with the switch.
*
- * Addresses are kept in 64-bit host-endian format.
+ * Addresses are kept in host-endian format.
*/
-relation ReservedMACAddress(addr: bit<64>)
+relation ReservedMACAddress(addr: bit<48>)
/* Add reserved address group (1). */
-ReservedMACAddress(.addr = eth_addr_to_uint64(lport_addrs.ea)) :-
+ReservedMACAddress(.addr = lport_addrs.ea.ha) :-
SwitchPortStaticAddresses(.addrs = lport_addrs).
/* Add reserved address group (2). */
-ReservedMACAddress(.addr = eth_addr_to_uint64(mac_addr)) :-
+ReservedMACAddress(.addr = mac_addr.ha) :-
&SwitchPort(.lsp = lsp, .static_dynamic_mac = Some{mac_addr}).
/* Add reserved address group (3). */
-ReservedMACAddress(.addr = eth_addr_to_uint64(rport.networks.ea)) :-
+ReservedMACAddress(.addr = rport.networks.ea.ha) :-
&SwitchPort(.peer = Some{&rport}).
/* Aggregate all reserved MAC addresses. */
-relation ReservedMACAddresses(addrs: Set<bit<64>>)
+relation ReservedMACAddresses(addrs: Set<bit<48>>)
ReservedMACAddresses(addrs) :-
ReservedMACAddress(addr),
@@ -360,7 +356,7 @@ ReservedMACAddresses(set_empty()) :-
* Case 2: needs dynamic MAC, has dynamic MAC, has existing dynamic MAC with the right prefix
* needs dynamic MAC, does not have fixed dynamic MAC, doesn't have existing dynamic MAC with correct prefix
*/
-relation SwitchPortAllocatedMACDynAddress(lsport: uuid, dyn_addr: bit<64>)
+relation SwitchPortAllocatedMACDynAddress(lsport: uuid, dyn_addr: bit<48>)
SwitchPortAllocatedMACDynAddress(lsport, dyn_addr),
SwitchPortDuplicateMACAddress(dup_addrs) :-
@@ -380,8 +376,8 @@ SwitchPortDuplicateMACAddress(dup_addrs) :-
None -> Some { mac_prefix | 1 },
Some{addr} -> {
/* The tentative MAC's suffix will be in the interval (1, 0xfffffe). */
- var mac_suffix: bit<24> = iptohl(addr)[23:0] % ((mAC_ADDR_SPACE() - 1)[23:0]) + 1;
- Some{ mac_prefix | (40'd0 ++ mac_suffix) }
+ var mac_suffix: bit<24> = addr.a[23:0] % ((mAC_ADDR_SPACE() - 1)[23:0]) + 1;
+ Some{ mac_prefix | (24'd0 ++ mac_suffix) }
}
};
match (port.dynamic_address) {
@@ -390,7 +386,7 @@ SwitchPortDuplicateMACAddress(dup_addrs) :-
need_addr.push((port.lsp._uuid, hint))
},
Some{dynaddr} -> {
- var haddr = eth_addr_to_uint64(dynaddr.ea);
+ var haddr = dynaddr.ea.ha;
if ((haddr ^ mac_prefix) >> 24 != 0) {
/* existing dynamic address is no longer valid */
need_addr.push((port.lsp._uuid, hint))
@@ -413,7 +409,7 @@ SwitchPortDuplicateMACAddress(dup_addrs) :-
var res_strs = vec_empty();
for (x in res) {
(var uuid, var addr) = x;
- res_strs.push("${uuid2str(uuid)}: ${eth_addr_from_uint64(addr)}")
+ res_strs.push("${uuid2str(uuid)}: ${EthAddr{addr}}")
};
(res, dup_addrs)
},
@@ -449,7 +445,7 @@ SwitchPortNewMACDynAddress(lsp._uuid, mac_addr) :-
}
}.
-SwitchPortNewMACDynAddress(lsport, Some{eth_addr_from_uint64(addr)}) :-
+SwitchPortNewMACDynAddress(lsport, Some{EthAddr{addr}}) :-
SwitchPortAllocatedMACDynAddress(lsport, addr).
SwitchPortNewMACDynAddress(lsp._uuid, addr) :-
@@ -462,7 +458,7 @@ SwitchPortNewMACDynAddress(lsp._uuid, addr) :-
/*
* Dynamic IPv6 address allocation.
- * `needs_dynamic_ipv6address` -> in6_generate_eui64(mac, ipv6_prefix)
+ * `needs_dynamic_ipv6address` -> mac.to_ipv6_eui64(ipv6_prefix)
*/
relation SwitchPortNewDynamicAddress(port: Ref<SwitchPort>, address: Option<lport_addresses>)
@@ -479,7 +475,7 @@ SwitchPortNewDynamicAddress(port, lport_address) :-
SwitchPortNewIPv4DynAddress(lsp._uuid, opt_ip4_addr),
var ip6_addr = match ((static_dynamic_ipv6, needs_dynamic_ipv6address, sw.ipv6_prefix)) {
(Some{ipv6}, _, _) -> " ${ipv6}",
- (_, true, Some{prefix}) -> " ${in6_generate_eui64(mac_addr, prefix)}",
+ (_, true, Some{prefix}) -> " ${mac_addr.to_ipv6_eui64(prefix)}",
_ -> ""
},
var ip4_addr = match (opt_ip4_addr) {
@@ -655,7 +655,7 @@ function find_lrp_member_ip(networks: lport_addresses, ip: v46_ip): Option<v46_i
match (ip) {
IPv4{ip4} -> {
for (na in networks.ipv4_addrs) {
- if (ip_same_network((na.addr, ip4), ipv4_netaddr_mask(na))) {
+ if ((na.addr, ip4).same_network(na.netmask())) {
/* There should be only 1 interface that matches the
* supplied IP. Otherwise, it's a configuration error,
* because subnets of a router's interfaces should NOT
@@ -667,7 +667,7 @@ function find_lrp_member_ip(networks: lport_addresses, ip: v46_ip): Option<v46_i
},
IPv6{ip6} -> {
for (na in networks.ipv6_addrs) {
- if (ipv6_same_network((na.addr, ip6), ipv6_netaddr_mask(na))) {
+ if ((na.addr, ip6).same_network(na.netmask())) {
/* There should be only 1 interface that matches the
* supplied IP. Otherwise, it's a configuration error,
* because subnets of a router's interfaces should NOT
@@ -242,12 +242,11 @@ function ipv6_parse_prefix(s: string): Option<in6_addr> {
None
},
Right{(subnet, mask)} -> {
- if (ip_count_cidr_bits(mask) == Some{32}
- or not ip_is_cidr(mask)) {
+ if (mask.cidr_bits() == Some{32} or not mask.is_cidr()) {
warn("bad 'subnet' ${subnet_str}");
None
} else {
- Some{(subnet, mask, (iptohl(subnet) & iptohl(mask)) + 1, ~iptohl(mask))}
+ Some{(subnet, mask, (subnet.a & mask.a) + 1, ~mask.a)}
}
}
}
@@ -732,7 +731,7 @@ function get_svc_monitor_mac(options: Map<string,string>, uuid: uuid)
};
match (existing_mac) {
Some{mac} -> mac,
- None -> eth_addr_from_uint64(pseudorandom_mac(uuid, 'h5678))
+ None -> eth_addr_pseudorandom(uuid, 'h5678)
}
}
function put_svc_monitor_mac(options: Map<string,string>,
@@ -224,7 +224,7 @@ IgmpRouterGroupPort(address, rtr_port.router, rtr_port.lrp._uuid) :-
* (RFC 4291 2.7).
*/
match (ipv6_parse(address)) {
- Some{ipv6} -> ipv6_is_routable_multicast(ipv6),
+ Some{ipv6} -> ipv6.is_routable_multicast(),
None -> true
},
var flood_port = FlatMap(sw_flood_ports),
@@ -23,90 +23,69 @@ function is_enabled(s: Option<bool>): bool = {
/*
* Ethernet addresses
*/
-extern type eth_addr
+typedef eth_addr = EthAddr {
+ ha: bit<48> // In host byte order, e.g. ha[40] is the multicast bit.
+}
-extern function eth_addr_zero(): eth_addr
-extern function eth_addr2string(addr: eth_addr): string
function to_string(addr: eth_addr): string {
eth_addr2string(addr)
}
-extern function scan_eth_addr(s: string): Option<eth_addr>
-extern function scan_eth_addr_prefix(s: string): Option<bit<64>>
extern function eth_addr_from_string(s: string): Option<eth_addr>
-extern function eth_addr_to_uint64(ea: eth_addr): bit<64>
-extern function eth_addr_from_uint64(x: bit<64>): eth_addr
-extern function eth_addr_mark_random(ea: eth_addr): eth_addr
+extern function scan_eth_addr(s: string): Option<eth_addr>
+extern function scan_eth_addr_prefix(s: string): Option<eth_addr>
+function eth_addr_zero(): eth_addr { EthAddr{0} }
+function eth_addr_pseudorandom(seed: uuid, variant: bit<16>) : eth_addr {
+ EthAddr{hash64(seed ++ variant) as bit<48>}.mark_random()
+}
+function mark_random(ea: eth_addr): eth_addr { EthAddr{ea.ha & ~(1 << 40) | (1 << 41)} }
-function pseudorandom_mac(seed: uuid, variant: bit<16>) : bit<64> = {
- eth_addr_to_uint64(eth_addr_mark_random(eth_addr_from_uint64(hash64(seed ++ variant))))
+function to_eui64(ea: eth_addr): bit<64> {
+ var ha = ea.ha as u64;
+ (((ha & 64'hffffff000000) << 16) | 64'hfffe000000 | (ha & 64'hffffff)) ^ (1 << 57)
}
+extern function eth_addr2string(addr: eth_addr): string
+
/*
* IPv4 addresses
*/
-extern type in_addr
-
-function to_string(ip: in_addr): string = {
- var x = iptohl(ip);
- "${x >> 24}.${(x >> 16) & 'hff}.${(x >> 8) & 'hff}.${x & 'hff}"
-}
-
-function ip_is_cidr(netmask: in_addr): bool {
- var x = ~iptohl(netmask);
- (x & (x + 1)) == 0
-}
-function ip_is_local_multicast(ip: in_addr): bool {
- (iptohl(ip) & 32'hffffff00) == 32'he0000000
-}
-
-function ip_create_mask(plen: bit<32>): in_addr {
- hltoip((64'h00000000ffffffff << (32 - plen))[31:0])
-}
-
-function ip_bitxor(a: in_addr, b: in_addr): in_addr {
- hltoip(iptohl(a) ^ iptohl(b))
-}
-
-function ip_bitand(a: in_addr, b: in_addr): in_addr {
- hltoip(iptohl(a) & iptohl(b))
-}
-
-function ip_network(addr: in_addr, mask: in_addr): in_addr {
- hltoip(iptohl(addr) & iptohl(mask))
-}
-
-function ip_host(addr: in_addr, mask: in_addr): in_addr {
- hltoip(iptohl(addr) & ~iptohl(mask))
+typedef in_addr = InAddr {
+ a: bit<32> // In host byte order.
}
-function ip_host_is_zero(addr: in_addr, mask: in_addr): bool {
- ip_is_zero(ip_host(addr, mask))
-}
+extern function ip_parse(s: string): Option<in_addr>
+extern function ip_parse_masked(s: string): Either<string/*err*/, (in_addr/*host_ip*/, in_addr/*mask*/)>
+extern function ip_parse_cidr(s: string): Either<string/*err*/, (in_addr/*ip*/, bit<32>/*plen*/)>
+extern function scan_static_dynamic_ip(s: string): Option<in_addr>
+function ip_create_mask(plen: bit<32>): in_addr { InAddr{(64'hffffffff << (32 - plen))[31:0]} }
-function ip_is_zero(a: in_addr): bool {
- iptohl(a) == 0
+function to_string(ip: in_addr): string = {
+ "${ip.a >> 24}.${(ip.a >> 16) & 'hff}.${(ip.a >> 8) & 'hff}.${ip.a & 'hff}"
}
-function ip_bcast(addr: in_addr, mask: in_addr): in_addr {
- hltoip(iptohl(addr) | ~iptohl(mask))
+function is_cidr(netmask: in_addr): bool { var x = ~netmask.a; (x & (x + 1)) == 0 }
+function is_local_multicast(ip: in_addr): bool { (ip.a & 32'hffffff00) == 32'he0000000 }
+function is_zero(a: in_addr): bool { a.a == 0 }
+function is_all_ones(a: in_addr): bool { a.a == 32'hffffffff }
+function cidr_bits(ip: in_addr): Option<bit<8>> {
+ if (ip.is_cidr()) {
+ Some{32 - ip.a.trailing_zeros() as u8}
+ } else {
+ None
+ }
}
-extern function ip_parse(s: string): Option<in_addr>
-extern function ip_parse_masked(s: string): Either<string/*err*/, (in_addr/*host_ip*/, in_addr/*mask*/)>
-extern function ip_parse_cidr(s: string): Either<string/*err*/, (in_addr/*ip*/, bit<32>/*plen*/)>
-extern function ip_count_cidr_bits(ip: in_addr): Option<bit<8>>
+function network(addr: in_addr, mask: in_addr): in_addr { InAddr{addr.a & mask.a} }
+function host(addr: in_addr, mask: in_addr): in_addr { InAddr{addr.a & ~mask.a} }
+function bcast(addr: in_addr, mask: in_addr): in_addr { InAddr{addr.a | ~mask.a} }
/* True if both 'ips' are in the same network as defined by netmask 'mask',
* false otherwise. */
-function ip_same_network(ips: (in_addr, in_addr), mask: in_addr): bool {
- ((iptohl(ips.0) ^ iptohl(ips.1)) & iptohl(mask)) == 0
+function same_network(ips: (in_addr, in_addr), mask: in_addr): bool {
+ ((ips.0.a ^ ips.1.a) & mask.a) == 0
}
-extern function iptohl(addr: in_addr): bit<32>
-extern function hltoip(addr: bit<32>): in_addr
-extern function scan_static_dynamic_ip(s: string): Option<in_addr>
-
/*
* parse IPv4 address list of the form:
* "10.0.0.4 10.0.0.10 10.0.0.20..10.0.0.50 10.0.0.100..10.0.0.110"
@@ -116,48 +95,79 @@ extern function parse_ip_list(ips: string): Either<string, Vec<(in_addr, Option<
/*
* IPv6 addresses
*/
-extern type in6_addr
-
-extern function in6_generate_lla(ea: eth_addr): in6_addr
-extern function in6_generate_eui64(ea: eth_addr, prefix: in6_addr): in6_addr
-extern function in6_is_lla(addr: in6_addr): bool
-extern function in6_addr_solicited_node(ip6: in6_addr): in6_addr
+typedef in6_addr = In6Addr {
+ aaaa: bit<128> // In host byte order.
+}
-extern function ipv6_string_mapped(addr: in6_addr): string
-extern function ipv6_parse_masked(s: string): Either<string/*err*/, (in6_addr/*ip*/, in6_addr/*mask*/)>
extern function ipv6_parse(s: string): Option<in6_addr>
+extern function ipv6_parse_masked(s: string): Either<string/*err*/, (in6_addr/*ip*/, in6_addr/*mask*/)>
extern function ipv6_parse_cidr(s: string): Either<string/*err*/, (in6_addr/*ip*/, bit<32>/*plen*/)>
-extern function ipv6_bitxor(a: in6_addr, b: in6_addr): in6_addr
-extern function ipv6_bitand(a: in6_addr, b: in6_addr): in6_addr
-extern function ipv6_bitnot(a: in6_addr): in6_addr
-extern function ipv6_create_mask(mask: bit<32>): in6_addr
-extern function ipv6_is_zero(a: in6_addr): bool
-extern function ipv6_is_routable_multicast(a: in6_addr): bool
-extern function ipv6_is_all_hosts(a: in6_addr): bool
-function ipv6_network(addr: in6_addr, mask: in6_addr): in6_addr {
- ipv6_bitand(addr, mask)
+// Return IPv6 link local address for the given 'ea'.
+function to_ipv6_lla(ea: eth_addr): in6_addr {
+ In6Addr{(128'hfe80 << 112) | (ea.to_eui64() as u128)}
+}
+
+// Returns IPv6 EUI64 address for 'ea' with the given 'prefix'.
+function to_ipv6_eui64(ea: eth_addr, prefix: in6_addr): in6_addr {
+ In6Addr{(prefix.aaaa & ~128'hffffffffffffffff) | (ea.to_eui64() as u128)}
+}
+
+function ipv6_create_mask(plen: bit<32>): in6_addr {
+ if (plen == 0) {
+ In6Addr{0}
+ } else {
+ var shift = max(0, 128 - plen);
+ In6Addr{128'hffffffffffffffffffffffffffffffff << shift}
+ }
}
-function ipv6_host(addr: in6_addr, mask: in6_addr): in6_addr {
- ipv6_bitand(addr, ipv6_bitnot(mask))
+function is_zero(a: in6_addr): bool { a.aaaa == 0 }
+function is_all_ones(a: in6_addr): bool { a.aaaa == 128'hffffffffffffffffffffffffffffffff }
+function is_lla(a: in6_addr): bool { (a.aaaa >> 64) == 128'hfe80000000000000 }
+function is_all_hosts(a: in6_addr): bool { a.aaaa == 128'hff020000000000000000000000000001 }
+function is_cidr(netmask: in6_addr): bool { var x = ~netmask.aaaa; (x & (x + 1)) == 0 }
+function is_multicast(a: in6_addr): bool { (a.aaaa >> 120) == 128'hff }
+function is_routable_multicast(a: in6_addr): bool {
+ a.is_multicast() and match ((a.aaaa >> 112) as u8 & 8'hf) {
+ 0 -> false,
+ 1 -> false,
+ 2 -> false,
+ 3 -> false,
+ 15 -> false,
+ _ -> true
+ }
+}
+
+extern function string_mapped(addr: in6_addr): string
+
+function network(addr: in6_addr, mask: in6_addr): in6_addr { In6Addr{addr.aaaa & mask.aaaa} }
+function host(addr: in6_addr, mask: in6_addr): in6_addr { In6Addr{addr.aaaa & ~mask.aaaa} }
+function solicited_node(ip6: in6_addr): in6_addr {
+ In6Addr{(ip6.aaaa & 128'hffffff) | 128'hff02_0000_0000_0000_0000_0001_ff00_0000}
}
/* True if both 'ips' are in the same network as defined by netmask 'mask',
* false otherwise. */
-function ipv6_same_network(ips: (in6_addr, in6_addr), mask: in6_addr): bool {
- ipv6_network(ips.0, mask) == ipv6_network(ips.1, mask)
+function same_network(ips: (in6_addr, in6_addr), mask: in6_addr): bool {
+ ips.0.network(mask) == ips.1.network(mask)
}
-extern function ipv6_multicast_to_ethernet(ip6: in6_addr): eth_addr
-extern function ipv6_is_cidr(ip6: in6_addr): bool
-extern function ipv6_count_cidr_bits(ip6: in6_addr): Option<bit<8>>
+function multicast_to_ethernet(ip6: in6_addr): eth_addr {
+ EthAddr{48'h333300000000 | (ip6.aaaa as bit<48> & 48'hffffffff)}
+}
-extern function inet6_ntop(addr: in6_addr): string
-function to_string(addr: in6_addr): string = {
- inet6_ntop(addr)
+function cidr_bits(ip6: in6_addr): Option<bit<8>> {
+ if (ip6.is_cidr()) {
+ Some{128 - ip6.aaaa.trailing_zeros() as u8}
+ } else {
+ None
+ }
}
+function to_string(addr: in6_addr): string { inet6_ntop(addr) }
+extern function inet6_ntop(addr: in6_addr): string
+
/*
* IPv4 | IPv6 addresses
*/
@@ -210,70 +220,62 @@ function to_bracketed_string(ip46: v46_ip) : string = {
}
}
-function ip46_get_network(ip46: v46_ip, plen: bit<32>) : v46_ip {
+function network(ip46: v46_ip, plen: bit<32>) : v46_ip {
match (ip46) {
- IPv4{ipv4} -> IPv4{ip_bitand(ipv4, ip_create_mask(plen))},
- IPv6{ipv6} -> IPv6{ipv6_bitand(ipv6, ipv6_create_mask(plen))}
+ IPv4{ipv4} -> IPv4{InAddr{ipv4.a & ip_create_mask(plen).a}},
+ IPv6{ipv6} -> IPv6{In6Addr{ipv6.aaaa & ipv6_create_mask(plen).aaaa}}
}
}
-function ip46_is_all_ones(ip46: v46_ip) : bool {
+function is_all_ones(ip46: v46_ip) : bool {
match (ip46) {
- IPv4{ipv4} -> ipv4 == ip_create_mask(32),
- IPv6{ipv6} -> ipv6 == ipv6_create_mask(128)
+ IPv4{ipv4} -> ipv4.is_all_ones(),
+ IPv6{ipv6} -> ipv6.is_all_ones()
}
}
-function ip46_count_cidr_bits(ip46: v46_ip) : Option<bit<8>> {
+function cidr_bits(ip46: v46_ip) : Option<bit<8>> {
match (ip46) {
- IPv4{ipv4} -> ip_count_cidr_bits(ipv4),
- IPv6{ipv6} -> ipv6_count_cidr_bits(ipv6)
+ IPv4{ipv4} -> ipv4.cidr_bits(),
+ IPv6{ipv6} -> ipv6.cidr_bits()
}
}
-function ip46_ipX(ip46: v46_ip) : string {
+function ipX(ip46: v46_ip) : string {
match (ip46) {
IPv4{_} -> "ip4",
IPv6{_} -> "ip6"
}
}
-function ip46_xxreg(ip46: v46_ip) : string {
+function xxreg(ip46: v46_ip) : string {
match (ip46) {
IPv4{_} -> "",
IPv6{_} -> "xx"
}
}
+/*
+ * CIDR-masked IPv4 address
+ */
+
typedef ipv4_netaddr = IPV4NetAddr {
addr: in_addr, /* 192.168.10.123 */
plen: bit<32> /* CIDR Prefix: 24. */
}
-/* Returns the netmask. */
-function ipv4_netaddr_mask(na: ipv4_netaddr): in_addr {
- ip_create_mask(na.plen)
-}
-
-/* Returns the broadcast address. */
-function ipv4_netaddr_bcast(na: ipv4_netaddr): in_addr {
- ip_bcast(na.addr, ipv4_netaddr_mask(na))
-}
-
-/* Returns the network (with the host bits zeroed). */
-function ipv4_netaddr_network(na: ipv4_netaddr): in_addr {
- ip_network(na.addr, ipv4_netaddr_mask(na))
-}
+function netmask(na: ipv4_netaddr): in_addr { ip_create_mask(na.plen) }
+function bcast(na: ipv4_netaddr): in_addr { na.addr.bcast(na.netmask()) }
-/* Returns the host (with the network bits zeroed). */
-function ipv4_netaddr_host(na: ipv4_netaddr): in_addr {
- ip_host(na.addr, ipv4_netaddr_mask(na))
-}
+/* Returns the network (with the host bits zeroed)
+ * or the host (with the network bits zeroed). */
+function network(na: ipv4_netaddr): in_addr { na.addr.network(na.netmask()) }
+function host(na: ipv4_netaddr): in_addr { na.addr.host(na.netmask()) }
/* Match on the host, if the host part is nonzero, or on the network
* otherwise. */
-function ipv4_netaddr_match_host_or_network(na: ipv4_netaddr): string {
- if (na.plen < 32 and ip_is_zero(ipv4_netaddr_host(na))) {
+function match_host_or_network(na: ipv4_netaddr): string {
+ if (na.plen < 32 and na.host().is_zero()) {
"${na.addr}/${na.plen}"
} else {
"${na.addr}"
@@ -281,51 +283,48 @@ function ipv4_netaddr_match_host_or_network(na: ipv4_netaddr): string {
}
/* Match on the network. */
-function ipv4_netaddr_match_network(na: ipv4_netaddr): string {
+function match_network(na: ipv4_netaddr): string {
if (na.plen < 32) {
- "${ipv4_netaddr_network(na)}/${na.plen}"
+ "${na.network()}/${na.plen}"
} else {
"${na.addr}"
}
}
+/*
+ * CIDR-masked IPv6 address
+ */
+
typedef ipv6_netaddr = IPV6NetAddr {
addr: in6_addr, /* fc00::1 */
plen: bit<32> /* CIDR Prefix: 64 */
}
-/* Returns the netmask. */
-function ipv6_netaddr_mask(na: ipv6_netaddr): in6_addr {
- ipv6_create_mask(na.plen)
-}
+function netmask(na: ipv6_netaddr): in6_addr { ipv6_create_mask(na.plen) }
-/* Returns the network (with the host bits zeroed). */
-function ipv6_netaddr_network(na: ipv6_netaddr): in6_addr {
- ipv6_network(na.addr, ipv6_netaddr_mask(na))
-}
+/* Returns the network (with the host bits zeroed).
+ * or the host (with the network bits zeroed). */
+function network(na: ipv6_netaddr): in6_addr { na.addr.network(na.netmask()) }
+function host(na: ipv6_netaddr): in6_addr { na.addr.host(na.netmask()) }
-/* Returns the host (with the network bits zeroed). */
-function ipv6_netaddr_host(na: ipv6_netaddr): in6_addr {
- ipv6_host(na.addr, ipv6_netaddr_mask(na))
-}
+function solicited_node(na: ipv6_netaddr): in6_addr { na.addr.solicited_node() }
-function ipv6_netaddr_solicited_node(na: ipv6_netaddr): in6_addr {
- in6_addr_solicited_node(na.addr)
-}
-
-function ipv6_netaddr_is_lla(na: ipv6_netaddr): bool {
- return in6_is_lla(ipv6_netaddr_network(na))
-}
+function is_lla(na: ipv6_netaddr): bool { na.network().is_lla() }
/* Match on the network. */
-function ipv6_netaddr_match_network(na: ipv6_netaddr): string {
+function match_network(na: ipv6_netaddr): string {
if (na.plen < 128) {
- "${ipv6_netaddr_network(na)}/${na.plen}"
+ "${na.network()}/${na.plen}"
} else {
"${na.addr}"
}
}
+/*
+ * Set of addresses associated with a logical port.
+ *
+ * A logical port always has one Ethernet address, plus any number of IPv4 and IPv6 addresses.
+ */
typedef lport_addresses = LPortAddress {
ea: eth_addr,
ipv4_addrs: Vec<ipv4_netaddr>,
@@ -59,144 +59,77 @@ const AF_INET6: usize = 10;
#[repr(C)]
#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize, Debug, IntoRecord, Mutator)]
-pub struct eth_addr {
+pub struct eth_addr_c {
x: [u8; ETH_ADDR_SIZE]
}
-pub fn eth_addr_zero() -> eth_addr {
- eth_addr { x: [0; ETH_ADDR_SIZE] }
+impl eth_addr_c {
+ pub fn from_ddlog(d: ð_addr) -> Self {
+ eth_addr_c {
+ x: [(d.ha >> 40) as u8,
+ (d.ha >> 32) as u8,
+ (d.ha >> 24) as u8,
+ (d.ha >> 16) as u8,
+ (d.ha >> 8) as u8,
+ d.ha as u8]
+ }
+ }
+ pub fn to_ddlog(&self) -> eth_addr {
+ let ea0 = u16::from_be_bytes([self.x[0], self.x[1]]) as u64;
+ let ea1 = u16::from_be_bytes([self.x[2], self.x[3]]) as u64;
+ let ea2 = u16::from_be_bytes([self.x[4], self.x[5]]) as u64;
+ eth_addr { ha: (ea0 << 32) | (ea1 << 16) | ea2 }
+ }
}
pub fn eth_addr2string(addr: ð_addr) -> String {
+ let c = eth_addr_c::from_ddlog(addr);
format!("{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
- addr.x[0], addr.x[1], addr.x[2], addr.x[3], addr.x[4], addr.x[5])
+ c.x[0], c.x[1], c.x[2], c.x[3], c.x[4], c.x[5])
}
pub fn eth_addr_from_string(s: &String) -> ddlog_std::Option<eth_addr> {
- let mut ea: eth_addr = Default::default();
+ let mut ea: eth_addr_c = Default::default();
unsafe {
- if ovs::eth_addr_from_string(string2cstr(s).as_ptr(), &mut ea as *mut eth_addr) {
- ddlog_std::Option::Some{x: ea}
+ if ovs::eth_addr_from_string(string2cstr(s).as_ptr(), &mut ea as *mut eth_addr_c) {
+ ddlog_std::Option::Some{x: ea.to_ddlog()}
} else {
ddlog_std::Option::None
}
}
}
-pub fn eth_addr_from_uint64(x: &u64) -> eth_addr {
- let mut ea: eth_addr = Default::default();
- unsafe {
- ovs::eth_addr_from_uint64(*x as libc::uint64_t, &mut ea as *mut eth_addr);
- ea
- }
-}
-
-pub fn eth_addr_mark_random(ea: ð_addr) -> eth_addr {
- unsafe {
- let mut ea_new = ea.clone();
- ovs::eth_addr_mark_random(&mut ea_new as *mut eth_addr);
- ea_new
- }
-}
-
-pub fn eth_addr_to_uint64(ea: ð_addr) -> u64 {
- unsafe {
- ovs::eth_addr_to_uint64(ea.clone()) as u64
- }
-}
-
-
-impl FromRecord for eth_addr {
- fn from_record(val: &record::Record) -> Result<Self, String> {
- Ok(eth_addr{x: <[u8; ETH_ADDR_SIZE]>::from_record(val)?})
- }
-}
-
#[repr(C)]
-#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize, Debug, IntoRecord, Mutator)]
-pub struct in6_addr {
- x: [u8; IN6_ADDR_SIZE]
-}
-
-pub const in6addr_any: in6_addr = in6_addr{x: [0; IN6_ADDR_SIZE]};
-pub const in6addr_all_hosts: in6_addr = in6_addr{x: [
- 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 ]};
-
-impl FromRecord for in6_addr {
- fn from_record(val: &record::Record) -> Result<Self, String> {
- Ok(in6_addr{x: <[u8; IN6_ADDR_SIZE]>::from_record(val)?})
- }
-}
-
-pub fn in6_generate_lla(ea: ð_addr) -> in6_addr {
- let mut addr: in6_addr = Default::default();
- unsafe {ovs::in6_generate_lla(ea.clone(), &mut addr as *mut in6_addr)};
- addr
-}
-
-pub fn in6_generate_eui64(ea: ð_addr, prefix: &in6_addr) -> in6_addr {
- let mut addr: in6_addr = Default::default();
- unsafe {ovs::in6_generate_eui64(ea.clone(),
- prefix as *const in6_addr,
- &mut addr as *mut in6_addr)};
- addr
+struct in6_addr_c {
+ bytes: [u8; 16]
}
-pub fn in6_is_lla(addr: &in6_addr) -> bool {
- unsafe {ovs::in6_is_lla(addr as *const in6_addr)}
-}
-
-pub fn in6_addr_solicited_node(ip6: &in6_addr) -> in6_addr
-{
- let mut res: in6_addr = Default::default();
- unsafe {
- ovs::in6_addr_solicited_node(&mut res as *mut in6_addr, ip6 as *const in6_addr);
- }
- res
-}
-
-pub fn ipv6_bitand(a: &in6_addr, b: &in6_addr) -> in6_addr {
- unsafe {
- ovs::ipv6_addr_bitand(a as *const in6_addr, b as *const in6_addr)
+impl Default for in6_addr_c {
+ fn default() -> Self {
+ in6_addr_c {
+ bytes: [0; 16]
+ }
}
}
-pub fn ipv6_bitxor(a: &in6_addr, b: &in6_addr) -> in6_addr {
- unsafe {
- ovs::ipv6_addr_bitxor(a as *const in6_addr, b as *const in6_addr)
+impl in6_addr_c {
+ pub fn from_ddlog(d: &in6_addr) -> Self {
+ in6_addr_c{bytes: d.aaaa.to_be_bytes()}
}
-}
-
-pub fn ipv6_bitnot(a: &in6_addr) -> in6_addr {
- let mut result: in6_addr = Default::default();
- for i in 0..16 {
- result.x[i] = !a.x[i]
+ pub fn to_ddlog(&self) -> in6_addr {
+ in6_addr{aaaa: u128::from_be_bytes(self.bytes)}
}
- result
}
-pub fn ipv6_string_mapped(addr: &in6_addr) -> String {
+pub fn string_mapped(addr: &in6_addr) -> String {
+ let addr = in6_addr_c::from_ddlog(addr);
let mut addr_str = [0 as i8; INET6_ADDRSTRLEN];
unsafe {
- ovs::ipv6_string_mapped(&mut addr_str[0] as *mut raw::c_char, addr as *const in6_addr);
+ ovs::ipv6_string_mapped(&mut addr_str[0] as *mut raw::c_char, &addr as *const in6_addr_c);
cstr2string(&addr_str as *const raw::c_char)
}
}
-pub fn ipv6_is_zero(addr: &in6_addr) -> bool {
- *addr == in6addr_any
-}
-
-pub fn ipv6_count_cidr_bits(ip6: &in6_addr) -> ddlog_std::Option<u8> {
- unsafe {
- match (ipv6_is_cidr(ip6)) {
- true => ddlog_std::Option::Some{x: ovs::ipv6_count_cidr_bits(ip6 as *const in6_addr) as u8},
- false => ddlog_std::Option::None
- }
- }
-}
-
pub fn json_string_escape(s: &String) -> String {
let mut ds = ovs_ds::new();
unsafe {
@@ -263,15 +196,15 @@ pub fn ovn_internal_version() -> String {
pub fn ipv6_parse_masked(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple2<in6_addr, in6_addr>>
{
unsafe {
- let mut ip: in6_addr = Default::default();
- let mut mask: in6_addr = Default::default();
- let err = ovs::ipv6_parse_masked(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr, &mut mask as *mut in6_addr);
+ let mut ip: in6_addr_c = Default::default();
+ let mut mask: in6_addr_c = Default::default();
+ let err = ovs::ipv6_parse_masked(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr_c, &mut mask as *mut in6_addr_c);
if (err != ptr::null_mut()) {
let errstr = cstr2string(err);
free(err as *mut raw::c_void);
ddlog_std::Either::Left{l: errstr}
} else {
- ddlog_std::Either::Right{r: ddlog_std::tuple2(ip, mask)}
+ ddlog_std::Either::Right{r: ddlog_std::tuple2(ip.to_ddlog(), mask.to_ddlog())}
}
}
}
@@ -279,15 +212,15 @@ pub fn ipv6_parse_masked(s: &String) -> ddlog_std::Either<String, ddlog_std::tup
pub fn ipv6_parse_cidr(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple2<in6_addr, u32>>
{
unsafe {
- let mut ip: in6_addr = Default::default();
+ let mut ip: in6_addr_c = Default::default();
let mut plen: raw::c_uint = 0;
- let err = ovs::ipv6_parse_cidr(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr, &mut plen as *mut raw::c_uint);
+ let err = ovs::ipv6_parse_cidr(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr_c, &mut plen as *mut raw::c_uint);
if (err != ptr::null_mut()) {
let errstr = cstr2string(err);
free(err as *mut raw::c_void);
ddlog_std::Either::Left{l: errstr}
} else {
- ddlog_std::Either::Right{r: ddlog_std::tuple2(ip, plen as u32)}
+ ddlog_std::Either::Right{r: ddlog_std::tuple2(ip.to_ddlog(), plen as u32)}
}
}
}
@@ -295,54 +228,25 @@ pub fn ipv6_parse_cidr(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple
pub fn ipv6_parse(s: &String) -> ddlog_std::Option<in6_addr>
{
unsafe {
- let mut ip: in6_addr = Default::default();
- let res = ovs::ipv6_parse(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr);
+ let mut ip: in6_addr_c = Default::default();
+ let res = ovs::ipv6_parse(string2cstr(s).as_ptr(), &mut ip as *mut in6_addr_c);
if (res) {
- ddlog_std::Option::Some{x: ip}
+ ddlog_std::Option::Some{x: ip.to_ddlog()}
} else {
ddlog_std::Option::None
}
}
}
-pub fn ipv6_create_mask(mask: &u32) -> in6_addr
-{
- unsafe {ovs::ipv6_create_mask(*mask as raw::c_uint)}
-}
-
-
-pub fn ipv6_is_routable_multicast(a: &in6_addr) -> bool
-{
- unsafe{ovn_c::ipv6_addr_is_routable_multicast(a as *const in6_addr)}
-}
-
-pub fn ipv6_is_all_hosts(a: &in6_addr) -> bool
-{
- return *a == in6addr_all_hosts;
-}
-
-pub fn ipv6_is_cidr(a: &in6_addr) -> bool
-{
- unsafe{ovs::ipv6_is_cidr(a as *const in6_addr)}
-}
-
-pub fn ipv6_multicast_to_ethernet(ip6: &in6_addr) -> eth_addr
-{
- let mut eth: eth_addr = Default::default();
- unsafe{
- ovs::ipv6_multicast_to_ethernet(&mut eth as *mut eth_addr, ip6 as *const in6_addr);
- }
- eth
-}
-
-pub type in_addr = u32;
pub type ovs_be32 = u32;
-pub fn iptohl(addr: &in_addr) -> u32 {
- ddlog_std::ntohl(addr)
-}
-pub fn hltoip(addr: &u32) -> in_addr {
- ddlog_std::htonl(addr)
+impl in_addr {
+ pub fn from_be32(nl: ovs_be32) -> in_addr {
+ in_addr{a: ddlog_std::ntohl(&nl)}
+ }
+ pub fn to_be32(&self) -> ovs_be32 {
+ ddlog_std::htonl(&self.a)
+ }
}
pub fn ip_parse_masked(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple2<in_addr, in_addr>>
@@ -356,7 +260,8 @@ pub fn ip_parse_masked(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple
free(err as *mut raw::c_void);
ddlog_std::Either::Left{l: errstr}
} else {
- ddlog_std::Either::Right{r: ddlog_std::tuple2(ip, mask)}
+ ddlog_std::Either::Right{r: ddlog_std::tuple2(in_addr::from_be32(ip),
+ in_addr::from_be32(mask))}
}
}
}
@@ -372,7 +277,7 @@ pub fn ip_parse_cidr(s: &String) -> ddlog_std::Either<String, ddlog_std::tuple2<
free(err as *mut raw::c_void);
ddlog_std::Either::Left{l: errstr}
} else {
- ddlog_std::Either::Right{r: ddlog_std::tuple2(ip, plen as u32)}
+ ddlog_std::Either::Right{r: ddlog_std::tuple2(in_addr::from_be32(ip), plen as u32)}
}
}
}
@@ -382,22 +287,13 @@ pub fn ip_parse(s: &String) -> ddlog_std::Option<in_addr>
unsafe {
let mut ip: ovs_be32 = 0;
if (ovs::ip_parse(string2cstr(s).as_ptr(), &mut ip as *mut ovs_be32)) {
- ddlog_std::Option::Some{x:ip}
+ ddlog_std::Option::Some{x: in_addr::from_be32(ip)}
} else {
ddlog_std::Option::None
}
}
}
-pub fn ip_count_cidr_bits(address: &in_addr) -> ddlog_std::Option<u8> {
- unsafe {
- match (ip_is_cidr(address)) {
- true => ddlog_std::Option::Some{x: ovs::ip_count_cidr_bits(*address) as u8},
- false => ddlog_std::Option::None
- }
- }
-}
-
pub fn is_dynamic_lsp_address(address: &String) -> bool {
unsafe {
ovn_c::is_dynamic_lsp_address(string2cstr(address).as_ptr())
@@ -414,21 +310,21 @@ pub fn split_addresses(addresses: &String) -> ddlog_std::tuple2<ddlog_std::Set<S
}
pub fn scan_eth_addr(s: &String) -> ddlog_std::Option<eth_addr> {
- let mut ea = eth_addr_zero();
+ let mut ea: eth_addr_c = Default::default();
unsafe {
if ovs::ovs_scan(string2cstr(s).as_ptr(), b"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\0".as_ptr() as *const raw::c_char,
&mut ea.x[0] as *mut u8, &mut ea.x[1] as *mut u8,
&mut ea.x[2] as *mut u8, &mut ea.x[3] as *mut u8,
&mut ea.x[4] as *mut u8, &mut ea.x[5] as *mut u8)
{
- ddlog_std::Option::Some{x: ea}
+ ddlog_std::Option::Some{x: ea.to_ddlog()}
} else {
ddlog_std::Option::None
}
}
}
-pub fn scan_eth_addr_prefix(s: &String) -> ddlog_std::Option<u64> {
+pub fn scan_eth_addr_prefix(s: &String) -> ddlog_std::Option<eth_addr> {
let mut b2: u8 = 0;
let mut b1: u8 = 0;
let mut b0: u8 = 0;
@@ -436,7 +332,7 @@ pub fn scan_eth_addr_prefix(s: &String) -> ddlog_std::Option<u64> {
if ovs::ovs_scan(string2cstr(s).as_ptr(), b"%hhx:%hhx:%hhx\0".as_ptr() as *const raw::c_char,
&mut b2 as *mut u8, &mut b1 as *mut u8, &mut b0 as *mut u8)
{
- ddlog_std::Option::Some{x: ((b2 as u64) << 40) | ((b1 as u64) << 32) | ((b0 as u64) << 24) }
+ ddlog_std::Option::Some{x: eth_addr{ha: ((b2 as u64) << 40) | ((b1 as u64) << 32) | ((b0 as u64) << 24)} }
} else {
ddlog_std::Option::None
}
@@ -457,7 +353,11 @@ pub fn scan_static_dynamic_ip(s: &String) -> ddlog_std::Option<in_addr> {
&mut ip3 as *mut u8,
&mut n) && s.len() == (n as usize)
{
- ddlog_std::Option::Some{x: ddlog_std::htonl(&(((ip0 as u32) << 24) | ((ip1 as u32) << 16) | ((ip2 as u32) << 8) | (ip3 as u32)))}
+ let a0 = (ip0 as u32) << 24;
+ let a1 = (ip1 as u32) << 16;
+ let a2 = (ip2 as u32) << 8;
+ let a3 = ip3 as u32;
+ ddlog_std::Option::Some{x: in_addr{a: a0 | a1 | a2 | a3}}
} else {
ddlog_std::Option::None
}
@@ -513,9 +413,10 @@ pub fn str_to_uint(s: &String, base: &u16) -> ddlog_std::Option<u64> {
}
pub fn inet6_ntop(addr: &in6_addr) -> String {
+ let addr_c = in6_addr_c::from_ddlog(addr);
let mut buf = [0 as i8; INET6_ADDRSTRLEN];
unsafe {
- let res = inet_ntop(AF_INET6 as raw::c_int, addr as *const in6_addr as *const raw::c_void,
+ let res = inet_ntop(AF_INET6 as raw::c_int, &addr_c as *const in6_addr_c as *const raw::c_void,
&mut buf[0] as *mut raw::c_char, INET6_ADDRSTRLEN as libc::socklen_t);
if res == ptr::null() {
warn(&format!("inet_ntop({:?}) failed", *addr));
@@ -611,9 +512,9 @@ impl Default for ipv4_netaddr_c {
}
impl ipv4_netaddr_c {
- pub unsafe fn to_ddlog(&self) -> ipv4_netaddr {
+ pub fn to_ddlog(&self) -> ipv4_netaddr {
ipv4_netaddr{
- addr: self.addr,
+ addr: in_addr::from_be32(self.addr),
plen: self.plen,
}
}
@@ -621,10 +522,10 @@ impl ipv4_netaddr_c {
#[repr(C)]
struct ipv6_netaddr_c {
- addr: in6_addr, /* fc00::1 */
- mask: in6_addr, /* ffff:ffff:ffff:ffff:: */
- sn_addr: in6_addr, /* ff02:1:ff00::1 */
- network: in6_addr, /* fc00:: */
+ addr: in6_addr_c, /* fc00::1 */
+ mask: in6_addr_c, /* ffff:ffff:ffff:ffff:: */
+ sn_addr: in6_addr_c, /* ff02:1:ff00::1 */
+ network: in6_addr_c, /* fc00:: */
plen: raw::c_uint, /* CIDR Prefix: 64 */
addr_s: [raw::c_char; INET6_ADDRSTRLEN + 1], /* "fc00::1" */
@@ -650,7 +551,7 @@ impl Default for ipv6_netaddr_c {
impl ipv6_netaddr_c {
pub unsafe fn to_ddlog(&self) -> ipv6_netaddr {
ipv6_netaddr{
- addr: self.addr.clone(),
+ addr: in6_addr_c::to_ddlog(&self.addr),
plen: self.plen
}
}
@@ -661,7 +562,7 @@ impl ipv6_netaddr_c {
#[repr(C)]
struct lport_addresses_c {
ea_s: [raw::c_char; ETH_ADDR_STRLEN + 1],
- ea: eth_addr,
+ ea: eth_addr_c,
n_ipv4_addrs: libc::size_t,
ipv4_addrs: *mut ipv4_netaddr_c,
n_ipv6_addrs: libc::size_t,
@@ -692,7 +593,7 @@ impl lport_addresses_c {
ipv6_addrs.push((&*self.ipv6_addrs.offset(i as isize)).to_ddlog())
}
let res = lport_addresses {
- ea: self.ea.clone(),
+ ea: self.ea.to_ddlog(),
ipv4_addrs: ipv4_addrs,
ipv6_addrs: ipv6_addrs
};
@@ -713,7 +614,7 @@ mod ovn_c {
use ::libc;
use super::lport_addresses_c;
use super::ovs_svec;
- use super::in6_addr;
+ use super::in6_addr_c;
#[link(name = "ovn")]
extern "C" {
@@ -727,7 +628,6 @@ mod ovn_c {
pub fn split_addresses(addresses: *const raw::c_char, ip4_addrs: *mut ovs_svec, ipv6_addrs: *mut ovs_svec);
pub fn ip_address_and_port_from_lb_key(key: *const raw::c_char, ip_address: *mut *mut raw::c_char,
port: *mut libc::uint16_t, addr_family: *mut raw::c_int);
- pub fn ipv6_addr_is_routable_multicast(ip: *const in6_addr) -> bool;
pub fn ovn_get_internal_version() -> *mut raw::c_char;
}
}
@@ -735,40 +635,24 @@ mod ovn_c {
mod ovs {
use ::std::os::raw;
use ::libc;
- use super::in6_addr;
+ use super::in6_addr_c;
use super::ovs_be32;
use super::ovs_ds;
- use super::eth_addr;
+ use super::eth_addr_c;
use super::ovs_svec;
/* functions imported from libopenvswitch */
#[link(name = "openvswitch")]
extern "C" {
// lib/packets.h
- pub fn ipv6_string_mapped(addr_str: *mut raw::c_char, addr: *const in6_addr) -> *const raw::c_char;
- pub fn ipv6_parse_masked(s: *const raw::c_char, ip: *mut in6_addr, mask: *mut in6_addr) -> *mut raw::c_char;
- pub fn ipv6_parse_cidr(s: *const raw::c_char, ip: *mut in6_addr, plen: *mut raw::c_uint) -> *mut raw::c_char;
- pub fn ipv6_parse(s: *const raw::c_char, ip: *mut in6_addr) -> bool;
- pub fn ipv6_mask_is_any(mask: *const in6_addr) -> bool;
- pub fn ipv6_count_cidr_bits(mask: *const in6_addr) -> raw::c_int;
- pub fn ipv6_is_cidr(mask: *const in6_addr) -> bool;
- pub fn ipv6_addr_bitxor(a: *const in6_addr, b: *const in6_addr) -> in6_addr;
- pub fn ipv6_addr_bitand(a: *const in6_addr, b: *const in6_addr) -> in6_addr;
- pub fn ipv6_create_mask(mask: raw::c_uint) -> in6_addr;
- pub fn ipv6_is_zero(a: *const in6_addr) -> bool;
- pub fn ipv6_multicast_to_ethernet(eth: *mut eth_addr, ip6: *const in6_addr);
+ pub fn ipv6_string_mapped(addr_str: *mut raw::c_char, addr: *const in6_addr_c) -> *const raw::c_char;
+ pub fn ipv6_parse_masked(s: *const raw::c_char, ip: *mut in6_addr_c, mask: *mut in6_addr_c) -> *mut raw::c_char;
+ pub fn ipv6_parse_cidr(s: *const raw::c_char, ip: *mut in6_addr_c, plen: *mut raw::c_uint) -> *mut raw::c_char;
+ pub fn ipv6_parse(s: *const raw::c_char, ip: *mut in6_addr_c) -> bool;
pub fn ip_parse_masked(s: *const raw::c_char, ip: *mut ovs_be32, mask: *mut ovs_be32) -> *mut raw::c_char;
pub fn ip_parse_cidr(s: *const raw::c_char, ip: *mut ovs_be32, plen: *mut raw::c_uint) -> *mut raw::c_char;
pub fn ip_parse(s: *const raw::c_char, ip: *mut ovs_be32) -> bool;
- pub fn ip_count_cidr_bits(mask: ovs_be32) -> raw::c_int;
- pub fn eth_addr_from_string(s: *const raw::c_char, ea: *mut eth_addr) -> bool;
- pub fn eth_addr_to_uint64(ea: eth_addr) -> libc::uint64_t;
- pub fn eth_addr_from_uint64(x: libc::uint64_t, ea: *mut eth_addr);
- pub fn eth_addr_mark_random(ea: *mut eth_addr);
- pub fn in6_generate_eui64(ea: eth_addr, prefix: *const in6_addr, lla: *mut in6_addr);
- pub fn in6_generate_lla(ea: eth_addr, lla: *mut in6_addr);
- pub fn in6_is_lla(addr: *const in6_addr) -> bool;
- pub fn in6_addr_solicited_node(addr: *mut in6_addr, ip6: *const in6_addr);
+ pub fn eth_addr_from_string(s: *const raw::c_char, ea: *mut eth_addr_c) -> bool;
// include/openvswitch/json.h
pub fn json_string_escape(str: *const raw::c_char, out: *mut ovs_ds);
@@ -1731,14 +1731,14 @@ function build_port_security_ipv6_flow(
var ip6_addrs = vec_empty();
/* Allow link-local address. */
- ip6_addrs.push(ipv6_string_mapped(in6_generate_lla(ea)));
+ ip6_addrs.push(ea.to_ipv6_lla().string_mapped());
/* Allow ip6.dst=ff00::/8 for multicast packets */
if (pipeline == Egress) {
ip6_addrs.push("ff00::/8")
};
for (addr in ipv6_addrs) {
- ip6_addrs.push(ipv6_netaddr_match_network(addr))
+ ip6_addrs.push(addr.match_network())
};
var dir = if (pipeline == Ingress) { "src" } else { "dst" };
@@ -1755,12 +1755,10 @@ function build_port_security_ipv6_nd_flow(
if (ipv6_addrs.is_empty()) {
__match ++ "))"
} else {
- var ip6_str = ipv6_string_mapped(in6_generate_lla(ea));
- __match = __match ++ " && (nd.target == ${ip6_str}";
+ __match = __match ++ " && (nd.target == ${ea.to_ipv6_lla()}";
for(addr in ipv6_addrs) {
- ip6_str = ipv6_netaddr_match_network(addr);
- __match = __match ++ " || nd.target == ${ip6_str}"
+ __match = __match ++ " || nd.target == ${addr.match_network()}"
};
__match ++ ")))"
}
@@ -1984,7 +1982,7 @@ function build_empty_lb_event_flow(key: string, lb: Ref<nb::Load_Balancer>,
};
var __match = vec_with_capacity(2);
- __match.push("${ip46_ipX(ip)}.dst == ${ip}");
+ __match.push("${ip.ipX()}.dst == ${ip}");
if (port != 0) {
__match.push("${protocol}.dst == ${port}");
};
@@ -2604,7 +2602,7 @@ for (SwitchPortDHCPv6Options(.port = &SwitchPort{.lsp = lsp, .sw = &sw},
if lsp.__type != "external") {
Some{var server_mac} = options.get("server_id") in
Some{var ea} = eth_addr_from_string(server_mac) in
- var server_ip = ipv6_string_mapped(in6_generate_lla(ea)) in
+ var server_ip = ea.to_ipv6_lla() in
/* Get the link local IP of the DHCPv6 server from the
* server MAC. */
var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in
@@ -3070,7 +3068,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps)
* address. If zero, the host is allowed to use any
* address in the subnet.
*/
- addrs.push(ipv4_netaddr_match_host_or_network(addr))
+ addrs.push(addr.match_host_or_network())
};
addrs
} in
@@ -3154,7 +3152,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps)
if (not ps.ipv4_addrs.is_empty()) {
var spas = vec_empty();
for (addr in ps.ipv4_addrs) {
- spas.push(ipv4_netaddr_match_host_or_network(addr))
+ spas.push(addr.match_host_or_network())
};
prefix ++ " && arp.spa == {${spas.join(\", \")}}"
} else {
@@ -3316,7 +3314,7 @@ for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam
(lsp_is_up(lsp) or lsp.__type == "router" or lsp.__type == "localport") and
lsp.__type != "external" and lsp.__type != "virtual")
{
- var __match = "nd_ns && ip6.dst == {${addr.addr}, ${ipv6_netaddr_solicited_node(addr)}} && nd.target == ${addr.addr}" in
+ var __match = "nd_ns && ip6.dst == {${addr.addr}, ${addr.solicited_node()}} && nd.target == ${addr.addr}" in
var actions = "${if (lsp.__type == \"router\") \"nd_na_router\" else \"nd_na\"} { "
"eth.src = ${ea}; "
"ip6.src = ${addr.addr}; "
@@ -3392,7 +3390,7 @@ function build_dhcpv4_action(
None
},
Right{(var host_ip, var mask)} -> {
- if (not ip_same_network((offer_ip, host_ip), mask)) {
+ if (not (offer_ip, host_ip).same_network(mask)) {
/* the offer ip of the logical port doesn't belong to the cidr
* defined in the DHCPv4 options.
*/
@@ -3451,7 +3449,7 @@ function build_dhcpv6_action(
None
},
Right{(var host_ip, var mask)} -> {
- if (not ipv6_same_network((offer_ip, host_ip), mask)) {
+ if (not (offer_ip, host_ip).same_network(mask)) {
/* offer_ip doesn't belongs to the cidr defined in lport's DHCPv6
* options.*/
//warn("ip does not belong to cidr");
@@ -3471,8 +3469,8 @@ function build_dhcpv6_action(
},
Some{ea} -> {
/* Get the link local IP of the DHCPv6 server from the server MAC. */
- var server_ip = ipv6_string_mapped(in6_generate_lla(ea));
- var ia_addr = ipv6_string_mapped(offer_ip);
+ var server_ip = ea.to_ipv6_lla().string_mapped();
+ var ia_addr = offer_ip.string_mapped();
var options = vec_empty();
/* Check whether the dhcpv6 options should be configured as stateful.
@@ -3862,10 +3860,10 @@ for (IgmpSwitchMulticastGroup(.address = address, .switch = &sw)) {
*/
Some{var ip} = ip46_parse(address) in
(var skip_address) = match (ip) {
- IPv4{ipv4} -> ip_is_local_multicast(ipv4),
- IPv6{ipv6} -> ipv6_is_all_hosts(ipv6)
+ IPv4{ipv4} -> ipv4.is_local_multicast(),
+ IPv6{ipv6} -> ipv6.is_all_hosts()
} in
- var ipX = ip46_ipX(ip) in
+ var ipX = ip.ipX() in
for (SwitchMcastFloodRelayPorts(&sw, relay_ports) if not skip_address) {
for (SwitchMcastFloodPorts(&sw, flood_ports)) {
var flood_relay = not relay_ports.is_empty() in
@@ -3933,7 +3931,7 @@ Flow(.logical_datapath = sp.sw.ls._uuid,
.__match = ("inport == ${json_string_escape(localnet_port.1)} && "
"eth.src == ${lp_addr.ea} && "
"!is_chassis_resident(${sp.json_name}) && "
- "nd_ns && ip6.dst == {${rp_addr.addr}, ${ipv6_netaddr_solicited_node(rp_addr)}} && "
+ "nd_ns && ip6.dst == {${rp_addr.addr}, ${rp_addr.solicited_node()}} && "
"nd.target == ${rp_addr.addr}"),
.actions = "drop;",
.external_ids = stage_hint(sp.lsp._uuid)) :-
@@ -4004,14 +4002,14 @@ function lrouter_port_ip_reachable(rp: Ref<RouterPort>, addr: v46_ip): bool {
match (addr) {
IPv4{ipv4} -> {
for (na in rp.networks.ipv4_addrs) {
- if (ip_same_network((ipv4, na.addr), ipv4_netaddr_mask(na))) {
+ if ((ipv4, na.addr).same_network(na.netmask())) {
return true
}
}
},
IPv6{ipv6} -> {
for (na in rp.networks.ipv6_addrs) {
- if (ipv6_same_network((ipv6, na.addr), ipv6_netaddr_mask(na))) {
+ if ((ipv6, na.addr).same_network(na.netmask())) {
return true
}
}
@@ -4356,9 +4354,9 @@ for (SwitchPortPSAddresses(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam
* address. If zero, the host is allowed to use any
* address in the subnet.
*/
- addrs.push(ipv4_netaddr_match_host_or_network(addr));
- if (addr.plen < 32 and not ip_is_zero(ipv4_netaddr_host(addr))) {
- addrs.push("${ipv4_netaddr_bcast(addr)}")
+ addrs.push(addr.match_host_or_network());
+ if (addr.plen < 32 and not addr.host().is_zero()) {
+ addrs.push("${addr.bcast()}")
}
};
addrs
@@ -4578,7 +4576,7 @@ for (RouterPortNetworksIPv4Addr(rp@&RouterPort{.router = router}, addr)) {
var rLNR = rEGBIT_LOOKUP_NEIGHBOR_RESULT() in
var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in
var match0 = "inport == ${rp.json_name} && "
- "arp.spa == ${ipv4_netaddr_match_network(addr)}" in
+ "arp.spa == ${addr.match_network()}" in
var match1 = "arp.op == 1" ++ chassis_residence in
var learn_from_arp_request = router.learn_from_arp_request in {
if (not learn_from_arp_request) {
@@ -4701,7 +4699,7 @@ function format_v4_networks(networks: lport_addresses, add_bcast: bool): string
for (addr in networks.ipv4_addrs) {
addrs.push("${addr.addr}");
if (add_bcast) {
- addrs.push("${ipv4_netaddr_bcast(addr)}")
+ addrs.push("${addr.bcast()}")
} else ()
};
if (addrs.len() == 1) {
@@ -4971,7 +4969,7 @@ Flow(.logical_datapath = lr.lr._uuid,
None -> ()
};
if (sn_ip) {
- clauses.push("ip6.dst == {${ip}, ${in6_addr_solicited_node(ip)}}")
+ clauses.push("ip6.dst == {${ip}, ${ip.solicited_node()}}")
};
clauses.push("nd_ns && nd.target == ${ip}");
clauses.append(extra_match.to_vec());
@@ -5018,7 +5016,7 @@ for (RouterPortNetworksIPv4Addr(.port = &RouterPort{.lrp = lrp,
* IP address. */
for (AddChassisResidentCheck(lrp._uuid, add_chassis_resident_check)) {
var __match =
- "arp.spa == ${ipv4_netaddr_match_network(addr)}" ++
+ "arp.spa == ${addr.match_network()}" ++
if (add_chassis_resident_check) {
" && is_chassis_resident(${router.redirect_port_name})"
} else "" in
@@ -5295,10 +5293,10 @@ for (RouterPortNetworksIPv6Addr(.port = &RouterPort{.router = &router,
.json_name = json_name},
.addr = addr)
/* skip link-local address */
- if (not ipv6_netaddr_is_lla(addr)))
+ if (not addr.is_lla()))
{
var __match = "inport == ${json_name} && ip6 && "
- "ip6.src == ${ipv6_netaddr_match_network(addr)} && "
+ "ip6.src == ${addr.match_network()} && "
"ip.ttl == {0, 1} && !ip.later_frag" in
var actions = "icmp6 {"
"eth.dst <-> eth.src; "
@@ -5396,7 +5394,7 @@ function lrouter_nat_add_ext_ip_match(
false -> {
/* S_ROUTER_OUT_SNAT uses priority (mask + 1 + 128 + 1) */
var is_gw_router = router.l3dgw_port == None;
- var mask_1bits = ip46_count_cidr_bits(mask).unwrap_or(8'd0) as integer;
+ var mask_1bits = mask.cidr_bits().unwrap_or(8'd0) as integer;
mask_1bits + 2 + { if (not is_gw_router) 128 else 0 }
}
};
@@ -5435,7 +5433,7 @@ Flow(.logical_datapath = logical_router,
.ips = ips,
.context = context),
var ip = FlatMap(ips),
- var ipX = ip46_ipX(ip).
+ var ipX = ip.ipX().
/* Higher priority rules to force SNAT with the router port ip.
* This only takes effect when the packet has already been
@@ -5488,12 +5486,12 @@ for (r in &Router(.lr = lr,
if l3dgw_port.is_some() or is_gateway)
{
for (LogicalRouterNAT(.lr = lr._uuid, .nat = nat)) {
- var ipX = ip46_ipX(nat.external_ip) in
- var xx = ip46_xxreg(nat.external_ip) in
+ var ipX = nat.external_ip.ipX() in
+ var xx = nat.external_ip.xxreg() in
/* Check the validity of nat->logical_ip. 'logical_ip' can
* be a subnet when the type is "snat". */
Some{(_, var mask)} = ip46_parse_masked(nat.nat.logical_ip) in
- true == match ((ip46_is_all_ones(mask), nat.nat.__type)) {
+ true == match ((mask.is_all_ones(), nat.nat.__type)) {
(_, "snat") -> true,
(false, _) -> {
warn("bad ip ${nat.nat.logical_ip} for dnat in router ${uuid2str(lr._uuid)}");
@@ -5725,7 +5723,7 @@ for (r in &Router(.lr = lr,
} else {
"ct_snat(${ip_and_ports});"
} in
- Some{var plen} = ip46_count_cidr_bits(mask) in
+ Some{var plen} = mask.cidr_bits() in
Flow(.logical_datapath = lr._uuid,
.stage = s_ROUTER_OUT_SNAT(),
.priority = plen as bit<64> + 1,
@@ -5761,7 +5759,7 @@ for (r in &Router(.lr = lr,
/* The priority here is calculated such that the
* nat->logical_ip with the longest mask gets a higher
* priority. */
- Some{var plen} = ip46_count_cidr_bits(mask) in
+ Some{var plen} = mask.cidr_bits() in
var priority = (plen as bit<64>) + 1 in
var centralized_boost = if (mac == None) 128 else 0 in
Flow(.logical_datapath = lr._uuid,
@@ -5934,7 +5932,7 @@ for (RouterLBVIP(
/* vip contains IP:port or just IP. */
Some{(var ip_address, var port)} = ip_address_and_port_from_lb_key(vip) in
- var ipX = ip46_ipX(ip_address) in
+ var ipX = ip_address.ipX() in
var proto = match (lb.protocol) {
Some{proto} -> proto,
_ -> "tcp"
@@ -6038,7 +6036,7 @@ for (RouterLBVIP(
} in
not conds.is_empty() in
var undnat_match =
- "${ip46_ipX(ip_address)} && (" ++ conds.join(" || ") ++
+ "${ip_address.ipX()} && (" ++ conds.join(" || ") ++
") && outport == ${json_string_escape(gwport.name)} && "
"is_chassis_resident(${redirect_port_name})" in
var action =
@@ -6123,11 +6121,11 @@ function copy_ra_to_sb(port: RouterPort, address_mode: string): Map<string, stri
};
var prefixes = vec_empty();
- for (addrs in port.networks.ipv6_addrs) {
- if (ipv6_netaddr_is_lla(addrs)) {
- options.insert("ipv6_ra_src_addr", "${addrs.addr}")
+ for (addr in port.networks.ipv6_addrs) {
+ if (addr.is_lla()) {
+ options.insert("ipv6_ra_src_addr", "${addr.addr}")
} else {
- prefixes.push(ipv6_netaddr_match_network(addrs))
+ prefixes.push(addr.match_network())
}
};
match (port.sb_options.get("ipv6_ra_pd_list")) {
@@ -6191,8 +6189,8 @@ for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None
var add_rs_response_flow = false;
var prefix = "";
for (addr in networks.ipv6_addrs) {
- if (not ipv6_netaddr_is_lla(addr)) {
- prefix = prefix ++ ", prefix = ${ipv6_netaddr_match_network(addr)}";
+ if (not addr.is_lla()) {
+ prefix = prefix ++ ", prefix = ${addr.match_network()}";
add_rs_response_flow = true
} else ()
};
@@ -6230,7 +6228,7 @@ for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None
var __match = "inport == ${json_name} && ip6.dst == ff02::2 && "
"nd_ra && ${rEGBIT_ND_RA_OPTS_RESULT()}" in
- var ip6_str = ipv6_string_mapped(in6_generate_lla(networks.ea)) in
+ var ip6_str = networks.ea.to_ipv6_lla().string_mapped() in
var actions = "eth.dst = eth.src; eth.src = ${networks.ea}; "
"ip6.dst = ip6.src; ip6.src = ${ip6_str}; "
"outport = inport; flags.loopback = 1; "
@@ -6275,7 +6273,7 @@ relation Route(key: route_key, // matching criteria
function build_route_match(key: route_key) : (string, bit<32>) =
{
- var ipX = ip46_ipX(key.ip_prefix);
+ var ipX = key.ip_prefix.ipX();
/* The priority here is calculated to implement longest-prefix-match
* routing. */
@@ -6284,7 +6282,7 @@ function build_route_match(key: route_key) : (string, bit<32>) =
DstIp -> ("dst", (key.plen * 2) + 1)
};
- var network = ip46_get_network(key.ip_prefix, key.plen);
+ var network = key.ip_prefix.network(key.plen);
var __match = "${ipX}.${dir} == ${network}/${key.plen}";
(__match, priority)
@@ -6294,11 +6292,11 @@ for (Route(.port = port,
.src_ip = src_ip,
.gateway = gateway))
{
- var ipX = ip46_ipX(key.ip_prefix) in
- var xx = ip46_xxreg(key.ip_prefix) in
+ var ipX = key.ip_prefix.ipX() in
+ var xx = key.ip_prefix.xxreg() in
/* IPv6 link-local addresses must be scoped to the local router port. */
var inport_match = match (key.ip_prefix) {
- IPv6{prefix} -> if (in6_is_lla(prefix)) {
+ IPv6{prefix} -> if (prefix.is_lla()) {
"inport == ${port.json_name} && "
} else "",
_ -> ""
@@ -6432,7 +6430,7 @@ Flow(.logical_datapath = router.lr._uuid,
EcmpGroup(group_id, router, key, dsts, _, _),
var member_id_and_dst = FlatMap(numbered_vec(dsts)),
(var member_id, var dst) = member_id_and_dst,
- var xx = ip46_xxreg(dst.nexthop),
+ var xx = dst.nexthop.xxreg(),
var __match = "${rEG_ECMP_GROUP_ID()} == ${group_id} && "
"${rEG_ECMP_MEMBER_ID()} == ${member_id}",
var actions = "${xx}${rEG_NEXT_HOP()} = ${dst.nexthop}; "
@@ -6512,7 +6510,7 @@ Flow(.logical_datapath = router.lr._uuid,
.external_ids = map_empty()) :-
EcmpSymmetricReply(router, dst, route_match, tunkey),
var ecmp_reply = "ct.rpl && ct_label.ecmp_reply_port == ${tunkey}",
- var xx = ip46_xxreg(dst.nexthop).
+ var xx = dst.nexthop.xxreg().
/* IP Multicast lookup. Here we set the output port, adjust TTL and advance
@@ -6545,7 +6543,7 @@ for (IgmpRouterMulticastGroup(address, &rtr, ports)) {
}
} in
Some{var ip} = ip46_parse(address) in
- var ipX = ip46_ipX(ip) in
+ var ipX = ip.ipX() in
UniqueFlow[Flow{.logical_datapath = rtr.lr._uuid,
.stage = s_ROUTER_IN_IP_ROUTING(),
.priority = 500,
@@ -6646,7 +6644,7 @@ Flow(.logical_datapath = r.lr._uuid,
" priority %"PRId64" nexthop %s",
rule->priority, rule->nexthop);
*/
- var xx = ip46_xxreg(src_ip),
+ var xx = src_ip.xxreg(),
var actions = (pkt_mark_policy(policy.options) ++
"${xx}${rEG_NEXT_HOP()} = ${nexthop}; "
"${xx}${rEG_SRC()} = ${src_ip}; "
@@ -6697,7 +6695,7 @@ Flow(.logical_datapath = r.lr._uuid,
Some{var nexthop} = ip46_parse(nexthop_s),
out_port in &RouterPort(.router = r),
Some{var src_ip} = find_lrp_member_ip(out_port.networks, nexthop), // or warn
- var xx = ip46_xxreg(src_ip),
+ var xx = src_ip.xxreg(),
var actions = (pkt_mark_policy(policy.options) ++
"${xx}${rEG_NEXT_HOP()} = ${nexthop}; "
"${xx}${rEG_SRC()} = ${src_ip}; "
@@ -7161,9 +7159,9 @@ Flow(.logical_datapath = router.lr._uuid,
IPv6{var gw_ip6} = dst.nexthop,
var __match = "eth.dst == 00:00:00:00:00:00 && "
"ip6 && xx${rEG_NEXT_HOP()} == ${dst.nexthop}",
- var sn_addr = in6_addr_solicited_node(gw_ip6),
- var eth_dst = ipv6_multicast_to_ethernet(sn_addr),
- var sn_addr_s = ipv6_string_mapped(sn_addr),
+ var sn_addr = gw_ip6.solicited_node(),
+ var eth_dst = sn_addr.multicast_to_ethernet(),
+ var sn_addr_s = sn_addr.string_mapped(),
var actions = "nd_ns { "
"eth.dst = ${eth_dst}; "
"ip6.dst = ${sn_addr_s}; "
All of these were defined as opaque "extern" types in the ddlog code. I have found that they are easier to work with and understand if the ddlog code can look into their implementations. This commit re-defines them in terms of proper ddlog types. It also renames many of the functions that operate on them so that they can be used in an object-like form, as well as defining many of these functions in ddlog code rather than as externs. This code refactoring shouldn't change ovn-northd-ddlog behavior. Signed-off-by: Ben Pfaff <blp@ovn.org> --- northd/ipam.dl | 64 +++++----- northd/lrouter.dl | 4 +- northd/lswitch.dl | 7 +- northd/multicast.dl | 2 +- northd/ovn.dl | 281 +++++++++++++++++++++-------------------- northd/ovn.rs | 290 +++++++++++++------------------------------ northd/ovn_northd.dl | 116 +++++++++-------- 7 files changed, 320 insertions(+), 444 deletions(-)