From 0821305449728ae4eae71636bb64fb4440a3dbe6 Mon Sep 17 00:00:00 2001 From: YiFei Zhu Date: Mon, 6 Jul 2026 22:57:25 +0000 Subject: [PATCH] Limit filter hwports mask to only interfaces with the filtered IP Ths change adds a module option to, when a filter is installed, the filter is only installed to interfaces with the IP of that filter. For wild sockets, Onload duplicates the filter for each local address. The original behavior would be that each such filter would be installed to every active interface. Assuming N interfaces and each interface has a different IP, this would result in N filters being installed to each interface, and N^2 filters installed in total. With this option on, however, each interface would get only one filter and N filters being installed in total. When new local addresses are being added, the code will retroactively add apply it existing filters, just like original behavior. However, if an existing local address of one interface is added to a new interface, the original code ignores it, since it assumes that the filter for that existing local address has already been added to all active interfaces. This assumption no longer holds with this patch, so the filters will be re-applied. For local address removal, original code postpones filter removal until the local address is unused on all active interfaces. This behavior is preserved because local address removal is a rare operation not worth optimizing for, in my opinion. The module option is defaulted off for backwards compatibility, in case a user depends on the original behavior, such as relying on a connection being accelerated even when it is received on an interface when the destination address corresponds to a different interface. Multicast logic is untouched. DNAT logic I was unable to test. Signed-off-by: YiFei Zhu --- src/driver/linux_onload/driver.c | 7 ++ src/include/onload/oof_interface.h | 1 + src/lib/efthrm/oof_filters.c | 131 +++++++++++++++++++++-------- 3 files changed, 102 insertions(+), 37 deletions(-) diff --git a/src/driver/linux_onload/driver.c b/src/driver/linux_onload/driver.c index 8d883ec51..77ed2f2bf 100644 --- a/src/driver/linux_onload/driver.c +++ b/src/driver/linux_onload/driver.c @@ -120,6 +120,13 @@ MODULE_PARM_DESC(oof_use_all_local_ip_addresses, "of the network interface type.\n" "See also cplane_use_prefsrc_as_local module option."); +module_param(oof_limit_filter_to_interface_ip, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(oof_limit_filter_to_interface_ip, + "By default Onload installs filters for each local IP address " + "to every Onloadable network interface. This option limits " + "Onload such that only filters for local IP addresses on each " + "interface is installed to the corresponding interface."); + #ifdef EFRM_DO_USER_NS /* The code in this function and below are based on the kernel's * STANDARD_PARAM_DEF macros, but modified to add in the extra translation diff --git a/src/include/onload/oof_interface.h b/src/include/onload/oof_interface.h index 0681e7d1c..ced02fcc1 100644 --- a/src/include/onload/oof_interface.h +++ b/src/include/onload/oof_interface.h @@ -33,6 +33,7 @@ extern int oof_shared_keep_thresh; extern int oof_shared_steal_thresh; extern int oof_all_ports_required; extern int oof_use_all_local_ip_addresses; +extern int oof_limit_filter_to_interface_ip; extern struct oof_manager* oof_manager_alloc(unsigned local_addr_max, void* owner_private); diff --git a/src/lib/efthrm/oof_filters.c b/src/lib/efthrm/oof_filters.c index 50e6e8ee9..1c3d9a9a6 100644 --- a/src/lib/efthrm/oof_filters.c +++ b/src/lib/efthrm/oof_filters.c @@ -81,6 +81,9 @@ int oof_shared_steal_thresh = 200; /* Module option to handle all local IP addresses. */ int oof_use_all_local_ip_addresses = 0; +/* Module option to limit filter IP to corresponding interface IP */ +int oof_limit_filter_to_interface_ip = 0; + #define IPF_LOG(...) OO_DEBUG_IPF(ci_log(__VA_ARGS__)) #define ERR_LOG(...) OO_DEBUG_ERR(ci_log(__VA_ARGS__)) @@ -175,7 +178,7 @@ static int __oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, int af_space, struct oo_hw_filter* oofilter, ci_addr_t laddr, ci_uint16 lport, ci_uint16 protocol, - int stack_locked); + unsigned hwport_mask, int stack_locked); static struct oof_local_port* oof_local_port_find(struct oof_manager* fm, int protocol, int lport); @@ -681,7 +684,7 @@ oof_local_port_alloc(struct oof_manager* fm, int protocol, int lport) static unsigned -oof_local_interface_hwport_mask(struct oof_manager* fm) +oof_local_interface_hwport_mask_all(struct oof_manager* fm) { struct oof_local_interface_details* lid; unsigned hwport_mask = 0; @@ -745,6 +748,30 @@ oof_local_interface_details_free(struct oof_manager* fm, CI_FREE_OBJ(lid); } +static unsigned +oof_local_interface_hwport_mask_active_ifs(struct oof_manager* fm, + ci_dllist *la_active_ifs) +{ + struct oof_local_interface_details* lid; + struct oof_local_interface* li; + unsigned hwport_mask = 0; + + ci_assert(spin_is_locked(&fm->fm_inner_lock)); + + /* If not limited, install to all hwports */ + if( !oof_limit_filter_to_interface_ip ) + return -1; + + CI_DLLIST_FOR_EACH2(struct oof_local_interface, li, li_active_ifs_link, + la_active_ifs) { + lid = oof_local_interface_details_find(fm, li->li_ifindex); + hwport_mask |= lid->lid_hwport_mask; + } + + return hwport_mask; +} + + /********************************************************************** *********************************************************************** **********************************************************************/ @@ -1309,6 +1336,7 @@ static void oof_local_port_addr_fixup_wild(struct oof_manager* fm, struct oof_local_port* lp, struct oof_local_port_addr* lpa, + struct oof_local_addr* la, ci_addr_t laddr, enum fixup_wild_why why); static int oof_socket_add_full_hw(struct oof_manager* fm, struct oof_socket* skf, @@ -1326,6 +1354,7 @@ __oof_manager_addr_add(struct oof_manager *fm, int af, ci_addr_t laddr, struct oof_socket* skf; int hash, la_i, is_new, is_active; ci_dllist *la_active_ifs; + unsigned hwport_mask; /* We do not care about crazy local addresses. */ if( CI_IPX_ADDR_IS_ANY(laddr) || CI_IPX_IS_MULTICAST(laddr) ) @@ -1356,8 +1385,8 @@ __oof_manager_addr_add(struct oof_manager *fm, int af, ci_addr_t laddr, ci_dllist_push(la_active_ifs, &li->li_active_ifs_link); } if( is_active ) - /* This local address is already active, nothing further to do. */ - return; + /* This local address is already active, add new filters. */ + goto new_filters; is_new = 0; } else { @@ -1411,7 +1440,9 @@ __oof_manager_addr_add(struct oof_manager *fm, int af, ci_addr_t laddr, ci_assert( ! ci_dllist_not_empty(&lpa->lpa_semi_wild_socks) || ! is_new ); } +new_filters: /* Add new filters, and set new filters for wildcard users. */ + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, la_active_ifs); for( hash = 0; hash < OOF_LOCAL_PORT_TBL_SIZE; ++hash ) CI_DLLIST_FOR_EACH2(struct oof_local_port, lp, lp_manager_link, &fm->fm_local_ports[hash]) { @@ -1422,7 +1453,7 @@ __oof_manager_addr_add(struct oof_manager *fm, int af, ci_addr_t laddr, oof_socket_stack_effective(skf), oof_socket_thc_effective(skf), af, lp->lp_protocol, addr_any, 0, laddr, lp->lp_lport, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT, 1); /* Add h/w filters for full-match sockets. */ CI_DLLIST_FOR_EACH2(struct oof_socket, skf, sf_lp_link, @@ -1433,7 +1464,7 @@ __oof_manager_addr_add(struct oof_manager *fm, int af, ci_addr_t laddr, oof_socket_add_full_hw(fm, skf, lpa, af); } /* fixup in case sockets need to share non-existent 3-tuple filters */ - oof_local_port_addr_fixup_wild(fm, lp, lpa, laddr, fuw_3tuple_sharers); + oof_local_port_addr_fixup_wild(fm, lp, lpa, la, laddr, fuw_3tuple_sharers); oof_manager_sw_filter_insert(fm, af, laddr, lp, la_i); } } @@ -1546,7 +1577,8 @@ __oof_manager_addr_del(struct oof_manager *fm, int af, ci_addr_t laddr, } if( ci_dllist_not_empty(la_active_ifs) ) { - /* Not yet, unused, so don't do anything yet */ + /* Not yet, unused, so don't do anything yet + * (postpone removal until unused on all interfaces) */ return; } @@ -1620,10 +1652,12 @@ oof_manager_dnat_add(struct oof_manager* fm, int af, ci_uint16 lp_protocol, { struct oof_local_port_addr* lpa; struct oof_local_port* lp; + struct oof_local_addr* la; struct oof_socket* skf; struct oof_nat_filter *nat_filter; struct oof_nat_table* nat_table = oof_cb_nat_table(fm->fm_owner_private); int la_i, rc; + unsigned hwport_mask; rc = 0; mutex_lock(&fm->fm_outer_lock); @@ -1648,9 +1682,11 @@ oof_manager_dnat_add(struct oof_manager* fm, int af, ci_uint16 lp_protocol, else { nat_filter->orig_addr = orig_addr; nat_filter->orig_port = orig_port; + la = &fm->fm_local_addrs[la_i]; + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); rc = __oof_socket_add_wild(fm, skf, af, &nat_filter->natf_hwfilter, nat_filter->orig_addr, nat_filter->orig_port, - lp->lp_protocol, 0); + lp->lp_protocol, hwport_mask, 0); if( rc == 0 ) ci_dllist_push(&lpa->lpa_nat_filters, &nat_filter->link); else @@ -1752,6 +1788,7 @@ oof_manager_update_all_filters(struct oof_manager* fm) struct oof_local_port_addr* lpa; struct oof_mcast_filter* mf; struct oof_local_port* lp; + struct oof_local_addr* la; struct oof_tproxy* ft; struct oof_socket* skf; unsigned hwport_mask; @@ -1767,14 +1804,16 @@ oof_manager_update_all_filters(struct oof_manager* fm) /* Find and update unicast filters. */ for( la_i = 0; la_i < fm->fm_local_addr_n; ++la_i ) { lpa = &lp->lp_addr[la_i]; + la = &fm->fm_local_addrs[la_i]; laddr = fm->fm_local_addrs[la_i].la_laddr; + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); if( ! oo_hw_filter_is_empty(&lpa->lpa_filter) ) oof_hw_filter_update(fm, &lpa->lpa_filter, lpa->lpa_filter.trs, CI_IS_ADDR_IP6(laddr) ? AF_INET6 : AF_INET, lp->lp_protocol, addr_any, 0, laddr, lp->lp_lport, OO_HW_VLAN_UNSPEC, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT); CI_DLLIST_FOR_EACH2(struct oof_socket, skf, sf_lp_link, &lpa->lpa_full_socks) { @@ -1786,7 +1825,7 @@ oof_manager_update_all_filters(struct oof_manager* fm) lp->lp_protocol, skf->sf_raddr, skf->sf_rport, skf->sf_laddr, lp->lp_lport, OO_HW_VLAN_UNSPEC, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT); } } @@ -2109,6 +2148,7 @@ static int oof_full_socks_add_hw_filters(struct oof_manager* fm, struct oof_local_port* lp, struct oof_local_port_addr* lpa, + struct oof_local_addr* la, int af) { /* For each full-match socket that is relying on the filter associated @@ -2117,6 +2157,7 @@ oof_full_socks_add_hw_filters(struct oof_manager* fm, * stack. */ struct oof_socket* skf; + unsigned hwport_mask; int rc = 0; ci_assert(spin_is_locked(&fm->fm_inner_lock)); @@ -2129,6 +2170,8 @@ oof_full_socks_add_hw_filters(struct oof_manager* fm, return -EINVAL; } + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); + /* oof_hw_filter_set() drops the spin lock, so we need to be * extremely careful here. * In the loop we are guaranteed that skf is not removed from list @@ -2153,8 +2196,8 @@ oof_full_socks_add_hw_filters(struct oof_manager* fm, * none making making the `if` statements below mutually exclusive. * FIXME: this is to be changed */ if( fm->fm_hwports_no5tuple ) /* TODO use mask to act per interface */ - hwports_no5tuple = fm->fm_hwports_available & fm->fm_hwports_up; - hwports_5tuple = fm->fm_hwports_available & fm->fm_hwports_up & ~hwports_no5tuple; + hwports_no5tuple = fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask; + hwports_5tuple = fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask & ~hwports_no5tuple; if( hwports_5tuple ) { rc = oof_hw_filter_set(fm, skf, &skf->sf_full_match_filter, @@ -2183,6 +2226,7 @@ static void oof_local_port_addr_fixup_wild(struct oof_manager* fm, struct oof_local_port* lp, struct oof_local_port_addr* lpa, + struct oof_local_addr* la, ci_addr_t laddr, enum fixup_wild_why why) { struct oof_socket* skf; @@ -2191,6 +2235,7 @@ oof_local_port_addr_fixup_wild(struct oof_manager* fm, int thresh; int af = CI_IS_ADDR_IP6(laddr) ? AF_INET6 : AF_INET; int hwports_no5tuple = 0; + unsigned hwport_mask; if( ! oof_local_port_addr_valid(fm, lpa) ) { ci_assert(oo_hw_filter_is_empty(&lpa->lpa_filter)); @@ -2251,7 +2296,7 @@ oof_local_port_addr_fixup_wild(struct oof_manager* fm, } if( unshare_full_match ) { - rc = oof_full_socks_add_hw_filters(fm, lp, lpa, af); + rc = oof_full_socks_add_hw_filters(fm, lp, lpa, la, af); if( rc < 0 ) { if( (oo_debug_bits & __OO_DEBUGIPF__) || ((oo_debug_bits & __OO_DEBUGERR__) && why != fuw_del_full) ) { @@ -2271,13 +2316,14 @@ oof_local_port_addr_fixup_wild(struct oof_manager* fm, if( skf != NULL ) { skf_has_filter = 0; + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); if( oo_hw_filter_is_empty(&lpa->lpa_filter) ) { ci_assert(lpa->lpa_n_full_sharers == 0 || hwports_no5tuple); rc = oof_hw_filter_set(fm, skf, &lpa->lpa_filter, oof_socket_stack_effective(skf), oof_socket_thc_effective(skf), af, lp->lp_protocol, addr_any, 0, laddr, lp->lp_lport, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT, 1); skf_has_filter = rc == 0; } @@ -2296,7 +2342,7 @@ oof_local_port_addr_fixup_wild(struct oof_manager* fm, oof_socket_stack_effective(skf), oof_socket_thc_effective(skf), af, lp->lp_protocol, addr_any, 0, laddr, lp->lp_lport, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT, 1); skf_has_filter = rc == 0; } @@ -2304,7 +2350,7 @@ oof_local_port_addr_fixup_wild(struct oof_manager* fm, /* Clustered sockets cannot have hardware filters moved */ ci_assert_equal(lpa->lpa_filter.thc, NULL); oof_hw_filter_move(fm, skf, lp, lpa, laddr, af, - fm->fm_hwports_available & fm->fm_hwports_up); + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask); ci_assert(lpa->lpa_filter.trs == oof_cb_socket_stack(skf)); skf_has_filter = 1; } @@ -2331,7 +2377,7 @@ oof_local_port_fixup_wild(struct oof_manager* fm, struct oof_local_port* lp, continue; if( ci_dllist_not_empty(&la->la_active_ifs) ) - oof_local_port_addr_fixup_wild(fm, lp, &lp->lp_addr[la_i], + oof_local_port_addr_fixup_wild(fm, lp, &lp->lp_addr[la_i], la, la->la_laddr, why); } } @@ -2394,7 +2440,7 @@ oof_socket_del_wild_sw(struct oof_manager* fm, struct oof_socket* skf, static void oof_socket_del_full(struct oof_manager* fm, struct oof_socket* skf, - struct oof_local_port_addr* lpa) + struct oof_local_port_addr* lpa, struct oof_local_addr* la) { oof_socket_remove_from_list(skf); oof_socket_del_full_sw(skf, 1); @@ -2405,7 +2451,7 @@ oof_socket_del_full(struct oof_manager* fm, struct oof_socket* skf, ci_assert(oof_local_port_addr_valid(fm, lpa)); ci_assert(lpa->lpa_n_full_sharers > 0); --lpa->lpa_n_full_sharers; - oof_local_port_addr_fixup_wild(fm, skf->sf_local_port, lpa, + oof_local_port_addr_fixup_wild(fm, skf->sf_local_port, lpa, la, skf->sf_laddr, fuw_del_full); } } @@ -2426,11 +2472,16 @@ oof_socket_add_full_hw(struct oof_manager* fm, struct oof_socket* skf, if( ! oof_socket_can_share_hw_filter(skf, &lpa->lpa_filter) && ! hwports_no5tuple ) { struct oof_local_port* lp = skf->sf_local_port; + struct oof_local_addr* la; + unsigned hwport_mask; + + la = &fm->fm_local_addrs[skf->sf_la_i]; + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); rc = oof_hw_filter_set(fm, skf, &skf->sf_full_match_filter, oof_cb_socket_stack(skf), NULL, af, lp->lp_protocol, skf->sf_raddr, skf->sf_rport, skf->sf_laddr, lp->lp_lport, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT, 1); if( rc < 0 ) { /* I think there are the following ways this can fail: @@ -2473,7 +2524,7 @@ static int __oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, int af_space, struct oo_hw_filter* oofilter, ci_addr_t laddr, ci_uint16 lport, ci_uint16 protocol, - int stack_locked) + unsigned hwport_mask, int stack_locked) { int rc = oof_cb_sw_filter_insert(skf, af_space, laddr, lport, addr_any, 0, protocol, stack_locked); @@ -2485,7 +2536,7 @@ __oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, oof_socket_thc_effective(skf), IS_AF_SPACE_IP6(af_space) ? AF_INET6 : AF_INET, protocol, addr_any, 0, laddr, lport, - fm->fm_hwports_available & fm->fm_hwports_up, + fm->fm_hwports_available & fm->fm_hwports_up & hwport_mask, OOF_SRC_FLAGS_DEFAULT, 1); if( rc != 0 ) oof_cb_sw_filter_remove(skf, skf->af_space, laddr, lport, addr_any, 0, @@ -2503,7 +2554,7 @@ __oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, static int oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, int af_space, struct oof_local_port_addr* lpa, - ci_addr_t laddr, int stack_locked) + ci_addr_t laddr, unsigned hwport_mask, int stack_locked) { struct oof_local_port* lp = skf->sf_local_port; struct oof_socket* other_skf; @@ -2546,7 +2597,8 @@ oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, * of that filter, so as to prevent us from trying to insert another one. */ rc = __oof_socket_add_wild(fm, skf, af_space, already_has_hw_filter ? NULL : &lpa->lpa_filter, - laddr, lp->lp_lport, lp->lp_protocol, stack_locked); + laddr, lp->lp_lport, lp->lp_protocol, + hwport_mask, stack_locked); if( ! already_has_hw_filter ) { int i; for( i = 0; rc == 0 && i < nat_preimage.n_results; ++i ) { @@ -2562,7 +2614,7 @@ oof_socket_add_wild(struct oof_manager* fm, struct oof_socket* skf, &nat_filter->natf_hwfilter, nat_filter->orig_addr, nat_filter->orig_port, lp->lp_protocol, - stack_locked); + hwport_mask, stack_locked); if( rc == 0 ) ci_dllist_push(&lpa->lpa_nat_filters, &nat_filter->link); else @@ -2613,6 +2665,7 @@ oof_socket_steal_or_add_wild(struct oof_manager* fm, struct oof_socket* skf) int has_fail = 0; int rc, saved_rc = 0; int af_space; + unsigned hwport_mask; ci_assert(CI_IPX_ADDR_IS_ANY(skf->sf_laddr)); ci_assert(CI_IPX_ADDR_IS_ANY(skf->sf_raddr)); @@ -2633,7 +2686,8 @@ oof_socket_steal_or_add_wild(struct oof_manager* fm, struct oof_socket* skf) if( oof_socket_list_find_matching_stack(&lpa->lpa_semi_wild_socks, skf_stack, af_space, 0) == NULL ) { - rc = oof_socket_add_wild(fm, skf, af_space, lpa, la->la_laddr, 1); + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); + rc = oof_socket_add_wild(fm, skf, af_space, lpa, la->la_laddr, hwport_mask, 1); if( rc == 0 && ! has_ok ) has_ok = 1; else if( rc != 0 && ! has_fail ) { @@ -2688,6 +2742,7 @@ __oof_socket_add(struct oof_manager* fm, struct oof_socket* skf, int do_arm_only /* helper flags to describe what operations will be done for wild sockets */ int do_arm = ! dummy && !oof_socket_no_unicast(skf); int do_insert = ! do_arm_only; + unsigned hwport_mask; ci_assert(ci_dllink_is_free(&skf->sf_lp_link)); /* we need to do something */ @@ -2745,7 +2800,7 @@ __oof_socket_add(struct oof_manager* fm, struct oof_socket* skf, int do_arm_only /* in case of no5tuple NICs a wild filters might be needed * hence we call fixup_wild */ - oof_local_port_addr_fixup_wild(fm, lp, lpa, skf->sf_laddr, + oof_local_port_addr_fixup_wild(fm, lp, lpa, la, skf->sf_laddr, fuw_3tuple_sharers); } else { @@ -2758,13 +2813,15 @@ __oof_socket_add(struct oof_manager* fm, struct oof_socket* skf, int do_arm_only if( rc < 0 ) return rc; } - if( do_arm ) - rc = oof_socket_add_wild(fm, skf, skf->af_space, lpa, skf->sf_laddr, 1); + if( do_arm ) { + hwport_mask = oof_local_interface_hwport_mask_active_ifs(fm, &la->la_active_ifs); + rc = oof_socket_add_wild(fm, skf, skf->af_space, lpa, skf->sf_laddr, hwport_mask, 1); + } if( rc < 0 && rc != -EFILTERSSOME ) return rc; ci_dllist_push(&lpa->lpa_semi_wild_socks, &skf->sf_lp_link); if( do_arm ) - oof_local_port_addr_fixup_wild(fm, lp, lpa, skf->sf_laddr, + oof_local_port_addr_fixup_wild(fm, lp, lpa, la, skf->sf_laddr, fuw_add_wild); } if( inc_laddr_ref ) @@ -3237,7 +3294,7 @@ __oof_socket_del_wild(struct oof_manager* fm, static void oof_socket_del_semi_wild(struct oof_manager* fm, struct oof_socket* skf, - struct oof_local_port_addr* lpa) + struct oof_local_port_addr* lpa, struct oof_local_addr* la) { int hidden; @@ -3248,7 +3305,7 @@ oof_socket_del_semi_wild(struct oof_manager* fm, struct oof_socket* skf, if( ! hidden ) { __oof_socket_del_wild(fm, skf, skf->af_space, oof_cb_socket_stack(skf), lpa, skf->sf_laddr); - oof_local_port_addr_fixup_wild(fm, skf->sf_local_port, lpa, + oof_local_port_addr_fixup_wild(fm, skf->sf_local_port, lpa, la, skf->sf_laddr, fuw_del_wild); } } @@ -3344,9 +3401,9 @@ oof_socket_del(struct oof_manager* fm, struct oof_socket* skf) lpa = &lp->lp_addr[skf->sf_la_i]; la = &fm->fm_local_addrs[skf->sf_la_i]; if( !CI_IPX_ADDR_IS_ANY(skf->sf_raddr) ) - oof_socket_del_full(fm, skf, lpa); + oof_socket_del_full(fm, skf, lpa, la); else - oof_socket_del_semi_wild(fm, skf, lpa); + oof_socket_del_semi_wild(fm, skf, lpa, la); ci_assert(la->la_sockets > 0); if( --la->la_sockets == 0 && ci_dllist_is_empty(&la->la_active_ifs) ) oof_manager_addr_dead(fm, la); @@ -3732,9 +3789,9 @@ oof_udp_connect(struct oof_manager* fm, struct oof_socket* skf, int af_space, * h/w filter, and may delete or move the wild h/w filter(s). */ if( !CI_IPX_ADDR_IS_ANY(laddr_old) ) { - oof_local_port_addr_fixup_wild(fm, lp, &lp->lp_addr[la_i_old], - laddr_old, fuw_udp_connect); la = &fm->fm_local_addrs[la_i_old]; + oof_local_port_addr_fixup_wild(fm, lp, &lp->lp_addr[la_i_old], la, + laddr_old, fuw_udp_connect); if( --la->la_sockets == 0 && ci_dllist_is_empty(&la->la_active_ifs) ) oof_manager_addr_dead(fm, la); } @@ -4320,7 +4377,7 @@ __oof_manager_update_interface(struct oof_manager* fm, /* Now we've updated this interface's hwport usage we need to check what * other interfaces may be using to correctly determine hwport availability. */ - in_use_hwport_mask = oof_local_interface_hwport_mask(fm); + in_use_hwport_mask = oof_local_interface_hwport_mask_all(fm); /* All interface hwport masks have now been updated, so if this interface * is using an hwport it should be present in the in_use mask.