1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2019-2021 Marvell International Ltd. All rights reserved */ 3 4 #include <linux/kernel.h> 5 #include <linux/types.h> 6 #include <linux/inetdevice.h> 7 #include <net/switchdev.h> 8 9 #include "prestera.h" 10 #include "prestera_router_hw.h" 11 12 /* This util to be used, to convert kernel rules for default vr in hw_vr */ 13 static u32 prestera_fix_tb_id(u32 tb_id) 14 { 15 if (tb_id == RT_TABLE_UNSPEC || 16 tb_id == RT_TABLE_LOCAL || 17 tb_id == RT_TABLE_DEFAULT) 18 tb_id = RT_TABLE_MAIN; 19 20 return tb_id; 21 } 22 23 static int __prestera_inetaddr_port_event(struct net_device *port_dev, 24 unsigned long event, 25 struct netlink_ext_ack *extack) 26 { 27 struct prestera_port *port = netdev_priv(port_dev); 28 struct prestera_rif_entry_key re_key = {}; 29 struct prestera_rif_entry *re; 30 u32 kern_tb_id; 31 int err; 32 33 err = prestera_is_valid_mac_addr(port, port_dev->dev_addr); 34 if (err) { 35 NL_SET_ERR_MSG_MOD(extack, "RIF MAC must have the same prefix"); 36 return err; 37 } 38 39 kern_tb_id = l3mdev_fib_table(port_dev); 40 re_key.iface.type = PRESTERA_IF_PORT_E; 41 re_key.iface.dev_port.hw_dev_num = port->dev_id; 42 re_key.iface.dev_port.port_num = port->hw_id; 43 re = prestera_rif_entry_find(port->sw, &re_key); 44 45 switch (event) { 46 case NETDEV_UP: 47 if (re) { 48 NL_SET_ERR_MSG_MOD(extack, "RIF already exist"); 49 return -EEXIST; 50 } 51 re = prestera_rif_entry_create(port->sw, &re_key, 52 prestera_fix_tb_id(kern_tb_id), 53 port_dev->dev_addr); 54 if (!re) { 55 NL_SET_ERR_MSG_MOD(extack, "Can't create RIF"); 56 return -EINVAL; 57 } 58 dev_hold(port_dev); 59 break; 60 case NETDEV_DOWN: 61 if (!re) { 62 NL_SET_ERR_MSG_MOD(extack, "Can't find RIF"); 63 return -EEXIST; 64 } 65 prestera_rif_entry_destroy(port->sw, re); 66 dev_put(port_dev); 67 break; 68 } 69 70 return 0; 71 } 72 73 static int __prestera_inetaddr_event(struct prestera_switch *sw, 74 struct net_device *dev, 75 unsigned long event, 76 struct netlink_ext_ack *extack) 77 { 78 if (!prestera_netdev_check(dev) || netif_is_bridge_port(dev) || 79 netif_is_lag_port(dev) || netif_is_ovs_port(dev)) 80 return 0; 81 82 return __prestera_inetaddr_port_event(dev, event, extack); 83 } 84 85 static int __prestera_inetaddr_cb(struct notifier_block *nb, 86 unsigned long event, void *ptr) 87 { 88 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 89 struct net_device *dev = ifa->ifa_dev->dev; 90 struct prestera_router *router = container_of(nb, 91 struct prestera_router, 92 inetaddr_nb); 93 struct in_device *idev; 94 int err = 0; 95 96 if (event != NETDEV_DOWN) 97 goto out; 98 99 /* Ignore if this is not latest address */ 100 idev = __in_dev_get_rtnl(dev); 101 if (idev && idev->ifa_list) 102 goto out; 103 104 err = __prestera_inetaddr_event(router->sw, dev, event, NULL); 105 out: 106 return notifier_from_errno(err); 107 } 108 109 static int __prestera_inetaddr_valid_cb(struct notifier_block *nb, 110 unsigned long event, void *ptr) 111 { 112 struct in_validator_info *ivi = (struct in_validator_info *)ptr; 113 struct net_device *dev = ivi->ivi_dev->dev; 114 struct prestera_router *router = container_of(nb, 115 struct prestera_router, 116 inetaddr_valid_nb); 117 struct in_device *idev; 118 int err = 0; 119 120 if (event != NETDEV_UP) 121 goto out; 122 123 /* Ignore if this is not first address */ 124 idev = __in_dev_get_rtnl(dev); 125 if (idev && idev->ifa_list) 126 goto out; 127 128 if (ipv4_is_multicast(ivi->ivi_addr)) { 129 NL_SET_ERR_MSG_MOD(ivi->extack, 130 "Multicast addr on RIF is not supported"); 131 err = -EINVAL; 132 goto out; 133 } 134 135 err = __prestera_inetaddr_event(router->sw, dev, event, ivi->extack); 136 out: 137 return notifier_from_errno(err); 138 } 139 140 int prestera_router_init(struct prestera_switch *sw) 141 { 142 struct prestera_router *router; 143 int err; 144 145 router = kzalloc(sizeof(*sw->router), GFP_KERNEL); 146 if (!router) 147 return -ENOMEM; 148 149 sw->router = router; 150 router->sw = sw; 151 152 err = prestera_router_hw_init(sw); 153 if (err) 154 goto err_router_lib_init; 155 156 router->inetaddr_valid_nb.notifier_call = __prestera_inetaddr_valid_cb; 157 err = register_inetaddr_validator_notifier(&router->inetaddr_valid_nb); 158 if (err) 159 goto err_register_inetaddr_validator_notifier; 160 161 router->inetaddr_nb.notifier_call = __prestera_inetaddr_cb; 162 err = register_inetaddr_notifier(&router->inetaddr_nb); 163 if (err) 164 goto err_register_inetaddr_notifier; 165 166 return 0; 167 168 err_register_inetaddr_notifier: 169 unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb); 170 err_register_inetaddr_validator_notifier: 171 prestera_router_hw_fini(sw); 172 err_router_lib_init: 173 kfree(sw->router); 174 return err; 175 } 176 177 void prestera_router_fini(struct prestera_switch *sw) 178 { 179 unregister_inetaddr_notifier(&sw->router->inetaddr_nb); 180 unregister_inetaddr_validator_notifier(&sw->router->inetaddr_valid_nb); 181 prestera_router_hw_fini(sw); 182 kfree(sw->router); 183 sw->router = NULL; 184 } 185