From: David Lebrun <david.lebrun@uclouvain.be>
To: <netdev@vger.kernel.org>
Cc: David Lebrun <david.lebrun@uclouvain.be>
Subject: [PATCH net-next v5 5/9] ipv6: sr: implement API to control SR HMAC structure
Date: Tue, 8 Nov 2016 14:59:18 +0100 [thread overview]
Message-ID: <1478613562-27947-1-git-send-email-david.lebrun@uclouvain.be> (raw)
In-Reply-To: <1478613467-27712-1-git-send-email-david.lebrun@uclouvain.be>
This patch provides an implementation of the genetlink commands
to associate a given HMAC key identifier with an hashing algorithm
and a secret.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/seg6.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 229 insertions(+)
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 9c78053..50f6e06 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -25,6 +25,9 @@
#include <net/genetlink.h>
#include <linux/seg6.h>
#include <linux/seg6_genl.h>
+#ifdef CONFIG_IPV6_SEG6_HMAC
+#include <net/seg6_hmac.h>
+#endif
bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
{
@@ -76,11 +79,90 @@ static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {
[SEG6_ATTR_HMACINFO] = { .type = NLA_NESTED, },
};
+#ifdef CONFIG_IPV6_SEG6_HMAC
+
+static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
+{
+ struct net *net = genl_info_net(info);
+ struct seg6_pernet_data *sdata;
+ struct seg6_hmac_info *hinfo;
+ u32 hmackeyid;
+ char *secret;
+ int err = 0;
+ u8 algid;
+ u8 slen;
+
+ sdata = seg6_pernet(net);
+
+ if (!info->attrs[SEG6_ATTR_HMACKEYID] ||
+ !info->attrs[SEG6_ATTR_SECRETLEN] ||
+ !info->attrs[SEG6_ATTR_ALGID])
+ return -EINVAL;
+
+ hmackeyid = nla_get_u32(info->attrs[SEG6_ATTR_HMACKEYID]);
+ slen = nla_get_u8(info->attrs[SEG6_ATTR_SECRETLEN]);
+ algid = nla_get_u8(info->attrs[SEG6_ATTR_ALGID]);
+
+ if (hmackeyid == 0)
+ return -EINVAL;
+
+ if (slen > SEG6_HMAC_SECRET_LEN)
+ return -EINVAL;
+
+ mutex_lock(&sdata->lock);
+ hinfo = seg6_hmac_info_lookup(net, hmackeyid);
+
+ if (!slen) {
+ if (!hinfo)
+ err = -ENOENT;
+
+ err = seg6_hmac_info_del(net, hmackeyid);
+
+ goto out_unlock;
+ }
+
+ if (!info->attrs[SEG6_ATTR_SECRET]) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (hinfo) {
+ err = seg6_hmac_info_del(net, hmackeyid);
+ if (err)
+ goto out_unlock;
+ }
+
+ secret = (char *)nla_data(info->attrs[SEG6_ATTR_SECRET]);
+
+ hinfo = kzalloc(sizeof(*hinfo), GFP_KERNEL);
+ if (!hinfo) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ memcpy(hinfo->secret, secret, slen);
+ hinfo->slen = slen;
+ hinfo->alg_id = algid;
+ hinfo->hmackeyid = hmackeyid;
+
+ err = seg6_hmac_info_add(net, hmackeyid, hinfo);
+ if (err)
+ kfree(hinfo);
+
+out_unlock:
+ mutex_unlock(&sdata->lock);
+ return err;
+}
+
+#else
+
static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
{
return -ENOTSUPP;
}
+#endif
+
static int seg6_genl_set_tunsrc(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
@@ -145,11 +227,135 @@ static int seg6_genl_get_tunsrc(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
}
+#ifdef CONFIG_IPV6_SEG6_HMAC
+
+static int __seg6_hmac_fill_info(struct seg6_hmac_info *hinfo,
+ struct sk_buff *msg)
+{
+ if (nla_put_u32(msg, SEG6_ATTR_HMACKEYID, hinfo->hmackeyid) ||
+ nla_put_u8(msg, SEG6_ATTR_SECRETLEN, hinfo->slen) ||
+ nla_put(msg, SEG6_ATTR_SECRET, hinfo->slen, hinfo->secret) ||
+ nla_put_u8(msg, SEG6_ATTR_ALGID, hinfo->alg_id))
+ return -1;
+
+ return 0;
+}
+
+static int __seg6_genl_dumphmac_element(struct seg6_hmac_info *hinfo,
+ u32 portid, u32 seq, u32 flags,
+ struct sk_buff *skb, u8 cmd)
+{
+ void *hdr;
+
+ hdr = genlmsg_put(skb, portid, seq, &seg6_genl_family, flags, cmd);
+ if (!hdr)
+ return -ENOMEM;
+
+ if (__seg6_hmac_fill_info(hinfo, skb) < 0)
+ goto nla_put_failure;
+
+ genlmsg_end(skb, hdr);
+ return 0;
+
+nla_put_failure:
+ genlmsg_cancel(skb, hdr);
+ return -EMSGSIZE;
+}
+
+static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
+{
+ struct net *net = sock_net(cb->skb->sk);
+ struct seg6_pernet_data *sdata;
+ struct rhashtable_iter *iter;
+
+ sdata = seg6_pernet(net);
+ iter = (struct rhashtable_iter *)cb->args[0];
+
+ if (!iter) {
+ iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+ if (!iter)
+ return -ENOMEM;
+
+ cb->args[0] = (long)iter;
+ }
+
+ rhashtable_walk_enter(&sdata->hmac_infos, iter);
+
+ return 0;
+}
+
+static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
+{
+ struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
+
+ rhashtable_walk_exit(iter);
+
+ kfree(iter);
+
+ return 0;
+}
+
+static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
+ struct net *net = sock_net(skb->sk);
+ struct seg6_pernet_data *sdata;
+ struct seg6_hmac_info *hinfo;
+ int ret;
+
+ sdata = seg6_pernet(net);
+
+ ret = rhashtable_walk_start(iter);
+ if (ret && ret != -EAGAIN)
+ goto done;
+
+ for (;;) {
+ hinfo = rhashtable_walk_next(iter);
+
+ if (IS_ERR(hinfo)) {
+ if (PTR_ERR(hinfo) == -EAGAIN)
+ continue;
+ ret = PTR_ERR(hinfo);
+ goto done;
+ } else if (!hinfo) {
+ break;
+ }
+
+ ret = __seg6_genl_dumphmac_element(hinfo,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ skb, SEG6_CMD_DUMPHMAC);
+ if (ret)
+ goto done;
+ }
+
+ ret = skb->len;
+
+done:
+ rhashtable_walk_stop(iter);
+ return ret;
+}
+
+#else
+
+static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
+{
+ return 0;
+}
+
+static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
+{
+ return 0;
+}
+
static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
{
return -ENOTSUPP;
}
+#endif
+
static int __net_init seg6_net_init(struct net *net)
{
struct seg6_pernet_data *sdata;
@@ -168,6 +374,10 @@ static int __net_init seg6_net_init(struct net *net)
net->ipv6.seg6_data = sdata;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_net_init(net);
+#endif
+
return 0;
}
@@ -175,6 +385,10 @@ static void __net_exit seg6_net_exit(struct net *net)
{
struct seg6_pernet_data *sdata = seg6_pernet(net);
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_net_exit(net);
+#endif
+
kfree(sdata->tun_src);
kfree(sdata);
}
@@ -193,7 +407,9 @@ static const struct genl_ops seg6_genl_ops[] = {
},
{
.cmd = SEG6_CMD_DUMPHMAC,
+ .start = seg6_genl_dumphmac_start,
.dumpit = seg6_genl_dumphmac,
+ .done = seg6_genl_dumphmac_done,
.policy = seg6_genl_policy,
.flags = GENL_ADMIN_PERM,
},
@@ -239,10 +455,20 @@ int __init seg6_init(void)
if (err)
goto out_unregister_pernet;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ err = seg6_hmac_init();
+ if (err)
+ goto out_unregister_iptun;
+#endif
+
pr_info("Segment Routing with IPv6\n");
out:
return err;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+out_unregister_iptun:
+ seg6_iptunnel_exit();
+#endif
out_unregister_pernet:
unregister_pernet_subsys(&ip6_segments_ops);
out_unregister_genl:
@@ -252,6 +478,9 @@ int __init seg6_init(void)
void seg6_exit(void)
{
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ seg6_hmac_exit();
+#endif
seg6_iptunnel_exit();
unregister_pernet_subsys(&ip6_segments_ops);
genl_unregister_family(&seg6_genl_family);
--
2.7.3
next prev parent reply other threads:[~2016-11-08 13:57 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-08 13:57 [PATCH net-next v5 0/9] net: add support for IPv6 Segment Routing David Lebrun
2016-11-08 13:57 ` [PATCH net-next v5 1/9] ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header) David Lebrun
2016-11-08 13:57 ` [PATCH net-next v5 2/9] ipv6: sr: add code base for control plane support of SR-IPv6 David Lebrun
2016-11-08 13:57 ` [PATCH net-next v5 3/9] ipv6: sr: add support for SRH encapsulation and injection with lwtunnels David Lebrun
2016-11-08 13:57 ` [PATCH net-next v5 4/9] ipv6: sr: add core files for SR HMAC support David Lebrun
2016-11-08 13:59 ` David Lebrun [this message]
2016-11-08 13:59 ` [PATCH net-next v5 6/9] ipv6: sr: add calls to verify and insert HMAC signatures David Lebrun
2016-11-08 13:59 ` [PATCH net-next v5 7/9] ipv6: add source address argument for ipv6_push_nfrag_opts David Lebrun
2016-11-08 13:59 ` [PATCH net-next v5 8/9] ipv6: sr: add support for SRH injection through setsockopt David Lebrun
2016-11-08 13:59 ` [PATCH net-next v5 9/9] ipv6: sr: add documentation file for per-interface sysctls David Lebrun
2016-11-10 1:40 ` [PATCH net-next v5 0/9] net: add support for IPv6 Segment Routing David Miller
2016-11-10 8:19 ` David Lebrun
2016-11-10 14:45 ` David Miller
2016-11-10 8:35 ` Lorenzo Colitti
2016-11-10 9:09 ` David Lebrun
2016-11-10 9:14 ` Lorenzo Colitti
2016-11-10 9:26 ` David Lebrun
2016-11-10 9:27 ` Lorenzo Colitti
2016-11-10 9:55 ` [PATCH net-next] ipv6: sr: fix IPv6 initialization failure without lwtunnels David Lebrun
2016-11-10 11:20 ` kbuild test robot
2016-11-10 12:32 ` kbuild test robot
2016-11-10 12:26 ` [PATCH net-next v2] " David Lebrun
2016-11-13 5:20 ` David Miller
2016-11-13 5:23 ` David Miller
2016-11-13 19:59 ` David Lebrun
2016-11-14 14:22 ` Roopa Prabhu
2016-11-15 10:17 ` David Lebrun
2016-11-15 15:18 ` David Miller
2016-11-16 15:49 ` Roopa Prabhu
2016-11-16 16:31 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1478613562-27947-1-git-send-email-david.lebrun@uclouvain.be \
--to=david.lebrun@uclouvain.be \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).