]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: marvell: prestera: add stub handler neighbour events
authorYevhen Orlov <yevhen.orlov@plvision.eu>
Sat, 1 Oct 2022 09:34:15 +0000 (12:34 +0300)
committerJakub Kicinski <kuba@kernel.org>
Tue, 4 Oct 2022 00:14:53 +0000 (17:14 -0700)
Actual handler will be added in next patches

Co-developed-by: Taras Chornyi <tchornyi@marvell.com>
Signed-off-by: Taras Chornyi <tchornyi@marvell.com>
Co-developed-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/prestera/prestera.h
drivers/net/ethernet/marvell/prestera/prestera_router.c

index fe0d6001a6b607a7f41c828f99642701a6a50b2a..2f2f80e7e358aebf5b6847d8c711a17131904390 100644 (file)
@@ -320,6 +320,7 @@ struct prestera_router {
        struct notifier_block inetaddr_nb;
        struct notifier_block inetaddr_valid_nb;
        struct notifier_block fib_nb;
+       struct notifier_block netevent_nb;
        u8 *nhgrp_hw_state_cache; /* Bitmap cached hw state of nhs */
        unsigned long nhgrp_hw_cache_kick; /* jiffies */
 };
index 607efd481782599700a3b8a7c198ce778461fdae..d31dd1fe66330734a2080d01a2376d8ff4593909 100644 (file)
@@ -8,6 +8,7 @@
 #include <net/switchdev.h>
 #include <linux/rhashtable.h>
 #include <net/nexthop.h>
+#include <net/netevent.h>
 
 #include "prestera.h"
 #include "prestera_router_hw.h"
@@ -604,6 +605,56 @@ static int __prestera_router_fib_event(struct notifier_block *nb,
        return NOTIFY_DONE;
 }
 
+struct prestera_netevent_work {
+       struct work_struct work;
+       struct prestera_switch *sw;
+       struct neighbour *n;
+};
+
+static void prestera_router_neigh_event_work(struct work_struct *work)
+{
+       struct prestera_netevent_work *net_work =
+               container_of(work, struct prestera_netevent_work, work);
+       struct neighbour *n = net_work->n;
+
+       /* neigh - its not hw related object. It stored only in kernel. So... */
+       rtnl_lock();
+
+       /* TODO: handler */
+
+       neigh_release(n);
+       rtnl_unlock();
+       kfree(net_work);
+}
+
+static int prestera_router_netevent_event(struct notifier_block *nb,
+                                         unsigned long event, void *ptr)
+{
+       struct prestera_netevent_work *net_work;
+       struct prestera_router *router;
+       struct neighbour *n = ptr;
+
+       router = container_of(nb, struct prestera_router, netevent_nb);
+
+       switch (event) {
+       case NETEVENT_NEIGH_UPDATE:
+               if (n->tbl->family != AF_INET)
+                       return NOTIFY_DONE;
+
+               net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
+               if (WARN_ON(!net_work))
+                       return NOTIFY_BAD;
+
+               neigh_clone(n);
+               net_work->n = n;
+               net_work->sw = router->sw;
+               INIT_WORK(&net_work->work, prestera_router_neigh_event_work);
+               prestera_queue_work(&net_work->work);
+       }
+
+       return NOTIFY_DONE;
+}
+
 int prestera_router_init(struct prestera_switch *sw)
 {
        struct prestera_router *router;
@@ -642,6 +693,11 @@ int prestera_router_init(struct prestera_switch *sw)
        if (err)
                goto err_register_inetaddr_notifier;
 
+       router->netevent_nb.notifier_call = prestera_router_netevent_event;
+       err = register_netevent_notifier(&router->netevent_nb);
+       if (err)
+               goto err_register_netevent_notifier;
+
        router->fib_nb.notifier_call = __prestera_router_fib_event;
        err = register_fib_notifier(&init_net, &router->fib_nb,
                                    /* TODO: flush fib entries */ NULL, NULL);
@@ -651,6 +707,8 @@ int prestera_router_init(struct prestera_switch *sw)
        return 0;
 
 err_register_fib_notifier:
+       unregister_netevent_notifier(&router->netevent_nb);
+err_register_netevent_notifier:
        unregister_inetaddr_notifier(&router->inetaddr_nb);
 err_register_inetaddr_notifier:
        unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
@@ -668,6 +726,7 @@ err_router_lib_init:
 void prestera_router_fini(struct prestera_switch *sw)
 {
        unregister_fib_notifier(&init_net, &sw->router->fib_nb);
+       unregister_netevent_notifier(&sw->router->netevent_nb);
        unregister_inetaddr_notifier(&sw->router->inetaddr_nb);
        unregister_inetaddr_validator_notifier(&sw->router->inetaddr_valid_nb);
        prestera_queue_drain();