Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  SR-IPv6 implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  David Lebrun <david.lebrun@uclouvain.be>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/rhashtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <net/protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <net/seg6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/seg6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/seg6_genl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <net/seg6_hmac.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	unsigned int tlv_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	int max_last_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	int trailing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (srh->type != IPV6_SRCRT_TYPE_4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (((srh->hdrlen + 1) << 3) != len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (!reduced && srh->segments_left > srh->first_segment) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		max_last_entry = (srh->hdrlen / 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		if (srh->first_segment > max_last_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		if (srh->segments_left > srh->first_segment + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	trailing = len - tlv_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	if (trailing < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	while (trailing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		struct sr6_tlv *tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		unsigned int tlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		if (trailing < sizeof(*tlv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		tlv = (struct sr6_tlv *)((unsigned char *)srh + tlv_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		tlv_len = sizeof(*tlv) + tlv->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		trailing -= tlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		if (trailing < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		tlv_offset += tlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static struct genl_family seg6_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	[SEG6_ATTR_DST]				= { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		.len = sizeof(struct in6_addr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	[SEG6_ATTR_DSTLEN]			= { .type = NLA_S32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	[SEG6_ATTR_HMACKEYID]		= { .type = NLA_U32, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	[SEG6_ATTR_SECRET]			= { .type = NLA_BINARY, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	[SEG6_ATTR_SECRETLEN]		= { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	[SEG6_ATTR_ALGID]			= { .type = NLA_U8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	[SEG6_ATTR_HMACINFO]		= { .type = NLA_NESTED, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct seg6_pernet_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct seg6_hmac_info *hinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	u32 hmackeyid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	char *secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	u8 algid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	u8 slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	sdata = seg6_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (!info->attrs[SEG6_ATTR_HMACKEYID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	    !info->attrs[SEG6_ATTR_SECRETLEN] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	    !info->attrs[SEG6_ATTR_ALGID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	hmackeyid = nla_get_u32(info->attrs[SEG6_ATTR_HMACKEYID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	slen = nla_get_u8(info->attrs[SEG6_ATTR_SECRETLEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	algid = nla_get_u8(info->attrs[SEG6_ATTR_ALGID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (hmackeyid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (slen > SEG6_HMAC_SECRET_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	mutex_lock(&sdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	hinfo = seg6_hmac_info_lookup(net, hmackeyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (!slen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (!hinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		err = seg6_hmac_info_del(net, hmackeyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (!info->attrs[SEG6_ATTR_SECRET]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (hinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		err = seg6_hmac_info_del(net, hmackeyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	secret = (char *)nla_data(info->attrs[SEG6_ATTR_SECRET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	hinfo = kzalloc(sizeof(*hinfo), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (!hinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	memcpy(hinfo->secret, secret, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	hinfo->slen = slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	hinfo->alg_id = algid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	hinfo->hmackeyid = hmackeyid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	err = seg6_hmac_info_add(net, hmackeyid, hinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		kfree(hinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	mutex_unlock(&sdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int seg6_genl_set_tunsrc(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct in6_addr *val, *t_old, *t_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct seg6_pernet_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	sdata = seg6_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (!info->attrs[SEG6_ATTR_DST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	val = nla_data(info->attrs[SEG6_ATTR_DST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	t_new = kmemdup(val, sizeof(*val), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (!t_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	mutex_lock(&sdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	t_old = sdata->tun_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	rcu_assign_pointer(sdata->tun_src, t_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	mutex_unlock(&sdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	kfree(t_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int seg6_genl_get_tunsrc(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct in6_addr *tun_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	msg = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			  &seg6_genl_family, 0, SEG6_CMD_GET_TUNSRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	tun_src = rcu_dereference(seg6_pernet(net)->tun_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (nla_put(msg, SEG6_ATTR_DST, sizeof(struct in6_addr), tun_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int __seg6_hmac_fill_info(struct seg6_hmac_info *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				 struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (nla_put_u32(msg, SEG6_ATTR_HMACKEYID, hinfo->hmackeyid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	    nla_put_u8(msg, SEG6_ATTR_SECRETLEN, hinfo->slen) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	    nla_put(msg, SEG6_ATTR_SECRET, hinfo->slen, hinfo->secret) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	    nla_put_u8(msg, SEG6_ATTR_ALGID, hinfo->alg_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int __seg6_genl_dumphmac_element(struct seg6_hmac_info *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 					u32 portid, u32 seq, u32 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 					struct sk_buff *skb, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	hdr = genlmsg_put(skb, portid, seq, &seg6_genl_family, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (__seg6_hmac_fill_info(hinfo, skb) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	struct net *net = sock_net(cb->skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	struct seg6_pernet_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	struct rhashtable_iter *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	sdata = seg6_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	iter = (struct rhashtable_iter *)cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (!iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		iter = kmalloc(sizeof(*iter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		if (!iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		cb->args[0] = (long)iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	rhashtable_walk_enter(&sdata->hmac_infos, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	rhashtable_walk_exit(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	kfree(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	struct seg6_hmac_info *hinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	rhashtable_walk_start(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		hinfo = rhashtable_walk_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		if (IS_ERR(hinfo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			if (PTR_ERR(hinfo) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			ret = PTR_ERR(hinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		} else if (!hinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		ret = __seg6_genl_dumphmac_element(hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 						   NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 						   cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 						   NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 						   skb, SEG6_CMD_DUMPHMAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	ret = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	rhashtable_walk_stop(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int seg6_genl_dumphmac_start(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int seg6_genl_dumphmac_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int __net_init seg6_net_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct seg6_pernet_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	sdata = kzalloc(sizeof(*sdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (!sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	mutex_init(&sdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	sdata->tun_src = kzalloc(sizeof(*sdata->tun_src), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	if (!sdata->tun_src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		kfree(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	net->ipv6.seg6_data = sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	seg6_hmac_net_init(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static void __net_exit seg6_net_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	struct seg6_pernet_data *sdata = seg6_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	seg6_hmac_net_exit(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	kfree(sdata->tun_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	kfree(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static struct pernet_operations ip6_segments_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	.init = seg6_net_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	.exit = seg6_net_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static const struct genl_ops seg6_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		.cmd	= SEG6_CMD_SETHMAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		.doit	= seg6_genl_sethmac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		.flags	= GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		.cmd	= SEG6_CMD_DUMPHMAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		.start	= seg6_genl_dumphmac_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		.dumpit	= seg6_genl_dumphmac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		.done	= seg6_genl_dumphmac_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		.flags	= GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		.cmd	= SEG6_CMD_SET_TUNSRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		.doit	= seg6_genl_set_tunsrc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		.flags	= GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		.cmd	= SEG6_CMD_GET_TUNSRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		.doit	= seg6_genl_get_tunsrc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		.flags	= GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static struct genl_family seg6_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	.hdrsize	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	.name		= SEG6_GENL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	.version	= SEG6_GENL_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	.maxattr	= SEG6_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	.policy = seg6_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	.netnsok	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	.parallel_ops	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	.ops		= seg6_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	.n_ops		= ARRAY_SIZE(seg6_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	.module		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int __init seg6_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	err = genl_register_family(&seg6_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	err = register_pernet_subsys(&ip6_segments_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		goto out_unregister_genl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	err = seg6_iptunnel_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		goto out_unregister_pernet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	err = seg6_local_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		goto out_unregister_pernet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	err = seg6_hmac_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		goto out_unregister_iptun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	pr_info("Segment Routing with IPv6\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) out_unregister_iptun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	seg6_local_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	seg6_iptunnel_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) out_unregister_pernet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	unregister_pernet_subsys(&ip6_segments_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) out_unregister_genl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	genl_unregister_family(&seg6_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void seg6_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) #ifdef CONFIG_IPV6_SEG6_HMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	seg6_hmac_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	seg6_iptunnel_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	unregister_pernet_subsys(&ip6_segments_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	genl_unregister_family(&seg6_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }