Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153849340
D25070.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D25070.diff
View Options
Index: head/sys/net/route/route_ctl.h
===================================================================
--- head/sys/net/route/route_ctl.h
+++ head/sys/net/route/route_ctl.h
@@ -64,5 +64,20 @@
typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
void rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, void *);
void rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg);
+
+enum rib_subscription_type {
+ RIB_NOTIFY_IMMEDIATE,
+ RIB_NOTIFY_DELAYED
+};
+
+struct rib_subscription;
+typedef void rib_subscription_cb_t(struct rib_head *rnh, struct rib_cmd_info *rc,
+ void *arg);
+
+struct rib_subscription *rib_subscribe(uint32_t fibnum, int family,
+ rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
+ int waitok);
+int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs);
+
#endif
Index: head/sys/net/route/route_ctl.c
===================================================================
--- head/sys/net/route/route_ctl.c
+++ head/sys/net/route/route_ctl.c
@@ -68,10 +68,19 @@
* All functions assumes they are called in net epoch.
*/
+struct rib_subscription {
+ CK_STAILQ_ENTRY(rib_subscription) next;
+ rib_subscription_cb_t *func;
+ void *arg;
+ enum rib_subscription_type type;
+ struct epoch_context epoch_ctx;
+};
+
static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
struct rib_cmd_info *rc);
static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info);
+static void destroy_subscription_epoch(epoch_context_t ctx);
static struct rib_head *
get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
@@ -263,6 +272,9 @@
}
RIB_WUNLOCK(rnh);
+ if ((rn != NULL) || (rt_old != NULL))
+ rib_notify(rnh, RIB_NOTIFY_DELAYED, rc);
+
if (rt_old != NULL) {
rt_notifydelete(rt_old, info);
rtfree(rt_old);
@@ -419,6 +431,7 @@
if (error != 0)
return (error);
+ rib_notify(rnh, RIB_NOTIFY_DELAYED, rc);
rt_notifydelete(rt, info);
/*
@@ -559,11 +572,12 @@
/* Update generation id to reflect rtable change */
rnh->rnh_gen++;
-
rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
RIB_WUNLOCK(rnh);
+ rib_notify(rnh, RIB_NOTIFY_DELAYED, rc);
+
nhop_free(nh_orig);
return (0);
@@ -614,6 +628,7 @@
struct rt_addrinfo info;
struct rib_head *rnh;
struct rtentry *head;
+ struct rib_cmd_info rc;
};
/*
@@ -643,7 +658,13 @@
return (0);
}
- /* Entry was unlinked. Add to the list and return */
+ /* Entry was unlinked. Notify subscribers */
+ di->rnh->rnh_gen++;
+ di->rc.rc_rt = rt;
+ di->rc.rc_nh_old = rt->rt_nhop;
+ rib_notify(di->rnh, RIB_NOTIFY_IMMEDIATE, &di->rc);
+
+ /* Add to the list and return */
rt->rt_chain = di->head;
di->head = rt;
@@ -665,6 +686,7 @@
struct rib_head *rnh;
struct rt_delinfo di;
struct rtentry *rt;
+ struct epoch_tracker et;
rnh = rt_tables_get_rnh(fibnum, family);
if (rnh == NULL)
@@ -674,20 +696,24 @@
di.info.rti_filter = filter_f;
di.info.rti_filterdata = arg;
di.rnh = rnh;
+ di.rc.rc_cmd = RTM_DELETE;
+ NET_EPOCH_ENTER(et);
+
RIB_WLOCK(rnh);
rnh->rnh_walktree(&rnh->head, rt_checkdelroute, &di);
RIB_WUNLOCK(rnh);
- if (di.head == NULL)
- return;
-
/* We might have something to reclaim. */
while (di.head != NULL) {
rt = di.head;
di.head = rt->rt_chain;
rt->rt_chain = NULL;
+ di.rc.rc_rt = rt;
+ di.rc.rc_nh_old = rt->rt_nhop;
+ rib_notify(rnh, RIB_NOTIFY_DELAYED, &di.rc);
+
/* TODO std rt -> rt_addrinfo export */
di.info.rti_info[RTAX_DST] = rt_key(rt);
di.info.rti_info[RTAX_NETMASK] = rt_mask(rt);
@@ -699,6 +725,8 @@
fibnum);
rtfree(rt);
}
+
+ NET_EPOCH_EXIT(et);
}
static void
@@ -713,6 +741,13 @@
}
}
+/*
+ * Subscribe for the changes in the routing table specified by @fibnum and
+ * @family.
+ * Needs to be run in network epoch.
+ *
+ * Returns pointer to the subscription structure on success.
+ */
struct rib_subscription *
rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg,
enum rib_subscription_type type, int waitok)
@@ -740,6 +775,13 @@
return (rs);
}
+/*
+ * Remove rtable subscription @rs from the table specified by @fibnum
+ * and @family.
+ * Needs to be run in network epoch.
+ *
+ * Returns 0 on success.
+ */
int
rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs)
{
@@ -756,7 +798,21 @@
CK_STAILQ_REMOVE(&rnh->rnh_subscribers, rs, rib_subscription, next);
RIB_WUNLOCK(rnh);
- free(rs, M_RTABLE);
+ epoch_call(net_epoch_preempt, destroy_subscription_epoch,
+ &rs->epoch_ctx);
+
return (0);
}
+/*
+ * Epoch callback indicating subscription is safe to destroy
+ */
+static void
+destroy_subscription_epoch(epoch_context_t ctx)
+{
+ struct rib_subscription *rs;
+
+ rs = __containerof(ctx, struct rib_subscription, epoch_ctx);
+
+ free(rs, M_RTABLE);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 25, 6:05 AM (16 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32112728
Default Alt Text
D25070.diff (4 KB)
Attached To
Mode
D25070: Add rib subscription API.
Attached
Detach File
Event Timeline
Log In to Comment