diff options
author | Andrea Mayer | 2020-12-02 14:05:13 +0100 |
---|---|---|
committer | Jakub Kicinski | 2020-12-04 13:30:50 -0800 |
commit | cfdf64a03406351a9d6c1fe568a141a9a85d4710 (patch) | |
tree | 3e5de5891f8fc237b8825be93aca2d0688c9ddf0 /net | |
parent | 0a3021f1d4e553d9f3e7fc20e994b91af0687eb4 (diff) |
seg6: add callbacks for customizing the creation/destruction of a behavior
We introduce two callbacks used for customizing the creation/destruction of
a SRv6 behavior. Such callbacks are defined in the new struct
seg6_local_lwtunnel_ops and hereafter we provide a brief description of
them:
- build_state(...): used for calling the custom constructor of the
behavior during its initialization phase and after all the attributes
have been parsed successfully;
- destroy_state(...): used for calling the custom destructor of the
behavior before it is completely destroyed.
Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/seg6_local.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 3b5657c622a0..da5bf4167a52 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -33,6 +33,13 @@ struct seg6_local_lwt; +/* callbacks used for customizing the creation and destruction of a behavior */ +struct seg6_local_lwtunnel_ops { + int (*build_state)(struct seg6_local_lwt *slwt, const void *cfg, + struct netlink_ext_ack *extack); + void (*destroy_state)(struct seg6_local_lwt *slwt); +}; + struct seg6_action_desc { int action; unsigned long attrs; @@ -53,6 +60,8 @@ struct seg6_action_desc { int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt); int static_headroom; + + struct seg6_local_lwtunnel_ops slwt_ops; }; struct bpf_lwt_prog { @@ -1055,6 +1064,38 @@ parse_optattrs_err: return err; } +/* call the custom constructor of the behavior during its initialization phase + * and after that all its attributes have been parsed successfully. + */ +static int +seg6_local_lwtunnel_build_state(struct seg6_local_lwt *slwt, const void *cfg, + struct netlink_ext_ack *extack) +{ + struct seg6_action_desc *desc = slwt->desc; + struct seg6_local_lwtunnel_ops *ops; + + ops = &desc->slwt_ops; + if (!ops->build_state) + return 0; + + return ops->build_state(slwt, cfg, extack); +} + +/* call the custom destructor of the behavior which is invoked before the + * tunnel is going to be destroyed. + */ +static void seg6_local_lwtunnel_destroy_state(struct seg6_local_lwt *slwt) +{ + struct seg6_action_desc *desc = slwt->desc; + struct seg6_local_lwtunnel_ops *ops; + + ops = &desc->slwt_ops; + if (!ops->destroy_state) + return; + + ops->destroy_state(slwt); +} + static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt) { struct seg6_action_param *param; @@ -1154,6 +1195,10 @@ static int seg6_local_build_state(struct net *net, struct nlattr *nla, if (err < 0) goto out_free; + err = seg6_local_lwtunnel_build_state(slwt, cfg, extack); + if (err < 0) + goto out_destroy_attrs; + newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; newts->headroom = slwt->headroom; @@ -1162,6 +1207,8 @@ static int seg6_local_build_state(struct net *net, struct nlattr *nla, return 0; +out_destroy_attrs: + destroy_attrs(slwt); out_free: kfree(newts); return err; @@ -1171,6 +1218,8 @@ static void seg6_local_destroy_state(struct lwtunnel_state *lwt) { struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); + seg6_local_lwtunnel_destroy_state(slwt); + destroy_attrs(slwt); return; |