LCOV - code coverage report
Current view: top level - include/net - ipv6.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 67 187 35.8 %
Date: 2022-03-28 13:20:08 Functions: 4 10 40.0 %
Branches: 46 338 13.6 %

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

Generated by: LCOV version 1.14