Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netdevsim: create devlink instance per netdevsim instance

Currently there is one devlink instance created per network namespace.
That is quite odd considering the fact that devlink instance should
represent an ASIC. The following patches are going to move the devlink
instance even more down to a bus device, but until then, have one
devlink instance per netdevsim instance. Struct nsim_devlink is
introduced to hold fib setting.

The changes in the fib code are only related to holding the
configuration per devlink instance instead of network namespace.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Pirko and committed by
David S. Miller
5fc49422 1daf36c0

+126 -204
+66 -117
drivers/net/netdevsim/devlink.c
··· 15 15 */ 16 16 17 17 #include <linux/device.h> 18 + #include <linux/rtnetlink.h> 18 19 #include <net/devlink.h> 19 - #include <net/netns/generic.h> 20 20 21 21 #include "netdevsim.h" 22 22 23 - static unsigned int nsim_devlink_id; 24 - 25 - /* place holder until devlink and namespaces is sorted out */ 26 - static struct net *nsim_devlink_net(struct devlink *devlink) 27 - { 28 - return &init_net; 29 - } 23 + struct nsim_devlink { 24 + struct nsim_fib_data *fib_data; 25 + }; 30 26 31 27 /* IPv4 32 28 */ 33 29 static u64 nsim_ipv4_fib_resource_occ_get(void *priv) 34 30 { 35 - struct net *net = priv; 31 + struct nsim_devlink *nsim_devlink = priv; 36 32 37 - return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false); 33 + return nsim_fib_get_val(nsim_devlink->fib_data, 34 + NSIM_RESOURCE_IPV4_FIB, false); 38 35 } 39 36 40 37 static u64 nsim_ipv4_fib_rules_res_occ_get(void *priv) 41 38 { 42 - struct net *net = priv; 39 + struct nsim_devlink *nsim_devlink = priv; 43 40 44 - return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false); 41 + return nsim_fib_get_val(nsim_devlink->fib_data, 42 + NSIM_RESOURCE_IPV4_FIB_RULES, false); 45 43 } 46 44 47 45 /* IPv6 48 46 */ 49 47 static u64 nsim_ipv6_fib_resource_occ_get(void *priv) 50 48 { 51 - struct net *net = priv; 49 + struct nsim_devlink *nsim_devlink = priv; 52 50 53 - return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false); 51 + return nsim_fib_get_val(nsim_devlink->fib_data, 52 + NSIM_RESOURCE_IPV6_FIB, false); 54 53 } 55 54 56 55 static u64 nsim_ipv6_fib_rules_res_occ_get(void *priv) 57 56 { 58 - struct net *net = priv; 57 + struct nsim_devlink *nsim_devlink = priv; 59 58 60 - return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false); 59 + return nsim_fib_get_val(nsim_devlink->fib_data, 60 + NSIM_RESOURCE_IPV6_FIB_RULES, false); 61 61 } 62 62 63 63 static int devlink_resources_register(struct devlink *devlink) 64 64 { 65 + struct nsim_devlink *nsim_devlink = devlink_priv(devlink); 65 66 struct devlink_resource_size_params params = { 66 67 .size_max = (u64)-1, 67 68 .size_granularity = 1, 68 69 .unit = DEVLINK_RESOURCE_UNIT_ENTRY 69 70 }; 70 - struct net *net = nsim_devlink_net(devlink); 71 71 int err; 72 72 u64 n; 73 73 ··· 81 81 goto out; 82 82 } 83 83 84 - n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true); 84 + n = nsim_fib_get_val(nsim_devlink->fib_data, 85 + NSIM_RESOURCE_IPV4_FIB, true); 85 86 err = devlink_resource_register(devlink, "fib", n, 86 87 NSIM_RESOURCE_IPV4_FIB, 87 88 NSIM_RESOURCE_IPV4, &params); ··· 91 90 return err; 92 91 } 93 92 94 - n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true); 93 + n = nsim_fib_get_val(nsim_devlink->fib_data, 94 + NSIM_RESOURCE_IPV4_FIB_RULES, true); 95 95 err = devlink_resource_register(devlink, "fib-rules", n, 96 96 NSIM_RESOURCE_IPV4_FIB_RULES, 97 97 NSIM_RESOURCE_IPV4, &params); ··· 111 109 goto out; 112 110 } 113 111 114 - n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true); 112 + n = nsim_fib_get_val(nsim_devlink->fib_data, 113 + NSIM_RESOURCE_IPV6_FIB, true); 115 114 err = devlink_resource_register(devlink, "fib", n, 116 115 NSIM_RESOURCE_IPV6_FIB, 117 116 NSIM_RESOURCE_IPV6, &params); ··· 121 118 return err; 122 119 } 123 120 124 - n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true); 121 + n = nsim_fib_get_val(nsim_devlink->fib_data, 122 + NSIM_RESOURCE_IPV6_FIB_RULES, true); 125 123 err = devlink_resource_register(devlink, "fib-rules", n, 126 124 NSIM_RESOURCE_IPV6_FIB_RULES, 127 125 NSIM_RESOURCE_IPV6, &params); ··· 134 130 devlink_resource_occ_get_register(devlink, 135 131 NSIM_RESOURCE_IPV4_FIB, 136 132 nsim_ipv4_fib_resource_occ_get, 137 - net); 133 + nsim_devlink); 138 134 devlink_resource_occ_get_register(devlink, 139 135 NSIM_RESOURCE_IPV4_FIB_RULES, 140 136 nsim_ipv4_fib_rules_res_occ_get, 141 - net); 137 + nsim_devlink); 142 138 devlink_resource_occ_get_register(devlink, 143 139 NSIM_RESOURCE_IPV6_FIB, 144 140 nsim_ipv6_fib_resource_occ_get, 145 - net); 141 + nsim_devlink); 146 142 devlink_resource_occ_get_register(devlink, 147 143 NSIM_RESOURCE_IPV6_FIB_RULES, 148 144 nsim_ipv6_fib_rules_res_occ_get, 149 - net); 145 + nsim_devlink); 150 146 out: 151 147 return err; 152 148 } ··· 154 150 static int nsim_devlink_reload(struct devlink *devlink, 155 151 struct netlink_ext_ack *extack) 156 152 { 153 + struct nsim_devlink *nsim_devlink = devlink_priv(devlink); 157 154 enum nsim_resource_id res_ids[] = { 158 155 NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, 159 156 NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES 160 157 }; 161 - struct net *net = nsim_devlink_net(devlink); 162 158 int i; 163 159 164 160 for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { ··· 167 163 168 164 err = devlink_resource_size_get(devlink, res_ids[i], &val); 169 165 if (!err) { 170 - err = nsim_fib_set_max(net, res_ids[i], val, extack); 166 + err = nsim_fib_set_max(nsim_devlink->fib_data, 167 + res_ids[i], val, extack); 171 168 if (err) 172 169 return err; 173 170 } ··· 177 172 return 0; 178 173 } 179 174 180 - static void nsim_devlink_net_reset(struct net *net) 181 - { 182 - enum nsim_resource_id res_ids[] = { 183 - NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, 184 - NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES 185 - }; 186 - int i; 187 - 188 - for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { 189 - if (nsim_fib_set_max(net, res_ids[i], (u64)-1, NULL)) { 190 - pr_err("Failed to reset limit for resource %u\n", 191 - res_ids[i]); 192 - } 193 - } 194 - } 195 - 196 175 static const struct devlink_ops nsim_devlink_ops = { 197 176 .reload = nsim_devlink_reload, 198 177 }; 199 178 200 - /* once devlink / namespace issues are sorted out 201 - * this needs to be net in which a devlink instance 202 - * is to be created. e.g., dev_net(ns->netdev) 203 - */ 204 - static struct net *nsim_to_net(struct netdevsim *ns) 179 + static int __nsim_devlink_init(struct netdevsim *ns) 205 180 { 206 - return &init_net; 207 - } 208 - 209 - void nsim_devlink_teardown(struct netdevsim *ns) 210 - { 211 - if (ns->devlink) { 212 - struct net *net = nsim_to_net(ns); 213 - bool *reg_devlink = net_generic(net, nsim_devlink_id); 214 - 215 - devlink_resources_unregister(ns->devlink, NULL); 216 - devlink_unregister(ns->devlink); 217 - devlink_free(ns->devlink); 218 - ns->devlink = NULL; 219 - 220 - nsim_devlink_net_reset(net); 221 - *reg_devlink = true; 222 - } 223 - } 224 - 225 - int nsim_devlink_setup(struct netdevsim *ns) 226 - { 227 - struct net *net = nsim_to_net(ns); 228 - bool *reg_devlink = net_generic(net, nsim_devlink_id); 181 + struct nsim_devlink *nsim_devlink; 229 182 struct devlink *devlink; 230 183 int err; 231 184 232 - /* only one device per namespace controls devlink */ 233 - if (!*reg_devlink) { 234 - ns->devlink = NULL; 235 - return 0; 236 - } 237 - 238 - devlink = devlink_alloc(&nsim_devlink_ops, 0); 185 + devlink = devlink_alloc(&nsim_devlink_ops, sizeof(*nsim_devlink)); 239 186 if (!devlink) 240 187 return -ENOMEM; 188 + nsim_devlink = devlink_priv(devlink); 241 189 242 - err = devlink_register(devlink, &ns->dev); 243 - if (err) 190 + nsim_devlink->fib_data = nsim_fib_create(); 191 + if (IS_ERR(nsim_devlink->fib_data)) { 192 + err = PTR_ERR(nsim_devlink->fib_data); 244 193 goto err_devlink_free; 194 + } 245 195 246 196 err = devlink_resources_register(devlink); 247 197 if (err) 248 - goto err_dl_unregister; 198 + goto err_fib_destroy; 199 + 200 + err = devlink_register(devlink, &ns->dev); 201 + if (err) 202 + goto err_resources_unregister; 249 203 250 204 ns->devlink = devlink; 251 205 252 - *reg_devlink = false; 253 - 254 206 return 0; 255 207 256 - err_dl_unregister: 257 - devlink_unregister(devlink); 208 + err_resources_unregister: 209 + devlink_resources_unregister(devlink, NULL); 210 + err_fib_destroy: 211 + nsim_fib_destroy(nsim_devlink->fib_data); 258 212 err_devlink_free: 259 213 devlink_free(devlink); 260 214 261 215 return err; 262 216 } 263 217 264 - /* Initialize per network namespace state */ 265 - static int __net_init nsim_devlink_netns_init(struct net *net) 266 - { 267 - bool *reg_devlink = net_generic(net, nsim_devlink_id); 268 - 269 - *reg_devlink = true; 270 - 271 - return 0; 272 - } 273 - 274 - static struct pernet_operations nsim_devlink_net_ops = { 275 - .init = nsim_devlink_netns_init, 276 - .id = &nsim_devlink_id, 277 - .size = sizeof(bool), 278 - }; 279 - 280 - void nsim_devlink_exit(void) 281 - { 282 - unregister_pernet_subsys(&nsim_devlink_net_ops); 283 - nsim_fib_exit(); 284 - } 285 - 286 - int nsim_devlink_init(void) 218 + int nsim_devlink_init(struct netdevsim *ns) 287 219 { 288 220 int err; 289 221 290 - err = nsim_fib_init(); 291 - if (err) 292 - goto err_out; 293 - 294 - err = register_pernet_subsys(&nsim_devlink_net_ops); 295 - if (err) 296 - nsim_fib_exit(); 297 - 298 - err_out: 222 + dev_hold(ns->netdev); 223 + rtnl_unlock(); 224 + err = __nsim_devlink_init(ns); 225 + rtnl_lock(); 226 + dev_put(ns->netdev); 299 227 return err; 228 + } 229 + 230 + void nsim_devlink_exit(struct netdevsim *ns) 231 + { 232 + struct devlink *devlink = ns->devlink; 233 + struct nsim_devlink *nsim_devlink = devlink_priv(devlink); 234 + 235 + devlink_unregister(devlink); 236 + devlink_resources_unregister(devlink, NULL); 237 + nsim_fib_destroy(nsim_devlink->fib_data); 238 + devlink_free(devlink); 300 239 }
+41 -61
drivers/net/netdevsim/fib.c
··· 18 18 #include <net/ip_fib.h> 19 19 #include <net/ip6_fib.h> 20 20 #include <net/fib_rules.h> 21 - #include <net/netns/generic.h> 22 21 23 22 #include "netdevsim.h" 24 23 ··· 32 33 }; 33 34 34 35 struct nsim_fib_data { 36 + struct notifier_block fib_nb; 35 37 struct nsim_per_fib_data ipv4; 36 38 struct nsim_per_fib_data ipv6; 37 39 }; 38 40 39 - static unsigned int nsim_fib_net_id; 40 - 41 - u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max) 41 + u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, 42 + enum nsim_resource_id res_id, bool max) 42 43 { 43 - struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); 44 44 struct nsim_fib_entry *entry; 45 45 46 46 switch (res_id) { ··· 62 64 return max ? entry->max : entry->num; 63 65 } 64 66 65 - int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, 67 + int nsim_fib_set_max(struct nsim_fib_data *fib_data, 68 + enum nsim_resource_id res_id, u64 val, 66 69 struct netlink_ext_ack *extack) 67 70 { 68 - struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); 69 71 struct nsim_fib_entry *entry; 70 72 int err = 0; 71 73 ··· 118 120 return err; 119 121 } 120 122 121 - static int nsim_fib_rule_event(struct fib_notifier_info *info, bool add) 123 + static int nsim_fib_rule_event(struct nsim_fib_data *data, 124 + struct fib_notifier_info *info, bool add) 122 125 { 123 - struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); 124 126 struct netlink_ext_ack *extack = info->extack; 125 127 int err = 0; 126 128 ··· 155 157 return err; 156 158 } 157 159 158 - static int nsim_fib_event(struct fib_notifier_info *info, bool add) 160 + static int nsim_fib_event(struct nsim_fib_data *data, 161 + struct fib_notifier_info *info, bool add) 159 162 { 160 - struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); 161 163 struct netlink_ext_ack *extack = info->extack; 162 164 int err = 0; 163 165 ··· 176 178 static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, 177 179 void *ptr) 178 180 { 181 + struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data, 182 + fib_nb); 179 183 struct fib_notifier_info *info = ptr; 180 184 int err = 0; 181 185 182 186 switch (event) { 183 187 case FIB_EVENT_RULE_ADD: /* fall through */ 184 188 case FIB_EVENT_RULE_DEL: 185 - err = nsim_fib_rule_event(info, event == FIB_EVENT_RULE_ADD); 189 + err = nsim_fib_rule_event(data, info, 190 + event == FIB_EVENT_RULE_ADD); 186 191 break; 187 192 188 193 case FIB_EVENT_ENTRY_ADD: /* fall through */ 189 194 case FIB_EVENT_ENTRY_DEL: 190 - err = nsim_fib_event(info, event == FIB_EVENT_ENTRY_ADD); 195 + err = nsim_fib_event(data, info, 196 + event == FIB_EVENT_ENTRY_ADD); 191 197 break; 192 198 } 193 199 ··· 201 199 /* inconsistent dump, trying again */ 202 200 static void nsim_fib_dump_inconsistent(struct notifier_block *nb) 203 201 { 204 - struct nsim_fib_data *data; 205 - struct net *net; 202 + struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data, 203 + fib_nb); 206 204 207 - rcu_read_lock(); 208 - for_each_net_rcu(net) { 209 - data = net_generic(net, nsim_fib_net_id); 210 - 211 - data->ipv4.fib.num = 0ULL; 212 - data->ipv4.rules.num = 0ULL; 213 - 214 - data->ipv6.fib.num = 0ULL; 215 - data->ipv6.rules.num = 0ULL; 216 - } 217 - rcu_read_unlock(); 205 + data->ipv4.fib.num = 0ULL; 206 + data->ipv4.rules.num = 0ULL; 207 + data->ipv6.fib.num = 0ULL; 208 + data->ipv6.rules.num = 0ULL; 218 209 } 219 210 220 - static struct notifier_block nsim_fib_nb = { 221 - .notifier_call = nsim_fib_event_nb, 222 - }; 223 - 224 - /* Initialize per network namespace state */ 225 - static int __net_init nsim_fib_netns_init(struct net *net) 211 + struct nsim_fib_data *nsim_fib_create(void) 226 212 { 227 - struct nsim_fib_data *data = net_generic(net, nsim_fib_net_id); 213 + struct nsim_fib_data *data; 214 + int err; 215 + 216 + data = kzalloc(sizeof(*data), GFP_KERNEL); 217 + if (!data) 218 + return ERR_PTR(-ENOMEM); 228 219 229 220 data->ipv4.fib.max = (u64)-1; 230 221 data->ipv4.rules.max = (u64)-1; ··· 225 230 data->ipv6.fib.max = (u64)-1; 226 231 data->ipv6.rules.max = (u64)-1; 227 232 228 - return 0; 229 - } 230 - 231 - static struct pernet_operations nsim_fib_net_ops = { 232 - .init = nsim_fib_netns_init, 233 - .id = &nsim_fib_net_id, 234 - .size = sizeof(struct nsim_fib_data), 235 - }; 236 - 237 - void nsim_fib_exit(void) 238 - { 239 - unregister_pernet_subsys(&nsim_fib_net_ops); 240 - unregister_fib_notifier(&nsim_fib_nb); 241 - } 242 - 243 - int nsim_fib_init(void) 244 - { 245 - int err; 246 - 247 - err = register_pernet_subsys(&nsim_fib_net_ops); 248 - if (err < 0) { 249 - pr_err("Failed to register pernet subsystem\n"); 250 - goto err_out; 251 - } 252 - 253 - err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent); 254 - if (err < 0) { 233 + data->fib_nb.notifier_call = nsim_fib_event_nb; 234 + err = register_fib_notifier(&data->fib_nb, nsim_fib_dump_inconsistent); 235 + if (err) { 255 236 pr_err("Failed to register fib notifier\n"); 256 237 goto err_out; 257 238 } 258 239 240 + return data; 241 + 259 242 err_out: 260 - return err; 243 + kfree(data); 244 + return ERR_PTR(err); 245 + } 246 + 247 + void nsim_fib_destroy(struct nsim_fib_data *data) 248 + { 249 + unregister_fib_notifier(&data->fib_nb); 250 + kfree(data); 261 251 }
+10 -17
drivers/net/netdevsim/netdev.c
··· 161 161 char sdev_link_name[32]; 162 162 int err; 163 163 164 - ns->netdev = dev; 165 164 ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir); 166 165 if (IS_ERR_OR_NULL(ns->ddir)) 167 166 return -ENOMEM; ··· 173 174 if (err) 174 175 goto err_debugfs_destroy; 175 176 176 - err = nsim_devlink_setup(ns); 177 - if (err) 178 - goto err_bpf_uninit; 179 - 180 177 nsim_ipsec_init(ns); 181 178 182 179 return 0; 183 180 184 - err_bpf_uninit: 185 - nsim_bpf_uninit(ns); 186 181 err_debugfs_destroy: 187 182 debugfs_remove_recursive(ns->ddir); 188 183 return err; ··· 187 194 struct netdevsim *ns = netdev_priv(dev); 188 195 189 196 nsim_ipsec_teardown(ns); 190 - nsim_devlink_teardown(ns); 191 197 debugfs_remove_recursive(ns->ddir); 192 198 nsim_bpf_uninit(ns); 193 199 } ··· 195 203 { 196 204 struct netdevsim *ns = netdev_priv(dev); 197 205 206 + nsim_devlink_exit(ns); 198 207 device_unregister(&ns->dev); 199 208 /* netdev and vf state will be freed out of device_release() */ 200 209 nsim_sdev_put(ns->sdev); ··· 504 511 goto err_sdev_put; 505 512 506 513 SET_NETDEV_DEV(dev, &ns->dev); 514 + ns->netdev = dev; 515 + 516 + err = nsim_devlink_init(ns); 517 + if (err) 518 + goto err_unreg_dev; 507 519 508 520 err = register_netdevice(dev); 509 521 if (err) 510 - goto err_unreg_dev; 522 + goto err_devlink_exit; 511 523 return 0; 512 524 525 + err_devlink_exit: 526 + nsim_devlink_exit(ns); 513 527 err_unreg_dev: 514 528 device_unregister(&ns->dev); 515 529 err_sdev_put: ··· 548 548 if (err) 549 549 goto err_sdev_exit; 550 550 551 - err = nsim_devlink_init(); 551 + err = rtnl_link_register(&nsim_link_ops); 552 552 if (err) 553 553 goto err_unreg_bus; 554 554 555 - err = rtnl_link_register(&nsim_link_ops); 556 - if (err) 557 - goto err_dl_fini; 558 - 559 555 return 0; 560 556 561 - err_dl_fini: 562 - nsim_devlink_exit(); 563 557 err_unreg_bus: 564 558 bus_unregister(&nsim_bus); 565 559 err_sdev_exit: ··· 566 572 static void __exit nsim_module_exit(void) 567 573 { 568 574 rtnl_link_unregister(&nsim_link_ops); 569 - nsim_devlink_exit(); 570 575 bus_unregister(&nsim_bus); 571 576 nsim_sdev_exit(); 572 577 debugfs_remove_recursive(nsim_ddir);
+9 -9
drivers/net/netdevsim/netdevsim.h
··· 30 30 struct bpf_offload_dev; 31 31 struct dentry; 32 32 struct nsim_vf_config; 33 + struct nsim_fib_data; 33 34 34 35 struct netdevsim_shared_dev { 35 36 unsigned int refcnt; ··· 154 153 NSIM_RESOURCE_IPV6_FIB_RULES, 155 154 }; 156 155 157 - int nsim_devlink_setup(struct netdevsim *ns); 158 - void nsim_devlink_teardown(struct netdevsim *ns); 156 + int nsim_devlink_init(struct netdevsim *ns); 157 + void nsim_devlink_exit(struct netdevsim *ns); 159 158 160 - int nsim_devlink_init(void); 161 - void nsim_devlink_exit(void); 162 - 163 - int nsim_fib_init(void); 164 - void nsim_fib_exit(void); 165 - u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); 166 - int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, 159 + struct nsim_fib_data *nsim_fib_create(void); 160 + void nsim_fib_destroy(struct nsim_fib_data *fib_data); 161 + u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, 162 + enum nsim_resource_id res_id, bool max); 163 + int nsim_fib_set_max(struct nsim_fib_data *fib_data, 164 + enum nsim_resource_id res_id, u64 val, 167 165 struct netlink_ext_ack *extack); 168 166 169 167 #if IS_ENABLED(CONFIG_XFRM_OFFLOAD)