IfAPI: Add iterator to complement if_foreach()
Summary: Sometimes an if_foreach() callback can be trivial, or need a lot of outer context. In this case a regular `for` loop makes more sense. To keep things hidden in the new API, use an opaque `if_iter` structure that can still be instantiated on the stack. The current implementation uses just a single pointer out of the 4 alotted to the opaque context, and the cleanup does nothing, but may be used in the future. Reviewed by: melifaro Sponsored by: Juniper Networks, Inc. Differential Revision: https://reviews.freebsd.org/D39138
This commit is contained in:
parent
2f181c0cd6
commit
f20b0353c3
36
sys/net/if.c
36
sys/net/if.c
@ -4600,6 +4600,42 @@ if_foreach_sleep(if_foreach_match_t match_cb, void *match_arg, if_foreach_cb_t c
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Uses just 1 pointer of the 4 available in the public struct.
|
||||
*/
|
||||
if_t
|
||||
if_iter_start(struct if_iter *iter)
|
||||
{
|
||||
if_t ifp;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
|
||||
bzero(iter, sizeof(*iter));
|
||||
ifp = CK_STAILQ_FIRST(&V_ifnet);
|
||||
if (ifp != NULL)
|
||||
iter->context[0] = CK_STAILQ_NEXT(ifp, if_link);
|
||||
else
|
||||
iter->context[0] = NULL;
|
||||
return (ifp);
|
||||
}
|
||||
|
||||
if_t
|
||||
if_iter_next(struct if_iter *iter)
|
||||
{
|
||||
if_t cur_ifp = iter->context[0];
|
||||
|
||||
if (cur_ifp != NULL)
|
||||
iter->context[0] = CK_STAILQ_NEXT(cur_ifp, if_link);
|
||||
return (cur_ifp);
|
||||
}
|
||||
|
||||
void
|
||||
if_iter_finish(struct if_iter *iter)
|
||||
{
|
||||
/* Nothing to do here for now. */
|
||||
}
|
||||
|
||||
u_int
|
||||
if_foreach_lladdr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
|
||||
{
|
||||
|
@ -684,6 +684,15 @@ typedef bool (*if_foreach_match_t)(if_t, void *);
|
||||
int if_foreach(if_foreach_cb_t, void *);
|
||||
int if_foreach_sleep(if_foreach_match_t, void *, if_foreach_cb_t, void *);
|
||||
|
||||
/* Opaque iterator structure for iterating over interfaces. */
|
||||
struct if_iter {
|
||||
void *context[4];
|
||||
};
|
||||
|
||||
if_t if_iter_start(struct if_iter *);
|
||||
if_t if_iter_next(struct if_iter *);
|
||||
void if_iter_finish(struct if_iter *);
|
||||
|
||||
/* Functions */
|
||||
void if_setinitfn(if_t ifp, if_init_fn_t);
|
||||
void if_setinputfn(if_t ifp, if_input_fn_t);
|
||||
|
Loading…
Reference in New Issue
Block a user