ila: Flush netlink command to clear xlat table
Add ILA_CMD_FLUSH netlink command to clear the ILA translation table. Signed-off-by: Tom Herbert <tom@quantonium.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ad68147ef2
commit
b6e71bdebb
|
@ -30,6 +30,7 @@ enum {
|
|||
ILA_CMD_ADD,
|
||||
ILA_CMD_DEL,
|
||||
ILA_CMD_GET,
|
||||
ILA_CMD_FLUSH,
|
||||
|
||||
__ILA_CMD_MAX,
|
||||
};
|
||||
|
|
|
@ -123,6 +123,7 @@ void ila_xlat_exit_net(struct net *net);
|
|||
int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info);
|
||||
int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info);
|
||||
int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info);
|
||||
int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info);
|
||||
int ila_xlat_nl_dump_start(struct netlink_callback *cb);
|
||||
int ila_xlat_nl_dump_done(struct netlink_callback *cb);
|
||||
int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
|
|
|
@ -26,6 +26,12 @@ static const struct genl_ops ila_nl_ops[] = {
|
|||
.policy = ila_nl_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
{
|
||||
.cmd = ILA_CMD_FLUSH,
|
||||
.doit = ila_xlat_nl_cmd_flush,
|
||||
.policy = ila_nl_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
{
|
||||
.cmd = ILA_CMD_GET,
|
||||
.doit = ila_xlat_nl_cmd_get_mapping,
|
||||
|
|
|
@ -164,9 +164,9 @@ static inline void ila_release(struct ila_map *ila)
|
|||
kfree_rcu(ila, rcu);
|
||||
}
|
||||
|
||||
static void ila_free_cb(void *ptr, void *arg)
|
||||
static void ila_free_node(struct ila_map *ila)
|
||||
{
|
||||
struct ila_map *ila = (struct ila_map *)ptr, *next;
|
||||
struct ila_map *next;
|
||||
|
||||
/* Assume rcu_readlock held */
|
||||
while (ila) {
|
||||
|
@ -176,6 +176,11 @@ static void ila_free_cb(void *ptr, void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
static void ila_free_cb(void *ptr, void *arg)
|
||||
{
|
||||
ila_free_node((struct ila_map *)ptr);
|
||||
}
|
||||
|
||||
static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila);
|
||||
|
||||
static unsigned int
|
||||
|
@ -365,6 +370,59 @@ int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline spinlock_t *lock_from_ila_map(struct ila_net *ilan,
|
||||
struct ila_map *ila)
|
||||
{
|
||||
return ila_get_lock(ilan, ila->xp.ip.locator_match);
|
||||
}
|
||||
|
||||
int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net *net = genl_info_net(info);
|
||||
struct ila_net *ilan = net_generic(net, ila_net_id);
|
||||
struct rhashtable_iter iter;
|
||||
struct ila_map *ila;
|
||||
spinlock_t *lock;
|
||||
int ret;
|
||||
|
||||
ret = rhashtable_walk_init(&ilan->xlat.rhash_table, &iter, GFP_KERNEL);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
rhashtable_walk_start(&iter);
|
||||
|
||||
for (;;) {
|
||||
ila = rhashtable_walk_next(&iter);
|
||||
|
||||
if (IS_ERR(ila)) {
|
||||
if (PTR_ERR(ila) == -EAGAIN)
|
||||
continue;
|
||||
ret = PTR_ERR(ila);
|
||||
goto done;
|
||||
} else if (!ila) {
|
||||
break;
|
||||
}
|
||||
|
||||
lock = lock_from_ila_map(ilan, ila);
|
||||
|
||||
spin_lock(lock);
|
||||
|
||||
ret = rhashtable_remove_fast(&ilan->xlat.rhash_table,
|
||||
&ila->node, rht_params);
|
||||
if (!ret)
|
||||
ila_free_node(ila);
|
||||
|
||||
spin_unlock(lock);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
rhashtable_walk_stop(&iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
|
||||
{
|
||||
if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
|
||||
|
|
Loading…
Reference in New Issue
Block a user