]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: Ensure the ospf6 interface hello timer pops in all cases
authorDonald Sharp <sharpd@nvidia.com>
Mon, 16 May 2022 19:20:12 +0000 (15:20 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 16 May 2022 21:52:10 +0000 (17:52 -0400)
If a end users does something like this:

int enp39s0
  ipv6 ospf6 hello-interval 65535

And then the timer pops and we send the hello and immediately
if the end user does this:

  ipv6 ospf6 hello-interval 5

The timer is not being reset and FRR waits the full 65k seconds
before sending the hello again, which then immediately sets
the next hello to go out in 5 seconds.

When FRR receives the new timer value, look at how much time
is left on the timer in seconds.  If this value is greater
than the new hello timer, stop the timer and set it too that
value.

This should fix a CI system test failure found, where the
system is testing setting timer from things like 12 seconds
to 65k seconds then back down to 12 and that the ospf6 neighbor
relationship stays up.

The code was also changed from thread_add_event to thread_add_timer
in all cases.  I am not sure what would happen if a show command
comes in for a thread timer remaining with an event instead of a timer
just make it consistent.

This was chased down because the support bundle showed this:
r0# show ipv6 ospf6 vrf all interface
r0-r1-eth0 is up, type BROADCAST
  Interface ID: 6
  Internet Address:
    inet6: fe80::a4ea:d3ff:fe35:cef1/64
    inet6: fd00::1/64
  Instance ID 0, Interface MTU 1500 (autodetect: 1500)
  MTU mismatch detection: enabled
  Area ID 0.0.0.0, Cost 10
  State DR, Transmit Delay 1 sec, Priority 1
  Timer intervals configured:
   Hello 12(65480.960), Dead 48, Retransmit 5

And looking at the test code is doing stuff like this:
2022/05/16 17:08:15 OSPF6: [M7Q4P-46WDR] vty[5]@(config)# interface r1-r0-eth0

2022/05/16 17:08:15 OSPF6: [M7Q4P-46WDR] vty[5]@(config-if)# ipv6 ospf6 hello-interval 65535

2022/05/16 17:08:15 OSPF6: [M7Q4P-46WDR] vty[5]@(config-if)# no ipv6 ospf6 hello-interval
2022/05/16 17:08:16 OSPF6: [M7Q4P-46WDR] vty[5]@(config-if)# ipv6 ospf6 hello-interval 1
2022/05/16 17:08:16 OSPF6: [M7Q4P-46WDR] vty[5]@(config-if)# ipv6 ospf6 hello-interval 12

If the old timer value pops, the hello interval is set to 65k and never reset again.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
ospf6d/ospf6_interface.c
ospf6d/ospf6_message.c

index e259befc67abbbed8aec955aac517818250fa1e3..c58bb3a0fbad9807c561a8dec4110bfcdf94f3b2 100644 (file)
@@ -827,7 +827,7 @@ void interface_up(struct thread *thread)
        /* Schedule Hello */
        if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
            && !if_is_loopback(oi->interface)) {
-               thread_add_event(master, ospf6_hello_send, oi, 0,
+               thread_add_timer(master, ospf6_hello_send, oi, 0,
                                 &oi->thread_send_hello);
        }
 
@@ -2102,6 +2102,16 @@ DEFUN (ipv6_ospf6_hellointerval,
        oi->hello_interval = strmatch(argv[0]->text, "no")
                                     ? OSPF_HELLO_INTERVAL_DEFAULT
                                     : strtoul(argv[idx_number]->arg, NULL, 10);
+
+       /*
+        * If the thread is scheduled, send the new hello now.
+        */
+       if (thread_is_scheduled(oi->thread_send_hello)) {
+               THREAD_OFF(oi->thread_send_hello);
+
+               thread_add_timer(master, ospf6_hello_send, oi, 0,
+                                &oi->thread_send_hello);
+       }
        return CMD_SUCCESS;
 }
 
@@ -2348,7 +2358,7 @@ DEFUN (no_ipv6_ospf6_passive,
 
        /* don't send hellos over loopback interface */
        if (!if_is_loopback(oi->interface))
-               thread_add_event(master, ospf6_hello_send, oi, 0,
+               thread_add_timer(master, ospf6_hello_send, oi, 0,
                                 &oi->thread_send_hello);
 
        return CMD_SUCCESS;
index 6645f83b00dff5f036f5295f48a9538dc077bce5..1eede57232f8b469e15febcbcbe6b04001c634bc 100644 (file)
@@ -2242,7 +2242,6 @@ void ospf6_hello_send(struct thread *thread)
        uint16_t length = OSPF6_HEADER_SIZE;
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
-       oi->thread_send_hello = (struct thread *)NULL;
 
        if (oi->state <= OSPF6_INTERFACE_DOWN) {
                if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND_HDR))