net: add ifnet_rename_event EVENTHANDLER(9) for interface renaming
and don't trigger ifnet_arrival_event and ifnet_departure_event for a rename, as the interface isn't being detached from any protocol. The consumers of the arrival/departure events are divided into a few categories: - which indeed need to do the same actions as if interface was fully detached and attached: routing socket and netlink notifications to userland and the Linux sysfs. All addressed by this commit. - which build their logic based on an interface name, but should actually update their database on rename: packet filters. This commit leaves them with the old behavior - emulate full detach & attach, but this should be improved. - which shouldn't do anything on rename, not touched by the commit. - ng_ether and if_tuntap, that are special and will be addressed by separate commits.
This commit is contained in:
@@ -45,7 +45,7 @@
|
|||||||
#include <compat/linsysfs/linsysfs.h>
|
#include <compat/linsysfs/linsysfs.h>
|
||||||
|
|
||||||
struct pfs_node *net;
|
struct pfs_node *net;
|
||||||
static eventhandler_tag if_arrival_tag, if_departure_tag;
|
static eventhandler_tag if_arrival_tag, if_departure_tag, if_rename_tag;
|
||||||
|
|
||||||
static uint32_t net_latch_count = 0;
|
static uint32_t net_latch_count = 0;
|
||||||
static struct mtx net_latch_mtx;
|
static struct mtx net_latch_mtx;
|
||||||
@@ -312,6 +312,16 @@ linsysfs_if_departure(void *arg __unused, if_t ifp)
|
|||||||
linsysfs_net_latch_rele();
|
linsysfs_net_latch_rele();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
linsysfs_if_rename(void *arg __unused, if_t ifp)
|
||||||
|
{
|
||||||
|
|
||||||
|
linsysfs_net_latch_hold();
|
||||||
|
linsysfs_net_delif(ifp);
|
||||||
|
(void)linsysfs_net_addif(ifp, net);
|
||||||
|
linsysfs_net_latch_rele();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
linsysfs_net_init(void)
|
linsysfs_net_init(void)
|
||||||
{
|
{
|
||||||
@@ -324,6 +334,8 @@ linsysfs_net_init(void)
|
|||||||
linsysfs_if_arrival, NULL, EVENTHANDLER_PRI_ANY);
|
linsysfs_if_arrival, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
if_departure_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
if_departure_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||||
linsysfs_if_departure, NULL, EVENTHANDLER_PRI_ANY);
|
linsysfs_if_departure, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
|
if_rename_tag = EVENTHANDLER_REGISTER(ifnet_rename_event,
|
||||||
|
linsysfs_if_rename, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
|
|
||||||
linsysfs_net_latch_hold();
|
linsysfs_net_latch_hold();
|
||||||
VNET_LIST_RLOCK();
|
VNET_LIST_RLOCK();
|
||||||
@@ -343,6 +355,7 @@ linsysfs_net_uninit(void)
|
|||||||
|
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, if_arrival_tag);
|
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, if_arrival_tag);
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_departure_tag);
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_departure_tag);
|
||||||
|
EVENTHANDLER_DEREGISTER(ifnet_rename_event, if_rename_tag);
|
||||||
|
|
||||||
linsysfs_net_latch_hold();
|
linsysfs_net_latch_hold();
|
||||||
TAILQ_FOREACH_SAFE(nq, &ifp_nodes_q, ifp_nodes_next, nq_tmp) {
|
TAILQ_FOREACH_SAFE(nq, &ifp_nodes_q, ifp_nodes_next, nq_tmp) {
|
||||||
|
|||||||
+1
-3
@@ -3035,8 +3035,6 @@ if_rename(struct ifnet *ifp, char *new_name)
|
|||||||
*/
|
*/
|
||||||
ifp->if_flags |= IFF_RENAMING;
|
ifp->if_flags |= IFF_RENAMING;
|
||||||
|
|
||||||
EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
|
|
||||||
|
|
||||||
if_printf(ifp, "changing name to '%s'\n", new_name);
|
if_printf(ifp, "changing name to '%s'\n", new_name);
|
||||||
|
|
||||||
IF_ADDR_WLOCK(ifp);
|
IF_ADDR_WLOCK(ifp);
|
||||||
@@ -3063,7 +3061,7 @@ if_rename(struct ifnet *ifp, char *new_name)
|
|||||||
sdl->sdl_data[--namelen] = 0xff;
|
sdl->sdl_data[--namelen] = 0xff;
|
||||||
IF_ADDR_WUNLOCK(ifp);
|
IF_ADDR_WUNLOCK(ifp);
|
||||||
|
|
||||||
EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
|
EVENTHANDLER_INVOKE(ifnet_rename_event, ifp, old_name);
|
||||||
|
|
||||||
ifp->if_flags &= ~IFF_RENAMING;
|
ifp->if_flags &= ~IFF_RENAMING;
|
||||||
|
|
||||||
|
|||||||
+8
-3
@@ -361,19 +361,24 @@ EVENTHANDLER_DECLARE(ifaddr_event_ext, ifaddr_event_ext_handler_t);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Interface arrival & departure events.
|
* Interface arrival & departure events.
|
||||||
* The ifnet_arrival_event is executed before the is yet globally visible.
|
* The ifnet_arrival_event is executed before the interface is yet globally
|
||||||
* Protocols shall use this event to attach themselves. Protocols shall not
|
* visible. Protocols shall use this event to attach themselves. Protocols
|
||||||
* expect other protocols to be fully attached.
|
* shall not expect other protocols to be fully attached.
|
||||||
* The ifnet_attached_event is executed after the interface is attached to all
|
* The ifnet_attached_event is executed after the interface is attached to all
|
||||||
* protocols, is globally visible and fully functional.
|
* protocols, is globally visible and fully functional.
|
||||||
* The ifnet_departure_event is complementary to ifnet_arrival_event. The
|
* The ifnet_departure_event is complementary to ifnet_arrival_event. The
|
||||||
* interface is no longer globally visible, protocols may detach.
|
* interface is no longer globally visible, protocols may detach.
|
||||||
* XXXGL: immediate memory reclamation may not be safe in ifnet_departure_event.
|
* XXXGL: immediate memory reclamation may not be safe in ifnet_departure_event.
|
||||||
|
* The ifnet_rename_event is executed after an interface is renamed. The
|
||||||
|
* handlers would see the new name of the interface, and are also passed with
|
||||||
|
* old name in the argument.
|
||||||
*/
|
*/
|
||||||
typedef void (*ifnet_event_handler_t)(void *, if_t);
|
typedef void (*ifnet_event_handler_t)(void *, if_t);
|
||||||
EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_event_handler_t);
|
EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_event_handler_t);
|
||||||
EVENTHANDLER_DECLARE(ifnet_attached_event, ifnet_event_handler_t);
|
EVENTHANDLER_DECLARE(ifnet_attached_event, ifnet_event_handler_t);
|
||||||
EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_event_handler_t);
|
EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_event_handler_t);
|
||||||
|
typedef void (*ifnet_rename_event_handler_t)(void *, if_t, const char *);
|
||||||
|
EVENTHANDLER_DECLARE(ifnet_rename_event, ifnet_rename_event_handler_t);
|
||||||
|
|
||||||
/* Interface link state change event */
|
/* Interface link state change event */
|
||||||
typedef void (*ifnet_link_event_handler_t)(void *, if_t, int);
|
typedef void (*ifnet_link_event_handler_t)(void *, if_t, int);
|
||||||
|
|||||||
+19
-9
@@ -208,7 +208,7 @@ static int sysctl_ifmalist(int af, struct walkarg *w);
|
|||||||
static void rt_getmetrics(const struct rtentry *rt,
|
static void rt_getmetrics(const struct rtentry *rt,
|
||||||
const struct nhop_object *nh, struct rt_metrics *out);
|
const struct nhop_object *nh, struct rt_metrics *out);
|
||||||
static void rt_dispatch(struct mbuf *, sa_family_t);
|
static void rt_dispatch(struct mbuf *, sa_family_t);
|
||||||
static void rt_ifannouncemsg(struct ifnet *ifp, int what);
|
static void rt_ifannouncemsg(struct ifnet *, int, const char *);
|
||||||
static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
|
static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
|
||||||
struct rt_msghdr *rtm, struct rib_cmd_info *rc);
|
struct rt_msghdr *rtm, struct rib_cmd_info *rc);
|
||||||
static int update_rtm_from_rc(struct rt_addrinfo *info,
|
static int update_rtm_from_rc(struct rt_addrinfo *info,
|
||||||
@@ -319,17 +319,26 @@ SYSINIT(rtsock_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rtsock_init, NULL);
|
|||||||
static void
|
static void
|
||||||
rts_ifnet_attached(void *arg __unused, struct ifnet *ifp)
|
rts_ifnet_attached(void *arg __unused, struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
|
rt_ifannouncemsg(ifp, IFAN_ARRIVAL, NULL);
|
||||||
}
|
}
|
||||||
EVENTHANDLER_DEFINE(ifnet_attached_event, rts_ifnet_attached, NULL, 0);
|
EVENTHANDLER_DEFINE(ifnet_attached_event, rts_ifnet_attached, NULL, 0);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rts_handle_ifnet_departure(void *arg __unused, struct ifnet *ifp)
|
rts_handle_ifnet_departure(void *arg __unused, struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
|
rt_ifannouncemsg(ifp, IFAN_DEPARTURE, NULL);
|
||||||
}
|
}
|
||||||
EVENTHANDLER_DEFINE(ifnet_departure_event, rts_handle_ifnet_departure, NULL, 0);
|
EVENTHANDLER_DEFINE(ifnet_departure_event, rts_handle_ifnet_departure, NULL, 0);
|
||||||
|
|
||||||
|
static void
|
||||||
|
rts_handle_ifnet_rename(void *arg __unused, struct ifnet *ifp,
|
||||||
|
const char *old_name)
|
||||||
|
{
|
||||||
|
rt_ifannouncemsg(ifp, IFAN_DEPARTURE, old_name);
|
||||||
|
rt_ifannouncemsg(ifp, IFAN_ARRIVAL, NULL);
|
||||||
|
}
|
||||||
|
EVENTHANDLER_DEFINE(ifnet_rename_event, rts_handle_ifnet_rename, NULL, 0);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rts_append_data(struct socket *so, struct mbuf *m)
|
rts_append_data(struct socket *so, struct mbuf *m)
|
||||||
{
|
{
|
||||||
@@ -2143,7 +2152,7 @@ rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
|
|||||||
|
|
||||||
static struct mbuf *
|
static struct mbuf *
|
||||||
rt_makeifannouncemsg(struct ifnet *ifp, int type, int what,
|
rt_makeifannouncemsg(struct ifnet *ifp, int type, int what,
|
||||||
struct rt_addrinfo *info)
|
struct rt_addrinfo *info, const char *ifname)
|
||||||
{
|
{
|
||||||
struct if_announcemsghdr *ifan;
|
struct if_announcemsghdr *ifan;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
@@ -2155,8 +2164,9 @@ rt_makeifannouncemsg(struct ifnet *ifp, int type, int what,
|
|||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
ifan = mtod(m, struct if_announcemsghdr *);
|
ifan = mtod(m, struct if_announcemsghdr *);
|
||||||
ifan->ifan_index = ifp->if_index;
|
ifan->ifan_index = ifp->if_index;
|
||||||
strlcpy(ifan->ifan_name, ifp->if_xname,
|
strlcpy(ifan->ifan_name,
|
||||||
sizeof(ifan->ifan_name));
|
ifname != NULL ? ifname : ifp->if_xname,
|
||||||
|
sizeof(ifan->ifan_name));
|
||||||
ifan->ifan_what = what;
|
ifan->ifan_what = what;
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
@@ -2173,7 +2183,7 @@ rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len)
|
|||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct rt_addrinfo info;
|
struct rt_addrinfo info;
|
||||||
|
|
||||||
m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info);
|
m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info, NULL);
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
/*
|
/*
|
||||||
* Append the ieee80211 data. Try to stick it in the
|
* Append the ieee80211 data. Try to stick it in the
|
||||||
@@ -2207,12 +2217,12 @@ rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len)
|
|||||||
* network interface arrival and departure.
|
* network interface arrival and departure.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rt_ifannouncemsg(struct ifnet *ifp, int what)
|
rt_ifannouncemsg(struct ifnet *ifp, int what, const char *ifname)
|
||||||
{
|
{
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct rt_addrinfo info;
|
struct rt_addrinfo info;
|
||||||
|
|
||||||
m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
|
m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info, ifname);
|
||||||
if (m != NULL)
|
if (m != NULL)
|
||||||
rt_dispatch(m, AF_UNSPEC);
|
rt_dispatch(m, AF_UNSPEC);
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-11
@@ -70,7 +70,8 @@ struct netlink_walkargs {
|
|||||||
int dumped;
|
int dumped;
|
||||||
};
|
};
|
||||||
|
|
||||||
static eventhandler_tag ifdetach_event, ifattach_event, iflink_event, ifaddr_event;
|
static eventhandler_tag ifdetach_event, ifattach_event, ifrename_event,
|
||||||
|
iflink_event, ifaddr_event;
|
||||||
|
|
||||||
static SLIST_HEAD(, nl_cloner) nl_cloners = SLIST_HEAD_INITIALIZER(nl_cloners);
|
static SLIST_HEAD(, nl_cloner) nl_cloners = SLIST_HEAD_INITIALIZER(nl_cloners);
|
||||||
|
|
||||||
@@ -288,7 +289,7 @@ dump_iface_caps(struct nl_writer *nw, struct ifnet *ifp)
|
|||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
|
dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
|
||||||
int if_flags_mask)
|
int if_flags_mask, const char *ifname)
|
||||||
{
|
{
|
||||||
struct epoch_tracker et;
|
struct epoch_tracker et;
|
||||||
struct ifinfomsg *ifinfo;
|
struct ifinfomsg *ifinfo;
|
||||||
@@ -312,7 +313,8 @@ dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
|
|||||||
if (ifs.ifla_operstate == IF_OPER_UP)
|
if (ifs.ifla_operstate == IF_OPER_UP)
|
||||||
ifinfo->ifi_flags |= IFF_LOWER_UP;
|
ifinfo->ifi_flags |= IFF_LOWER_UP;
|
||||||
|
|
||||||
nlattr_add_string(nw, IFLA_IFNAME, if_name(ifp));
|
nlattr_add_string(nw, IFLA_IFNAME,
|
||||||
|
ifname != NULL ? ifname : if_name(ifp));
|
||||||
nlattr_add_u8(nw, IFLA_OPERSTATE, ifs.ifla_operstate);
|
nlattr_add_u8(nw, IFLA_OPERSTATE, ifs.ifla_operstate);
|
||||||
nlattr_add_u8(nw, IFLA_CARRIER, ifs.ifla_carrier);
|
nlattr_add_u8(nw, IFLA_CARRIER, ifs.ifla_carrier);
|
||||||
|
|
||||||
@@ -438,7 +440,7 @@ static int
|
|||||||
dump_cb(if_t ifp, void *_arg)
|
dump_cb(if_t ifp, void *_arg)
|
||||||
{
|
{
|
||||||
struct netlink_walkargs *wa = (struct netlink_walkargs *)_arg;
|
struct netlink_walkargs *wa = (struct netlink_walkargs *)_arg;
|
||||||
if (!dump_iface(wa->nw, ifp, &wa->hdr, 0))
|
if (!dump_iface(wa->nw, ifp, &wa->hdr, 0, NULL))
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -488,7 +490,7 @@ rtnl_handle_getlink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
|
|||||||
|
|
||||||
if (ifp != NULL) {
|
if (ifp != NULL) {
|
||||||
if (match_iface(ifp, &attrs)) {
|
if (match_iface(ifp, &attrs)) {
|
||||||
if (!dump_iface(wa.nw, ifp, &wa.hdr, 0))
|
if (!dump_iface(wa.nw, ifp, &wa.hdr, 0, NULL))
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
} else
|
} else
|
||||||
error = ENODEV;
|
error = ENODEV;
|
||||||
@@ -1399,7 +1401,8 @@ rtnl_handle_ifaddr(void *arg __unused, struct ifaddr *ifa, int cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtnl_handle_ifevent(if_t ifp, int nlmsg_type, int if_flags_mask)
|
rtnl_handle_ifevent(if_t ifp, int nlmsg_type, int if_flags_mask,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
struct nlmsghdr hdr = { .nlmsg_type = nlmsg_type };
|
struct nlmsghdr hdr = { .nlmsg_type = nlmsg_type };
|
||||||
struct nl_writer nw;
|
struct nl_writer nw;
|
||||||
@@ -1409,7 +1412,7 @@ rtnl_handle_ifevent(if_t ifp, int nlmsg_type, int if_flags_mask)
|
|||||||
NL_LOG(LOG_DEBUG, "error allocating group writer");
|
NL_LOG(LOG_DEBUG, "error allocating group writer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dump_iface(&nw, ifp, &hdr, if_flags_mask);
|
dump_iface(&nw, ifp, &hdr, if_flags_mask, ifname);
|
||||||
nlmsg_flush(&nw);
|
nlmsg_flush(&nw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1417,28 +1420,35 @@ static void
|
|||||||
rtnl_handle_ifattach(void *arg, if_t ifp)
|
rtnl_handle_ifattach(void *arg, if_t ifp)
|
||||||
{
|
{
|
||||||
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
||||||
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
|
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtnl_handle_ifdetach(void *arg, if_t ifp)
|
rtnl_handle_ifdetach(void *arg, if_t ifp)
|
||||||
{
|
{
|
||||||
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
||||||
rtnl_handle_ifevent(ifp, NL_RTM_DELLINK, 0);
|
rtnl_handle_ifevent(ifp, NL_RTM_DELLINK, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtnl_handle_ifrename(void *arg, if_t ifp, const char *old_name)
|
||||||
|
{
|
||||||
|
rtnl_handle_ifevent(ifp, NL_RTM_DELLINK, 0, old_name);
|
||||||
|
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtnl_handle_iflink(void *arg, if_t ifp, int link_state __unused)
|
rtnl_handle_iflink(void *arg, if_t ifp, int link_state __unused)
|
||||||
{
|
{
|
||||||
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
||||||
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
|
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rtnl_handle_ifnet_event(if_t ifp, int if_flags_mask)
|
rtnl_handle_ifnet_event(if_t ifp, int if_flags_mask)
|
||||||
{
|
{
|
||||||
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
|
||||||
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, if_flags_mask);
|
rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, if_flags_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct rtnl_cmd_handler cmd_handlers[] = {
|
static const struct rtnl_cmd_handler cmd_handlers[] = {
|
||||||
@@ -1513,6 +1523,9 @@ rtnl_ifaces_init(void)
|
|||||||
ifdetach_event = EVENTHANDLER_REGISTER(
|
ifdetach_event = EVENTHANDLER_REGISTER(
|
||||||
ifnet_departure_event, rtnl_handle_ifdetach, NULL,
|
ifnet_departure_event, rtnl_handle_ifdetach, NULL,
|
||||||
EVENTHANDLER_PRI_ANY);
|
EVENTHANDLER_PRI_ANY);
|
||||||
|
ifrename_event = EVENTHANDLER_REGISTER(
|
||||||
|
ifnet_rename_event, rtnl_handle_ifrename, NULL,
|
||||||
|
EVENTHANDLER_PRI_ANY);
|
||||||
ifaddr_event = EVENTHANDLER_REGISTER(
|
ifaddr_event = EVENTHANDLER_REGISTER(
|
||||||
rt_addrmsg, rtnl_handle_ifaddr, NULL,
|
rt_addrmsg, rtnl_handle_ifaddr, NULL,
|
||||||
EVENTHANDLER_PRI_ANY);
|
EVENTHANDLER_PRI_ANY);
|
||||||
@@ -1528,6 +1541,7 @@ rtnl_ifaces_destroy(void)
|
|||||||
{
|
{
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ifattach_event);
|
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ifattach_event);
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_event);
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_event);
|
||||||
|
EVENTHANDLER_DEREGISTER(ifnet_rename_event, ifrename_event);
|
||||||
EVENTHANDLER_DEREGISTER(rt_addrmsg, ifaddr_event);
|
EVENTHANDLER_DEREGISTER(rt_addrmsg, ifaddr_event);
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_link_event, iflink_event);
|
EVENTHANDLER_DEREGISTER(ifnet_link_event, iflink_event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,10 @@ VNET_DEFINE(ipf_main_softc_t, ipfmain) = {
|
|||||||
|
|
||||||
VNET_DEFINE_STATIC(eventhandler_tag, ipf_arrivetag);
|
VNET_DEFINE_STATIC(eventhandler_tag, ipf_arrivetag);
|
||||||
VNET_DEFINE_STATIC(eventhandler_tag, ipf_departtag);
|
VNET_DEFINE_STATIC(eventhandler_tag, ipf_departtag);
|
||||||
|
VNET_DEFINE_STATIC(eventhandler_tag, ipf_renametag);
|
||||||
#define V_ipf_arrivetag VNET(ipf_arrivetag)
|
#define V_ipf_arrivetag VNET(ipf_arrivetag)
|
||||||
#define V_ipf_departtag VNET(ipf_departtag)
|
#define V_ipf_departtag VNET(ipf_departtag)
|
||||||
|
#define V_ipf_renametag VNET(ipf_renametag)
|
||||||
|
|
||||||
static void ipf_ifevent(void *arg, struct ifnet *ifp);
|
static void ipf_ifevent(void *arg, struct ifnet *ifp);
|
||||||
|
|
||||||
@@ -1349,6 +1351,9 @@ ipf_event_reg(void)
|
|||||||
V_ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
|
V_ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
|
||||||
ipf_ifevent, NULL, \
|
ipf_ifevent, NULL, \
|
||||||
EVENTHANDLER_PRI_ANY);
|
EVENTHANDLER_PRI_ANY);
|
||||||
|
V_ipf_renametag = EVENTHANDLER_REGISTER(ifnet_rename_event, \
|
||||||
|
ipf_ifevent, NULL, \
|
||||||
|
EVENTHANDLER_PRI_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1360,6 +1365,9 @@ ipf_event_dereg(void)
|
|||||||
if (V_ipf_departtag != NULL) {
|
if (V_ipf_departtag != NULL) {
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event, V_ipf_departtag);
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event, V_ipf_departtag);
|
||||||
}
|
}
|
||||||
|
if (V_ipf_renametag != NULL) {
|
||||||
|
EVENTHANDLER_DEREGISTER(ifnet_rename_event, V_ipf_renametag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -77,12 +77,13 @@ static struct ipfw_sopt_handler scodes[] = {
|
|||||||
/*
|
/*
|
||||||
* FreeBSD Kernel interface.
|
* FreeBSD Kernel interface.
|
||||||
*/
|
*/
|
||||||
static void ipfw_kifhandler(void *arg, struct ifnet *ifp);
|
static void ipfw_kifhandler(void *, struct ifnet *, const char *);
|
||||||
static int ipfw_kiflookup(char *name);
|
static int ipfw_kiflookup(char *name);
|
||||||
static void iface_khandler_register(void);
|
static void iface_khandler_register(void);
|
||||||
static void iface_khandler_deregister(void);
|
static void iface_khandler_deregister(void);
|
||||||
|
|
||||||
static eventhandler_tag ipfw_ifdetach_event, ipfw_ifattach_event;
|
static eventhandler_tag ipfw_ifdetach_event, ipfw_ifattach_event,
|
||||||
|
ipfw_rename_event;
|
||||||
static int num_vnets = 0;
|
static int num_vnets = 0;
|
||||||
static struct mtx vnet_mtx;
|
static struct mtx vnet_mtx;
|
||||||
|
|
||||||
@@ -90,19 +91,21 @@ static struct mtx vnet_mtx;
|
|||||||
* Checks if kernel interface is contained in our tracked
|
* Checks if kernel interface is contained in our tracked
|
||||||
* interface list and calls attach/detach handler.
|
* interface list and calls attach/detach handler.
|
||||||
*/
|
*/
|
||||||
|
enum ifevent { ARRIVAL, DEPARTURE, RENAME };
|
||||||
static void
|
static void
|
||||||
ipfw_kifhandler(void *arg, struct ifnet *ifp)
|
ipfw_kifhandler(void *arg, struct ifnet *ifp, const char *old_name)
|
||||||
{
|
{
|
||||||
|
enum ifevent *what = arg;
|
||||||
struct ip_fw_chain *ch;
|
struct ip_fw_chain *ch;
|
||||||
struct ipfw_iface *iif;
|
struct ipfw_iface *iif;
|
||||||
struct namedobj_instance *ii;
|
struct namedobj_instance *ii;
|
||||||
uintptr_t htype;
|
|
||||||
|
MPASS(*what != RENAME || old_name != NULL);
|
||||||
|
|
||||||
if (V_ipfw_vnet_ready == 0)
|
if (V_ipfw_vnet_ready == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ch = &V_layer3_chain;
|
ch = &V_layer3_chain;
|
||||||
htype = (uintptr_t)arg;
|
|
||||||
|
|
||||||
IPFW_UH_WLOCK(ch);
|
IPFW_UH_WLOCK(ch);
|
||||||
ii = CHAIN_TO_II(ch);
|
ii = CHAIN_TO_II(ch);
|
||||||
@@ -111,12 +114,23 @@ ipfw_kifhandler(void *arg, struct ifnet *ifp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iif = (struct ipfw_iface*)ipfw_objhash_lookup_name(ii, 0,
|
iif = (struct ipfw_iface*)ipfw_objhash_lookup_name(ii, 0,
|
||||||
if_name(ifp));
|
*what == RENAME ? old_name : if_name(ifp));
|
||||||
if (iif != NULL) {
|
if (iif != NULL) {
|
||||||
if (htype == 1)
|
switch (*what) {
|
||||||
|
case ARRIVAL:
|
||||||
handle_ifattach(ch, iif, ifp->if_index);
|
handle_ifattach(ch, iif, ifp->if_index);
|
||||||
else
|
break;
|
||||||
|
case DEPARTURE:
|
||||||
handle_ifdetach(ch, iif, ifp->if_index);
|
handle_ifdetach(ch, iif, ifp->if_index);
|
||||||
|
break;
|
||||||
|
case RENAME:
|
||||||
|
/*
|
||||||
|
* XXXGL: should be handled better.
|
||||||
|
*/
|
||||||
|
handle_ifdetach(ch, iif, ifp->if_index);
|
||||||
|
handle_ifattach(ch, iif, ifp->if_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IPFW_UH_WUNLOCK(ch);
|
IPFW_UH_WUNLOCK(ch);
|
||||||
}
|
}
|
||||||
@@ -143,12 +157,12 @@ iface_khandler_register(void)
|
|||||||
|
|
||||||
printf("IPFW: starting up interface tracker\n");
|
printf("IPFW: starting up interface tracker\n");
|
||||||
|
|
||||||
ipfw_ifdetach_event = EVENTHANDLER_REGISTER(
|
ipfw_ifdetach_event = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||||
ifnet_departure_event, ipfw_kifhandler, NULL,
|
ipfw_kifhandler, (void*)(uintptr_t)DEPARTURE, EVENTHANDLER_PRI_ANY);
|
||||||
EVENTHANDLER_PRI_ANY);
|
ipfw_ifattach_event = EVENTHANDLER_REGISTER(ifnet_arrival_event,
|
||||||
ipfw_ifattach_event = EVENTHANDLER_REGISTER(
|
ipfw_kifhandler, (void*)(uintptr_t)ARRIVAL, EVENTHANDLER_PRI_ANY);
|
||||||
ifnet_arrival_event, ipfw_kifhandler, (void*)((uintptr_t)1),
|
ipfw_rename_event = EVENTHANDLER_REGISTER(ifnet_rename_event,
|
||||||
EVENTHANDLER_PRI_ANY);
|
ipfw_kifhandler, (void*)(uintptr_t)RENAME, EVENTHANDLER_PRI_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -171,10 +185,9 @@ iface_khandler_deregister(void)
|
|||||||
if (destroy == 0)
|
if (destroy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_arrival_event,
|
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipfw_ifattach_event);
|
||||||
ipfw_ifattach_event);
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipfw_ifdetach_event);
|
||||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event,
|
EVENTHANDLER_DEREGISTER(ifnet_rename_event, ipfw_rename_event);
|
||||||
ipfw_ifdetach_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ VNET_DEFINE(struct pfi_kkif *, pf_kifmarker);
|
|||||||
|
|
||||||
static eventhandler_tag pfi_attach_cookie;
|
static eventhandler_tag pfi_attach_cookie;
|
||||||
static eventhandler_tag pfi_detach_cookie;
|
static eventhandler_tag pfi_detach_cookie;
|
||||||
|
static eventhandler_tag pfi_rename_cookie;
|
||||||
static eventhandler_tag pfi_attach_group_cookie;
|
static eventhandler_tag pfi_attach_group_cookie;
|
||||||
static eventhandler_tag pfi_change_group_cookie;
|
static eventhandler_tag pfi_change_group_cookie;
|
||||||
static eventhandler_tag pfi_detach_group_cookie;
|
static eventhandler_tag pfi_detach_group_cookie;
|
||||||
@@ -95,6 +96,7 @@ static int pfi_skip_if(const char *, struct pfi_kkif *);
|
|||||||
static int pfi_unmask(void *);
|
static int pfi_unmask(void *);
|
||||||
static void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
|
static void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
|
||||||
static void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
|
static void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
|
||||||
|
static void pfi_rename_ifnet_event(void * __unused, struct ifnet *);
|
||||||
static void pfi_attach_group_event(void * __unused, struct ifg_group *);
|
static void pfi_attach_group_event(void * __unused, struct ifg_group *);
|
||||||
static void pfi_change_group_event(void * __unused, char *);
|
static void pfi_change_group_event(void * __unused, char *);
|
||||||
static void pfi_detach_group_event(void * __unused, struct ifg_group *);
|
static void pfi_detach_group_event(void * __unused, struct ifg_group *);
|
||||||
@@ -172,6 +174,8 @@ pfi_initialize(void)
|
|||||||
pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||||
pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
|
pfi_rename_cookie = EVENTHANDLER_REGISTER(ifnet_rename_event,
|
||||||
|
pfi_rename_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
|
pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
|
||||||
pfi_attach_group_event, NULL, EVENTHANDLER_PRI_ANY);
|
pfi_attach_group_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
|
pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
|
||||||
@@ -1069,6 +1073,14 @@ pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
|||||||
NET_EPOCH_EXIT(et);
|
NET_EPOCH_EXIT(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pfi_rename_ifnet_event(void *arg, struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
/* XXXGL: should be handled better */
|
||||||
|
pfi_detach_ifnet_event(arg, ifp);
|
||||||
|
pfi_attach_ifnet_event(arg, ifp);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user