Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102855784
D37597.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D37597.diff
View Options
diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -209,7 +209,7 @@
ifp->if_ioctl = usbpf_ioctl;
if_attach(ifp);
ifp->if_flags |= IFF_UP;
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, IFF_UP);
/*
* XXX According to the specification of DLT_USB, it indicates
* packets beginning with USB setup header. But not sure all
diff --git a/sys/net/if.h b/sys/net/if.h
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -164,6 +164,7 @@
#define IFF_DYING 0x200000 /* (n) interface is winding down */
#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */
#define IFF_NOGROUP 0x800000 /* (n) interface is not part of any groups */
+#define IFF_NETLINK_1 0x1000000 /* (n) used by netlink */
/*
* Old names for driver flags so that user space tools can continue to use
diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2138,7 +2138,7 @@
if (ifp->if_carp)
(*carp_linkstate_p)(ifp);
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, IFF_UP);
}
/*
@@ -2155,7 +2155,7 @@
getmicrotime(&ifp->if_lastchange);
if (ifp->if_carp)
(*carp_linkstate_p)(ifp);
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, IFF_UP);
#ifdef INET6
in6_if_up(ifp);
#endif
@@ -2199,7 +2199,7 @@
link_state = ifp->if_link_state;
CURVNET_SET(ifp->if_vnet);
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, 0);
if (ifp->if_vlantrunk != NULL)
(*vlan_link_state_p)(ifp);
@@ -2845,7 +2845,7 @@
error = (*ifp->if_ioctl)(ifp, cmd, data);
if (error == 0) {
getmicrotime(&ifp->if_lastchange);
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, 0);
#ifdef INET
DEBUGNET_NOTIFY_MTU(ifp);
#endif
@@ -3274,7 +3274,7 @@
if (error)
goto recover;
/* Notify userland that interface flags have changed */
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, flag);
return (0);
recover:
diff --git a/sys/net/route.h b/sys/net/route.h
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -412,7 +412,7 @@
struct rib_head;
void rt_ieee80211msg(struct ifnet *, int, void *, size_t);
-void rt_ifmsg(struct ifnet *);
+void rt_ifmsg(struct ifnet *, int);
void rt_missmsg(int, struct rt_addrinfo *, int, int);
void rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int);
int rt_addrmsg(int, struct ifaddr *, int);
diff --git a/sys/net/route.c b/sys/net/route.c
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -695,12 +695,28 @@
return (rtsock_routemsg_info(cmd, info, fibnum));
}
+void
+rt_ifmsg(struct ifnet *ifp, int if_flags_mask)
+{
+ rtsock_callback_p->ifmsg_f(ifp, if_flags_mask);
+ netlink_callback_p->ifmsg_f(ifp, if_flags_mask);
+}
+
/* Netlink-related callbacks needed to glue rtsock, netlink and linuxolator */
static void
ignore_route_event(uint32_t fibnum, const struct rib_cmd_info *rc)
{
}
-static struct rtbridge ignore_cb = { .route_f = ignore_route_event };
+
+static void
+ignore_ifmsg_event(struct ifnet *ifp, int if_flags_mask)
+{
+}
+
+static struct rtbridge ignore_cb = {
+ .route_f = ignore_route_event,
+ .ifmsg_f = ignore_ifmsg_event,
+};
void *linux_netlink_p = NULL; /* Callback pointer for Linux translator functions */
struct rtbridge *rtsock_callback_p = &ignore_cb;
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -191,8 +191,10 @@
/* Event bridge */
typedef void route_event_f(uint32_t fibnum, const struct rib_cmd_info *rc);
+typedef void ifmsg_event_f(struct ifnet *ifp, int if_flags_mask);
struct rtbridge{
route_event_f *route_f;
+ ifmsg_event_f *ifmsg_f;
};
extern struct rtbridge *rtsock_callback_p;
extern struct rtbridge *netlink_callback_p;
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -220,6 +220,7 @@
static bool can_export_rte(struct ucred *td_ucred, bool rt_is_host,
const struct sockaddr *rt_dst);
static void rtsock_notify_event(uint32_t fibnum, const struct rib_cmd_info *rc);
+static void rtsock_ifmsg(struct ifnet *ifp, int if_flags_mask);
static struct netisr_handler rtsock_nh = {
.nh_name = "rtsock",
@@ -297,7 +298,10 @@
#endif
report_route_event(rc, (void *)(uintptr_t)fibnum);
}
-static struct rtbridge rtsbridge = { .route_f = rts_handle_route_event };
+static struct rtbridge rtsbridge = {
+ .route_f = rts_handle_route_event,
+ .ifmsg_f = rtsock_ifmsg,
+};
static struct rtbridge *rtsbridge_orig_p;
static void
@@ -1916,8 +1920,8 @@
* This routine is called to generate a message from the routing
* socket indicating that the status of a network interface has changed.
*/
-void
-rt_ifmsg(struct ifnet *ifp)
+static void
+rtsock_ifmsg(struct ifnet *ifp, int if_flags_mask __unused)
{
struct if_msghdr *ifm;
struct mbuf *m;
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -1020,7 +1020,7 @@
}
void
-ieee80211_notify_ifnet_change(struct ieee80211vap *vap)
+ieee80211_notify_ifnet_change(struct ieee80211vap *vap, int if_flags_mask)
{
struct ifnet *ifp = vap->iv_ifp;
@@ -1028,7 +1028,7 @@
"interface state change");
CURVNET_SET(ifp->if_vnet);
- rt_ifmsg(ifp);
+ rt_ifmsg(ifp, if_flags_mask);
CURVNET_RESTORE();
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -462,5 +462,5 @@
void ieee80211_notify_country(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN], const uint8_t cc[2]);
void ieee80211_notify_radio(struct ieee80211com *, int);
-void ieee80211_notify_ifnet_change(struct ieee80211vap *);
+void ieee80211_notify_ifnet_change(struct ieee80211vap *, int);
#endif /* _NET80211_IEEE80211_PROTO_H_ */
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1993,7 +1993,7 @@
* back in here and complete the work.
*/
ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ieee80211_notify_ifnet_change(vap);
+ ieee80211_notify_ifnet_change(vap, IFF_DRV_RUNNING);
/*
* We are not running; if this we are the first vap
@@ -2107,7 +2107,7 @@
ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; /* mark us stopped */
- ieee80211_notify_ifnet_change(vap);
+ ieee80211_notify_ifnet_change(vap, IFF_DRV_RUNNING);
if (--ic->ic_nrunning == 0) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
diff --git a/sys/netlink/netlink_route.c b/sys/netlink/netlink_route.c
--- a/sys/netlink/netlink_route.c
+++ b/sys/netlink/netlink_route.c
@@ -106,7 +106,10 @@
return (error);
}
-static struct rtbridge nlbridge = { .route_f = rtnl_handle_route_event };
+static struct rtbridge nlbridge = {
+ .route_f = rtnl_handle_route_event,
+ .ifmsg_f = rtnl_handle_ifnet_event,
+};
static struct rtbridge *nlbridge_orig_p;
static void
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -68,7 +68,7 @@
int dumped;
};
-static eventhandler_tag ifdetach_event, ifattach_event, ifaddr_event;
+static eventhandler_tag ifdetach_event, ifattach_event, iflink_event, ifaddr_event;
static SLIST_HEAD(, nl_cloner) nl_cloners = SLIST_HEAD_INITIALIZER(nl_cloners);
@@ -234,11 +234,13 @@
* @nw: message writer
* @ifp: target interface
* @hdr: template header
+ * @if_flags_mask: changed if_[drv]_flags bitmask
*
* This function is called without epoch and MAY sleep.
*/
static bool
-dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr)
+dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr,
+ int if_flags_mask)
{
struct ifinfomsg *ifinfo;
@@ -253,13 +255,15 @@
ifinfo->ifi_type = ifp->if_type;
ifinfo->ifi_index = ifp->if_index;
ifinfo->ifi_flags = ifp_flags_to_netlink(ifp);
- ifinfo->ifi_change = 0;
-
- nlattr_add_string(nw, IFLA_IFNAME, if_name(ifp));
+ ifinfo->ifi_change = if_flags_mask;
struct if_state ifs = {};
get_operstate(ifp, &ifs);
+ if (ifs.ifla_operstate == IF_OPER_UP)
+ ifinfo->ifi_flags |= IFF_LOWER_UP;
+
+ nlattr_add_string(nw, IFLA_IFNAME, if_name(ifp));
nlattr_add_u8(nw, IFLA_OPERSTATE, ifs.ifla_operstate);
nlattr_add_u8(nw, IFLA_CARRIER, ifs.ifla_carrier);
@@ -387,7 +391,7 @@
NLP_LOG(LOG_DEBUG3, nlp, "fast track -> searching index %u", attrs.ifi_index);
if (ifp != NULL) {
if (match_iface(&attrs, ifp)) {
- if (!dump_iface(wa.nw, ifp, &wa.hdr))
+ if (!dump_iface(wa.nw, ifp, &wa.hdr, 0))
error = ENOMEM;
} else
error = ESRCH;
@@ -439,7 +443,7 @@
NL_LOG(LOG_DEBUG2, "Matched %d interface(s), dumping", offset);
for (int i = 0; error == 0 && i < offset; i++) {
- if (!dump_iface(wa.nw, match_array[i], &wa.hdr))
+ if (!dump_iface(wa.nw, match_array[i], &wa.hdr, 0))
error = ENOMEM;
}
for (int i = 0; i < offset; i++)
@@ -767,9 +771,9 @@
}
static void
-rtnl_handle_ifattach(void *arg, struct ifnet *ifp)
+rtnl_handle_ifevent(struct ifnet *ifp, int nlmsg_type, int if_flags_mask)
{
- struct nlmsghdr hdr = { .nlmsg_type = NL_RTM_NEWLINK };
+ struct nlmsghdr hdr = { .nlmsg_type = nlmsg_type };
struct nl_writer nw = {};
if (!nl_has_listeners(NETLINK_ROUTE, RTNLGRP_LINK))
@@ -779,25 +783,36 @@
NL_LOG(LOG_DEBUG, "error allocating mbuf");
return;
}
- dump_iface(&nw, ifp, &hdr);
+ dump_iface(&nw, ifp, &hdr, if_flags_mask);
nlmsg_flush(&nw);
}
+static void
+rtnl_handle_ifattach(void *arg, struct ifnet *ifp)
+{
+ NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
+ rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
+}
+
static void
rtnl_handle_ifdetach(void *arg, struct ifnet *ifp)
{
- struct nlmsghdr hdr = { .nlmsg_type = NL_RTM_DELLINK };
- struct nl_writer nw = {};
+ NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
+ rtnl_handle_ifevent(ifp, NL_RTM_DELLINK, 0);
+}
- if (!nl_has_listeners(NETLINK_ROUTE, RTNLGRP_LINK))
- return;
+static void
+rtnl_handle_iflink(void *arg, struct ifnet *ifp)
+{
+ NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
+ rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
+}
- if (!nlmsg_get_group_writer(&nw, NLMSG_LARGE, NETLINK_ROUTE, RTNLGRP_LINK)) {
- NL_LOG(LOG_DEBUG, "error allocating mbuf");
- return;
- }
- dump_iface(&nw, ifp, &hdr);
- nlmsg_flush(&nw);
+void
+rtnl_handle_ifnet_event(struct ifnet *ifp, int if_flags_mask)
+{
+ NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
+ rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, if_flags_mask);
}
static const struct rtnl_cmd_handler cmd_handlers[] = {
@@ -867,6 +882,9 @@
ifaddr_event = EVENTHANDLER_REGISTER(
rt_addrmsg, rtnl_handle_ifaddr, NULL,
EVENTHANDLER_PRI_ANY);
+ iflink_event = EVENTHANDLER_REGISTER(
+ ifnet_link_event, rtnl_handle_iflink, NULL,
+ EVENTHANDLER_PRI_ANY);
NL_VERIFY_PARSERS(all_parsers);
rtnl_iface_drivers_register();
rtnl_register_messages(cmd_handlers, NL_ARRAY_LEN(cmd_handlers));
@@ -878,4 +896,5 @@
EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ifattach_event);
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_event);
EVENTHANDLER_DEREGISTER(rt_addrmsg, ifaddr_event);
+ EVENTHANDLER_DEREGISTER(ifnet_link_event, iflink_event);
}
diff --git a/sys/netlink/route/interface.h b/sys/netlink/route/interface.h
--- a/sys/netlink/route/interface.h
+++ b/sys/netlink/route/interface.h
@@ -42,6 +42,9 @@
unsigned ifi_change; /* IFF_* change mask */
};
+/* Linux-specific link-level state flag */
+#define IFF_LOWER_UP IFF_NETLINK_1
+
#ifndef _KERNEL
/* Compatilbility helpers */
#define _IFINFO_HDRLEN ((int)sizeof(struct ifinfomsg))
diff --git a/sys/netlink/route/route_var.h b/sys/netlink/route/route_var.h
--- a/sys/netlink/route/route_var.h
+++ b/sys/netlink/route/route_var.h
@@ -88,6 +88,7 @@
void rtnl_ifaces_destroy(void);
void rtnl_iface_add_cloner(struct nl_cloner *cloner);
void rtnl_iface_del_cloner(struct nl_cloner *cloner);
+void rtnl_handle_ifnet_event(struct ifnet *ifp, int if_change_mask);
/* iface_drivers.c */
void rtnl_iface_drivers_register(void);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 19, 1:23 AM (22 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14708062
Default Alt Text
D37597.diff (11 KB)
Attached To
Mode
D37597: netlink: add interface notification on link status / flags change.
Attached
Detach File
Event Timeline
Log In to Comment