|
|
@@ -33,6 +33,7 @@
|
|
|
#include <net/rtnetlink.h>
|
|
|
#include <net/netevent.h>
|
|
|
#include <net/arp.h>
|
|
|
+#include <net/fib_rules.h>
|
|
|
#include <linux/io-64-nonatomic-lo-hi.h>
|
|
|
#include <generated/utsrelease.h>
|
|
|
|
|
|
@@ -2175,7 +2176,10 @@ static const struct switchdev_ops rocker_port_switchdev_ops = {
|
|
|
|
|
|
struct rocker_fib_event_work {
|
|
|
struct work_struct work;
|
|
|
- struct fib_entry_notifier_info fen_info;
|
|
|
+ union {
|
|
|
+ struct fib_entry_notifier_info fen_info;
|
|
|
+ struct fib_rule_notifier_info fr_info;
|
|
|
+ };
|
|
|
struct rocker *rocker;
|
|
|
unsigned long event;
|
|
|
};
|
|
|
@@ -2185,6 +2189,7 @@ static void rocker_router_fib_event_work(struct work_struct *work)
|
|
|
struct rocker_fib_event_work *fib_work =
|
|
|
container_of(work, struct rocker_fib_event_work, work);
|
|
|
struct rocker *rocker = fib_work->rocker;
|
|
|
+ struct fib_rule *rule;
|
|
|
int err;
|
|
|
|
|
|
/* Protect internal structures from changes */
|
|
|
@@ -2202,7 +2207,10 @@ static void rocker_router_fib_event_work(struct work_struct *work)
|
|
|
break;
|
|
|
case FIB_EVENT_RULE_ADD: /* fall through */
|
|
|
case FIB_EVENT_RULE_DEL:
|
|
|
- rocker_world_fib4_abort(rocker);
|
|
|
+ rule = fib_work->fr_info.rule;
|
|
|
+ if (!fib4_rule_default(rule))
|
|
|
+ rocker_world_fib4_abort(rocker);
|
|
|
+ fib_rule_put(rule);
|
|
|
break;
|
|
|
}
|
|
|
rtnl_unlock();
|
|
|
@@ -2233,6 +2241,11 @@ static int rocker_router_fib_event(struct notifier_block *nb,
|
|
|
*/
|
|
|
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, ptr, sizeof(fib_work->fr_info));
|
|
|
+ fib_rule_get(fib_work->fr_info.rule);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
queue_work(rocker->rocker_owq, &fib_work->work);
|