diff options
author | Don Slice <dslice@cumulusnetworks.com> | 2017-06-22 18:17:24 +0200 |
---|---|---|
committer | Don Slice <dslice@cumulusnetworks.com> | 2017-06-26 17:07:23 +0200 |
commit | 0c7ef48afe13284d5eb429b89744886d6fa74b7e (patch) | |
tree | 39c843977e9f95fdeff65560f5100009fbe93e16 /ospf6d | |
parent | Merge pull request #745 from qlyoung/fix-lookup (diff) | |
download | frr-0c7ef48afe13284d5eb429b89744886d6fa74b7e.tar.xz frr-0c7ef48afe13284d5eb429b89744886d6fa74b7e.zip |
ospf6d: fix ifmtu settings when kernel changes values
Problem reported by customer that if an mtu value was set in the kernel,
quagga/frr would get very confused about what had been configured and
what had been learned. This caused peers to not be successfully established.
Resolved by keeping a configuration value separate than the operational value
and set the operational accordingly. If configured, it wins unless the config
defines a value that is higher than the kernel supports.
Ticket: CM-16876
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed By: CCR-6399
Testing Done: Manual testing successful, submitter tested, ospf-smoke completed
with no new failures.
Diffstat (limited to 'ospf6d')
-rw-r--r-- | ospf6d/ospf6_interface.c | 34 | ||||
-rw-r--r-- | ospf6d/ospf6_interface.h | 3 |
2 files changed, 30 insertions, 7 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 111ca3f3d..4d07e24b8 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -202,6 +202,7 @@ ospf6_interface_create (struct interface *ifp) oi->state = OSPF6_INTERFACE_DOWN; oi->flag = 0; oi->mtu_ignore = 0; + oi->c_ifmtu = 0; /* Try to adjust I/O buffer size with IfMtu */ oi->ifmtu = ifp->mtu6; @@ -388,6 +389,22 @@ ospf6_interface_state_update (struct interface *ifp) if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) return; + /* Adjust the mtu values if the kernel told us something new */ + if (ifp->mtu6 != oi->ifmtu) + { + /* If nothing configured, just accept it */ + if (!oi->c_ifmtu) + oi->ifmtu = ifp->mtu6; + else if (oi->c_ifmtu > ifp->mtu6) + { + oi->ifmtu = ifp->mtu6; + zlog_warn ("Configured mtu %u on %s overridden by kernel %u", + oi->c_ifmtu, ifp->name, ifp->mtu6); + } + else + oi->ifmtu = oi->c_ifmtu; + } + if (if_is_operative (ifp) && (ospf6_interface_get_linklocal_address(oi->interface) || if_is_loopback(oi->interface))) @@ -1112,7 +1129,7 @@ DEFUN (ipv6_ospf6_ifmtu, ifmtu = strtol (argv[idx_number]->arg, NULL, 10); - if (oi->ifmtu == ifmtu) + if (oi->c_ifmtu == ifmtu) return CMD_SUCCESS; if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) @@ -1129,13 +1146,13 @@ DEFUN (ipv6_ospf6_ifmtu, { vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s", ifp->name, iobuflen, VNL); - oi->ifmtu = iobuflen; + oi->ifmtu = oi->c_ifmtu = iobuflen; } else - oi->ifmtu = ifmtu; + oi->ifmtu = oi->c_ifmtu = ifmtu; } else - oi->ifmtu = ifmtu; + oi->ifmtu = oi->c_ifmtu = ifmtu; /* re-establish adjacencies */ for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) @@ -1149,11 +1166,12 @@ DEFUN (ipv6_ospf6_ifmtu, DEFUN (no_ipv6_ospf6_ifmtu, no_ipv6_ospf6_ifmtu_cmd, - "no ipv6 ospf6 ifmtu", + "no ipv6 ospf6 ifmtu [(1-65535)]", NO_STR IP6_STR OSPF6_STR "Interface MTU\n" + "OSPFv3 Interface MTU\n" ) { VTY_DECLVAR_CONTEXT(interface, ifp); @@ -1184,6 +1202,8 @@ DEFUN (no_ipv6_ospf6_ifmtu, else oi->ifmtu = ifp->mtu; + oi->c_ifmtu = 0; + /* re-establish adjacencies */ for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) { @@ -1745,8 +1765,8 @@ config_write_ospf6_interface (struct vty *vty) if (ifp->desc) vty_out (vty, " description %s%s", ifp->desc, VNL); - if (ifp->mtu6 != oi->ifmtu) - vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL); + if (oi->c_ifmtu) + vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->c_ifmtu, VNL); if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST)) vty_out (vty, " ipv6 ospf6 cost %d%s", diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index 0408fc69d..327402d75 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -76,6 +76,9 @@ struct ospf6_interface /* I/F MTU */ u_int32_t ifmtu; + /* Configured MTU */ + u_int32_t c_ifmtu; + /* Interface State */ u_char state; |