| 1 |
|
| 2 | |
| 3 | * Linux INET6 implementation
|
| 4 | *
|
| 5 | * Authors:
|
| 6 | * Pedro Roque <[email protected]>
|
| 7 |
|
| 8 |
|
| 9 | #ifndef _NET_IPV6_H
|
| 10 | #define _NET_IPV6_H
|
| 11 |
|
| 12 | #include <linux/ipv6.h>
|
| 13 | #include <linux/hardirq.h>
|
| 14 | #include <linux/jhash.h>
|
| 15 | #include <linux/refcount.h>
|
| 16 | #include <linux/jump_label_ratelimit.h>
|
| 17 | #include <net/if_inet6.h>
|
| 18 | #include <net/flow.h>
|
| 19 | #include <net/flow_dissector.h>
|
| 20 | #include <net/inet_dscp.h>
|
| 21 | #include <net/snmp.h>
|
| 22 | #include <net/netns/hash.h>
|
| 23 |
|
| 24 | struct ip_tunnel_info;
|
| 25 |
|
| 26 | #define SIN6_LEN_RFC2133 24
|
| 27 |
|
| 28 | |
| 29 | * NextHeader field of IPv6 header
|
| 30 |
|
| 31 |
|
| 32 | #define NEXTHDR_HOP 0
|
| 33 | #define NEXTHDR_IPV4 4
|
| 34 | #define NEXTHDR_TCP 6
|
| 35 | #define NEXTHDR_UDP 17
|
| 36 | #define NEXTHDR_IPV6 41
|
| 37 | #define NEXTHDR_ROUTING 43
|
| 38 | #define NEXTHDR_FRAGMENT 44
|
| 39 | #define NEXTHDR_GRE 47
|
| 40 | #define NEXTHDR_ESP 50
|
| 41 | #define NEXTHDR_AUTH 51
|
| 42 | #define NEXTHDR_ICMP 58
|
| 43 | #define NEXTHDR_NONE 59
|
| 44 | #define NEXTHDR_DEST 60
|
| 45 | #define NEXTHDR_SCTP 132
|
| 46 | #define NEXTHDR_MOBILITY 135
|
| 47 |
|
| 48 | #define NEXTHDR_MAX 255
|
| 49 |
|
| 50 | #define IPV6_DEFAULT_HOPLIMIT 64
|
| 51 | #define IPV6_DEFAULT_MCASTHOPS 1
|
| 52 |
|
| 53 | |
| 54 | *
|
| 55 | * Per RFC8200 there is no limit on the maximum number or lengths of options in
|
| 56 | * Hop-by-Hop or Destination options other then the packet must fit in an MTU.
|
| 57 | * We allow configurable limits in order to mitigate potential denial of
|
| 58 | * service attacks.
|
| 59 | *
|
| 60 | * There are three limits that may be set:
|
| 61 | * - Limit the number of options in a Hop-by-Hop or Destination options
|
| 62 | * extension header
|
| 63 | * - Limit the byte length of a Hop-by-Hop or Destination options extension
|
| 64 | * header
|
| 65 | * - Disallow unknown options
|
| 66 | *
|
| 67 | * The limits are expressed in corresponding sysctls:
|
| 68 | *
|
| 69 | * ipv6.sysctl.max_dst_opts_cnt
|
| 70 | * ipv6.sysctl.max_hbh_opts_cnt
|
| 71 | * ipv6.sysctl.max_dst_opts_len
|
| 72 | * ipv6.sysctl.max_hbh_opts_len
|
| 73 | *
|
| 74 | * max_*_opts_cnt is the number of TLVs that are allowed for Destination
|
| 75 | * options or Hop-by-Hop options. If the number is less than zero then unknown
|
| 76 | * TLVs are disallowed and the number of known options that are allowed is the
|
| 77 | * absolute value. Setting the value to INT_MAX indicates no limit.
|
| 78 | *
|
| 79 | * max_*_opts_len is the length limit in bytes of a Destination or
|
| 80 | * Hop-by-Hop options extension header. Setting the value to INT_MAX
|
| 81 | * indicates no length limit.
|
| 82 | *
|
| 83 | * If a limit is exceeded when processing an extension header the packet is
|
| 84 | * silently discarded.
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 | #define IP6_DEFAULT_MAX_DST_OPTS_CNT 8
|
| 89 | #define IP6_DEFAULT_MAX_HBH_OPTS_CNT 8
|
| 90 | #define IP6_DEFAULT_MAX_DST_OPTS_LEN INT_MAX
|
| 91 | #define IP6_DEFAULT_MAX_HBH_OPTS_LEN INT_MAX
|
| 92 |
|
| 93 |
|
| 94 | #define IP6_MAX_EXT_HDRS_CNT 12
|
| 95 |
|
| 96 | |
| 97 | * Addr type
|
| 98 | *
|
| 99 | * type - unicast | multicast
|
| 100 | * scope - local | site | global
|
| 101 | * v4 - compat
|
| 102 | * v4mapped
|
| 103 | * any
|
| 104 | * loopback
|
| 105 |
|
| 106 |
|
| 107 | #define IPV6_ADDR_ANY 0x0000U
|
| 108 |
|
| 109 | #define IPV6_ADDR_UNICAST 0x0001U
|
| 110 | #define IPV6_ADDR_MULTICAST 0x0002U
|
| 111 |
|
| 112 | #define IPV6_ADDR_LOOPBACK 0x0010U
|
| 113 | #define IPV6_ADDR_LINKLOCAL 0x0020U
|
| 114 | #define IPV6_ADDR_SITELOCAL 0x0040U
|
| 115 |
|
| 116 | #define IPV6_ADDR_COMPATv4 0x0080U
|
| 117 |
|
| 118 | #define IPV6_ADDR_SCOPE_MASK 0x00f0U
|
| 119 |
|
| 120 | #define IPV6_ADDR_MAPPED 0x1000U
|
| 121 |
|
| 122 | |
| 123 | * Addr scopes
|
| 124 |
|
| 125 | #define IPV6_ADDR_MC_SCOPE(a) \
|
| 126 | ((a)->s6_addr[1] & 0x0f)
|
| 127 | #define __IPV6_ADDR_SCOPE_INVALID -1
|
| 128 | #define IPV6_ADDR_SCOPE_NODELOCAL 0x01
|
| 129 | #define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
|
| 130 | #define IPV6_ADDR_SCOPE_SITELOCAL 0x05
|
| 131 | #define IPV6_ADDR_SCOPE_ORGLOCAL 0x08
|
| 132 | #define IPV6_ADDR_SCOPE_GLOBAL 0x0e
|
| 133 |
|
| 134 | |
| 135 | * Addr flags
|
| 136 |
|
| 137 | #define IPV6_ADDR_MC_FLAG_TRANSIENT(a) \
|
| 138 | ((a)->s6_addr[1] & 0x10)
|
| 139 | #define IPV6_ADDR_MC_FLAG_PREFIX(a) \
|
| 140 | ((a)->s6_addr[1] & 0x20)
|
| 141 | #define IPV6_ADDR_MC_FLAG_RENDEZVOUS(a) \
|
| 142 | ((a)->s6_addr[1] & 0x40)
|
| 143 |
|
| 144 | |
| 145 | * fragmentation header
|
| 146 |
|
| 147 |
|
| 148 | struct frag_hdr {
|
| 149 | __u8 nexthdr;
|
| 150 | __u8 reserved;
|
| 151 | __be16 frag_off;
|
| 152 | __be32 identification;
|
| 153 | };
|
| 154 |
|
| 155 | #define IP6_MF 0x0001
|
| 156 | #define IP6_OFFSET 0xFFF8
|
| 157 |
|
| 158 | struct ip6_fraglist_iter {
|
| 159 | struct ipv6hdr *tmp_hdr;
|
| 160 | struct sk_buff *frag;
|
| 161 | int offset;
|
| 162 | unsigned int hlen;
|
| 163 | __be32 frag_id;
|
| 164 | u8 nexthdr;
|
| 165 | };
|
| 166 |
|
| 167 | int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
|
| 168 | u8 nexthdr, __be32 frag_id,
|
| 169 | struct ip6_fraglist_iter *iter);
|
| 170 | void ip6_fraglist_prepare(struct sk_buff *skb, struct ip6_fraglist_iter *iter);
|
| 171 |
|
| 172 | static inline struct sk_buff *ip6_fraglist_next(struct ip6_fraglist_iter *iter)
|
| 173 | {
|
| 174 | struct sk_buff *skb = iter->frag;
|
| 175 |
|
| 176 | iter->frag = skb->next;
|
| 177 | skb_mark_not_on_list(skb);
|
| 178 |
|
| 179 | return skb;
|
| 180 | }
|
| 181 |
|
| 182 | struct ip6_frag_state {
|
| 183 | u8 *prevhdr;
|
| 184 | unsigned int hlen;
|
| 185 | unsigned int mtu;
|
| 186 | unsigned int left;
|
| 187 | int offset;
|
| 188 | int ptr;
|
| 189 | int hroom;
|
| 190 | int troom;
|
| 191 | __be32 frag_id;
|
| 192 | u8 nexthdr;
|
| 193 | };
|
| 194 |
|
| 195 | void ip6_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int mtu,
|
| 196 | unsigned short needed_tailroom, int hdr_room, u8 *prevhdr,
|
| 197 | u8 nexthdr, __be32 frag_id, struct ip6_frag_state *state);
|
| 198 | struct sk_buff *ip6_frag_next(struct sk_buff *skb,
|
| 199 | struct ip6_frag_state *state);
|
| 200 |
|
| 201 | #define IP6_REPLY_MARK(net, mark) \
|
| 202 | ((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0)
|
| 203 |
|
| 204 | #include <net/sock.h>
|
| 205 |
|
| 206 |
|
| 207 | extern int sysctl_mld_max_msf;
|
| 208 | extern int sysctl_mld_qrv;
|
| 209 |
|
| 210 | #define _DEVINC(net, statname, mod, idev, field) \
|
| 211 | ({ \
|
| 212 | struct inet6_dev *_idev = (idev); \
|
| 213 | if (likely(_idev != NULL)) \
|
| 214 | mod##SNMP_INC_STATS64((_idev)->stats.statname, (field));\
|
| 215 | mod##SNMP_INC_STATS64((net)->mib.statname##_statistics, (field));\
|
| 216 | })
|
| 217 |
|
| 218 |
|
| 219 | #define _DEVINCATOMIC(net, statname, mod, idev, field) \
|
| 220 | ({ \
|
| 221 | struct inet6_dev *_idev = (idev); \
|
| 222 | if (likely(_idev != NULL)) \
|
| 223 | SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
|
| 224 | mod##SNMP_INC_STATS((net)->mib.statname##_statistics, (field));\
|
| 225 | })
|
| 226 |
|
| 227 |
|
| 228 | #define _DEVINC_ATOMIC_ATOMIC(net, statname, idev, field) \
|
| 229 | ({ \
|
| 230 | struct inet6_dev *_idev = (idev); \
|
| 231 | if (likely(_idev != NULL)) \
|
| 232 | SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
|
| 233 | SNMP_INC_STATS_ATOMIC_LONG((net)->mib.statname##_statistics, (field));\
|
| 234 | })
|
| 235 |
|
| 236 | #define _DEVADD(net, statname, mod, idev, field, val) \
|
| 237 | ({ \
|
| 238 | struct inet6_dev *_idev = (idev); \
|
| 239 | unsigned long _field = (field); \
|
| 240 | unsigned long _val = (val); \
|
| 241 | if (likely(_idev != NULL)) \
|
| 242 | mod##SNMP_ADD_STATS((_idev)->stats.statname, _field, _val); \
|
| 243 | mod##SNMP_ADD_STATS((net)->mib.statname##_statistics, _field, _val);\
|
| 244 | })
|
| 245 |
|
| 246 | #define _DEVUPD(net, statname, mod, idev, field, val) \
|
| 247 | ({ \
|
| 248 | struct inet6_dev *_idev = (idev); \
|
| 249 | unsigned long _val = (val); \
|
| 250 | if (likely(_idev != NULL)) \
|
| 251 | mod##SNMP_UPD_PO_STATS((_idev)->stats.statname, field, _val); \
|
| 252 | mod##SNMP_UPD_PO_STATS((net)->mib.statname##_statistics, field, _val);\
|
| 253 | })
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 | #define IP6_INC_STATS(net, idev,field) \
|
| 258 | _DEVINC(net, ipv6, , idev, field)
|
| 259 | #define __IP6_INC_STATS(net, idev,field) \
|
| 260 | _DEVINC(net, ipv6, __, idev, field)
|
| 261 | #define IP6_ADD_STATS(net, idev,field,val) \
|
| 262 | _DEVADD(net, ipv6, , idev, field, val)
|
| 263 | #define __IP6_ADD_STATS(net, idev,field,val) \
|
| 264 | _DEVADD(net, ipv6, __, idev, field, val)
|
| 265 | #define IP6_UPD_PO_STATS(net, idev,field,val) \
|
| 266 | _DEVUPD(net, ipv6, , idev, field, val)
|
| 267 | #define __IP6_UPD_PO_STATS(net, idev,field,val) \
|
| 268 | _DEVUPD(net, ipv6, __, idev, field, val)
|
| 269 | #define ICMP6_INC_STATS(net, idev, field) \
|
| 270 | _DEVINCATOMIC(net, icmpv6, , idev, field)
|
| 271 | #define __ICMP6_INC_STATS(net, idev, field) \
|
| 272 | _DEVINCATOMIC(net, icmpv6, __, idev, field)
|
| 273 |
|
| 274 | #define ICMP6MSGOUT_INC_STATS(net, idev, field) \
|
| 275 | _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256)
|
| 276 | #define ICMP6MSGIN_INC_STATS(net, idev, field) \
|
| 277 | _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field)
|
| 278 |
|
| 279 | struct ip6_ra_chain {
|
| 280 | struct ip6_ra_chain *next;
|
| 281 | struct sock *sk;
|
| 282 | int sel;
|
| 283 | void (*destructor)(struct sock *);
|
| 284 | };
|
| 285 |
|
| 286 | extern struct ip6_ra_chain *ip6_ra_chain;
|
| 287 | extern rwlock_t ip6_ra_lock;
|
| 288 |
|
| 289 | |
| 290 | This structure is prepared by protocol, when parsing
|
| 291 | ancillary data and passed to IPv6.
|
| 292 |
|
| 293 |
|
| 294 | struct ipv6_txoptions {
|
| 295 | refcount_t refcnt;
|
| 296 |
|
| 297 | int tot_len;
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 | __u16 opt_flen;
|
| 302 | __u16 opt_nflen;
|
| 303 |
|
| 304 | struct ipv6_opt_hdr *hopopt;
|
| 305 | struct ipv6_opt_hdr *dst0opt;
|
| 306 | struct ipv6_rt_hdr *srcrt;
|
| 307 | struct ipv6_opt_hdr *dst1opt;
|
| 308 | struct rcu_head rcu;
|
| 309 |
|
| 310 | };
|
| 311 |
|
| 312 |
|
| 313 | enum flowlabel_reflect {
|
| 314 | FLOWLABEL_REFLECT_ESTABLISHED = 1,
|
| 315 | FLOWLABEL_REFLECT_TCP_RESET = 2,
|
| 316 | FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES = 4,
|
| 317 | };
|
| 318 |
|
| 319 | struct ip6_flowlabel {
|
| 320 | struct ip6_flowlabel __rcu *next;
|
| 321 | __be32 label;
|
| 322 | atomic_t users;
|
| 323 | struct in6_addr dst;
|
| 324 | struct ipv6_txoptions *opt;
|
| 325 | unsigned long linger;
|
| 326 | struct rcu_head rcu;
|
| 327 | u8 share;
|
| 328 | union {
|
| 329 | struct pid *pid;
|
| 330 | kuid_t uid;
|
| 331 | } owner;
|
| 332 | unsigned long lastuse;
|
| 333 | unsigned long expires;
|
| 334 | struct net *fl_net;
|
| 335 | };
|
| 336 |
|
| 337 | #define IPV6_FLOWINFO_MASK cpu_to_be32(0x0FFFFFFF)
|
| 338 | #define IPV6_FLOWLABEL_MASK cpu_to_be32(0x000FFFFF)
|
| 339 | #define IPV6_FLOWLABEL_STATELESS_FLAG cpu_to_be32(0x00080000)
|
| 340 |
|
| 341 | #define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK)
|
| 342 | #define IPV6_TCLASS_SHIFT 20
|
| 343 |
|
| 344 | struct ipv6_fl_socklist {
|
| 345 | struct ipv6_fl_socklist __rcu *next;
|
| 346 | struct ip6_flowlabel *fl;
|
| 347 | struct rcu_head rcu;
|
| 348 | };
|
| 349 |
|
| 350 | struct ipcm6_cookie {
|
| 351 | struct sockcm_cookie sockc;
|
| 352 | __s16 hlimit;
|
| 353 | __s16 tclass;
|
| 354 | __u16 gso_size;
|
| 355 | __s8 dontfrag;
|
| 356 | struct ipv6_txoptions *opt;
|
| 357 | };
|
| 358 |
|
| 359 | static inline void ipcm6_init_sk(struct ipcm6_cookie *ipc6,
|
| 360 | const struct sock *sk)
|
| 361 | {
|
| 362 | *ipc6 = (struct ipcm6_cookie) {
|
| 363 | .hlimit = -1,
|
| 364 | .tclass = inet6_sk(sk)->tclass,
|
| 365 | .dontfrag = inet6_test_bit(DONTFRAG, sk),
|
| 366 | };
|
| 367 |
|
| 368 | sockcm_init(&ipc6->sockc, sk);
|
| 369 | }
|
| 370 |
|
| 371 | static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
|
| 372 | {
|
| 373 | struct ipv6_txoptions *opt;
|
| 374 |
|
| 375 | rcu_read_lock();
|
| 376 | opt = rcu_dereference(np->opt);
|
| 377 | if (opt) {
|
| 378 | if (!refcount_inc_not_zero(&opt->refcnt))
|
| 379 | opt = NULL;
|
| 380 | else
|
| 381 | opt = rcu_pointer_handoff(opt);
|
| 382 | }
|
| 383 | rcu_read_unlock();
|
| 384 | return opt;
|
| 385 | }
|
| 386 |
|
| 387 | static inline void txopt_put(struct ipv6_txoptions *opt)
|
| 388 | {
|
| 389 | if (opt && refcount_dec_and_test(&opt->refcnt))
|
| 390 | kfree_rcu(opt, rcu);
|
| 391 | }
|
| 392 |
|
| 393 | #if IS_ENABLED(CONFIG_IPV6)
|
| 394 | struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label);
|
| 395 |
|
| 396 | extern struct static_key_false_deferred ipv6_flowlabel_exclusive;
|
| 397 | static inline struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk,
|
| 398 | __be32 label)
|
| 399 | {
|
| 400 | if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key) &&
|
| 401 | READ_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl))
|
| 402 | return __fl6_sock_lookup(sk, label) ? : ERR_PTR(-ENOENT);
|
| 403 |
|
| 404 | return NULL;
|
| 405 | }
|
| 406 | #endif
|
| 407 |
|
| 408 | struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
|
| 409 | struct ip6_flowlabel *fl,
|
| 410 | struct ipv6_txoptions *fopt);
|
| 411 | void fl6_free_socklist(struct sock *sk);
|
| 412 | int ipv6_flowlabel_opt(struct sock *sk, sockptr_t optval, int optlen);
|
| 413 | int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
|
| 414 | int flags);
|
| 415 | int ip6_flowlabel_init(void);
|
| 416 | void ip6_flowlabel_cleanup(void);
|
| 417 | bool ip6_autoflowlabel(struct net *net, const struct sock *sk);
|
| 418 |
|
| 419 | static inline void fl6_sock_release(struct ip6_flowlabel *fl)
|
| 420 | {
|
| 421 | if (fl)
|
| 422 | atomic_dec(&fl->users);
|
| 423 | }
|
| 424 |
|
| 425 | enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
|
| 426 | u8 code, __be32 info);
|
| 427 |
|
| 428 | void icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
|
| 429 | struct icmp6hdr *thdr, int len);
|
| 430 |
|
| 431 | int ip6_ra_control(struct sock *sk, int sel);
|
| 432 |
|
| 433 | int ipv6_parse_hopopts(struct sk_buff *skb);
|
| 434 |
|
| 435 | struct ipv6_txoptions *ipv6_dup_options(struct sock *sk,
|
| 436 | struct ipv6_txoptions *opt);
|
| 437 | struct ipv6_txoptions *ipv6_renew_options(struct sock *sk,
|
| 438 | struct ipv6_txoptions *opt,
|
| 439 | int newtype,
|
| 440 | struct ipv6_opt_hdr *newopt);
|
| 441 | struct ipv6_txoptions *__ipv6_fixup_options(struct ipv6_txoptions *opt_space,
|
| 442 | struct ipv6_txoptions *opt);
|
| 443 |
|
| 444 | static inline struct ipv6_txoptions *
|
| 445 | ipv6_fixup_options(struct ipv6_txoptions *opt_space, struct ipv6_txoptions *opt)
|
| 446 | {
|
| 447 | if (!opt)
|
| 448 | return NULL;
|
| 449 | return __ipv6_fixup_options(opt_space, opt);
|
| 450 | }
|
| 451 |
|
| 452 | bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb,
|
| 453 | const struct inet6_skb_parm *opt);
|
| 454 | struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
|
| 455 | struct ipv6_txoptions *opt);
|
| 456 |
|
| 457 | static inline bool ipv6_accept_ra(const struct inet6_dev *idev)
|
| 458 | {
|
| 459 | s32 accept_ra = READ_ONCE(idev->cnf.accept_ra);
|
| 460 |
|
| 461 | |
| 462 | * hybrid mode (accept_ra=2) is enabled.
|
| 463 |
|
| 464 | return READ_ONCE(idev->cnf.forwarding) ? accept_ra == 2 :
|
| 465 | accept_ra;
|
| 466 | }
|
| 467 |
|
| 468 | #define IPV6_FRAG_HIGH_THRESH (4 * 1024*1024)
|
| 469 | #define IPV6_FRAG_LOW_THRESH (3 * 1024*1024)
|
| 470 | #define IPV6_FRAG_TIMEOUT (60 * HZ)
|
| 471 |
|
| 472 | int __ipv6_addr_type(const struct in6_addr *addr);
|
| 473 | static inline int ipv6_addr_type(const struct in6_addr *addr)
|
| 474 | {
|
| 475 | return __ipv6_addr_type(addr) & 0xffff;
|
| 476 | }
|
| 477 |
|
| 478 | static inline int ipv6_addr_scope(const struct in6_addr *addr)
|
| 479 | {
|
| 480 | return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
|
| 481 | }
|
| 482 |
|
| 483 | static inline int __ipv6_addr_src_scope(int type)
|
| 484 | {
|
| 485 | return (type == IPV6_ADDR_ANY) ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16);
|
| 486 | }
|
| 487 |
|
| 488 | static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
|
| 489 | {
|
| 490 | return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
|
| 491 | }
|
| 492 |
|
| 493 | static inline bool __ipv6_addr_needs_scope_id(int type)
|
| 494 | {
|
| 495 | return type & IPV6_ADDR_LINKLOCAL ||
|
| 496 | (type & IPV6_ADDR_MULTICAST &&
|
| 497 | (type & (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)));
|
| 498 | }
|
| 499 |
|
| 500 | static inline __u32 ipv6_iface_scope_id(const struct in6_addr *addr, int iface)
|
| 501 | {
|
| 502 | return __ipv6_addr_needs_scope_id(__ipv6_addr_type(addr)) ? iface : 0;
|
| 503 | }
|
| 504 |
|
| 505 | static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
|
| 506 | {
|
| 507 | return memcmp(a1, a2, sizeof(struct in6_addr));
|
| 508 | }
|
| 509 |
|
| 510 | static inline bool
|
| 511 | ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
|
| 512 | const struct in6_addr *a2)
|
| 513 | {
|
| 514 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 515 | const unsigned long *ul1 = (const unsigned long *)a1;
|
| 516 | const unsigned long *ulm = (const unsigned long *)m;
|
| 517 | const unsigned long *ul2 = (const unsigned long *)a2;
|
| 518 |
|
| 519 | return !!(((ul1[0] ^ ul2[0]) & ulm[0]) |
|
| 520 | ((ul1[1] ^ ul2[1]) & ulm[1]));
|
| 521 | #else
|
| 522 | return !!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) |
|
| 523 | ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) |
|
| 524 | ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) |
|
| 525 | ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]));
|
| 526 | #endif
|
| 527 | }
|
| 528 |
|
| 529 | static inline void ipv6_addr_prefix(struct in6_addr *pfx,
|
| 530 | const struct in6_addr *addr,
|
| 531 | int plen)
|
| 532 | {
|
| 533 |
|
| 534 | int o = plen >> 3,
|
| 535 | b = plen & 0x7;
|
| 536 |
|
| 537 | memset(pfx->s6_addr, 0, sizeof(pfx->s6_addr));
|
| 538 | memcpy(pfx->s6_addr, addr, o);
|
| 539 | if (b != 0)
|
| 540 | pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
|
| 541 | }
|
| 542 |
|
| 543 | static inline void ipv6_addr_prefix_copy(struct in6_addr *addr,
|
| 544 | const struct in6_addr *pfx,
|
| 545 | int plen)
|
| 546 | {
|
| 547 |
|
| 548 | int o = plen >> 3,
|
| 549 | b = plen & 0x7;
|
| 550 |
|
| 551 | memcpy(addr->s6_addr, pfx, o);
|
| 552 | if (b != 0) {
|
| 553 | addr->s6_addr[o] &= ~(0xff00 >> b);
|
| 554 | addr->s6_addr[o] |= (pfx->s6_addr[o] & (0xff00 >> b));
|
| 555 | }
|
| 556 | }
|
| 557 |
|
| 558 | static inline void __ipv6_addr_set_half(__be32 *addr,
|
| 559 | __be32 wh, __be32 wl)
|
| 560 | {
|
| 561 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 562 | #if defined(__BIG_ENDIAN)
|
| 563 | if (__builtin_constant_p(wh) && __builtin_constant_p(wl)) {
|
| 564 | *(__force u64 *)addr = ((__force u64)(wh) << 32 | (__force u64)(wl));
|
| 565 | return;
|
| 566 | }
|
| 567 | #elif defined(__LITTLE_ENDIAN)
|
| 568 | if (__builtin_constant_p(wl) && __builtin_constant_p(wh)) {
|
| 569 | *(__force u64 *)addr = ((__force u64)(wl) << 32 | (__force u64)(wh));
|
| 570 | return;
|
| 571 | }
|
| 572 | #endif
|
| 573 | #endif
|
| 574 | addr[0] = wh;
|
| 575 | addr[1] = wl;
|
| 576 | }
|
| 577 |
|
| 578 | static inline void ipv6_addr_set(struct in6_addr *addr,
|
| 579 | __be32 w1, __be32 w2,
|
| 580 | __be32 w3, __be32 w4)
|
| 581 | {
|
| 582 | __ipv6_addr_set_half(&addr->s6_addr32[0], w1, w2);
|
| 583 | __ipv6_addr_set_half(&addr->s6_addr32[2], w3, w4);
|
| 584 | }
|
| 585 |
|
| 586 | static inline bool ipv6_addr_equal(const struct in6_addr *a1,
|
| 587 | const struct in6_addr *a2)
|
| 588 | {
|
| 589 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 590 | const unsigned long *ul1 = (const unsigned long *)a1;
|
| 591 | const unsigned long *ul2 = (const unsigned long *)a2;
|
| 592 |
|
| 593 | return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL;
|
| 594 | #else
|
| 595 | return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
|
| 596 | (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
|
| 597 | (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
|
| 598 | (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
|
| 599 | #endif
|
| 600 | }
|
| 601 |
|
| 602 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 603 | static inline bool __ipv6_prefix_equal64_half(const __be64 *a1,
|
| 604 | const __be64 *a2,
|
| 605 | unsigned int len)
|
| 606 | {
|
| 607 | if (len && ((*a1 ^ *a2) & cpu_to_be64((~0UL) << (64 - len))))
|
| 608 | return false;
|
| 609 | return true;
|
| 610 | }
|
| 611 |
|
| 612 | static inline bool ipv6_prefix_equal(const struct in6_addr *addr1,
|
| 613 | const struct in6_addr *addr2,
|
| 614 | unsigned int prefixlen)
|
| 615 | {
|
| 616 | const __be64 *a1 = (const __be64 *)addr1;
|
| 617 | const __be64 *a2 = (const __be64 *)addr2;
|
| 618 |
|
| 619 | if (prefixlen >= 64) {
|
| 620 | if (a1[0] ^ a2[0])
|
| 621 | return false;
|
| 622 | return __ipv6_prefix_equal64_half(a1 + 1, a2 + 1, prefixlen - 64);
|
| 623 | }
|
| 624 | return __ipv6_prefix_equal64_half(a1, a2, prefixlen);
|
| 625 | }
|
| 626 | #else
|
| 627 | static inline bool ipv6_prefix_equal(const struct in6_addr *addr1,
|
| 628 | const struct in6_addr *addr2,
|
| 629 | unsigned int prefixlen)
|
| 630 | {
|
| 631 | const __be32 *a1 = addr1->s6_addr32;
|
| 632 | const __be32 *a2 = addr2->s6_addr32;
|
| 633 | unsigned int pdw, pbi;
|
| 634 |
|
| 635 |
|
| 636 | pdw = prefixlen >> 5;
|
| 637 | if (pdw && memcmp(a1, a2, pdw << 2))
|
| 638 | return false;
|
| 639 |
|
| 640 |
|
| 641 | pbi = prefixlen & 0x1f;
|
| 642 | if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
|
| 643 | return false;
|
| 644 |
|
| 645 | return true;
|
| 646 | }
|
| 647 | #endif
|
| 648 |
|
| 649 | static inline bool ipv6_addr_any(const struct in6_addr *a)
|
| 650 | {
|
| 651 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 652 | const unsigned long *ul = (const unsigned long *)a;
|
| 653 |
|
| 654 | return (ul[0] | ul[1]) == 0UL;
|
| 655 | #else
|
| 656 | return (a->s6_addr32[0] | a->s6_addr32[1] |
|
| 657 | a->s6_addr32[2] | a->s6_addr32[3]) == 0;
|
| 658 | #endif
|
| 659 | }
|
| 660 |
|
| 661 | static inline u32 ipv6_addr_hash(const struct in6_addr *a)
|
| 662 | {
|
| 663 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 664 | const unsigned long *ul = (const unsigned long *)a;
|
| 665 | unsigned long x = ul[0] ^ ul[1];
|
| 666 |
|
| 667 | return (u32)(x ^ (x >> 32));
|
| 668 | #else
|
| 669 | return (__force u32)(a->s6_addr32[0] ^ a->s6_addr32[1] ^
|
| 670 | a->s6_addr32[2] ^ a->s6_addr32[3]);
|
| 671 | #endif
|
| 672 | }
|
| 673 |
|
| 674 |
|
| 675 | static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
|
| 676 | {
|
| 677 | return jhash2((__force const u32 *)a->s6_addr32,
|
| 678 | ARRAY_SIZE(a->s6_addr32), initval);
|
| 679 | }
|
| 680 |
|
| 681 | static inline bool ipv6_addr_loopback(const struct in6_addr *a)
|
| 682 | {
|
| 683 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 684 | const __be64 *be = (const __be64 *)a;
|
| 685 |
|
| 686 | return (be[0] | (be[1] ^ cpu_to_be64(1))) == 0UL;
|
| 687 | #else
|
| 688 | return (a->s6_addr32[0] | a->s6_addr32[1] |
|
| 689 | a->s6_addr32[2] | (a->s6_addr32[3] ^ cpu_to_be32(1))) == 0;
|
| 690 | #endif
|
| 691 | }
|
| 692 |
|
| 693 | |
| 694 | * Note that we must __force cast these to unsigned long to make sparse happy,
|
| 695 | * since all of the endian-annotated types are fixed size regardless of arch.
|
| 696 |
|
| 697 | static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
|
| 698 | {
|
| 699 | return (
|
| 700 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 701 | *(unsigned long *)a |
|
| 702 | #else
|
| 703 | (__force unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
|
| 704 | #endif
|
| 705 | (__force unsigned long)(a->s6_addr32[2] ^
|
| 706 | cpu_to_be32(0x0000ffff))) == 0UL;
|
| 707 | }
|
| 708 |
|
| 709 | static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a)
|
| 710 | {
|
| 711 | return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]);
|
| 712 | }
|
| 713 |
|
| 714 | static inline u32 ipv6_portaddr_hash(const struct net *net,
|
| 715 | const struct in6_addr *addr6,
|
| 716 | unsigned int port)
|
| 717 | {
|
| 718 | unsigned int hash, mix = net_hash_mix(net);
|
| 719 |
|
| 720 | if (ipv6_addr_any(addr6))
|
| 721 | hash = jhash_1word(0, mix);
|
| 722 | else if (ipv6_addr_v4mapped(addr6))
|
| 723 | hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
|
| 724 | else
|
| 725 | hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);
|
| 726 |
|
| 727 | return hash ^ port;
|
| 728 | }
|
| 729 |
|
| 730 | |
| 731 | * Check for a RFC 4843 ORCHID address
|
| 732 | * (Overlay Routable Cryptographic Hash Identifiers)
|
| 733 |
|
| 734 | static inline bool ipv6_addr_orchid(const struct in6_addr *a)
|
| 735 | {
|
| 736 | return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
|
| 737 | }
|
| 738 |
|
| 739 | static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
|
| 740 | {
|
| 741 | return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
|
| 742 | }
|
| 743 |
|
| 744 | static inline void ipv6_addr_set_v4mapped(const __be32 addr,
|
| 745 | struct in6_addr *v4mapped)
|
| 746 | {
|
| 747 | ipv6_addr_set(v4mapped,
|
| 748 | 0, 0,
|
| 749 | htonl(0x0000FFFF),
|
| 750 | addr);
|
| 751 | }
|
| 752 |
|
| 753 | |
| 754 | * find the first different bit between two addresses
|
| 755 | * length of address must be a multiple of 32bits
|
| 756 |
|
| 757 | static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
|
| 758 | {
|
| 759 | const __be32 *a1 = token1, *a2 = token2;
|
| 760 | int i;
|
| 761 |
|
| 762 | addrlen >>= 2;
|
| 763 |
|
| 764 | for (i = 0; i < addrlen; i++) {
|
| 765 | __be32 xb = a1[i] ^ a2[i];
|
| 766 | if (xb)
|
| 767 | return i * 32 + 31 - __fls(ntohl(xb));
|
| 768 | }
|
| 769 |
|
| 770 | |
| 771 | * we should *never* get to this point since that
|
| 772 | * would mean the addrs are equal
|
| 773 | *
|
| 774 | * However, we do get to it 8) And exactly, when
|
| 775 | * addresses are equal 8)
|
| 776 | *
|
| 777 | * ip route add 1111::/128 via ...
|
| 778 | * ip route add 1111::/64 via ...
|
| 779 | * and we are here.
|
| 780 | *
|
| 781 | * Ideally, this function should stop comparison
|
| 782 | * at prefix length. It does not, but it is still OK,
|
| 783 | * if returned value is greater than prefix length.
|
| 784 | * --ANK (980803)
|
| 785 |
|
| 786 | return addrlen << 5;
|
| 787 | }
|
| 788 |
|
| 789 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 790 | static inline int __ipv6_addr_diff64(const void *token1, const void *token2, int addrlen)
|
| 791 | {
|
| 792 | const __be64 *a1 = token1, *a2 = token2;
|
| 793 | int i;
|
| 794 |
|
| 795 | addrlen >>= 3;
|
| 796 |
|
| 797 | for (i = 0; i < addrlen; i++) {
|
| 798 | __be64 xb = a1[i] ^ a2[i];
|
| 799 | if (xb)
|
| 800 | return i * 64 + 63 - __fls(be64_to_cpu(xb));
|
| 801 | }
|
| 802 |
|
| 803 | return addrlen << 6;
|
| 804 | }
|
| 805 | #endif
|
| 806 |
|
| 807 | static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
|
| 808 | {
|
| 809 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
|
| 810 | if (__builtin_constant_p(addrlen) && !(addrlen & 7))
|
| 811 | return __ipv6_addr_diff64(token1, token2, addrlen);
|
| 812 | #endif
|
| 813 | return __ipv6_addr_diff32(token1, token2, addrlen);
|
| 814 | }
|
| 815 |
|
| 816 | static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
|
| 817 | {
|
| 818 | return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
|
| 819 | }
|
| 820 |
|
| 821 | __be32 ipv6_select_ident(struct net *net,
|
| 822 | const struct in6_addr *daddr,
|
| 823 | const struct in6_addr *saddr);
|
| 824 | __be32 ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
|
| 825 |
|
| 826 | int ip6_dst_hoplimit(struct dst_entry *dst);
|
| 827 |
|
| 828 | static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
|
| 829 | struct dst_entry *dst)
|
| 830 | {
|
| 831 | int hlimit;
|
| 832 |
|
| 833 | if (ipv6_addr_is_multicast(&fl6->daddr))
|
| 834 | hlimit = READ_ONCE(np->mcast_hops);
|
| 835 | else
|
| 836 | hlimit = READ_ONCE(np->hop_limit);
|
| 837 | if (hlimit < 0)
|
| 838 | hlimit = ip6_dst_hoplimit(dst);
|
| 839 | return hlimit;
|
| 840 | }
|
| 841 |
|
| 842 | |
| 843 | * Equivalent to : flow->v6addrs.src = iph->saddr;
|
| 844 | * flow->v6addrs.dst = iph->daddr;
|
| 845 |
|
| 846 | static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,
|
| 847 | const struct ipv6hdr *iph)
|
| 848 | {
|
| 849 | BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) !=
|
| 850 | offsetof(typeof(flow->addrs), v6addrs.src) +
|
| 851 | sizeof(flow->addrs.v6addrs.src));
|
| 852 | memcpy(&flow->addrs.v6addrs, &iph->addrs, sizeof(flow->addrs.v6addrs));
|
| 853 | flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
|
| 854 | }
|
| 855 |
|
| 856 | #if IS_ENABLED(CONFIG_IPV6)
|
| 857 |
|
| 858 | static inline bool ipv6_can_nonlocal_bind(const struct net *net,
|
| 859 | const struct inet_sock *inet)
|
| 860 | {
|
| 861 | return READ_ONCE(net->ipv6.sysctl.ip_nonlocal_bind) ||
|
| 862 | test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) ||
|
| 863 | test_bit(INET_FLAGS_TRANSPARENT, &inet->inet_flags);
|
| 864 | }
|
| 865 |
|
| 866 |
|
| 867 | #define IP6_AUTO_FLOW_LABEL_OFF 0
|
| 868 | #define IP6_AUTO_FLOW_LABEL_OPTOUT 1
|
| 869 | #define IP6_AUTO_FLOW_LABEL_OPTIN 2
|
| 870 | #define IP6_AUTO_FLOW_LABEL_FORCED 3
|
| 871 |
|
| 872 | #define IP6_AUTO_FLOW_LABEL_MAX IP6_AUTO_FLOW_LABEL_FORCED
|
| 873 |
|
| 874 | #define IP6_DEFAULT_AUTO_FLOW_LABELS IP6_AUTO_FLOW_LABEL_OPTOUT
|
| 875 |
|
| 876 | static inline __be32 ip6_make_flowlabel(const struct net *net,
|
| 877 | struct sk_buff *skb,
|
| 878 | __be32 flowlabel, bool autolabel,
|
| 879 | struct flowi6 *fl6)
|
| 880 | {
|
| 881 | u8 auto_flowlabels;
|
| 882 | u32 hash;
|
| 883 |
|
| 884 | |
| 885 | * Here we want only the flow label value.
|
| 886 |
|
| 887 | flowlabel &= IPV6_FLOWLABEL_MASK;
|
| 888 |
|
| 889 | if (flowlabel)
|
| 890 | return flowlabel;
|
| 891 |
|
| 892 | auto_flowlabels = READ_ONCE(net->ipv6.sysctl.auto_flowlabels);
|
| 893 | if (auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF ||
|
| 894 | (!autolabel && auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))
|
| 895 | return flowlabel;
|
| 896 |
|
| 897 | hash = skb_get_hash_flowi6(skb, fl6);
|
| 898 |
|
| 899 | |
| 900 | * to minimize possibility that any useful information to an
|
| 901 | * attacker is leaked. Only lower 20 bits are relevant.
|
| 902 |
|
| 903 | hash = rol32(hash, 16);
|
| 904 |
|
| 905 | flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
|
| 906 |
|
| 907 | if (READ_ONCE(net->ipv6.sysctl.flowlabel_state_ranges))
|
| 908 | flowlabel |= IPV6_FLOWLABEL_STATELESS_FLAG;
|
| 909 |
|
| 910 | return flowlabel;
|
| 911 | }
|
| 912 |
|
| 913 | static inline int ip6_default_np_autolabel(const struct net *net)
|
| 914 | {
|
| 915 | switch (READ_ONCE(net->ipv6.sysctl.auto_flowlabels)) {
|
| 916 | case IP6_AUTO_FLOW_LABEL_OFF:
|
| 917 | case IP6_AUTO_FLOW_LABEL_OPTIN:
|
| 918 | default:
|
| 919 | return 0;
|
| 920 | case IP6_AUTO_FLOW_LABEL_OPTOUT:
|
| 921 | case IP6_AUTO_FLOW_LABEL_FORCED:
|
| 922 | return 1;
|
| 923 | }
|
| 924 | }
|
| 925 | #else
|
| 926 | static inline __be32 ip6_make_flowlabel(const struct net *net, struct sk_buff *skb,
|
| 927 | __be32 flowlabel, bool autolabel,
|
| 928 | struct flowi6 *fl6)
|
| 929 | {
|
| 930 | return flowlabel;
|
| 931 | }
|
| 932 | static inline int ip6_default_np_autolabel(const struct net *net)
|
| 933 | {
|
| 934 | return 0;
|
| 935 | }
|
| 936 | #endif
|
| 937 |
|
| 938 | #if IS_ENABLED(CONFIG_IPV6)
|
| 939 | static inline int ip6_multipath_hash_policy(const struct net *net)
|
| 940 | {
|
| 941 | return READ_ONCE(net->ipv6.sysctl.multipath_hash_policy);
|
| 942 | }
|
| 943 | static inline u32 ip6_multipath_hash_fields(const struct net *net)
|
| 944 | {
|
| 945 | return READ_ONCE(net->ipv6.sysctl.multipath_hash_fields);
|
| 946 | }
|
| 947 | #else
|
| 948 | static inline int ip6_multipath_hash_policy(const struct net *net)
|
| 949 | {
|
| 950 | return 0;
|
| 951 | }
|
| 952 | static inline u32 ip6_multipath_hash_fields(const struct net *net)
|
| 953 | {
|
| 954 | return 0;
|
| 955 | }
|
| 956 | #endif
|
| 957 |
|
| 958 | |
| 959 | * policy 0 only, and only when txhash is set. >> 1 clears the top bit
|
| 960 | * (fib6_select_path() uses mp_hash as a signed 31-bit value); ?: 1 keeps the
|
| 961 | * result non-zero, since mp_hash 0 falls back to rt6_multipath_hash().
|
| 962 |
|
| 963 | static inline void ip6_ecmp_set_mp_hash(const struct net *net,
|
| 964 | struct flowi6 *fl6, u32 txhash)
|
| 965 | {
|
| 966 | if (ip6_multipath_hash_policy(net) == 0 && txhash)
|
| 967 | fl6->mp_hash = (txhash >> 1) ?: 1;
|
| 968 | }
|
| 969 |
|
| 970 | |
| 971 | * Header manipulation
|
| 972 |
|
| 973 | static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
|
| 974 | __be32 flowlabel)
|
| 975 | {
|
| 976 | *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
|
| 977 | }
|
| 978 |
|
| 979 | static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
|
| 980 | {
|
| 981 | return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
|
| 982 | }
|
| 983 |
|
| 984 | static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
|
| 985 | {
|
| 986 | return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
|
| 987 | }
|
| 988 |
|
| 989 | static inline u8 ip6_tclass(__be32 flowinfo)
|
| 990 | {
|
| 991 | return ntohl(flowinfo & IPV6_TCLASS_MASK) >> IPV6_TCLASS_SHIFT;
|
| 992 | }
|
| 993 |
|
| 994 | static inline dscp_t ip6_dscp(__be32 flowinfo)
|
| 995 | {
|
| 996 | return inet_dsfield_to_dscp(ip6_tclass(flowinfo));
|
| 997 | }
|
| 998 |
|
| 999 | static inline __be32 ip6_make_flowinfo(unsigned int tclass, __be32 flowlabel)
|
| 1000 | {
|
| 1001 | return htonl(tclass << IPV6_TCLASS_SHIFT) | flowlabel;
|
| 1002 | }
|
| 1003 |
|
| 1004 | static inline __be32 flowi6_get_flowlabel(const struct flowi6 *fl6)
|
| 1005 | {
|
| 1006 | return fl6->flowlabel & IPV6_FLOWLABEL_MASK;
|
| 1007 | }
|
| 1008 |
|
| 1009 | |
| 1010 | * Prototypes exported by ipv6
|
| 1011 |
|
| 1012 |
|
| 1013 | |
| 1014 | * rcv function (called from netdevice level)
|
| 1015 |
|
| 1016 |
|
| 1017 | int ipv6_rcv(struct sk_buff *skb, struct net_device *dev,
|
| 1018 | struct packet_type *pt, struct net_device *orig_dev);
|
| 1019 | void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
|
| 1020 | struct net_device *orig_dev);
|
| 1021 |
|
| 1022 | int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
|
| 1023 |
|
| 1024 | |
| 1025 | * upper-layer output functions
|
| 1026 |
|
| 1027 | int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
|
| 1028 | __u32 mark, struct ipv6_txoptions *opt, int tclass, u32 priority);
|
| 1029 |
|
| 1030 | int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
|
| 1031 |
|
| 1032 | int ip6_append_data(struct sock *sk,
|
| 1033 | int getfrag(void *from, char *to, int offset, int len,
|
| 1034 | int odd, struct sk_buff *skb),
|
| 1035 | void *from, size_t length, int transhdrlen,
|
| 1036 | struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
|
| 1037 | struct rt6_info *rt, unsigned int flags);
|
| 1038 |
|
| 1039 | int ip6_push_pending_frames(struct sock *sk);
|
| 1040 |
|
| 1041 | void ip6_flush_pending_frames(struct sock *sk);
|
| 1042 |
|
| 1043 | int ip6_send_skb(struct sk_buff *skb);
|
| 1044 |
|
| 1045 | struct sk_buff *__ip6_make_skb(struct sock *sk, struct sk_buff_head *queue,
|
| 1046 | struct inet_cork_full *cork);
|
| 1047 | struct sk_buff *ip6_make_skb(struct sock *sk,
|
| 1048 | int getfrag(void *from, char *to, int offset,
|
| 1049 | int len, int odd, struct sk_buff *skb),
|
| 1050 | void *from, size_t length, int transhdrlen,
|
| 1051 | struct ipcm6_cookie *ipc6,
|
| 1052 | struct rt6_info *rt, unsigned int flags,
|
| 1053 | struct inet_cork_full *cork);
|
| 1054 |
|
| 1055 | static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
|
| 1056 | {
|
| 1057 | return __ip6_make_skb(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
|
| 1058 | }
|
| 1059 |
|
| 1060 | int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
|
| 1061 | struct flowi6 *fl6);
|
| 1062 | #if IS_ENABLED(CONFIG_IPV6)
|
| 1063 | struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
|
| 1064 | const struct in6_addr *final_dst);
|
| 1065 | #else
|
| 1066 | static inline struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk,
|
| 1067 | struct flowi6 *fl6,
|
| 1068 | const struct in6_addr *final_dst)
|
| 1069 | {
|
| 1070 | return ERR_PTR(-EAFNOSUPPORT);
|
| 1071 | }
|
| 1072 | #endif
|
| 1073 |
|
| 1074 | struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
|
| 1075 | const struct in6_addr *final_dst,
|
| 1076 | bool connected);
|
| 1077 | struct dst_entry *ip6_blackhole_route(struct net *net,
|
| 1078 | struct dst_entry *orig_dst);
|
| 1079 |
|
| 1080 | |
| 1081 | * skb processing functions
|
| 1082 |
|
| 1083 |
|
| 1084 | int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
|
| 1085 | int ip6_forward(struct sk_buff *skb);
|
| 1086 | int ip6_input(struct sk_buff *skb);
|
| 1087 | int ip6_mc_input(struct sk_buff *skb);
|
| 1088 | void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
|
| 1089 | bool have_final);
|
| 1090 |
|
| 1091 | int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
| 1092 | int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
| 1093 |
|
| 1094 | |
| 1095 | * Extension header (options) processing
|
| 1096 |
|
| 1097 |
|
| 1098 | u8 ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
|
| 1099 | u8 proto, struct in6_addr **daddr_p,
|
| 1100 | struct in6_addr *saddr);
|
| 1101 | u8 ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
|
| 1102 | u8 proto);
|
| 1103 |
|
| 1104 | int ipv6_skip_exthdr(const struct sk_buff *, int start, u8 *nexthdrp,
|
| 1105 | __be16 *frag_offp);
|
| 1106 |
|
| 1107 | bool ipv6_ext_hdr(u8 nexthdr);
|
| 1108 |
|
| 1109 | enum {
|
| 1110 | IP6_FH_F_FRAG = (1 << 0),
|
| 1111 | IP6_FH_F_AUTH = (1 << 1),
|
| 1112 | IP6_FH_F_SKIP_RH = (1 << 2),
|
| 1113 | };
|
| 1114 |
|
| 1115 |
|
| 1116 | int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target,
|
| 1117 | unsigned short *fragoff, int *fragflg);
|
| 1118 |
|
| 1119 | int ipv6_find_tlv(const struct sk_buff *skb, int offset, int type);
|
| 1120 |
|
| 1121 | struct in6_addr *__fl6_update_dst(struct flowi6 *fl6,
|
| 1122 | const struct ipv6_txoptions *opt,
|
| 1123 | struct in6_addr *orig);
|
| 1124 |
|
| 1125 | static inline struct in6_addr *
|
| 1126 | fl6_update_dst(struct flowi6 *fl6, const struct ipv6_txoptions *opt,
|
| 1127 | struct in6_addr *orig)
|
| 1128 | {
|
| 1129 | if (likely(!opt))
|
| 1130 | return NULL;
|
| 1131 |
|
| 1132 | return __fl6_update_dst(fl6, opt, orig);
|
| 1133 | }
|
| 1134 |
|
| 1135 | |
| 1136 | * socket options (ipv6_sockglue.c)
|
| 1137 |
|
| 1138 | DECLARE_STATIC_KEY_FALSE(ip6_min_hopcount);
|
| 1139 |
|
| 1140 | int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
| 1141 | unsigned int optlen);
|
| 1142 | int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
|
| 1143 | unsigned int optlen);
|
| 1144 | int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
| 1145 | sockptr_t optval, sockptr_t optlen);
|
| 1146 | int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
| 1147 | char __user *optval, int __user *optlen);
|
| 1148 |
|
| 1149 | int __ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *addr,
|
| 1150 | int addr_len);
|
| 1151 | int ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *addr, int addr_len);
|
| 1152 | int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr_unsized *addr,
|
| 1153 | int addr_len);
|
| 1154 | int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr);
|
| 1155 | void ip6_datagram_release_cb(struct sock *sk);
|
| 1156 |
|
| 1157 | int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
|
| 1158 | int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
|
| 1159 | void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
|
| 1160 | u32 info, u8 *payload);
|
| 1161 | void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
|
| 1162 | void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
|
| 1163 |
|
| 1164 | void inet6_cleanup_sock(struct sock *sk);
|
| 1165 | void inet6_sock_destruct(struct sock *sk);
|
| 1166 | int inet6_release(struct socket *sock);
|
| 1167 | int __inet6_bind(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len,
|
| 1168 | u32 flags);
|
| 1169 | int inet6_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int addr_len);
|
| 1170 | int inet6_bind_sk(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len);
|
| 1171 | int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
|
| 1172 | int peer);
|
| 1173 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
|
| 1174 | int inet6_compat_ioctl(struct socket *sock, unsigned int cmd,
|
| 1175 | unsigned long arg);
|
| 1176 |
|
| 1177 | int inet6_hash_connect(struct inet_timewait_death_row *death_row,
|
| 1178 | struct sock *sk);
|
| 1179 | int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size);
|
| 1180 | int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
| 1181 | int flags);
|
| 1182 |
|
| 1183 | |
| 1184 | * reassembly.c
|
| 1185 |
|
| 1186 | extern const struct proto_ops inet6_stream_ops;
|
| 1187 | extern const struct proto_ops inet6_dgram_ops;
|
| 1188 | extern const struct proto_ops inet6_sockraw_ops;
|
| 1189 |
|
| 1190 | struct group_source_req;
|
| 1191 | struct group_filter;
|
| 1192 |
|
| 1193 | int ip6_mc_source(int add, int omode, struct sock *sk,
|
| 1194 | struct group_source_req *pgsr);
|
| 1195 | int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
|
| 1196 | struct sockaddr_storage *list);
|
| 1197 | int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
|
| 1198 | sockptr_t optval, size_t ss_offset);
|
| 1199 |
|
| 1200 | #ifdef CONFIG_PROC_FS
|
| 1201 | int ac6_proc_init(struct net *net);
|
| 1202 | void ac6_proc_exit(struct net *net);
|
| 1203 | int raw6_proc_init(void);
|
| 1204 | void raw6_proc_exit(void);
|
| 1205 | int tcp6_proc_init(struct net *net);
|
| 1206 | void tcp6_proc_exit(struct net *net);
|
| 1207 | int udp6_proc_init(struct net *net);
|
| 1208 | void udp6_proc_exit(struct net *net);
|
| 1209 | int ipv6_misc_proc_init(void);
|
| 1210 | void ipv6_misc_proc_exit(void);
|
| 1211 | int snmp6_register_dev(struct inet6_dev *idev);
|
| 1212 | int snmp6_unregister_dev(struct inet6_dev *idev);
|
| 1213 |
|
| 1214 | #else
|
| 1215 | static inline int ac6_proc_init(struct net *net) { return 0; }
|
| 1216 | static inline void ac6_proc_exit(struct net *net) { }
|
| 1217 | static inline int snmp6_register_dev(struct inet6_dev *idev) { return 0; }
|
| 1218 | static inline int snmp6_unregister_dev(struct inet6_dev *idev) { return 0; }
|
| 1219 | #endif
|
| 1220 |
|
| 1221 | #ifdef CONFIG_SYSCTL
|
| 1222 | struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
|
| 1223 | size_t ipv6_icmp_sysctl_table_size(void);
|
| 1224 | struct ctl_table *ipv6_route_sysctl_init(struct net *net);
|
| 1225 | size_t ipv6_route_sysctl_table_size(struct net *net);
|
| 1226 | int ipv6_sysctl_register(void);
|
| 1227 | void ipv6_sysctl_unregister(void);
|
| 1228 | #endif
|
| 1229 |
|
| 1230 | int ipv6_sock_mc_join(struct sock *sk, int ifindex,
|
| 1231 | const struct in6_addr *addr);
|
| 1232 | int ipv6_sock_mc_join_ssm(struct sock *sk, int ifindex,
|
| 1233 | const struct in6_addr *addr, unsigned int mode);
|
| 1234 | int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
|
| 1235 | const struct in6_addr *addr);
|
| 1236 |
|
| 1237 | static inline int ip6_sock_set_v6only(struct sock *sk)
|
| 1238 | {
|
| 1239 | int ret = 0;
|
| 1240 |
|
| 1241 | lock_sock(sk);
|
| 1242 | if (inet_sk(sk)->inet_num)
|
| 1243 | ret = -EINVAL;
|
| 1244 | else
|
| 1245 | sk->sk_ipv6only = true;
|
| 1246 | release_sock(sk);
|
| 1247 | return ret;
|
| 1248 | }
|
| 1249 |
|
| 1250 | static inline void ip6_sock_set_recverr(struct sock *sk)
|
| 1251 | {
|
| 1252 | inet6_set_bit(RECVERR6, sk);
|
| 1253 | }
|
| 1254 |
|
| 1255 | #define IPV6_PREFER_SRC_MASK (IPV6_PREFER_SRC_TMP | IPV6_PREFER_SRC_PUBLIC | \
|
| 1256 | IPV6_PREFER_SRC_COA)
|
| 1257 |
|
| 1258 | static inline int ip6_sock_set_addr_preferences(struct sock *sk, int val)
|
| 1259 | {
|
| 1260 | unsigned int prefmask = ~IPV6_PREFER_SRC_MASK;
|
| 1261 | unsigned int pref = 0;
|
| 1262 |
|
| 1263 |
|
| 1264 | switch (val & (IPV6_PREFER_SRC_PUBLIC |
|
| 1265 | IPV6_PREFER_SRC_TMP |
|
| 1266 | IPV6_PREFER_SRC_PUBTMP_DEFAULT)) {
|
| 1267 | case IPV6_PREFER_SRC_PUBLIC:
|
| 1268 | pref |= IPV6_PREFER_SRC_PUBLIC;
|
| 1269 | prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
|
| 1270 | IPV6_PREFER_SRC_TMP);
|
| 1271 | break;
|
| 1272 | case IPV6_PREFER_SRC_TMP:
|
| 1273 | pref |= IPV6_PREFER_SRC_TMP;
|
| 1274 | prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
|
| 1275 | IPV6_PREFER_SRC_TMP);
|
| 1276 | break;
|
| 1277 | case IPV6_PREFER_SRC_PUBTMP_DEFAULT:
|
| 1278 | prefmask &= ~(IPV6_PREFER_SRC_PUBLIC |
|
| 1279 | IPV6_PREFER_SRC_TMP);
|
| 1280 | break;
|
| 1281 | case 0:
|
| 1282 | break;
|
| 1283 | default:
|
| 1284 | return -EINVAL;
|
| 1285 | }
|
| 1286 |
|
| 1287 |
|
| 1288 | switch (val & (IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_COA)) {
|
| 1289 | case IPV6_PREFER_SRC_HOME:
|
| 1290 | prefmask &= ~IPV6_PREFER_SRC_COA;
|
| 1291 | break;
|
| 1292 | case IPV6_PREFER_SRC_COA:
|
| 1293 | pref |= IPV6_PREFER_SRC_COA;
|
| 1294 | break;
|
| 1295 | case 0:
|
| 1296 | break;
|
| 1297 | default:
|
| 1298 | return -EINVAL;
|
| 1299 | }
|
| 1300 |
|
| 1301 |
|
| 1302 | switch (val & (IPV6_PREFER_SRC_CGA|IPV6_PREFER_SRC_NONCGA)) {
|
| 1303 | case IPV6_PREFER_SRC_CGA:
|
| 1304 | case IPV6_PREFER_SRC_NONCGA:
|
| 1305 | case 0:
|
| 1306 | break;
|
| 1307 | default:
|
| 1308 | return -EINVAL;
|
| 1309 | }
|
| 1310 |
|
| 1311 | WRITE_ONCE(inet6_sk(sk)->srcprefs,
|
| 1312 | (READ_ONCE(inet6_sk(sk)->srcprefs) & prefmask) | pref);
|
| 1313 | return 0;
|
| 1314 | }
|
| 1315 |
|
| 1316 | static inline void ip6_sock_set_recvpktinfo(struct sock *sk)
|
| 1317 | {
|
| 1318 | lock_sock(sk);
|
| 1319 | inet6_sk(sk)->rxopt.bits.rxinfo = true;
|
| 1320 | release_sock(sk);
|
| 1321 | }
|
| 1322 |
|
| 1323 | #define IPV6_ADDR_WORDS 4
|
| 1324 |
|
| 1325 | static inline void ipv6_addr_cpu_to_be32(__be32 *dst, const u32 *src)
|
| 1326 | {
|
| 1327 | cpu_to_be32_array(dst, src, IPV6_ADDR_WORDS);
|
| 1328 | }
|
| 1329 |
|
| 1330 | static inline void ipv6_addr_be32_to_cpu(u32 *dst, const __be32 *src)
|
| 1331 | {
|
| 1332 | be32_to_cpu_array(dst, src, IPV6_ADDR_WORDS);
|
| 1333 | }
|
| 1334 |
|
| 1335 | #endif
|