|
@@ -3040,7 +3040,7 @@ struct mlxsw_sp_fib_event_work {
|
|
|
unsigned long event;
|
|
|
};
|
|
|
|
|
|
-static void mlxsw_sp_router_fib_event_work(struct work_struct *work)
|
|
|
+static void mlxsw_sp_router_fib4_event_work(struct work_struct *work)
|
|
|
{
|
|
|
struct mlxsw_sp_fib_event_work *fib_work =
|
|
|
container_of(work, struct mlxsw_sp_fib_event_work, work);
|
|
@@ -3085,6 +3085,42 @@ static void mlxsw_sp_router_fib_event_work(struct work_struct *work)
|
|
|
kfree(fib_work);
|
|
|
}
|
|
|
|
|
|
+static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work,
|
|
|
+ struct fib_notifier_info *info)
|
|
|
+{
|
|
|
+ switch (fib_work->event) {
|
|
|
+ case FIB_EVENT_ENTRY_REPLACE: /* fall through */
|
|
|
+ case FIB_EVENT_ENTRY_APPEND: /* fall through */
|
|
|
+ case FIB_EVENT_ENTRY_ADD: /* fall through */
|
|
|
+ case FIB_EVENT_ENTRY_DEL:
|
|
|
+ memcpy(&fib_work->fen_info, info, sizeof(fib_work->fen_info));
|
|
|
+ /* Take referece on fib_info to prevent it from being
|
|
|
+ * freed while work is queued. Release it afterwards.
|
|
|
+ */
|
|
|
+ fib_info_hold(fib_work->fen_info.fi);
|
|
|
+ break;
|
|
|
+ case FIB_EVENT_RULE_ADD: /* fall through */
|
|
|
+ case FIB_EVENT_RULE_DEL:
|
|
|
+ memcpy(&fib_work->fr_info, info, sizeof(fib_work->fr_info));
|
|
|
+ fib_rule_get(fib_work->fr_info.rule);
|
|
|
+ break;
|
|
|
+ case FIB_EVENT_NH_ADD: /* fall through */
|
|
|
+ case FIB_EVENT_NH_DEL:
|
|
|
+ memcpy(&fib_work->fnh_info, info, sizeof(fib_work->fnh_info));
|
|
|
+ fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
|
|
|
+ struct fib_notifier_info *info)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
/* Called with rcu_read_lock() */
|
|
|
static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
|
|
|
unsigned long event, void *ptr)
|
|
@@ -3100,31 +3136,18 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
|
|
|
if (WARN_ON(!fib_work))
|
|
|
return NOTIFY_BAD;
|
|
|
|
|
|
- INIT_WORK(&fib_work->work, mlxsw_sp_router_fib_event_work);
|
|
|
router = container_of(nb, struct mlxsw_sp_router, fib_nb);
|
|
|
fib_work->mlxsw_sp = router->mlxsw_sp;
|
|
|
fib_work->event = event;
|
|
|
|
|
|
- switch (event) {
|
|
|
- case FIB_EVENT_ENTRY_REPLACE: /* fall through */
|
|
|
- case FIB_EVENT_ENTRY_APPEND: /* fall through */
|
|
|
- case FIB_EVENT_ENTRY_ADD: /* fall through */
|
|
|
- case FIB_EVENT_ENTRY_DEL:
|
|
|
- memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
|
|
|
- /* Take referece on fib_info to prevent it from being
|
|
|
- * freed while work is queued. Release it afterwards.
|
|
|
- */
|
|
|
- fib_info_hold(fib_work->fen_info.fi);
|
|
|
+ switch (info->family) {
|
|
|
+ case AF_INET:
|
|
|
+ INIT_WORK(&fib_work->work, mlxsw_sp_router_fib4_event_work);
|
|
|
+ mlxsw_sp_router_fib4_event(fib_work, info);
|
|
|
break;
|
|
|
- case FIB_EVENT_RULE_ADD: /* fall through */
|
|
|
- case FIB_EVENT_RULE_DEL:
|
|
|
- memcpy(&fib_work->fr_info, ptr, sizeof(fib_work->fr_info));
|
|
|
- fib_rule_get(fib_work->fr_info.rule);
|
|
|
- break;
|
|
|
- case FIB_EVENT_NH_ADD: /* fall through */
|
|
|
- case FIB_EVENT_NH_DEL:
|
|
|
- memcpy(&fib_work->fnh_info, ptr, sizeof(fib_work->fnh_info));
|
|
|
- fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent);
|
|
|
+ case AF_INET6:
|
|
|
+ INIT_WORK(&fib_work->work, mlxsw_sp_router_fib6_event_work);
|
|
|
+ mlxsw_sp_router_fib6_event(fib_work, info);
|
|
|
break;
|
|
|
}
|
|
|
|