Commit 15fa9e8c authored by Yevhen Orlov's avatar Yevhen Orlov Committed by David S. Miller

net: marvell: prestera: Implement initial inetaddr notifiers

Add inetaddr notifiers to support add/del IPv4 address on switchdev
port. We create TRAP on first address, added on port and delete TRAP,
when last address removed.
Currently, driver supports only regular port to became routed.
Other port type support will be added later
Co-developed-by: default avatarTaras Chornyi <tchornyi@marvell.com>
Signed-off-by: default avatarTaras Chornyi <tchornyi@marvell.com>
Co-developed-by: default avatarOleksandr Mazur <oleksandr.mazur@plvision.eu>
Signed-off-by: default avatarOleksandr Mazur <oleksandr.mazur@plvision.eu>
Signed-off-by: default avatarYevhen Orlov <yevhen.orlov@plvision.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent da3c1639
...@@ -4,16 +4,31 @@ ...@@ -4,16 +4,31 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/inetdevice.h> #include <linux/inetdevice.h>
#include <net/switchdev.h>
#include "prestera.h" #include "prestera.h"
#include "prestera_router_hw.h" #include "prestera_router_hw.h"
/* This util to be used, to convert kernel rules for default vr in hw_vr */
static u32 prestera_fix_tb_id(u32 tb_id)
{
if (tb_id == RT_TABLE_UNSPEC ||
tb_id == RT_TABLE_LOCAL ||
tb_id == RT_TABLE_DEFAULT)
tb_id = RT_TABLE_MAIN;
return tb_id;
}
static int __prestera_inetaddr_port_event(struct net_device *port_dev, static int __prestera_inetaddr_port_event(struct net_device *port_dev,
unsigned long event, unsigned long event,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct prestera_port *port = netdev_priv(port_dev); struct prestera_port *port = netdev_priv(port_dev);
int err; int err;
struct prestera_rif_entry *re;
struct prestera_rif_entry_key re_key = {};
u32 kern_tb_id;
err = prestera_is_valid_mac_addr(port, port_dev->dev_addr); err = prestera_is_valid_mac_addr(port, port_dev->dev_addr);
if (err) { if (err) {
...@@ -21,9 +36,34 @@ static int __prestera_inetaddr_port_event(struct net_device *port_dev, ...@@ -21,9 +36,34 @@ static int __prestera_inetaddr_port_event(struct net_device *port_dev,
return err; return err;
} }
kern_tb_id = l3mdev_fib_table(port_dev);
re_key.iface.type = PRESTERA_IF_PORT_E;
re_key.iface.dev_port.hw_dev_num = port->dev_id;
re_key.iface.dev_port.port_num = port->hw_id;
re = prestera_rif_entry_find(port->sw, &re_key);
switch (event) { switch (event) {
case NETDEV_UP: case NETDEV_UP:
if (re) {
NL_SET_ERR_MSG_MOD(extack, "rif_entry already exist");
return -EEXIST;
}
re = prestera_rif_entry_create(port->sw, &re_key,
prestera_fix_tb_id(kern_tb_id),
port_dev->dev_addr);
if (!re) {
NL_SET_ERR_MSG_MOD(extack, "Can't create rif_entry");
return -EINVAL;
}
dev_hold(port_dev);
break;
case NETDEV_DOWN: case NETDEV_DOWN:
if (!re) {
NL_SET_ERR_MSG_MOD(extack, "rif_entry not exist");
return -EEXIST;
}
prestera_rif_entry_destroy(port->sw, re);
dev_put(port_dev);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment