Page MenuHomeFreeBSD

Rework lle deletion process.
ClosedPublic

Authored by melifaro on Sep 5 2015, 2:31 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Nov 26, 7:23 PM
Unknown Object (File)
Tue, Nov 26, 4:01 PM
Unknown Object (File)
Mon, Nov 25, 6:26 PM
Unknown Object (File)
Nov 22 2024, 10:35 PM
Unknown Object (File)
Nov 22 2024, 3:35 PM
Unknown Object (File)
Nov 5 2024, 3:15 AM
Unknown Object (File)
Oct 30 2024, 12:37 PM
Unknown Object (File)
Oct 27 2024, 10:47 AM
Subscribers

Details

Summary

Brief change list:

  • Do more fine-grained locking: call eventhandlers/free_entry without holding afdata wlock
  • convert per-af delete_address callback to global lltable_delete_entry() and more low-level "delete this lle" per-af callback
  • fix some bugs/inconsistencies in IPv4/IPv6 ifscrub procedures

Currently we have 3 control inputs:

  1. user issuing delete via rtsock
  2. interface address being removed
  3. interface going down

Changes:
Case 1 (arp -d .. / ndp -c ..):

Old behavior:
Handled by lla_delete (calls per-af in[6]_lltable_delete()) which

grabs afdata wlock
  finds entry (ignore ifaddr ones)
  marks deleted, call eventhandler
  calls free_entry
releases afdata wlock

Problems:

doing too much under afdata wlock

New behavior:
Handled by global lltable_delete_entry function which

grabs afdata wlock
  finds entry (ignore ifaddr ones)
  unlinks entry
releases afdata wlock
calls llt_delete_entry() cb which
  marks deleted, calls eventhandler
  calls free_entry

Case 2 (deleting interface address):
Old behavior (IPv4):

delete actual address in arp_ifscrub() under afdata wlock
See if this particular prefix exist elsewhere,
do not delete any lle if true

Problems:

In most common case (single prefix, no aliases) you acquire afdata wlock twice.
Suppose you have 10.0.0.1/24 on em1
  and 10.0.0.1/24 on em0 (currently active, e.g have route)
  then you removes 10.0.0.1 from em0 - nothing
  (except 10.0.0.1 itself) will be cleared.
Suppose you have
  10.0.0.1/24 and 10.0.0.10/25 on em0. You removes
  10.0.0.1 address - 10.0.0.10 iface entry is cleared, too

New behavior (IPv4):
Check if we really need to flush all prefix lles. Regardless of the result, call in_scrubprefixlle() which performs either prefix or single address deletion.
Since lltable_match_prefix callbacks were modified to receive actual @ia address instead of prefix, lltable_prefix_free is now capable of deleting single LLE_IFADDR lle corresponding to @ia address.

Old behavior (IPv6):

in6_purgeaddr() call nd6_rem_ifa_lle() which deletes ALL prefix entries including LLE_IFADDR ones.
After that, SIOCDIFADDR_IN6 handling logic checks if prefix refcount is 0, calls prelist_remove() if yes.
prelist_remove() would call nd6_prefix_offlink(), it would check if prefix exists elsewhere and finally call lltable_prefix_free() if not.

New behavior(IPv6):

Pospone nd6_rem_ifa_lle() call till in6_unlink_ifa(), where we already know if it was the last address within prefix.
Delete all dynamic/static prefix entries and LLE_IFADDR entry corresponding to @ifa address if true,
delete matching address only otherwise.

Case 3 (interface going down):
No changes here.
We have in_scrubprefix() called from rip_ctlinput() for
IPv4 part which kills all dynamic entries and interface
prefix routes. We have nothing for IPv6 case.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 411
Build 411: arc lint + arc unit

Event Timeline

melifaro retitled this revision from to Rework lle deletion process..
melifaro updated this object.
melifaro edited the test plan for this revision. (Show Details)
melifaro added a reviewer: network.
ae added a reviewer: ae.
This revision is now accepted and ready to land.Sep 14 2015, 8:27 AM
This revision was automatically updated to reflect the committed changes.