Project

General

Profile

Bug #11378

ncec_last_time_defended needs to be clock_t

Added by Dan McDonald 5 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
networking
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:

Description

Seen as unusually high ARP broadcast counts in Joyent, examination shows that the ncec_t field ncec_last_time_defended is only a uint_t, which mismatches lbolt's clock_t of 64-bits. Once a machine's uptime exceeds 2^32 clock ticks, bad things in ARP/NDP can happen. e.g.

        now = ddi_get_lbolt();
        if ((now - dst_ncec->ncec_last_time_defended) >
            MSEC_TO_TICK(ipst->ips_ipv4_dad_announce_interval)) {
            dst_ncec->ncec_last_time_defended = now;

That boolean in the if will evaluate true ALL of the time once 2^32 clock ticks uptime has been exceeded. Also:

    /*
     * Now figure out how many times we've defended ourselves.  Ignore
     * defenses that happened long in the past.
     */
    now = ddi_get_lbolt();
    elapsed = (drv_hztousec(now - ncec->ncec_last_time_defended))/1000000;
    mutex_enter(&ncec->ncec_lock);
    if ((defs = ncec->ncec_defense_count) > 0 &&
        elapsed > ipst->ips_ip_defend_interval) {
        /*
         * ip_defend_interval has elapsed.
         * reset the defense count.
         */
        ncec->ncec_defense_count = defs = 0;
    }
    ncec->ncec_defense_count++;

The elapsed time shown above will be very large once uptime exceeds 2^32 clock ticks.

Luckily the simple answer is changing ncec_last_time_defended. Because of how that structure is laid out, it won't even cost any more bytes!

History

#1

Updated by Dan McDonald 5 months ago

  • Status changed from New to Pending RTI

Testing notes:

Thanks to Patrick Mooney's mention of the lbolt_info_t structure that is used by event-driven lbolt.

> 0xfffffe064ab9f900::print -at lbolt_info_t lbi_debug_time
    fffffe064ab9f920 int64_t lbi_debug_time = 0x53e2

Altering that to be a value that warps lbolt to be above 2^32 (e.g. 0xfffffffe00000000) provides an easy simulation of long uptimes w.r.t. lbolt.

Then the test is:

- Establish lbolt (or just measure using small uptime).
- Snoop for ARPs where you see them both unicast and broadcast.
- ifconfig <NIC> down ; ifconfig <NIC> up
- ping -svn <broadcast-prefix> and let it run for 1-2 repeats.

Before this fix, the ARP replies triggered by the broadcast ping from the node under test will originate from the node but be sent to the MAC broadcast address if the lbolt is past 2^32. WITH this fix, it is not. And a just-brought-up lbolt will also show unicast ARP responses as they should be.

#2

Updated by Electric Monk 5 months ago

  • Status changed from Pending RTI to Closed
  • % Done changed from 0 to 100

git commit 6dc3349ea11b33c713d10bcd174888010862f0ee

commit  6dc3349ea11b33c713d10bcd174888010862f0ee
Author: Dan McDonald <danmcd@joyent.com>
Date:   2019-07-09T21:30:02.000Z

    11378 ncec_last_time_defended needs to be clock_t
    Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
    Reviewed by: Toomas Soome <tsoome@me.com>
    Reviewed by: Andy Stormont <astormont@racktopsystems.com>
    Approved by: Richard Lowe <richlowe@richlowe.net>

Also available in: Atom PDF