Page MenuHomeFreeBSD

Rework lle deletion process.
ClosedPublic

Authored by melifaro on Sep 5 2015, 2:31 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Aug 1, 10:27 PM
Unknown Object (File)
Wed, Jul 31, 11:48 PM
Unknown Object (File)
Mon, Jul 29, 7:50 PM
Unknown Object (File)
Jul 6 2024, 9:31 PM
Unknown Object (File)
Jul 4 2024, 10:11 AM
Unknown Object (File)
Jun 24 2024, 5:23 AM
Unknown Object (File)
Jun 22 2024, 6:41 AM
Unknown Object (File)
Jun 21 2024, 8:37 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 Not Applicable
Unit
Tests Not Applicable

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.