LCOV - code coverage report
Current view: top level - net/ipv6 - addrconf_core.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 78 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 20 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * IPv6 library code, needed by static components when full IPv6 support is
       4             :  * not configured or static.
       5             :  */
       6             : 
       7             : #include <linux/export.h>
       8             : #include <net/ipv6.h>
       9             : #include <net/ipv6_stubs.h>
      10             : #include <net/addrconf.h>
      11             : #include <net/ip.h>
      12             : 
      13             : /* if ipv6 module registers this function is used by xfrm to force all
      14             :  * sockets to relookup their nodes - this is fairly expensive, be
      15             :  * careful
      16             :  */
      17             : void (*__fib6_flush_trees)(struct net *);
      18             : EXPORT_SYMBOL(__fib6_flush_trees);
      19             : 
      20             : #define IPV6_ADDR_SCOPE_TYPE(scope)     ((scope) << 16)
      21             : 
      22           0 : static inline unsigned int ipv6_addr_scope2type(unsigned int scope)
      23             : {
      24           0 :         switch (scope) {
      25             :         case IPV6_ADDR_SCOPE_NODELOCAL:
      26             :                 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
      27             :                         IPV6_ADDR_LOOPBACK);
      28           0 :         case IPV6_ADDR_SCOPE_LINKLOCAL:
      29           0 :                 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
      30             :                         IPV6_ADDR_LINKLOCAL);
      31           0 :         case IPV6_ADDR_SCOPE_SITELOCAL:
      32           0 :                 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
      33             :                         IPV6_ADDR_SITELOCAL);
      34             :         }
      35           0 :         return IPV6_ADDR_SCOPE_TYPE(scope);
      36             : }
      37             : 
      38           0 : int __ipv6_addr_type(const struct in6_addr *addr)
      39             : {
      40           0 :         __be32 st;
      41             : 
      42           0 :         st = addr->s6_addr32[0];
      43             : 
      44             :         /* Consider all addresses with the first three bits different of
      45             :            000 and 111 as unicasts.
      46             :          */
      47           0 :         if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
      48             :             (st & htonl(0xE0000000)) != htonl(0xE0000000))
      49             :                 return (IPV6_ADDR_UNICAST |
      50             :                         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
      51             : 
      52           0 :         if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
      53             :                 /* multicast */
      54             :                 /* addr-select 3.1 */
      55           0 :                 return (IPV6_ADDR_MULTICAST |
      56           0 :                         ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
      57             :         }
      58             : 
      59           0 :         if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
      60             :                 return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
      61             :                         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));               /* addr-select 3.1 */
      62           0 :         if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
      63             :                 return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
      64             :                         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));               /* addr-select 3.1 */
      65           0 :         if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
      66             :                 return (IPV6_ADDR_UNICAST |
      67             :                         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));                  /* RFC 4193 */
      68             : 
      69           0 :         if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
      70           0 :                 if (addr->s6_addr32[2] == 0) {
      71           0 :                         if (addr->s6_addr32[3] == 0)
      72             :                                 return IPV6_ADDR_ANY;
      73             : 
      74           0 :                         if (addr->s6_addr32[3] == htonl(0x00000001))
      75             :                                 return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
      76             :                                         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));       /* addr-select 3.4 */
      77             : 
      78           0 :                         return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
      79             :                                 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
      80             :                 }
      81             : 
      82           0 :                 if (addr->s6_addr32[2] == htonl(0x0000ffff))
      83           0 :                         return (IPV6_ADDR_MAPPED |
      84             :                                 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
      85             :         }
      86             : 
      87             :         return (IPV6_ADDR_UNICAST |
      88             :                 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.4 */
      89             : }
      90             : EXPORT_SYMBOL(__ipv6_addr_type);
      91             : 
      92             : static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
      93             : static BLOCKING_NOTIFIER_HEAD(inet6addr_validator_chain);
      94             : 
      95           0 : int register_inet6addr_notifier(struct notifier_block *nb)
      96             : {
      97           0 :         return atomic_notifier_chain_register(&inet6addr_chain, nb);
      98             : }
      99             : EXPORT_SYMBOL(register_inet6addr_notifier);
     100             : 
     101           0 : int unregister_inet6addr_notifier(struct notifier_block *nb)
     102             : {
     103           0 :         return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
     104             : }
     105             : EXPORT_SYMBOL(unregister_inet6addr_notifier);
     106             : 
     107           0 : int inet6addr_notifier_call_chain(unsigned long val, void *v)
     108             : {
     109           0 :         return atomic_notifier_call_chain(&inet6addr_chain, val, v);
     110             : }
     111             : EXPORT_SYMBOL(inet6addr_notifier_call_chain);
     112             : 
     113           0 : int register_inet6addr_validator_notifier(struct notifier_block *nb)
     114             : {
     115           0 :         return blocking_notifier_chain_register(&inet6addr_validator_chain, nb);
     116             : }
     117             : EXPORT_SYMBOL(register_inet6addr_validator_notifier);
     118             : 
     119           0 : int unregister_inet6addr_validator_notifier(struct notifier_block *nb)
     120             : {
     121           0 :         return blocking_notifier_chain_unregister(&inet6addr_validator_chain,
     122             :                                                   nb);
     123             : }
     124             : EXPORT_SYMBOL(unregister_inet6addr_validator_notifier);
     125             : 
     126           0 : int inet6addr_validator_notifier_call_chain(unsigned long val, void *v)
     127             : {
     128           0 :         return blocking_notifier_call_chain(&inet6addr_validator_chain, val, v);
     129             : }
     130             : EXPORT_SYMBOL(inet6addr_validator_notifier_call_chain);
     131             : 
     132           0 : static struct dst_entry *eafnosupport_ipv6_dst_lookup_flow(struct net *net,
     133             :                                                            const struct sock *sk,
     134             :                                                            struct flowi6 *fl6,
     135             :                                                            const struct in6_addr *final_dst)
     136             : {
     137           0 :         return ERR_PTR(-EAFNOSUPPORT);
     138             : }
     139             : 
     140           0 : static int eafnosupport_ipv6_route_input(struct sk_buff *skb)
     141             : {
     142           0 :         return -EAFNOSUPPORT;
     143             : }
     144             : 
     145           0 : static struct fib6_table *eafnosupport_fib6_get_table(struct net *net, u32 id)
     146             : {
     147           0 :         return NULL;
     148             : }
     149             : 
     150             : static int
     151           0 : eafnosupport_fib6_table_lookup(struct net *net, struct fib6_table *table,
     152             :                                int oif, struct flowi6 *fl6,
     153             :                                struct fib6_result *res, int flags)
     154             : {
     155           0 :         return -EAFNOSUPPORT;
     156             : }
     157             : 
     158             : static int
     159           0 : eafnosupport_fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
     160             :                          struct fib6_result *res, int flags)
     161             : {
     162           0 :         return -EAFNOSUPPORT;
     163             : }
     164             : 
     165             : static void
     166           0 : eafnosupport_fib6_select_path(const struct net *net, struct fib6_result *res,
     167             :                               struct flowi6 *fl6, int oif, bool have_oif_match,
     168             :                               const struct sk_buff *skb, int strict)
     169             : {
     170           0 : }
     171             : 
     172             : static u32
     173           0 : eafnosupport_ip6_mtu_from_fib6(const struct fib6_result *res,
     174             :                                const struct in6_addr *daddr,
     175             :                                const struct in6_addr *saddr)
     176             : {
     177           0 :         return 0;
     178             : }
     179             : 
     180           0 : static int eafnosupport_fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
     181             :                                      struct fib6_config *cfg, gfp_t gfp_flags,
     182             :                                      struct netlink_ext_ack *extack)
     183             : {
     184           0 :         NL_SET_ERR_MSG(extack, "IPv6 support not enabled in kernel");
     185           0 :         return -EAFNOSUPPORT;
     186             : }
     187             : 
     188           0 : static int eafnosupport_ip6_del_rt(struct net *net, struct fib6_info *rt,
     189             :                                    bool skip_notify)
     190             : {
     191           0 :         return -EAFNOSUPPORT;
     192             : }
     193             : 
     194           0 : static int eafnosupport_ipv6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
     195             :                                       int (*output)(struct net *, struct sock *, struct sk_buff *))
     196             : {
     197           0 :         kfree_skb(skb);
     198           0 :         return -EAFNOSUPPORT;
     199             : }
     200             : 
     201             : const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) {
     202             :         .ipv6_dst_lookup_flow = eafnosupport_ipv6_dst_lookup_flow,
     203             :         .ipv6_route_input  = eafnosupport_ipv6_route_input,
     204             :         .fib6_get_table    = eafnosupport_fib6_get_table,
     205             :         .fib6_table_lookup = eafnosupport_fib6_table_lookup,
     206             :         .fib6_lookup       = eafnosupport_fib6_lookup,
     207             :         .fib6_select_path  = eafnosupport_fib6_select_path,
     208             :         .ip6_mtu_from_fib6 = eafnosupport_ip6_mtu_from_fib6,
     209             :         .fib6_nh_init      = eafnosupport_fib6_nh_init,
     210             :         .ip6_del_rt        = eafnosupport_ip6_del_rt,
     211             :         .ipv6_fragment     = eafnosupport_ipv6_fragment,
     212             : };
     213             : EXPORT_SYMBOL_GPL(ipv6_stub);
     214             : 
     215             : /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
     216             : const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
     217             : EXPORT_SYMBOL(in6addr_loopback);
     218             : const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
     219             : EXPORT_SYMBOL(in6addr_any);
     220             : const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
     221             : EXPORT_SYMBOL(in6addr_linklocal_allnodes);
     222             : const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
     223             : EXPORT_SYMBOL(in6addr_linklocal_allrouters);
     224             : const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
     225             : EXPORT_SYMBOL(in6addr_interfacelocal_allnodes);
     226             : const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
     227             : EXPORT_SYMBOL(in6addr_interfacelocal_allrouters);
     228             : const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
     229             : EXPORT_SYMBOL(in6addr_sitelocal_allrouters);
     230             : 
     231           0 : static void snmp6_free_dev(struct inet6_dev *idev)
     232             : {
     233           0 :         kfree(idev->stats.icmpv6msgdev);
     234           0 :         kfree(idev->stats.icmpv6dev);
     235           0 :         free_percpu(idev->stats.ipv6);
     236           0 : }
     237             : 
     238           0 : static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
     239             : {
     240           0 :         struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
     241             : 
     242           0 :         snmp6_free_dev(idev);
     243           0 :         kfree(idev);
     244           0 : }
     245             : 
     246             : /* Nobody refers to this device, we may destroy it. */
     247             : 
     248           0 : void in6_dev_finish_destroy(struct inet6_dev *idev)
     249             : {
     250           0 :         struct net_device *dev = idev->dev;
     251             : 
     252           0 :         WARN_ON(!list_empty(&idev->addr_list));
     253           0 :         WARN_ON(idev->mc_list);
     254           0 :         WARN_ON(timer_pending(&idev->rs_timer));
     255             : 
     256             : #ifdef NET_REFCNT_DEBUG
     257             :         pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL");
     258             : #endif
     259           0 :         dev_put(dev);
     260           0 :         if (!idev->dead) {
     261           0 :                 pr_warn("Freeing alive inet6 device %p\n", idev);
     262           0 :                 return;
     263             :         }
     264           0 :         call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
     265             : }
     266             : EXPORT_SYMBOL(in6_dev_finish_destroy);

Generated by: LCOV version 1.14