ipv6.h 35.0 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
L
Linus Torvalds 已提交
2 3 4 5 6 7 8 9 10 11 12 13
/*
 *	Linux INET6 implementation
 *
 *	Authors:
 *	Pedro Roque		<roque@di.fc.ul.pt>
 */

#ifndef _NET_IPV6_H
#define _NET_IPV6_H

#include <linux/ipv6.h>
#include <linux/hardirq.h>
E
Eric Dumazet 已提交
14
#include <linux/jhash.h>
15
#include <linux/refcount.h>
16
#include <linux/jump_label_ratelimit.h>
17
#include <net/if_inet6.h>
L
Linus Torvalds 已提交
18 19
#include <net/ndisc.h>
#include <net/flow.h>
20
#include <net/flow_dissector.h>
L
Linus Torvalds 已提交
21
#include <net/snmp.h>
22
#include <net/netns/hash.h>
L
Linus Torvalds 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

#define SIN6_LEN_RFC2133	24

#define IPV6_MAXPLEN		65535

/*
 *	NextHeader field of IPv6 header
 */

#define NEXTHDR_HOP		0	/* Hop-by-hop option header. */
#define NEXTHDR_TCP		6	/* TCP segment. */
#define NEXTHDR_UDP		17	/* UDP message. */
#define NEXTHDR_IPV6		41	/* IPv6 in IPv6 */
#define NEXTHDR_ROUTING		43	/* Routing header. */
#define NEXTHDR_FRAGMENT	44	/* Fragmentation/reassembly header. */
X
xeb@mail.ru 已提交
38
#define NEXTHDR_GRE		47	/* GRE header. */
L
Linus Torvalds 已提交
39 40 41 42 43
#define NEXTHDR_ESP		50	/* Encapsulating security payload. */
#define NEXTHDR_AUTH		51	/* Authentication header. */
#define NEXTHDR_ICMP		58	/* ICMP for IPv6. */
#define NEXTHDR_NONE		59	/* No next header */
#define NEXTHDR_DEST		60	/* Destination options header. */
J
Joe Stringer 已提交
44
#define NEXTHDR_SCTP		132	/* SCTP message. */
45
#define NEXTHDR_MOBILITY	135	/* Mobility header. */
L
Linus Torvalds 已提交
46 47 48 49 50 51

#define NEXTHDR_MAX		255

#define IPV6_DEFAULT_HOPLIMIT   64
#define IPV6_DEFAULT_MCASTHOPS	1

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
/* Limits on Hop-by-Hop and Destination options.
 *
 * Per RFC8200 there is no limit on the maximum number or lengths of options in
 * Hop-by-Hop or Destination options other then the packet must fit in an MTU.
 * We allow configurable limits in order to mitigate potential denial of
 * service attacks.
 *
 * There are three limits that may be set:
 *   - Limit the number of options in a Hop-by-Hop or Destination options
 *     extension header
 *   - Limit the byte length of a Hop-by-Hop or Destination options extension
 *     header
 *   - Disallow unknown options
 *
 * The limits are expressed in corresponding sysctls:
 *
 * ipv6.sysctl.max_dst_opts_cnt
 * ipv6.sysctl.max_hbh_opts_cnt
 * ipv6.sysctl.max_dst_opts_len
 * ipv6.sysctl.max_hbh_opts_len
 *
 * max_*_opts_cnt is the number of TLVs that are allowed for Destination
 * options or Hop-by-Hop options. If the number is less than zero then unknown
 * TLVs are disallowed and the number of known options that are allowed is the
 * absolute value. Setting the value to INT_MAX indicates no limit.
 *
 * max_*_opts_len is the length limit in bytes of a Destination or
 * Hop-by-Hop options extension header. Setting the value to INT_MAX
 * indicates no length limit.
 *
 * If a limit is exceeded when processing an extension header the packet is
 * silently discarded.
 */

/* Default limits for Hop-by-Hop and Destination options */
#define IP6_DEFAULT_MAX_DST_OPTS_CNT	 8
#define IP6_DEFAULT_MAX_HBH_OPTS_CNT	 8
#define IP6_DEFAULT_MAX_DST_OPTS_LEN	 INT_MAX /* No limit */
#define IP6_DEFAULT_MAX_HBH_OPTS_LEN	 INT_MAX /* No limit */

L
Linus Torvalds 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104
/*
 *	Addr type
 *	
 *	type	-	unicast | multicast
 *	scope	-	local	| site	    | global
 *	v4	-	compat
 *	v4mapped
 *	any
 *	loopback
 */

#define IPV6_ADDR_ANY		0x0000U

S
Stephen Hemminger 已提交
105 106
#define IPV6_ADDR_UNICAST	0x0001U
#define IPV6_ADDR_MULTICAST	0x0002U
L
Linus Torvalds 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

#define IPV6_ADDR_LOOPBACK	0x0010U
#define IPV6_ADDR_LINKLOCAL	0x0020U
#define IPV6_ADDR_SITELOCAL	0x0040U

#define IPV6_ADDR_COMPATv4	0x0080U

#define IPV6_ADDR_SCOPE_MASK	0x00f0U

#define IPV6_ADDR_MAPPED	0x1000U

/*
 *	Addr scopes
 */
#define IPV6_ADDR_MC_SCOPE(a)	\
	((a)->s6_addr[1] & 0x0f)	/* nonstandard */
#define __IPV6_ADDR_SCOPE_INVALID	-1
#define IPV6_ADDR_SCOPE_NODELOCAL	0x01
#define IPV6_ADDR_SCOPE_LINKLOCAL	0x02
#define IPV6_ADDR_SCOPE_SITELOCAL	0x05
#define IPV6_ADDR_SCOPE_ORGLOCAL	0x08
#define IPV6_ADDR_SCOPE_GLOBAL		0x0e

130 131 132 133 134 135 136 137 138 139
/*
 *	Addr flags
 */
#define IPV6_ADDR_MC_FLAG_TRANSIENT(a)	\
	((a)->s6_addr[1] & 0x10)
#define IPV6_ADDR_MC_FLAG_PREFIX(a)	\
	((a)->s6_addr[1] & 0x20)
#define IPV6_ADDR_MC_FLAG_RENDEZVOUS(a)	\
	((a)->s6_addr[1] & 0x40)

L
Linus Torvalds 已提交
140 141 142 143 144
/*
 *	fragmentation header
 */

struct frag_hdr {
A
Al Viro 已提交
145 146 147 148
	__u8	nexthdr;
	__u8	reserved;
	__be16	frag_off;
	__be32	identification;
L
Linus Torvalds 已提交
149 150
};

151 152
#define	IP6_MF		0x0001
#define	IP6_OFFSET	0xFFF8
L
Linus Torvalds 已提交
153

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
struct ip6_fraglist_iter {
	struct ipv6hdr	*tmp_hdr;
	struct sk_buff	*frag;
	int		offset;
	unsigned int	hlen;
	__be32		frag_id;
	u8		nexthdr;
};

int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
		      u8 nexthdr, __be32 frag_id,
		      struct ip6_fraglist_iter *iter);
void ip6_fraglist_prepare(struct sk_buff *skb, struct ip6_fraglist_iter *iter);

static inline struct sk_buff *ip6_fraglist_next(struct ip6_fraglist_iter *iter)
{
	struct sk_buff *skb = iter->frag;

	iter->frag = skb->next;
	skb_mark_not_on_list(skb);

	return skb;
}

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
struct ip6_frag_state {
	u8		*prevhdr;
	unsigned int	hlen;
	unsigned int	mtu;
	unsigned int	left;
	int		offset;
	int		ptr;
	int		hroom;
	int		troom;
	__be32		frag_id;
	u8		nexthdr;
};

void ip6_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int mtu,
		   unsigned short needed_tailroom, int hdr_room, u8 *prevhdr,
		   u8 nexthdr, __be32 frag_id, struct ip6_frag_state *state);
struct sk_buff *ip6_frag_next(struct sk_buff *skb,
			      struct ip6_frag_state *state);

197 198 199
#define IP6_REPLY_MARK(net, mark) \
	((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0)

L
Linus Torvalds 已提交
200 201 202 203
#include <net/sock.h>

/* sysctls */
extern int sysctl_mld_max_msf;
204
extern int sysctl_mld_qrv;
205

E
Eric Dumazet 已提交
206
#define _DEVINC(net, statname, mod, idev, field)			\
207
({									\
208 209
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
E
Eric Dumazet 已提交
210 211
		mod##SNMP_INC_STATS64((_idev)->stats.statname, (field));\
	mod##SNMP_INC_STATS64((net)->mib.statname##_statistics, (field));\
212
})
213

214
/* per device counters are atomic_long_t */
E
Eric Dumazet 已提交
215
#define _DEVINCATOMIC(net, statname, mod, idev, field)			\
216 217 218 219
({									\
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
		SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
E
Eric Dumazet 已提交
220
	mod##SNMP_INC_STATS((net)->mib.statname##_statistics, (field));\
221 222
})

223 224 225 226 227 228 229 230 231
/* per device and per net counters are atomic_long_t */
#define _DEVINC_ATOMIC_ATOMIC(net, statname, idev, field)		\
({									\
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
		SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
	SNMP_INC_STATS_ATOMIC_LONG((net)->mib.statname##_statistics, (field));\
})

E
Eric Dumazet 已提交
232
#define _DEVADD(net, statname, mod, idev, field, val)			\
233 234 235
({									\
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
E
Eric Dumazet 已提交
236 237
		mod##SNMP_ADD_STATS((_idev)->stats.statname, (field), (val)); \
	mod##SNMP_ADD_STATS((net)->mib.statname##_statistics, (field), (val));\
238 239
})

E
Eric Dumazet 已提交
240
#define _DEVUPD(net, statname, mod, idev, field, val)			\
241 242 243
({									\
	struct inet6_dev *_idev = (idev);				\
	if (likely(_idev != NULL))					\
E
Eric Dumazet 已提交
244 245
		mod##SNMP_UPD_PO_STATS((_idev)->stats.statname, field, (val)); \
	mod##SNMP_UPD_PO_STATS((net)->mib.statname##_statistics, field, (val));\
246 247
})

248 249
/* MIBs */

250
#define IP6_INC_STATS(net, idev,field)		\
E
Eric Dumazet 已提交
251
		_DEVINC(net, ipv6, , idev, field)
E
Eric Dumazet 已提交
252
#define __IP6_INC_STATS(net, idev,field)	\
E
Eric Dumazet 已提交
253
		_DEVINC(net, ipv6, __, idev, field)
254
#define IP6_ADD_STATS(net, idev,field,val)	\
E
Eric Dumazet 已提交
255
		_DEVADD(net, ipv6, , idev, field, val)
E
Eric Dumazet 已提交
256
#define __IP6_ADD_STATS(net, idev,field,val)	\
E
Eric Dumazet 已提交
257
		_DEVADD(net, ipv6, __, idev, field, val)
258
#define IP6_UPD_PO_STATS(net, idev,field,val)   \
E
Eric Dumazet 已提交
259
		_DEVUPD(net, ipv6, , idev, field, val)
260
#define __IP6_UPD_PO_STATS(net, idev,field,val)   \
E
Eric Dumazet 已提交
261
		_DEVUPD(net, ipv6, __, idev, field, val)
262
#define ICMP6_INC_STATS(net, idev, field)	\
263
		_DEVINCATOMIC(net, icmpv6, , idev, field)
E
Eric Dumazet 已提交
264
#define __ICMP6_INC_STATS(net, idev, field)	\
E
Eric Dumazet 已提交
265
		_DEVINCATOMIC(net, icmpv6, __, idev, field)
266 267

#define ICMP6MSGOUT_INC_STATS(net, idev, field)		\
268
	_DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256)
269
#define ICMP6MSGIN_INC_STATS(net, idev, field)	\
270
	_DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field)
271

E
Eric Dumazet 已提交
272
struct ip6_ra_chain {
L
Linus Torvalds 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286
	struct ip6_ra_chain	*next;
	struct sock		*sk;
	int			sel;
	void			(*destructor)(struct sock *);
};

extern struct ip6_ra_chain	*ip6_ra_chain;
extern rwlock_t ip6_ra_lock;

/*
   This structure is prepared by protocol, when parsing
   ancillary data and passed to IPv6.
 */

E
Eric Dumazet 已提交
287
struct ipv6_txoptions {
288
	refcount_t		refcnt;
L
Linus Torvalds 已提交
289 290 291 292 293 294 295 296 297 298 299 300
	/* Length of this structure */
	int			tot_len;

	/* length of extension headers   */

	__u16			opt_flen;	/* after fragment hdr */
	__u16			opt_nflen;	/* before fragment hdr */

	struct ipv6_opt_hdr	*hopopt;
	struct ipv6_opt_hdr	*dst0opt;
	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
	struct ipv6_opt_hdr	*dst1opt;
301
	struct rcu_head		rcu;
L
Linus Torvalds 已提交
302 303 304
	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};

305 306 307 308 309 310 311
/* flowlabel_reflect sysctl values */
enum flowlabel_reflect {
	FLOWLABEL_REFLECT_ESTABLISHED		= 1,
	FLOWLABEL_REFLECT_TCP_RESET		= 2,
	FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES	= 4,
};

E
Eric Dumazet 已提交
312
struct ip6_flowlabel {
313
	struct ip6_flowlabel __rcu *next;
A
Al Viro 已提交
314
	__be32			label;
315
	atomic_t		users;
L
Linus Torvalds 已提交
316 317 318
	struct in6_addr		dst;
	struct ipv6_txoptions	*opt;
	unsigned long		linger;
319
	struct rcu_head		rcu;
L
Linus Torvalds 已提交
320
	u8			share;
321 322 323 324
	union {
		struct pid *pid;
		kuid_t uid;
	} owner;
L
Linus Torvalds 已提交
325 326
	unsigned long		lastuse;
	unsigned long		expires;
327
	struct net		*fl_net;
L
Linus Torvalds 已提交
328 329
};

T
Tom Herbert 已提交
330 331 332 333
#define IPV6_FLOWINFO_MASK		cpu_to_be32(0x0FFFFFFF)
#define IPV6_FLOWLABEL_MASK		cpu_to_be32(0x000FFFFF)
#define IPV6_FLOWLABEL_STATELESS_FLAG	cpu_to_be32(0x00080000)

334
#define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK)
335
#define IPV6_TCLASS_SHIFT	20
L
Linus Torvalds 已提交
336

E
Eric Dumazet 已提交
337
struct ipv6_fl_socklist {
338 339 340
	struct ipv6_fl_socklist	__rcu	*next;
	struct ip6_flowlabel		*fl;
	struct rcu_head			rcu;
L
Linus Torvalds 已提交
341 342
};

W
Wei Wang 已提交
343
struct ipcm6_cookie {
344
	struct sockcm_cookie sockc;
W
Wei Wang 已提交
345 346 347 348
	__s16 hlimit;
	__s16 tclass;
	__s8  dontfrag;
	struct ipv6_txoptions *opt;
349
	__u16 gso_size;
W
Wei Wang 已提交
350 351
};

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
static inline void ipcm6_init(struct ipcm6_cookie *ipc6)
{
	*ipc6 = (struct ipcm6_cookie) {
		.hlimit = -1,
		.tclass = -1,
		.dontfrag = -1,
	};
}

static inline void ipcm6_init_sk(struct ipcm6_cookie *ipc6,
				 const struct ipv6_pinfo *np)
{
	*ipc6 = (struct ipcm6_cookie) {
		.hlimit = -1,
		.tclass = np->tclass,
		.dontfrag = np->dontfrag,
	};
}

371 372 373 374 375 376
static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
{
	struct ipv6_txoptions *opt;

	rcu_read_lock();
	opt = rcu_dereference(np->opt);
377
	if (opt) {
378
		if (!refcount_inc_not_zero(&opt->refcnt))
379 380 381 382
			opt = NULL;
		else
			opt = rcu_pointer_handoff(opt);
	}
383 384 385 386 387 388
	rcu_read_unlock();
	return opt;
}

static inline void txopt_put(struct ipv6_txoptions *opt)
{
389
	if (opt && refcount_dec_and_test(&opt->refcnt))
390 391 392
		kfree_rcu(opt, rcu);
}

393 394 395 396 397 398 399 400 401 402 403 404
struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label);

extern struct static_key_false_deferred ipv6_flowlabel_exclusive;
static inline struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk,
						    __be32 label)
{
	if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key))
		return __fl6_sock_lookup(sk, label) ? : ERR_PTR(-ENOENT);

	return NULL;
}

405 406 407 408
struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
					 struct ip6_flowlabel *fl,
					 struct ipv6_txoptions *fopt);
void fl6_free_socklist(struct sock *sk);
409
int ipv6_flowlabel_opt(struct sock *sk, sockptr_t optval, int optlen);
410 411
int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
			   int flags);
412 413
int ip6_flowlabel_init(void);
void ip6_flowlabel_cleanup(void);
414
bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np);
L
Linus Torvalds 已提交
415 416 417 418 419 420 421

static inline void fl6_sock_release(struct ip6_flowlabel *fl)
{
	if (fl)
		atomic_dec(&fl->users);
}

422
void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info);
423

424 425
void icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
				struct icmp6hdr *thdr, int len);
426

427
int ip6_ra_control(struct sock *sk, int sel);
L
Linus Torvalds 已提交
428

429
int ipv6_parse_hopopts(struct sk_buff *skb);
L
Linus Torvalds 已提交
430

431 432 433 434 435
struct ipv6_txoptions *ipv6_dup_options(struct sock *sk,
					struct ipv6_txoptions *opt);
struct ipv6_txoptions *ipv6_renew_options(struct sock *sk,
					  struct ipv6_txoptions *opt,
					  int newtype,
436
					  struct ipv6_opt_hdr *newopt);
437 438
struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
					  struct ipv6_txoptions *opt);
L
Linus Torvalds 已提交
439

440 441
bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb,
		       const struct inet6_skb_parm *opt);
442 443
struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
					   struct ipv6_txoptions *opt);
444

445 446 447 448 449 450 451 452 453
static inline bool ipv6_accept_ra(struct inet6_dev *idev)
{
	/* If forwarding is enabled, RA are not accepted unless the special
	 * hybrid mode (accept_ra=2) is enabled.
	 */
	return idev->cnf.forwarding ? idev->cnf.accept_ra == 2 :
	    idev->cnf.accept_ra;
}

454 455
#define IPV6_FRAG_HIGH_THRESH	(4 * 1024*1024)	/* 4194304 */
#define IPV6_FRAG_LOW_THRESH	(3 * 1024*1024)	/* 3145728 */
456
#define IPV6_FRAG_TIMEOUT	(60 * HZ)	/* 60 seconds */
L
Linus Torvalds 已提交
457

458
int __ipv6_addr_type(const struct in6_addr *addr);
459 460 461 462
static inline int ipv6_addr_type(const struct in6_addr *addr)
{
	return __ipv6_addr_type(addr) & 0xffff;
}
L
Linus Torvalds 已提交
463 464 465

static inline int ipv6_addr_scope(const struct in6_addr *addr)
{
466 467 468 469 470
	return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
}

static inline int __ipv6_addr_src_scope(int type)
{
E
Eric Dumazet 已提交
471
	return (type == IPV6_ADDR_ANY) ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16);
472 473 474 475 476
}

static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
{
	return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
L
Linus Torvalds 已提交
477 478
}

479 480 481 482 483 484 485 486 487 488 489 490
static inline bool __ipv6_addr_needs_scope_id(int type)
{
	return type & IPV6_ADDR_LINKLOCAL ||
	       (type & IPV6_ADDR_MULTICAST &&
		(type & (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)));
}

static inline __u32 ipv6_iface_scope_id(const struct in6_addr *addr, int iface)
{
	return __ipv6_addr_needs_scope_id(__ipv6_addr_type(addr)) ? iface : 0;
}

L
Linus Torvalds 已提交
491 492
static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
{
493
	return memcmp(a1, a2, sizeof(struct in6_addr));
L
Linus Torvalds 已提交
494 495
}

496
static inline bool
497 498 499
ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
		     const struct in6_addr *a2)
{
500 501 502 503 504 505 506 507
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
	const unsigned long *ul1 = (const unsigned long *)a1;
	const unsigned long *ulm = (const unsigned long *)m;
	const unsigned long *ul2 = (const unsigned long *)a2;

	return !!(((ul1[0] ^ ul2[0]) & ulm[0]) |
		  ((ul1[1] ^ ul2[1]) & ulm[1]));
#else
E
Eric Dumazet 已提交
508 509 510 511
	return !!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) |
		  ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) |
		  ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) |
		  ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]));
512
#endif
513 514
}

S
Stephen Hemminger 已提交
515
static inline void ipv6_addr_prefix(struct in6_addr *pfx,
L
Linus Torvalds 已提交
516 517 518 519 520 521 522
				    const struct in6_addr *addr,
				    int plen)
{
	/* caller must guarantee 0 <= plen <= 128 */
	int o = plen >> 3,
	    b = plen & 0x7;

523
	memset(pfx->s6_addr, 0, sizeof(pfx->s6_addr));
L
Linus Torvalds 已提交
524
	memcpy(pfx->s6_addr, addr, o);
525
	if (b != 0)
L
Linus Torvalds 已提交
526 527 528
		pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
}

A
Alexander Aring 已提交
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
static inline void ipv6_addr_prefix_copy(struct in6_addr *addr,
					 const struct in6_addr *pfx,
					 int plen)
{
	/* caller must guarantee 0 <= plen <= 128 */
	int o = plen >> 3,
	    b = plen & 0x7;

	memcpy(addr->s6_addr, pfx, o);
	if (b != 0) {
		addr->s6_addr[o] &= ~(0xff00 >> b);
		addr->s6_addr[o] |= (pfx->s6_addr[o] & (0xff00 >> b));
	}
}

544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
static inline void __ipv6_addr_set_half(__be32 *addr,
					__be32 wh, __be32 wl)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
#if defined(__BIG_ENDIAN)
	if (__builtin_constant_p(wh) && __builtin_constant_p(wl)) {
		*(__force u64 *)addr = ((__force u64)(wh) << 32 | (__force u64)(wl));
		return;
	}
#elif defined(__LITTLE_ENDIAN)
	if (__builtin_constant_p(wl) && __builtin_constant_p(wh)) {
		*(__force u64 *)addr = ((__force u64)(wl) << 32 | (__force u64)(wh));
		return;
	}
#endif
#endif
	addr[0] = wh;
	addr[1] = wl;
}

S
Stephen Hemminger 已提交
564
static inline void ipv6_addr_set(struct in6_addr *addr,
A
Al Viro 已提交
565 566
				     __be32 w1, __be32 w2,
				     __be32 w3, __be32 w4)
L
Linus Torvalds 已提交
567
{
568 569
	__ipv6_addr_set_half(&addr->s6_addr32[0], w1, w2);
	__ipv6_addr_set_half(&addr->s6_addr32[2], w3, w4);
L
Linus Torvalds 已提交
570 571
}

E
Eric Dumazet 已提交
572 573
static inline bool ipv6_addr_equal(const struct in6_addr *a1,
				   const struct in6_addr *a2)
L
Linus Torvalds 已提交
574
{
575 576 577 578 579 580
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
	const unsigned long *ul1 = (const unsigned long *)a1;
	const unsigned long *ul2 = (const unsigned long *)a2;

	return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL;
#else
E
Eric Dumazet 已提交
581 582 583 584
	return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
		(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
		(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
		(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
585
#endif
L
Linus Torvalds 已提交
586 587
}

588 589 590 591 592
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
static inline bool __ipv6_prefix_equal64_half(const __be64 *a1,
					      const __be64 *a2,
					      unsigned int len)
{
593
	if (len && ((*a1 ^ *a2) & cpu_to_be64((~0UL) << (64 - len))))
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
		return false;
	return true;
}

static inline bool ipv6_prefix_equal(const struct in6_addr *addr1,
				     const struct in6_addr *addr2,
				     unsigned int prefixlen)
{
	const __be64 *a1 = (const __be64 *)addr1;
	const __be64 *a2 = (const __be64 *)addr2;

	if (prefixlen >= 64) {
		if (a1[0] ^ a2[0])
			return false;
		return __ipv6_prefix_equal64_half(a1 + 1, a2 + 1, prefixlen - 64);
	}
	return __ipv6_prefix_equal64_half(a1, a2, prefixlen);
}
#else
613 614 615
static inline bool ipv6_prefix_equal(const struct in6_addr *addr1,
				     const struct in6_addr *addr2,
				     unsigned int prefixlen)
L
Linus Torvalds 已提交
616
{
617 618
	const __be32 *a1 = addr1->s6_addr32;
	const __be32 *a2 = addr2->s6_addr32;
619
	unsigned int pdw, pbi;
L
Linus Torvalds 已提交
620 621 622 623

	/* check complete u32 in prefix */
	pdw = prefixlen >> 5;
	if (pdw && memcmp(a1, a2, pdw << 2))
E
Eric Dumazet 已提交
624
		return false;
L
Linus Torvalds 已提交
625 626 627 628

	/* check incomplete u32 in prefix */
	pbi = prefixlen & 0x1f;
	if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
E
Eric Dumazet 已提交
629
		return false;
L
Linus Torvalds 已提交
630

E
Eric Dumazet 已提交
631
	return true;
L
Linus Torvalds 已提交
632
}
633
#endif
L
Linus Torvalds 已提交
634

E
Eric Dumazet 已提交
635
static inline bool ipv6_addr_any(const struct in6_addr *a)
L
Linus Torvalds 已提交
636
{
637 638 639 640 641
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
	const unsigned long *ul = (const unsigned long *)a;

	return (ul[0] | ul[1]) == 0UL;
#else
E
Eric Dumazet 已提交
642 643
	return (a->s6_addr32[0] | a->s6_addr32[1] |
		a->s6_addr32[2] | a->s6_addr32[3]) == 0;
644
#endif
L
Linus Torvalds 已提交
645 646
}

E
Eric Dumazet 已提交
647 648 649 650 651 652 653 654 655 656 657 658 659
static inline u32 ipv6_addr_hash(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
	const unsigned long *ul = (const unsigned long *)a;
	unsigned long x = ul[0] ^ ul[1];

	return (u32)(x ^ (x >> 32));
#else
	return (__force u32)(a->s6_addr32[0] ^ a->s6_addr32[1] ^
			     a->s6_addr32[2] ^ a->s6_addr32[3]);
#endif
}

E
Eric Dumazet 已提交
660
/* more secured version of ipv6_addr_hash() */
661
static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
E
Eric Dumazet 已提交
662 663 664 665 666 667
{
	u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];

	return jhash_3words(v,
			    (__force u32)a->s6_addr32[2],
			    (__force u32)a->s6_addr32[3],
668
			    initval);
E
Eric Dumazet 已提交
669 670
}

E
Eric Dumazet 已提交
671
static inline bool ipv6_addr_loopback(const struct in6_addr *a)
672
{
673
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
674
	const __be64 *be = (const __be64 *)a;
675

676
	return (be[0] | (be[1] ^ cpu_to_be64(1))) == 0UL;
677
#else
E
Eric Dumazet 已提交
678
	return (a->s6_addr32[0] | a->s6_addr32[1] |
679
		a->s6_addr32[2] | (a->s6_addr32[3] ^ cpu_to_be32(1))) == 0;
680
#endif
681 682
}

683 684 685 686
/*
 * Note that we must __force cast these to unsigned long to make sparse happy,
 * since all of the endian-annotated types are fixed size regardless of arch.
 */
E
Eric Dumazet 已提交
687
static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
B
Brian Haley 已提交
688
{
689 690
	return (
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
691
		*(unsigned long *)a |
692
#else
693
		(__force unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
694
#endif
695 696
		(__force unsigned long)(a->s6_addr32[2] ^
					cpu_to_be32(0x0000ffff))) == 0UL;
B
Brian Haley 已提交
697 698
}

699 700 701 702 703
static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a)
{
	return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]);
}

704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
static inline u32 ipv6_portaddr_hash(const struct net *net,
				     const struct in6_addr *addr6,
				     unsigned int port)
{
	unsigned int hash, mix = net_hash_mix(net);

	if (ipv6_addr_any(addr6))
		hash = jhash_1word(0, mix);
	else if (ipv6_addr_v4mapped(addr6))
		hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
	else
		hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);

	return hash ^ port;
}

720 721 722 723
/*
 * Check for a RFC 4843 ORCHID address
 * (Overlay Routable Cryptographic Hash Identifiers)
 */
E
Eric Dumazet 已提交
724
static inline bool ipv6_addr_orchid(const struct in6_addr *a)
725
{
E
Eric Dumazet 已提交
726
	return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
727 728
}

729 730 731 732 733
static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
{
	return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
}

734 735 736 737 738 739 740 741 742
static inline void ipv6_addr_set_v4mapped(const __be32 addr,
					  struct in6_addr *v4mapped)
{
	ipv6_addr_set(v4mapped,
			0, 0,
			htonl(0x0000FFFF),
			addr);
}

743 744 745 746
/*
 * find the first different bit between two addresses
 * length of address must be a multiple of 32bits
 */
747
static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
748
{
749
	const __be32 *a1 = token1, *a2 = token2;
750 751 752 753 754
	int i;

	addrlen >>= 2;

	for (i = 0; i < addrlen; i++) {
755 756
		__be32 xb = a1[i] ^ a2[i];
		if (xb)
757
			return i * 32 + 31 - __fls(ntohl(xb));
758 759 760
	}

	/*
S
Stephen Hemminger 已提交
761
	 *	we should *never* get to this point since that
762 763 764 765 766 767 768 769 770 771 772 773 774 775
	 *	would mean the addrs are equal
	 *
	 *	However, we do get to it 8) And exacly, when
	 *	addresses are equal 8)
	 *
	 *	ip route add 1111::/128 via ...
	 *	ip route add 1111::/64 via ...
	 *	and we are here.
	 *
	 *	Ideally, this function should stop comparison
	 *	at prefix length. It does not, but it is still OK,
	 *	if returned value is greater than prefix length.
	 *					--ANK (980803)
	 */
E
Eric Dumazet 已提交
776
	return addrlen << 5;
777 778
}

779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
static inline int __ipv6_addr_diff64(const void *token1, const void *token2, int addrlen)
{
	const __be64 *a1 = token1, *a2 = token2;
	int i;

	addrlen >>= 3;

	for (i = 0; i < addrlen; i++) {
		__be64 xb = a1[i] ^ a2[i];
		if (xb)
			return i * 64 + 63 - __fls(be64_to_cpu(xb));
	}

	return addrlen << 6;
}
#endif

static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
	if (__builtin_constant_p(addrlen) && !(addrlen & 7))
		return __ipv6_addr_diff64(token1, token2, addrlen);
#endif
	return __ipv6_addr_diff32(token1, token2, addrlen);
}

806 807 808 809 810
static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
{
	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
}

811 812 813
__be32 ipv6_select_ident(struct net *net,
			 const struct in6_addr *daddr,
			 const struct in6_addr *saddr);
814
__be32 ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
815

816
int ip6_dst_hoplimit(struct dst_entry *dst);
817

818 819 820 821 822 823 824 825 826 827 828 829 830 831
static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
				      struct dst_entry *dst)
{
	int hlimit;

	if (ipv6_addr_is_multicast(&fl6->daddr))
		hlimit = np->mcast_hops;
	else
		hlimit = np->hop_limit;
	if (hlimit < 0)
		hlimit = ip6_dst_hoplimit(dst);
	return hlimit;
}

832 833 834 835 836 837 838 839 840 841 842 843 844 845
/* copy IPv6 saddr & daddr to flow_keys, possibly using 64bit load/store
 * Equivalent to :	flow->v6addrs.src = iph->saddr;
 *			flow->v6addrs.dst = iph->daddr;
 */
static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,
					    const struct ipv6hdr *iph)
{
	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) !=
		     offsetof(typeof(flow->addrs), v6addrs.src) +
		     sizeof(flow->addrs.v6addrs.src));
	memcpy(&flow->addrs.v6addrs, &iph->saddr, sizeof(flow->addrs.v6addrs));
	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
}

846
#if IS_ENABLED(CONFIG_IPV6)
847

848 849 850 851 852 853 854
static inline bool ipv6_can_nonlocal_bind(struct net *net,
					  struct inet_sock *inet)
{
	return net->ipv6.sysctl.ip_nonlocal_bind ||
		inet->freebind || inet->transparent;
}

855 856 857 858 859 860 861 862
/* Sysctl settings for net ipv6.auto_flowlabels */
#define IP6_AUTO_FLOW_LABEL_OFF		0
#define IP6_AUTO_FLOW_LABEL_OPTOUT	1
#define IP6_AUTO_FLOW_LABEL_OPTIN	2
#define IP6_AUTO_FLOW_LABEL_FORCED	3

#define IP6_AUTO_FLOW_LABEL_MAX		IP6_AUTO_FLOW_LABEL_FORCED

863
#define IP6_DEFAULT_AUTO_FLOW_LABELS	IP6_AUTO_FLOW_LABEL_OPTOUT
864

865
static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
866 867
					__be32 flowlabel, bool autolabel,
					struct flowi6 *fl6)
868
{
869
	u32 hash;
870

871 872 873 874 875
	/* @flowlabel may include more than a flow label, eg, the traffic class.
	 * Here we want only the flow label value.
	 */
	flowlabel &= IPV6_FLOWLABEL_MASK;

876 877 878 879 880
	if (flowlabel ||
	    net->ipv6.sysctl.auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF ||
	    (!autolabel &&
	     net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))
		return flowlabel;
881

882
	hash = skb_get_hash_flowi6(skb, fl6);
883

884 885 886 887
	/* Since this is being sent on the wire obfuscate hash a bit
	 * to minimize possbility that any useful information to an
	 * attacker is leaked. Only lower 20 bits are relevant.
	 */
888
	hash = rol32(hash, 16);
T
Tom Herbert 已提交
889

890 891 892 893
	flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;

	if (net->ipv6.sysctl.flowlabel_state_ranges)
		flowlabel |= IPV6_FLOWLABEL_STATELESS_FLAG;
894 895 896

	return flowlabel;
}
897 898 899 900 901 902 903 904 905 906 907 908 909

static inline int ip6_default_np_autolabel(struct net *net)
{
	switch (net->ipv6.sysctl.auto_flowlabels) {
	case IP6_AUTO_FLOW_LABEL_OFF:
	case IP6_AUTO_FLOW_LABEL_OPTIN:
	default:
		return 0;
	case IP6_AUTO_FLOW_LABEL_OPTOUT:
	case IP6_AUTO_FLOW_LABEL_FORCED:
		return 1;
	}
}
910 911
#else
static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
912 913
					__be32 flowlabel, bool autolabel,
					struct flowi6 *fl6)
914 915 916
{
	return flowlabel;
}
917 918 919 920
static inline int ip6_default_np_autolabel(struct net *net)
{
	return 0;
}
921 922
#endif

923 924 925 926 927 928 929 930 931 932 933
#if IS_ENABLED(CONFIG_IPV6)
static inline int ip6_multipath_hash_policy(const struct net *net)
{
	return net->ipv6.sysctl.multipath_hash_policy;
}
#else
static inline int ip6_multipath_hash_policy(const struct net *net)
{
	return 0;
}
#endif
934

935 936 937 938 939 940
/*
 *	Header manipulation
 */
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
				__be32 flowlabel)
{
941
	*(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
942 943
}

944 945 946 947 948
static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
{
	return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
}

F
Florent Fourcot 已提交
949 950 951 952 953
static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
{
	return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
}

954 955 956 957
static inline u8 ip6_tclass(__be32 flowinfo)
{
	return ntohl(flowinfo & IPV6_TCLASS_MASK) >> IPV6_TCLASS_SHIFT;
}
958 959 960 961 962 963

static inline __be32 ip6_make_flowinfo(unsigned int tclass, __be32 flowlabel)
{
	return htonl(tclass << IPV6_TCLASS_SHIFT) | flowlabel;
}

964 965 966 967 968
static inline __be32 flowi6_get_flowlabel(const struct flowi6 *fl6)
{
	return fl6->flowlabel & IPV6_FLOWLABEL_MASK;
}

L
Linus Torvalds 已提交
969 970 971 972 973 974 975 976
/*
 *	Prototypes exported by ipv6
 */

/*
 *	rcv function (called from netdevice level)
 */

977 978
int ipv6_rcv(struct sk_buff *skb, struct net_device *dev,
	     struct packet_type *pt, struct net_device *orig_dev);
979 980
void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
		   struct net_device *orig_dev);
L
Linus Torvalds 已提交
981

982
int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
983

L
Linus Torvalds 已提交
984 985 986
/*
 *	upper-layer output functions
 */
987
int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
988
	     __u32 mark, struct ipv6_txoptions *opt, int tclass, u32 priority);
989 990 991 992 993 994

int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);

int ip6_append_data(struct sock *sk,
		    int getfrag(void *from, char *to, int offset, int len,
				int odd, struct sk_buff *skb),
W
Wei Wang 已提交
995 996
		    void *from, int length, int transhdrlen,
		    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
997
		    struct rt6_info *rt, unsigned int flags);
998 999 1000 1001 1002

int ip6_push_pending_frames(struct sock *sk);

void ip6_flush_pending_frames(struct sock *sk);

V
Vlad Yasevich 已提交
1003 1004 1005 1006 1007 1008 1009 1010 1011
int ip6_send_skb(struct sk_buff *skb);

struct sk_buff *__ip6_make_skb(struct sock *sk, struct sk_buff_head *queue,
			       struct inet_cork_full *cork,
			       struct inet6_cork *v6_cork);
struct sk_buff *ip6_make_skb(struct sock *sk,
			     int getfrag(void *from, char *to, int offset,
					 int len, int odd, struct sk_buff *skb),
			     void *from, int length, int transhdrlen,
W
Wei Wang 已提交
1012 1013
			     struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
			     struct rt6_info *rt, unsigned int flags,
1014
			     struct inet_cork_full *cork);
V
Vlad Yasevich 已提交
1015 1016 1017 1018 1019 1020 1021

static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
{
	return __ip6_make_skb(sk, &sk->sk_write_queue, &inet_sk(sk)->cork,
			      &inet6_sk(sk)->cork);
}

1022 1023
int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
		   struct flowi6 *fl6);
1024
struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
1025
				      const struct in6_addr *final_dst);
1026
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1027 1028
					 const struct in6_addr *final_dst,
					 bool connected);
1029 1030 1031 1032 1033 1034
struct dst_entry *ip6_dst_lookup_tunnel(struct sk_buff *skb,
					struct net_device *dev,
					struct net *net, struct socket *sock,
					struct in6_addr *saddr,
					const struct ip_tunnel_info *info,
					u8 protocol, bool use_cache);
1035 1036
struct dst_entry *ip6_blackhole_route(struct net *net,
				      struct dst_entry *orig_dst);
L
Linus Torvalds 已提交
1037 1038 1039 1040 1041

/*
 *	skb processing functions
 */

E
Eric W. Biederman 已提交
1042
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
1043 1044 1045
int ip6_forward(struct sk_buff *skb);
int ip6_input(struct sk_buff *skb);
int ip6_mc_input(struct sk_buff *skb);
1046 1047
void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
			      bool have_final);
L
Linus Torvalds 已提交
1048

1049
int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
1050
int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
H
Herbert Xu 已提交
1051

L
Linus Torvalds 已提交
1052 1053 1054 1055
/*
 *	Extension header (options) processing
 */

1056
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
1057 1058
			  u8 *proto, struct in6_addr **daddr_p,
			  struct in6_addr *saddr);
1059 1060
void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
			 u8 *proto);
L
Linus Torvalds 已提交
1061

1062 1063
int ipv6_skip_exthdr(const struct sk_buff *, int start, u8 *nexthdrp,
		     __be16 *frag_offp);
L
Linus Torvalds 已提交
1064

1065
bool ipv6_ext_hdr(u8 nexthdr);
L
Linus Torvalds 已提交
1066

1067
enum {
1068 1069 1070
	IP6_FH_F_FRAG		= (1 << 0),
	IP6_FH_F_AUTH		= (1 << 1),
	IP6_FH_F_SKIP_RH	= (1 << 2),
1071 1072 1073
};

/* find specified header and get offset to it */
1074 1075
int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target,
		  unsigned short *fragoff, int *fragflg);
1076

1077
int ipv6_find_tlv(const struct sk_buff *skb, int offset, int type);
1078

1079 1080 1081
struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
				const struct ipv6_txoptions *opt,
				struct in6_addr *orig);
1082

L
Linus Torvalds 已提交
1083 1084 1085 1086
/*
 *	socket options (ipv6_sockglue.c)
 */

1087 1088
int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
		    unsigned int optlen);
1089 1090 1091
int ipv6_getsockopt(struct sock *sk, int level, int optname,
		    char __user *optval, int __user *optlen);

1092 1093
int __ip6_datagram_connect(struct sock *sk, struct sockaddr *addr,
			   int addr_len);
1094
int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
1095 1096
int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr,
				 int addr_len);
1097
int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr);
1098
void ip6_datagram_release_cb(struct sock *sk);
1099

1100 1101 1102 1103
int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
		    int *addr_len);
int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
		     int *addr_len);
1104 1105 1106 1107 1108 1109 1110
void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
		     u32 info, u8 *payload);
void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);

int inet6_release(struct socket *sock);
int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
1111
int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
1112 1113
		  int peer);
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
1114 1115
int inet6_compat_ioctl(struct socket *sock, unsigned int cmd,
		unsigned long arg);
1116 1117

int inet6_hash_connect(struct inet_timewait_death_row *death_row,
1118
			      struct sock *sk);
1119 1120 1121
int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size);
int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
		  int flags);
1122

L
Linus Torvalds 已提交
1123 1124 1125
/*
 * reassembly.c
 */
1126 1127
extern const struct proto_ops inet6_stream_ops;
extern const struct proto_ops inet6_dgram_ops;
1128
extern const struct proto_ops inet6_sockraw_ops;
1129

1130 1131 1132
struct group_source_req;
struct group_filter;

1133 1134
int ip6_mc_source(int add, int omode, struct sock *sk,
		  struct group_source_req *pgsr);
1135 1136
int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
		  struct sockaddr_storage *list);
1137
int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
1138
		  struct sockaddr_storage __user *p);
1139 1140

#ifdef CONFIG_PROC_FS
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
int ac6_proc_init(struct net *net);
void ac6_proc_exit(struct net *net);
int raw6_proc_init(void);
void raw6_proc_exit(void);
int tcp6_proc_init(struct net *net);
void tcp6_proc_exit(struct net *net);
int udp6_proc_init(struct net *net);
void udp6_proc_exit(struct net *net);
int udplite6_proc_init(void);
void udplite6_proc_exit(void);
int ipv6_misc_proc_init(void);
void ipv6_misc_proc_exit(void);
int snmp6_register_dev(struct inet6_dev *idev);
int snmp6_unregister_dev(struct inet6_dev *idev);
1155

1156
#else
1157 1158 1159 1160
static inline int ac6_proc_init(struct net *net) { return 0; }
static inline void ac6_proc_exit(struct net *net) { }
static inline int snmp6_register_dev(struct inet6_dev *idev) { return 0; }
static inline int snmp6_unregister_dev(struct inet6_dev *idev) { return 0; }
1161
#endif
L
Linus Torvalds 已提交
1162

1163
#ifdef CONFIG_SYSCTL
1164 1165 1166 1167
struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
struct ctl_table *ipv6_route_sysctl_init(struct net *net);
int ipv6_sysctl_register(void);
void ipv6_sysctl_unregister(void);
1168
#endif
L
Linus Torvalds 已提交
1169

1170 1171
int ipv6_sock_mc_join(struct sock *sk, int ifindex,
		      const struct in6_addr *addr);
1172 1173
int ipv6_sock_mc_join_ssm(struct sock *sk, int ifindex,
			  const struct in6_addr *addr, unsigned int mode);
1174 1175
int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
		      const struct in6_addr *addr);
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186

static inline int ip6_sock_set_v6only(struct sock *sk)
{
	if (inet_sk(sk)->inet_num)
		return -EINVAL;
	lock_sock(sk);
	sk->sk_ipv6only = true;
	release_sock(sk);
	return 0;
}

1187 1188 1189 1190 1191 1192 1193
static inline void ip6_sock_set_recverr(struct sock *sk)
{
	lock_sock(sk);
	inet6_sk(sk)->recverr = true;
	release_sock(sk);
}

1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
static inline int __ip6_sock_set_addr_preferences(struct sock *sk, int val)
{
	unsigned int pref = 0;
	unsigned int prefmask = ~0;

	/* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */
	switch (val & (IPV6_PREFER_SRC_PUBLIC |
		       IPV6_PREFER_SRC_TMP |
		       IPV6_PREFER_SRC_PUBTMP_DEFAULT)) {
	case IPV6_PREFER_SRC_PUBLIC:
		pref |= IPV6_PREFER_SRC_PUBLIC;
		prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
			      IPV6_PREFER_SRC_TMP);
		break;
	case IPV6_PREFER_SRC_TMP:
		pref |= IPV6_PREFER_SRC_TMP;
		prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
			      IPV6_PREFER_SRC_TMP);
		break;
	case IPV6_PREFER_SRC_PUBTMP_DEFAULT:
		prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
			      IPV6_PREFER_SRC_TMP);
		break;
	case 0:
		break;
	default:
		return -EINVAL;
	}

	/* check HOME/COA conflicts */
	switch (val & (IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_COA)) {
	case IPV6_PREFER_SRC_HOME:
		prefmask &= ~IPV6_PREFER_SRC_COA;
		break;
	case IPV6_PREFER_SRC_COA:
		pref |= IPV6_PREFER_SRC_COA;
		break;
	case 0:
		break;
	default:
		return -EINVAL;
	}

	/* check CGA/NONCGA conflicts */
	switch (val & (IPV6_PREFER_SRC_CGA|IPV6_PREFER_SRC_NONCGA)) {
	case IPV6_PREFER_SRC_CGA:
	case IPV6_PREFER_SRC_NONCGA:
	case 0:
		break;
	default:
		return -EINVAL;
	}

	inet6_sk(sk)->srcprefs = (inet6_sk(sk)->srcprefs & prefmask) | pref;
	return 0;
}

static inline int ip6_sock_set_addr_preferences(struct sock *sk, bool val)
{
	int ret;

	lock_sock(sk);
	ret = __ip6_sock_set_addr_preferences(sk, val);
	release_sock(sk);
	return ret;
}

1261 1262 1263 1264 1265 1266 1267
static inline void ip6_sock_set_recvpktinfo(struct sock *sk)
{
	lock_sock(sk);
	inet6_sk(sk)->rxopt.bits.rxinfo = true;
	release_sock(sk);
}

1268
#endif /* _NET_IPV6_H */