diff --git a/Makefile b/Makefile index c7c2887..8227a36 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ gtp5g-y += api_version.o gtp5g-y += log.o util.o gtp5g-y += dev.o genl.o net.o link.o proc.o gtp5g-y += gtp.o pktinfo.o hash.o seid.o encap.o -gtp5g-y += pdr.o far.o qer.o bar.o urr.o genl.o genl_pdr.o genl_far.o genl_qer.o genl_bar.o genl_urr.o +gtp5g-y += pdr.o far.o qer.o bar.o urr.o genl.o genl_pdr.o genl_far.o genl_qer.o genl_bar.o genl_urr.o genl_version.o default: module diff --git a/genl.c b/genl.c index 0407b93..1705d9b 100644 --- a/genl.c +++ b/genl.c @@ -7,6 +7,7 @@ #include "genl_qer.h" #include "genl_bar.h" #include "genl_urr.h" +#include "genl_version.h" static const struct nla_policy gtp5g_genl_pdr_policy[GTP5G_PDR_ATTR_MAX + 1] = { [GTP5G_PDR_ID] = { .type = NLA_U32, }, @@ -134,6 +135,11 @@ static const struct genl_ops gtp5g_genl_ops[] = { .dumpit = gtp5g_genl_dump_bar, .flags = GENL_ADMIN_PERM, }, + { + .cmd = GTP5G_CMD_GET_VERSION, + .doit = gtp5g_genl_get_version, + .flags = GENL_ADMIN_PERM, + }, }; struct genl_family gtp5g_genl_family __ro_after_init = { diff --git a/genl.h b/genl.h index dac722b..01ff2be 100644 --- a/genl.h +++ b/genl.h @@ -29,6 +29,8 @@ enum gtp5g_cmd { * free5GC's UPF or libgtp5gnl * */ + GTP5G_CMD_GET_VERSION, + __GTP5G_CMD_MAX, }; #define GTP5G_CMD_MAX (__GTP5G_CMD_MAX - 1) diff --git a/genl_version.c b/genl_version.c new file mode 100644 index 0000000..1e7fe68 --- /dev/null +++ b/genl_version.c @@ -0,0 +1,47 @@ +#include "genl_version.h" + +static int gtp5g_genl_fill_ver(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, + u32 type) +{ + void *genlh; + + genlh = genlmsg_put(skb, snd_portid, snd_seq, >p5g_genl_family, 0, type); + if (!genlh) + goto genlmsg_fail; + + if (nla_put_string(skb, GTP5G_VERSION, DRV_VERSION)) + goto genlmsg_fail; + + genlmsg_end(skb, genlh); + return 0; + +genlmsg_fail: + genlmsg_cancel(skb, genlh); + return -EMSGSIZE; +} + +int gtp5g_genl_get_version(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *skb_ack; + int err; + + skb_ack = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + if (!skb_ack) { + rcu_read_unlock(); + return -ENOMEM; + } + + err = gtp5g_genl_fill_ver(skb_ack, + NETLINK_CB(skb).portid, + info->snd_seq, + info->nlhdr->nlmsg_type); + if (err) { + kfree_skb(skb_ack); + rcu_read_unlock(); + return err; + } + + rcu_read_unlock(); + + return genlmsg_unicast(genl_info_net(info), skb_ack, info->snd_portid); +} diff --git a/genl_version.h b/genl_version.h new file mode 100644 index 0000000..afa5eed --- /dev/null +++ b/genl_version.h @@ -0,0 +1,14 @@ +#ifndef __GENL_VERSION_H__ +#define __GENL_VERSION_H__ + +#include "genl.h" + +#define DRV_VERSION "0.6.4" + +enum gtp5g_version { + GTP5G_VERSION +}; + +extern int gtp5g_genl_get_version(struct sk_buff *, struct genl_info *); + +#endif // __GENL_VERSION_H__ \ No newline at end of file diff --git a/main.c b/main.c index 99ad213..3d13297 100644 --- a/main.c +++ b/main.c @@ -6,8 +6,7 @@ #include "proc.h" #include "hash.h" #include "log.h" - -#define DRV_VERSION "0.6.3" +#include "genl_version.h" static int __init gtp5g_init(void) {