Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf355b8d authored by David Lebrun's avatar David Lebrun Committed by David S. Miller
Browse files

ipv6: sr: add core files for SR HMAC support



This patch adds the necessary functions to compute and check the HMAC signature
of an SR-enabled packet. Two HMAC algorithms are supported: hmac(sha1) and
hmac(sha256).

In order to avoid dynamic memory allocation for each HMAC computation,
a per-cpu ring buffer is allocated for this purpose.

A new per-interface sysctl called seg6_require_hmac is added, allowing a
user-defined policy for processing HMAC-signed SR-enabled packets.
A value of -1 means that the HMAC field will always be ignored.
A value of 0 means that if an HMAC field is present, its validity will
be enforced (the packet is dropped is the signature is incorrect).
Finally, a value of 1 means that any SR-enabled packet that does not
contain an HMAC signature or whose signature is incorrect will be dropped.

Signed-off-by: default avatarDavid Lebrun <david.lebrun@uclouvain.be>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c8702c6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -65,6 +65,9 @@ struct ipv6_devconf {
	__s32		use_oif_addrs_only;
	__s32		keep_addr_on_down;
	__s32		seg6_enabled;
#ifdef CONFIG_IPV6_SEG6_HMAC
	__s32		seg6_require_hmac;
#endif

	struct ctl_table_header *sysctl_header;
};
+6 −0
Original line number Diff line number Diff line
#ifndef _LINUX_SEG6_HMAC_H
#define _LINUX_SEG6_HMAC_H

#include <uapi/linux/seg6_hmac.h>

#endif
+4 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/ipv6.h>
#include <net/lwtunnel.h>
#include <linux/seg6.h>
#include <linux/rhashtable.h>

static inline void update_csum_diff4(struct sk_buff *skb, __be32 from,
				     __be32 to)
@@ -41,6 +42,9 @@ static inline void update_csum_diff16(struct sk_buff *skb, __be32 *from,
struct seg6_pernet_data {
	struct mutex lock;
	struct in6_addr __rcu *tun_src;
#ifdef CONFIG_IPV6_SEG6_HMAC
	struct rhashtable hmac_infos;
#endif
};

static inline struct seg6_pernet_data *seg6_pernet(struct net *net)
+62 −0
Original line number Diff line number Diff line
/*
 *  SR-IPv6 implementation
 *
 *  Author:
 *  David Lebrun <david.lebrun@uclouvain.be>
 *
 *
 *  This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */

#ifndef _NET_SEG6_HMAC_H
#define _NET_SEG6_HMAC_H

#include <net/flow.h>
#include <net/ip6_fib.h>
#include <net/sock.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/route.h>
#include <net/seg6.h>
#include <linux/seg6_hmac.h>
#include <linux/rhashtable.h>

#define SEG6_HMAC_MAX_DIGESTSIZE	160
#define SEG6_HMAC_RING_SIZE		256

struct seg6_hmac_info {
	struct rhash_head node;
	struct rcu_head rcu;

	u32 hmackeyid;
	char secret[SEG6_HMAC_SECRET_LEN];
	u8 slen;
	u8 alg_id;
};

struct seg6_hmac_algo {
	u8 alg_id;
	char name[64];
	struct crypto_shash * __percpu *tfms;
	struct shash_desc * __percpu *shashs;
};

extern int seg6_hmac_compute(struct seg6_hmac_info *hinfo,
			     struct ipv6_sr_hdr *hdr, struct in6_addr *saddr,
			     u8 *output);
extern struct seg6_hmac_info *seg6_hmac_info_lookup(struct net *net, u32 key);
extern int seg6_hmac_info_add(struct net *net, u32 key,
			      struct seg6_hmac_info *hinfo);
extern int seg6_hmac_info_del(struct net *net, u32 key);
extern int seg6_push_hmac(struct net *net, struct in6_addr *saddr,
			  struct ipv6_sr_hdr *srh);
extern bool seg6_hmac_validate_skb(struct sk_buff *skb);
extern int seg6_hmac_init(void);
extern void seg6_hmac_exit(void);
extern int seg6_hmac_net_init(struct net *net);
extern void seg6_hmac_net_exit(struct net *net);

#endif
+1 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ enum {
	DEVCONF_KEEP_ADDR_ON_DOWN,
	DEVCONF_RTR_SOLICIT_MAX_INTERVAL,
	DEVCONF_SEG6_ENABLED,
	DEVCONF_SEG6_REQUIRE_HMAC,
	DEVCONF_MAX
};

Loading