diff mbox series

[ovs-dev,05/11] ovn-northd-ddlog: Make map_get_*() more object-like.

Message ID 20210304041012.4128938-6-blp@ovn.org
State Deferred
Headers show
Series ovn-northd-ddlog improvements | expand

Commit Message

Ben Pfaff March 4, 2021, 4:10 a.m. UTC
These functions were introduced before the object-like invocation
form was added to DDlog.  It's usually easier to read the object-like
form, so this changes the functions to this form and updates all the
callers.

It seemed to me that map_get_int_def_limit() was more general if we
just introduced a general-purpose clamp() function, so I did that.

This code refactoring shouldn't change ovn-northd-ddlog behavior.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 northd/helpers.dl    | 22 ++++++------
 northd/lrouter.dl    |  4 +--
 northd/lswitch.dl    |  4 +--
 northd/multicast.dl  | 50 +++++++++------------------
 northd/ovn_northd.dl | 82 +++++++++++++++++---------------------------
 5 files changed, 63 insertions(+), 99 deletions(-)
diff mbox series

Patch

diff --git a/northd/helpers.dl b/northd/helpers.dl
index 985a13264398..32a5526d59d5 100644
--- a/northd/helpers.dl
+++ b/northd/helpers.dl
@@ -63,8 +63,7 @@  SwitchRouterPeer(lsp, lsp_name, lrp) :-
     Some{var router_port} = options.get("router-port"),
     nb::Logical_Router_Port(.name = router_port, ._uuid = lrp).
 
-function map_get_bool_def(m: Map<string, string>,
-                          k: string, def: bool): bool = {
+function get_bool_def(m: Map<string, string>, k: string, def: bool): bool = {
     m.get(k)
      .and_then(|x| match (str_to_lower(x)) {
                        "false" -> Some{false},
@@ -74,18 +73,19 @@  function map_get_bool_def(m: Map<string, string>,
      .unwrap_or(def)
 }
 
-function map_get_int_def(m: Map<string, string>, k: string,
-                         def: integer): integer = {
+function get_int_def(m: Map<string, string>, k: string, def: integer): integer = {
     m.get(k).and_then(parse_dec_u64).unwrap_or(def)
 }
 
-function map_get_int_def_limit(m: Map<string, string>, k: string, def: integer,
-                               min: integer, max: integer): integer = {
-    var v = map_get_int_def(m, k, def);
-    var v1 = {
-        if (v < min) min else v
-    };
-    if (v1 > max) max else v1
+function clamp(x: 'A, range: ('A, 'A)): 'A {
+    (var min, var max) = range;
+    if (x < min) {
+        min
+    } else if (x > max) {
+        max
+    } else {
+        x
+    }
 }
 
 function ha_chassis_group_uuid(uuid: uuid): uuid { hash128("hacg" ++ uuid) }
diff --git a/northd/lrouter.dl b/northd/lrouter.dl
index 2d700e718340..7bcacfe2aeb6 100644
--- a/northd/lrouter.dl
+++ b/northd/lrouter.dl
@@ -457,7 +457,7 @@  relation &Router(
     LogicalRouterLBs(lr._uuid, lbs),
     LogicalRouterSnatIPs(lr._uuid, snat_ips),
     mcast_cfg in &McastRouterCfg(.datapath = lr._uuid),
-    var learn_from_arp_request = map_get_bool_def(lr.options, "always_learn_from_arp_request", true).
+    var learn_from_arp_request = lr.options.get_bool_def("always_learn_from_arp_request", true).
 
 /* RouterLB: many-to-many relation between logical routers and nb::LB */
 relation RouterLB(router: Ref<Router>, lb: Ref<nb::Load_Balancer>)
@@ -646,7 +646,7 @@  relation &StaticRoute(lrsr: nb::Logical_Router_Static_Route,
         (IPv6{_}, IPv6{_}) -> true,
         _ -> false
     },
-    var esr = map_get_bool_def(lrsr.options, "ecmp_symmetric_reply", false).
+    var esr = lrsr.options.get_bool_def("ecmp_symmetric_reply", false).
 
 /* Returns the IP address of the router port 'op' that
  * overlaps with 'ip'.  If one is not found, returns None. */
diff --git a/northd/lswitch.dl b/northd/lswitch.dl
index 3ade241cf4e5..5fcb3871c341 100644
--- a/northd/lswitch.dl
+++ b/northd/lswitch.dl
@@ -258,7 +258,7 @@  function ipv6_parse_prefix(s: string): Option<in6_addr> {
             None -> None,
             Some{prefix} -> ipv6_parse_prefix(prefix)
         },
-    var is_vlan_transparent = map_get_bool_def(ls.other_config, "vlan-passthru", false).
+    var is_vlan_transparent = ls.other_config.get_bool_def("vlan-passthru", false).
 
 /* SwitchLB: many-to-many relation between logical switches and nb::LB */
 relation SwitchLB(sw_uuid: uuid, lb: Ref<nb::Load_Balancer>)
@@ -494,7 +494,7 @@  SwitchPortUp0(lsp) :-
     nb::Logical_Switch_Port(._uuid = lsp, .name = lsp_name, .__type = __type),
     sb::Port_Binding(.logical_port = lsp_name, .up = up, .chassis = Some{chassis_uuid}),
     sb::Chassis(._uuid = chassis_uuid, .other_config = other_config),
-    if (map_get_bool_def(other_config, oVN_FEATURE_PORT_UP_NOTIF(), false)) {
+    if (other_config.get_bool_def(oVN_FEATURE_PORT_UP_NOTIF(), false)) {
         up == Some{true}
     } else {
         true
diff --git a/northd/multicast.dl b/northd/multicast.dl
index c3ab31e94d3e..f3989e7899d2 100644
--- a/northd/multicast.dl
+++ b/northd/multicast.dl
@@ -23,12 +23,10 @@  import lrouter
 function mCAST_DEFAULT_MAX_ENTRIES(): integer = 2048
 
 function mCAST_DEFAULT_IDLE_TIMEOUT_S(): integer     = 300
-function mCAST_DEFAULT_MIN_IDLE_TIMEOUT_S(): integer = 15
-function mCAST_DEFAULT_MAX_IDLE_TIMEOUT_S(): integer = 3600
+function mCAST_IDLE_TIMEOUT_S_RANGE(): (integer, integer) = (15, 3600)
 
-function mCAST_DEFAULT_MIN_QUERY_INTERVAL_S(): integer = 1
-function mCAST_DEFAULT_MAX_QUERY_INTERVAL_S(): integer =
-    mCAST_DEFAULT_MAX_IDLE_TIMEOUT_S()
+function mCAST_DEFAULT_QUERY_INTERVAL_S(): integer = 1
+function mCAST_QUERY_INTERVAL_S_RANGE(): (integer, integer) = (1, 3600)
 
 function mCAST_DEFAULT_QUERY_MAX_RESPONSE_S(): integer = 1
 
@@ -53,37 +51,24 @@  relation &McastSwitchCfg(
 
 &McastSwitchCfg(
         .datapath       = ls_uuid,
-        .enabled        = map_get_bool_def(other_config, "mcast_snoop",
-                                           false),
-        .querier        = map_get_bool_def(other_config, "mcast_querier",
-                                           true),
-        .flood_unreg    = map_get_bool_def(other_config,
-                                           "mcast_flood_unregistered",
-                                           false),
+        .enabled        = other_config.get_bool_def("mcast_snoop", false),
+        .querier        = other_config.get_bool_def("mcast_querier", true),
+        .flood_unreg    = other_config.get_bool_def("mcast_flood_unregistered", false),
         .eth_src        = other_config.get("mcast_eth_src").unwrap_or(""),
         .ip4_src        = other_config.get("mcast_ip4_src").unwrap_or(""),
         .ip6_src        = other_config.get("mcast_ip6_src").unwrap_or(""),
-        .table_size     = map_get_int_def(other_config,
-                                          "mcast_table_size",
-                                          mCAST_DEFAULT_MAX_ENTRIES()),
+        .table_size     = other_config.get_int_def("mcast_table_size", mCAST_DEFAULT_MAX_ENTRIES()),
         .idle_timeout   = idle_timeout,
         .query_interval = query_interval,
         .query_max_resp = query_max_resp) :-
     nb::Logical_Switch(._uuid        = ls_uuid,
                       .other_config = other_config),
-    var idle_timeout =
-        map_get_int_def_limit(other_config, "mcast_idle_timeout",
-                              mCAST_DEFAULT_IDLE_TIMEOUT_S(),
-                              mCAST_DEFAULT_MIN_IDLE_TIMEOUT_S(),
-                              mCAST_DEFAULT_MAX_IDLE_TIMEOUT_S()),
-    var query_interval =
-        map_get_int_def_limit(other_config, "mcast_query_interval",
-                              idle_timeout / 2,
-                              mCAST_DEFAULT_MIN_QUERY_INTERVAL_S(),
-                              mCAST_DEFAULT_MAX_QUERY_INTERVAL_S()),
-    var query_max_resp =
-        map_get_int_def(other_config, "mcast_query_max_response",
-                        mCAST_DEFAULT_QUERY_MAX_RESPONSE_S()).
+    var idle_timeout = other_config.get_int_def("mcast_idle_timeout", mCAST_DEFAULT_IDLE_TIMEOUT_S())
+                                   .clamp(mCAST_IDLE_TIMEOUT_S_RANGE()),
+    var query_interval = other_config.get_int_def("mcast_query_interval", idle_timeout / 2)
+                                     .clamp(mCAST_QUERY_INTERVAL_S_RANGE()),
+    var query_max_resp = other_config.get_int_def("mcast_query_max_response",
+                                                  mCAST_DEFAULT_QUERY_MAX_RESPONSE_S()).
 
 /* IP Multicast per router configuration. */
 relation &McastRouterCfg(
@@ -93,7 +78,7 @@  relation &McastRouterCfg(
 
 &McastRouterCfg(lr_uuid, mcast_relay) :-
     nb::Logical_Router(._uuid = lr_uuid, .options = options),
-    var mcast_relay = map_get_bool_def(options, "mcast_relay", false).
+    var mcast_relay = options.get_bool_def("mcast_relay", false).
 
 /* IP Multicast port configuration. */
 relation &McastPortCfg(
@@ -105,13 +90,12 @@  relation &McastPortCfg(
 
 &McastPortCfg(lsp_uuid, false, flood, flood_reports) :-
     nb::Logical_Switch_Port(._uuid = lsp_uuid, .options = options),
-    var flood = map_get_bool_def(options, "mcast_flood", false),
-    var flood_reports = map_get_bool_def(options, "mcast_flood_reports",
-                                         false).
+    var flood = options.get_bool_def("mcast_flood", false),
+    var flood_reports = options.get_bool_def("mcast_flood_reports", false).
 
 &McastPortCfg(lrp_uuid, true, flood, flood) :-
     nb::Logical_Router_Port(._uuid = lrp_uuid, .options = options),
-    var flood = map_get_bool_def(options, "mcast_flood", false).
+    var flood = options.get_bool_def("mcast_flood", false).
 
 /* Mapping between Switch and the set of router port uuids on which to flood
  * IP multicast for relay.
diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl
index 9285e38f5148..4b4775a9d3bf 100644
--- a/northd/ovn_northd.dl
+++ b/northd/ovn_northd.dl
@@ -90,7 +90,7 @@  OutProxy_Datapath_Binding(uuid, set_empty(), external_ids) :-
             None -> (),
             Some{zone} -> eids.insert("snat-ct-zone", "${zone}")
         };
-        var learn_from_arp_request = map_get_bool_def(options, "always_learn_from_arp_request", true);
+        var learn_from_arp_request = options.get_bool_def("always_learn_from_arp_request", true);
         if (not learn_from_arp_request) {
             eids.insert("always_learn_from_arp_request", "false")
         };
@@ -227,8 +227,7 @@  OutProxy_Port_Binding(._uuid              = lsp._uuid,
      * */
     var garp_nat_addresses = match (peer) {
         Some{rport} -> match (
-            (map_get_bool_def(rport.lrp.options, "reside-on-redirect-chassis",
-                              false)
+            (rport.lrp.options.get_bool_def("reside-on-redirect-chassis", false)
              and l3dgw_port.is_some()) or
             Some{rport.lrp} == l3dgw_port or
             (rport.router.lr.options.contains_key("chassis") and
@@ -267,8 +266,8 @@  OutProxy_Port_Binding(._uuid              = lrp._uuid,
     var options3 = match ((peer, rp.networks.ipv6_addrs.is_empty())) {
         (PeerSwitch{_, _}, false) -> {
             var enabled = lrp.is_enabled();
-            var pd = map_get_bool_def(lrp.options, "prefix_delegation", false);
-            var p = map_get_bool_def(lrp.options, "prefix", false);
+            var pd = lrp.options.get_bool_def("prefix_delegation", false);
+            var p = lrp.options.get_bool_def("prefix", false);
             ["ipv6_prefix_delegation" -> "${pd and enabled}",
              "ipv6_prefix" -> "${p and enabled}"]
         },
@@ -588,7 +587,7 @@  sb::Out_SB_Global(._uuid          = sb_global._uuid,
 relation ChassisPrivate(
     cp: sb::Chassis_Private,
     is_remote: bool)
-ChassisPrivate(cp, map_get_bool_def(c.other_config, "is-remote", false)) :-
+ChassisPrivate(cp, c.other_config.get_bool_def("is-remote", false)) :-
     cp in sb::Chassis_Private(.chassis = Some{uuid}),
     c in sb::Chassis(._uuid = uuid).
 ChassisPrivate(cp, false),
@@ -680,7 +679,7 @@  Northd_Probe_Interval[interval] :-
 relation CheckLspIsUp[bool]
 CheckLspIsUp[check_lsp_is_up] :-
     nb in nb::NB_Global(),
-    var check_lsp_is_up = not map_get_bool_def(nb.options, "ignore_lsp_down", false).
+    var check_lsp_is_up = not nb.options.get_bool_def("ignore_lsp_down", false).
 CheckLspIsUp[true] :-
     Unit(),
     not nb in nb::NB_Global().
@@ -1340,7 +1339,7 @@  nb::Out_Logical_Switch_Port(._uuid                  = lsp._uuid,
 relation LRPIPv6Prefix0(lrp_uuid: uuid, ipv6_prefix: string)
 LRPIPv6Prefix0(lrp._uuid, ipv6_prefix) :-
     lrp in nb::Logical_Router_Port(),
-    map_get_bool_def(lrp.options, "prefix", false),
+    lrp.options.get_bool_def("prefix", false),
     sb::Port_Binding(.logical_port = lrp.name, .options = options),
     Some{var ipv6_ra_pd_list} = options.get("ipv6_ra_pd_list"),
     var parts = string_split(ipv6_ra_pd_list, ","),
@@ -1583,7 +1582,7 @@  relation Flow(
 relation UseLogicalDatapathGroups[bool]
 UseLogicalDatapathGroups[use_logical_dp_groups] :-
     nb in nb::NB_Global(),
-    var use_logical_dp_groups = map_get_bool_def(nb.options, "use_logical_dp_groups", false).
+    var use_logical_dp_groups = nb.options.get_bool_def("use_logical_dp_groups", false).
 UseLogicalDatapathGroups[false] :-
     Unit(),
     not nb in nb::NB_Global().
@@ -2012,9 +2011,9 @@  function build_empty_lb_event_flow(key: string, lb: Ref<nb::Load_Balancer>,
 relation LoadBalancerEmptyEvents(lb: Ref<nb::Load_Balancer>)
 LoadBalancerEmptyEvents(lb) :-
     nb::NB_Global(.options = global_options),
-    var global_events = map_get_bool_def(global_options, "controller_event", false),
+    var global_events = global_options.get_bool_def("controller_event", false),
     lb in &LoadBalancerRef[nb::Load_Balancer{.options = local_options}],
-    var local_events = map_get_bool_def(local_options, "event", false),
+    var local_events = local_options.get_bool_def("event", false),
     global_events or local_events.
 
 Flow(.logical_datapath = sw.ls._uuid,
@@ -2025,7 +2024,7 @@  Flow(.logical_datapath = sw.ls._uuid,
      .external_ids     = stage_hint(lb._uuid)) :-
     SwitchLBVIP(.sw_uuid = sw_uuid, .lb = lb, .vip = vip, .backends = backends),
     LoadBalancerEmptyEvents(lb),
-    not map_get_bool_def(lb.options, "reject", false),
+    not lb.options.get_bool_def("reject", false),
     sw in &Switch(.ls = nb::Logical_Switch{._uuid = sw_uuid}),
     backends == "",
     HasEventElbMeter(has_elb_meter),
@@ -2896,7 +2895,7 @@  function build_lb_vip_actions(lbvip: Ref<LBVIPWithStatus>,
     };
 
     if (up_backends.is_empty()) {
-        if (map_get_bool_def(lbvip.lb.options, "reject", false)) {
+        if (lbvip.lb.options.get_bool_def("reject", false)) {
             return "reg0 = 0; reject { outport <-> inport; ${next_to_stage(stage)};};"
         } else if (lbvip.health_check.is_some()) {
             return "drop;"
@@ -3478,7 +3477,7 @@  function build_dhcpv6_action(
 
                                 /* Check whether the dhcpv6 options should be configured as stateful.
                                  * Only reply with ia_addr option for dhcpv6 stateful address mode. */
-                                if (map_get_bool_def(dhcpv6_options.options, "dhcpv6_stateless", false) == false) {
+                                if (not dhcpv6_options.options.get_bool_def("dhcpv6_stateless", false)) {
                                     options.push("ia_addr = ${ia_addr}")
                                 } else ();
 
@@ -4182,7 +4181,7 @@  for (&SwitchPort(.lsp = lsp,
               * this logical switch should be run on the chassis
               * hosting the gateway port.
               */
-              map_get_bool_def(lrp.options, "reside-on-redirect-chassis", false)) in
+              lrp.options.get_bool_def("reside-on-redirect-chassis", false)) in
         var __match = if (add_chassis_resident_check) {
             /* The destination lookup flow for the router's
              * distributed gateway port MAC address should only be
@@ -4751,7 +4750,7 @@  AddChassisResidentCheck_(lrp._uuid, res) :-
          * hosting the gateway port and it should reply to the
          * ARP requests for the router port IPs.
          */
-        map_get_bool_def(lrp.options, "reside-on-redirect-chassis", false)
+        lrp.options.get_bool_def("reside-on-redirect-chassis", false)
     }.
 
 
@@ -5916,7 +5915,7 @@  for (RouterLBVIP(
         .backends = backends)
      if l3dgw_port.is_some() or is_gateway)
 {
-    if (backends == "" and not map_get_bool_def(lb.options, "reject", false)) {
+    if (backends == "" and not lb.options.get_bool_def("reject", false)) {
         for (LoadBalancerEmptyEvents(lb)) {
             for (HasEventElbMeter(has_elb_meter)) {
                 Some {(var __match, var __action)} =
@@ -5973,7 +5972,7 @@  for (RouterLBVIP(
                 (110, "")
             } in
         var __match = match1 ++ match2 ++
-            match ((l3dgw_port, backends != "" or map_get_bool_def(lb.options, "reject", false))) {
+            match ((l3dgw_port, backends != "" or lb.options.get_bool_def("reject", false))) {
                 (Some{gwport}, true) -> " && is_chassis_resident(${redirect_port_name})",
                 _ -> ""
             } in
@@ -6088,17 +6087,14 @@  Flow(.logical_datapath = r.lr._uuid,
  * 6.2.1
  */
 function nD_RA_MAX_INTERVAL_DEFAULT(): integer = 600
+function nD_RA_MAX_INTERVAL_RANGE(): (integer, integer) { (4, 1800) }
 
 function nd_ra_min_interval_default(max: integer): integer =
 {
     if (max >= 9) { max / 3 } else { max * 3 / 4 }
 }
 
-function nD_RA_MAX_INTERVAL_MAX(): integer = 1800
-function nD_RA_MAX_INTERVAL_MIN(): integer = 4
-
-function nD_RA_MIN_INTERVAL_MAX(max: integer): integer = ((max * 3) / 4)
-function nD_RA_MIN_INTERVAL_MIN(): integer = 3
+function nD_RA_MIN_INTERVAL_RANGE(max: integer): (integer, integer) = (3, ((max * 3) / 4))
 
 function nD_MTU_DEFAULT(): integer = 0
 
@@ -6109,33 +6105,17 @@  function copy_ra_to_sb(port: RouterPort, address_mode: string): Map<string, stri
     options.insert("ipv6_ra_send_periodic", "true");
     options.insert("ipv6_ra_address_mode", address_mode);
 
-    var max_interval = map_get_int_def(port.lrp.ipv6_ra_configs, "max_interval",
-            nD_RA_MAX_INTERVAL_DEFAULT());
-
-    if (max_interval > nD_RA_MAX_INTERVAL_MAX()) {
-        max_interval = nD_RA_MAX_INTERVAL_MAX()
-    };
-
-    if (max_interval < nD_RA_MAX_INTERVAL_MIN()) {
-        max_interval = nD_RA_MAX_INTERVAL_MIN()
-    };
-
+    var max_interval = port.lrp.ipv6_ra_configs
+        .get_int_def("max_interval", nD_RA_MAX_INTERVAL_DEFAULT())
+        .clamp(nD_RA_MAX_INTERVAL_RANGE());
     options.insert("ipv6_ra_max_interval", "${max_interval}");
 
-    var min_interval = map_get_int_def(port.lrp.ipv6_ra_configs,
-            "min_interval", nd_ra_min_interval_default(max_interval));
-
-    if (min_interval > nD_RA_MIN_INTERVAL_MAX(max_interval)) {
-        min_interval = nD_RA_MIN_INTERVAL_MAX(max_interval)
-    } else ();
-
-    if (min_interval < nD_RA_MIN_INTERVAL_MIN()) {
-        min_interval = nD_RA_MIN_INTERVAL_MIN()
-    } else ();
-
+    var min_interval = port.lrp.ipv6_ra_configs
+        .get_int_def("min_interval", nd_ra_min_interval_default(max_interval))
+        .clamp(nD_RA_MIN_INTERVAL_RANGE(max_interval));
     options.insert("ipv6_ra_min_interval", "${min_interval}");
 
-    var mtu = map_get_int_def(port.lrp.ipv6_ra_configs, "mtu", nD_MTU_DEFAULT());
+    var mtu = port.lrp.ipv6_ra_configs.get_int_def("mtu", nD_MTU_DEFAULT());
 
     /* RFC 2460 requires the MTU for IPv6 to be at least 1280 */
     if (mtu != 0 and mtu >= 1280) {
@@ -6202,7 +6182,7 @@  for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None
             false
         } else { true } in
     {
-        if (map_get_bool_def(lrp.ipv6_ra_configs, "send_periodic", false)) {
+        if (lrp.ipv6_ra_configs.get_bool_def("send_periodic", false)) {
             RouterPortRAOptions(lrp._uuid, copy_ra_to_sb(port, address_mode))
         };
 
@@ -6992,7 +6972,7 @@  for (&SwitchPort(.lsp = lsp1,
                  .peer = Some{&peer1@RouterPort{.router = &peer_router}},
                  .sw = &sw)
      if lsp1.is_enabled() and
-        not map_get_bool_def(peer_router.lr.options, "dynamic_neigh_routers", false))
+        not peer_router.lr.options.get_bool_def("dynamic_neigh_routers", false))
 {
     for (&SwitchPort(.lsp = lsp2, .peer = Some{&peer2},
                      .sw = &Switch{.ls = nb::Logical_Switch{._uuid = sw.ls._uuid}})
@@ -7075,7 +7055,7 @@  Flow(.logical_datapath = lr._uuid,
     Some{var l3dgw_port} = r.l3dgw_port,
     var l3dgw_port_json_name = json_string_escape(l3dgw_port.name),
     r.redirect_port_name != "",
-    var gw_mtu = map_get_int_def(l3dgw_port.options, "gateway_mtu", 0),
+    var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0),
     gw_mtu > 0,
     var mtu = gw_mtu + vLAN_ETH_HEADER_LEN().
 Flow(.logical_datapath = lr._uuid,
@@ -7100,7 +7080,7 @@  Flow(.logical_datapath = lr._uuid,
     Some{var l3dgw_port} = r.l3dgw_port,
     var l3dgw_port_json_name = json_string_escape(l3dgw_port.name),
     r.redirect_port_name != "",
-    var gw_mtu = map_get_int_def(l3dgw_port.options, "gateway_mtu", 0),
+    var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0),
     gw_mtu > 0,
     rp in &RouterPort(.router = r),
     rp.lrp != l3dgw_port,
@@ -7127,7 +7107,7 @@  Flow(.logical_datapath = lr._uuid,
     Some{var l3dgw_port} = r.l3dgw_port,
     var l3dgw_port_json_name = json_string_escape(l3dgw_port.name),
     r.redirect_port_name != "",
-    var gw_mtu = map_get_int_def(l3dgw_port.options, "gateway_mtu", 0),
+    var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0),
     gw_mtu > 0,
     rp in &RouterPort(.router = r),
     rp.lrp != l3dgw_port,