Commit 8610c7c6 authored by Alexander Aring's avatar Alexander Aring Committed by David S. Miller
Browse files

net: ipv6: add support for rpl sr exthdr



This patch adds rpl source routing receive handling. Everything works
only if sysconf "rpl_seg_enabled" and source routing is enabled. Mostly
the same behaviour as IPv6 segmentation routing. To handle compression
and uncompression a rpl.c file is created which contains the necessary
functionality. The receive handling will also care about IPv6
encapsulated so far it's specified as possible nexthdr in RFC 6554.

Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f37c6059
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct ipv6_devconf {
	__u32		addr_gen_mode;
	__s32		disable_policy;
	__s32           ndisc_tclass;
	__s32		rpl_seg_enabled;

	struct ctl_table_header *sysctl_header;
};

include/net/rpl.h

0 → 100644
+34 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *  RPL implementation
 *
 *  Author:
 *  (C) 2020 Alexander Aring <alex.aring@gmail.com>
 */

#ifndef _NET_RPL_H
#define _NET_RPL_H

#include <linux/rpl.h>

/* Worst decompression memory usage ipv6 address (16) + pad 7 */
#define IPV6_RPL_SRH_WORST_SWAP_SIZE (sizeof(struct in6_addr) + 7)

static inline size_t ipv6_rpl_srh_alloc_size(unsigned char n)
{
	return sizeof(struct ipv6_rpl_sr_hdr) +
		((n + 1) * sizeof(struct in6_addr));
}

size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
			 unsigned char cmpre);

void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr,
			     const struct ipv6_rpl_sr_hdr *inhdr,
			     const struct in6_addr *daddr, unsigned char n);

void ipv6_rpl_srh_compress(struct ipv6_rpl_sr_hdr *outhdr,
			   const struct ipv6_rpl_sr_hdr *inhdr,
			   const struct in6_addr *daddr, unsigned char n);

#endif /* _NET_RPL_H */
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct in6_ifreq {
#define IPV6_SRCRT_STRICT	0x01	/* Deprecated; will be removed */
#define IPV6_SRCRT_TYPE_0	0	/* Deprecated; will be removed */
#define IPV6_SRCRT_TYPE_2	2	/* IPv6 type 2 Routing Header	*/
#define IPV6_SRCRT_TYPE_3	3	/* RPL Segment Routing with IPv6 */
#define IPV6_SRCRT_TYPE_4	4	/* Segment Routing with IPv6 */

/*
@@ -187,6 +188,7 @@ enum {
	DEVCONF_DISABLE_POLICY,
	DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
	DEVCONF_NDISC_TCLASS,
	DEVCONF_RPL_SEG_ENABLED,
	DEVCONF_MAX
};

+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
		raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
		exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o \
		udp_offload.o seg6.o fib6_notifier.o
		udp_offload.o seg6.o fib6_notifier.o rpl.o

ipv6-offload :=	ip6_offload.o tcpv6_offload.o exthdrs_offload.o

+10 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
	.enhanced_dad           = 1,
	.addr_gen_mode		= IN6_ADDR_GEN_MODE_EUI64,
	.disable_policy		= 0,
	.rpl_seg_enabled	= 0,
};

static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -290,6 +291,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
	.enhanced_dad           = 1,
	.addr_gen_mode		= IN6_ADDR_GEN_MODE_EUI64,
	.disable_policy		= 0,
	.rpl_seg_enabled	= 0,
};

/* Check if link is ready: is it up and is a valid qdisc available */
@@ -5520,6 +5522,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
	array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
	array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
	array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
	array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled;
}

static inline size_t inet6_ifla6_size(void)
@@ -6900,6 +6903,13 @@ static const struct ctl_table addrconf_sysctl[] = {
		.extra1		= (void *)SYSCTL_ZERO,
		.extra2		= (void *)&two_five_five,
	},
	{
		.procname	= "rpl_seg_enabled",
		.data		= &ipv6_devconf.rpl_seg_enabled,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
	},
	{
		/* sentinel */
	}
Loading