Skip to content
Permalink
Browse files

Get "dynamic <IPv6addr>" working for IPAM.

Similar to static_dynamic_ip, this adds a static_dynamic_ip6 field for
SwitchPort to indicate if there is a static IPv6 address configured for
a dynamic MAC. This is then used as part of the calcultion for if a
dynamic IPv6 address needs to be generated.

NOTE: THIS CODE IS CURRENTLY BROKEN

Currently when run, this results in a transaction failure. This results
in ovn-northd-ddlog being no longer functional.
  • Loading branch information
Mark Michelson
Mark Michelson committed Sep 23, 2019
1 parent 73298e9 commit 0ea3b23d1b6a11f88a870acc4cf15b324c3ffb35
Showing with 38 additions and 4 deletions.
  1. +24 −3 northd/lswitch.dl
  2. +3 −1 northd/ovn-northd-ddlog.c
  3. +1 −0 northd/ovn.dl
  4. +10 −0 northd/ovn.rs
@@ -248,8 +248,10 @@ SwitchPortUp(lsp, up) :-
* - `peer` - peer router port, if any
* - `static_dynamic_mac` - port has a "dynamic" address that contains a static MAC,
* e.g., "80:fa:5b:06:72:b7 dynamic"
* - `static_dynamic_ip` - port has a "dynamic" address that contains a static IP,
* - `static_dynamic_ip` - port has a "dynamic" address that contains a static IPv4 address,
* e.g., "dynamic 192.168.1.2"
* - `static_dynamic_ip6` - port has a "dynamic" address that contains a static IPv6 address,
* e.g., "dymaic aef0::1"
* - `needs_dynamic_ipv4address` - port requires a dynamically allocated IPv4 address
* - `needs_dynamic_macaddress` - port requires a dynamically allocated MAC address
* - `needs_dynamic_tag` - port requires a dynamically allocated tag
@@ -264,6 +266,7 @@ relation &SwitchPort(
dynamic_address: Option<lport_addresses>,
static_dynamic_mac: Option<bit<64>>,
static_dynamic_ip: Option<ovs_be32>,
static_dynamic_ip6: Option<in6_addr>,
ps_addresses: Vec<lport_addresses>,
ps_eth_addresses: Vec<string>,
parent_name: Option<string>,
@@ -282,6 +285,7 @@ relation &SwitchPort(
.dynamic_address = dynamic_address,
.static_dynamic_mac = static_dynamic_mac,
.static_dynamic_ip = static_dynamic_ip,
.static_dynamic_ip6 = static_dynamic_ip6,
.ps_addresses = ps_addresses,
.ps_eth_addresses = ps_eth_addresses,
.parent_name = parent_name,
@@ -346,14 +350,30 @@ relation &SwitchPort(
var opt_ip: Option<bit<32>> = None;
for (addr in lsp.addresses) {
match (scan_static_dynamic_ip(addr)) {
None -> (),
None -> {
warn("No static dynamic IPv4 addresses");
()
},
Some{ip_addr} -> {
warn("Got static dynamic IPv4 address");
opt_ip = Some{ip_addr}
}
}
};
opt_ip
},
var static_dynamic_ip6 = {
var opt_ip6: Option<in6_addr> = None;
for (addr in lsp.addresses) {
match (scan_static_dynamic_ip6(addr)) {
None -> (),
Some{ip6_addr} -> {
opt_ip6 = Some{ip6_addr}
}
}
};
opt_ip6
},
var has_dyn_lsp_addr = {
var has_dyn_lsp_addr = false;
for (addr in lsp.addresses) {
@@ -368,7 +388,8 @@ relation &SwitchPort(
var needs_dynamic_macaddress = has_dyn_lsp_addr and is_none(peer) and is_none(static_dynamic_mac) and
(is_some(subnet) or is_some(ipv6_prefix) or
map_get(other_config, "mac_only") == Some{"true"}),
var needs_dynamic_ipv6address = has_dyn_lsp_addr and is_none(peer) and is_some(ipv6_prefix),
var needs_dynamic_ipv6address = has_dyn_lsp_addr and is_none(peer) and is_some(ipv6_prefix) and
is_none(static_dynamic_ip6),
var parent_name: Option<string> = match (set_nth(lsp.parent_name, 0)) {
None -> None,
Some{pname} -> if (pname == "") { None } else { Some{pname} }
@@ -49,7 +49,7 @@
#include "northd/ovn_northd_ddlog/ddlog.h"

/* Uncomment to record DDlog commands in a file. */
//#define DDLOG_RECORDING
#define DDLOG_RECORDING

VLOG_DEFINE_THIS_MODULE(ovn_northd);

@@ -257,6 +257,8 @@ ddlog_debug_dump(ddlog_prog ddlog OVS_UNUSED)
ddlog_string_free(profile);
#endif

ddlog_table_debug_dump(ddlog, "lswitch.SwitchPort");

This comment has been minimized.

Copy link
@ryzhyk

ryzhyk Sep 23, 2019

Contributor

Only tables declared as output can be dumped. My approach is to temporarily mark tables as output for debugging.


#if 0
ddlog_table_debug_dump(ddlog, "lswitch.SwitchPortIPv4Address");
ddlog_table_debug_dump(ddlog, "OVN_Southbound.Out_Port_Binding");
@@ -122,6 +122,7 @@ extern function ipv6_multicast_to_ethernet(ip6: in6_addr): eth_addr
extern function scan_eth_addr(s: string): Option<eth_addr>
extern function scan_eth_addr_prefix(s: string): Option<bit<64>>
extern function scan_static_dynamic_ip(s: string): Option<ovs_be32>
extern function scan_static_dynamic_ip6(s: string): Option<in6_addr>
extern function json_string_escape(s: string): string
extern function ip_parse(s: string): Option<ovs_be32>
extern function ip_parse_masked(s: string): Either<string/*err*/, (ovs_be32/*host_ip*/, ovs_be32/*mask*/)>
@@ -399,6 +399,16 @@ pub fn ovn_scan_static_dynamic_ip(s: &String) -> std_Option<ovn_ovs_be32> {
}
}

pub fn ovn_scan_static_dynamic_ip6(s: &String) -> std_Option<ovn_in6_addr> {

This comment has been minimized.

Copy link
@ryzhyk

ryzhyk Sep 23, 2019

Contributor

Rust stack trace suggests that this function crashes due to an array bounds violation. I thin split_whitespace() returns an empty iterator when invoked with empty string.

stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:200
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:214
   6: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
   7: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:384
   8: rust_begin_unwind
             at src/libstd/panicking.rs:311
   9: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  10: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:61
  11: ovn_northd_ddlog::__ovn::ovn_scan_static_dynamic_ip6
  12: ovn_northd_ddlog::prog::__f
  13: differential_dataflow::operators::EditList<V,T,R>::map
  14: differential_dataflow::operators::join::Deferred<K,V1,V2,T,R1,R2,R3,C1,C2,M,D>::work
  15: <timely::dataflow::operators::generic::builder_raw::OperatorCore<T,PEP,PIP> as timely::scheduling::Schedule>::schedule
  16: <timely::progress::subgraph::Subgraph<TOuter,TInner> as timely::scheduling::Schedule>::schedule
  17: timely::worker::Wrapper::step
  18: timely::worker::Worker<A>::step

This comment has been minimized.

Copy link
@ryzhyk

ryzhyk Sep 24, 2019

Contributor

Correction: it seems the crash actually occurs in line 408:

ovn_ipv6_parse(&f[1].to_string())

Did you intend to return from function in line 406, i.e., should () be return std_None.

unsafe {
let f: Vec<&str> = s.split_whitespace().collect();
if (f[0] != "dynamic" || f.len() == 1) {
()
}
ovn_ipv6_parse(&f[1].to_string())
}
}

pub fn ovn_ip_address_and_port_from_lb_key(k: &String) ->
std_Option<(String, u16, u32)> {
unsafe {

0 comments on commit 0ea3b23

Please sign in to comment.
You can’t perform that action at this time.