Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * IPv6 library code, needed by static components when full IPv6 support is
0004  * not configured or static.
0005  */
0006 
0007 #include <linux/export.h>
0008 #include <net/ipv6.h>
0009 #include <net/ipv6_stubs.h>
0010 #include <net/addrconf.h>
0011 #include <net/ip.h>
0012 
0013 /* if ipv6 module registers this function is used by xfrm to force all
0014  * sockets to relookup their nodes - this is fairly expensive, be
0015  * careful
0016  */
0017 void (*__fib6_flush_trees)(struct net *);
0018 EXPORT_SYMBOL(__fib6_flush_trees);
0019 
0020 #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
0021 
0022 static inline unsigned int ipv6_addr_scope2type(unsigned int scope)
0023 {
0024     switch (scope) {
0025     case IPV6_ADDR_SCOPE_NODELOCAL:
0026         return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
0027             IPV6_ADDR_LOOPBACK);
0028     case IPV6_ADDR_SCOPE_LINKLOCAL:
0029         return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
0030             IPV6_ADDR_LINKLOCAL);
0031     case IPV6_ADDR_SCOPE_SITELOCAL:
0032         return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
0033             IPV6_ADDR_SITELOCAL);
0034     }
0035     return IPV6_ADDR_SCOPE_TYPE(scope);
0036 }
0037 
0038 int __ipv6_addr_type(const struct in6_addr *addr)
0039 {
0040     __be32 st;
0041 
0042     st = addr->s6_addr32[0];
0043 
0044     /* Consider all addresses with the first three bits different of
0045        000 and 111 as unicasts.
0046      */
0047     if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
0048         (st & htonl(0xE0000000)) != htonl(0xE0000000))
0049         return (IPV6_ADDR_UNICAST |
0050             IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
0051 
0052     if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
0053         /* multicast */
0054         /* addr-select 3.1 */
0055         return (IPV6_ADDR_MULTICAST |
0056             ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
0057     }
0058 
0059     if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
0060         return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
0061             IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));       /* addr-select 3.1 */
0062     if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
0063         return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
0064             IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));       /* addr-select 3.1 */
0065     if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
0066         return (IPV6_ADDR_UNICAST |
0067             IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));          /* RFC 4193 */
0068 
0069     if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
0070         if (addr->s6_addr32[2] == 0) {
0071             if (addr->s6_addr32[3] == 0)
0072                 return IPV6_ADDR_ANY;
0073 
0074             if (addr->s6_addr32[3] == htonl(0x00000001))
0075                 return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
0076                     IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));   /* addr-select 3.4 */
0077 
0078             return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
0079                 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
0080         }
0081 
0082         if (addr->s6_addr32[2] == htonl(0x0000ffff))
0083             return (IPV6_ADDR_MAPPED |
0084                 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
0085     }
0086 
0087     return (IPV6_ADDR_UNICAST |
0088         IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.4 */
0089 }
0090 EXPORT_SYMBOL(__ipv6_addr_type);
0091 
0092 static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
0093 static BLOCKING_NOTIFIER_HEAD(inet6addr_validator_chain);
0094 
0095 int register_inet6addr_notifier(struct notifier_block *nb)
0096 {
0097     return atomic_notifier_chain_register(&inet6addr_chain, nb);
0098 }
0099 EXPORT_SYMBOL(register_inet6addr_notifier);
0100 
0101 int unregister_inet6addr_notifier(struct notifier_block *nb)
0102 {
0103     return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
0104 }
0105 EXPORT_SYMBOL(unregister_inet6addr_notifier);
0106 
0107 int inet6addr_notifier_call_chain(unsigned long val, void *v)
0108 {
0109     return atomic_notifier_call_chain(&inet6addr_chain, val, v);
0110 }
0111 EXPORT_SYMBOL(inet6addr_notifier_call_chain);
0112 
0113 int register_inet6addr_validator_notifier(struct notifier_block *nb)
0114 {
0115     return blocking_notifier_chain_register(&inet6addr_validator_chain, nb);
0116 }
0117 EXPORT_SYMBOL(register_inet6addr_validator_notifier);
0118 
0119 int unregister_inet6addr_validator_notifier(struct notifier_block *nb)
0120 {
0121     return blocking_notifier_chain_unregister(&inet6addr_validator_chain,
0122                           nb);
0123 }
0124 EXPORT_SYMBOL(unregister_inet6addr_validator_notifier);
0125 
0126 int inet6addr_validator_notifier_call_chain(unsigned long val, void *v)
0127 {
0128     return blocking_notifier_call_chain(&inet6addr_validator_chain, val, v);
0129 }
0130 EXPORT_SYMBOL(inet6addr_validator_notifier_call_chain);
0131 
0132 static struct dst_entry *eafnosupport_ipv6_dst_lookup_flow(struct net *net,
0133                                const struct sock *sk,
0134                                struct flowi6 *fl6,
0135                                const struct in6_addr *final_dst)
0136 {
0137     return ERR_PTR(-EAFNOSUPPORT);
0138 }
0139 
0140 static int eafnosupport_ipv6_route_input(struct sk_buff *skb)
0141 {
0142     return -EAFNOSUPPORT;
0143 }
0144 
0145 static struct fib6_table *eafnosupport_fib6_get_table(struct net *net, u32 id)
0146 {
0147     return NULL;
0148 }
0149 
0150 static int
0151 eafnosupport_fib6_table_lookup(struct net *net, struct fib6_table *table,
0152                    int oif, struct flowi6 *fl6,
0153                    struct fib6_result *res, int flags)
0154 {
0155     return -EAFNOSUPPORT;
0156 }
0157 
0158 static int
0159 eafnosupport_fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
0160              struct fib6_result *res, int flags)
0161 {
0162     return -EAFNOSUPPORT;
0163 }
0164 
0165 static void
0166 eafnosupport_fib6_select_path(const struct net *net, struct fib6_result *res,
0167                   struct flowi6 *fl6, int oif, bool have_oif_match,
0168                   const struct sk_buff *skb, int strict)
0169 {
0170 }
0171 
0172 static u32
0173 eafnosupport_ip6_mtu_from_fib6(const struct fib6_result *res,
0174                    const struct in6_addr *daddr,
0175                    const struct in6_addr *saddr)
0176 {
0177     return 0;
0178 }
0179 
0180 static int eafnosupport_fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
0181                      struct fib6_config *cfg, gfp_t gfp_flags,
0182                      struct netlink_ext_ack *extack)
0183 {
0184     NL_SET_ERR_MSG(extack, "IPv6 support not enabled in kernel");
0185     return -EAFNOSUPPORT;
0186 }
0187 
0188 static int eafnosupport_ip6_del_rt(struct net *net, struct fib6_info *rt,
0189                    bool skip_notify)
0190 {
0191     return -EAFNOSUPPORT;
0192 }
0193 
0194 static int eafnosupport_ipv6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
0195                       int (*output)(struct net *, struct sock *, struct sk_buff *))
0196 {
0197     kfree_skb(skb);
0198     return -EAFNOSUPPORT;
0199 }
0200 
0201 static struct net_device *eafnosupport_ipv6_dev_find(struct net *net, const struct in6_addr *addr,
0202                              struct net_device *dev)
0203 {
0204     return ERR_PTR(-EAFNOSUPPORT);
0205 }
0206 
0207 const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) {
0208     .ipv6_dst_lookup_flow = eafnosupport_ipv6_dst_lookup_flow,
0209     .ipv6_route_input  = eafnosupport_ipv6_route_input,
0210     .fib6_get_table    = eafnosupport_fib6_get_table,
0211     .fib6_table_lookup = eafnosupport_fib6_table_lookup,
0212     .fib6_lookup       = eafnosupport_fib6_lookup,
0213     .fib6_select_path  = eafnosupport_fib6_select_path,
0214     .ip6_mtu_from_fib6 = eafnosupport_ip6_mtu_from_fib6,
0215     .fib6_nh_init      = eafnosupport_fib6_nh_init,
0216     .ip6_del_rt    = eafnosupport_ip6_del_rt,
0217     .ipv6_fragment     = eafnosupport_ipv6_fragment,
0218     .ipv6_dev_find     = eafnosupport_ipv6_dev_find,
0219 };
0220 EXPORT_SYMBOL_GPL(ipv6_stub);
0221 
0222 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
0223 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
0224 EXPORT_SYMBOL(in6addr_loopback);
0225 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
0226 EXPORT_SYMBOL(in6addr_any);
0227 const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
0228 EXPORT_SYMBOL(in6addr_linklocal_allnodes);
0229 const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
0230 EXPORT_SYMBOL(in6addr_linklocal_allrouters);
0231 const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
0232 EXPORT_SYMBOL(in6addr_interfacelocal_allnodes);
0233 const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
0234 EXPORT_SYMBOL(in6addr_interfacelocal_allrouters);
0235 const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
0236 EXPORT_SYMBOL(in6addr_sitelocal_allrouters);
0237 
0238 static void snmp6_free_dev(struct inet6_dev *idev)
0239 {
0240     kfree(idev->stats.icmpv6msgdev);
0241     kfree(idev->stats.icmpv6dev);
0242     free_percpu(idev->stats.ipv6);
0243 }
0244 
0245 static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
0246 {
0247     struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
0248 
0249     snmp6_free_dev(idev);
0250     kfree(idev);
0251 }
0252 
0253 /* Nobody refers to this device, we may destroy it. */
0254 
0255 void in6_dev_finish_destroy(struct inet6_dev *idev)
0256 {
0257     struct net_device *dev = idev->dev;
0258 
0259     WARN_ON(!list_empty(&idev->addr_list));
0260     WARN_ON(rcu_access_pointer(idev->mc_list));
0261     WARN_ON(timer_pending(&idev->rs_timer));
0262 
0263 #ifdef NET_REFCNT_DEBUG
0264     pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL");
0265 #endif
0266     netdev_put(dev, &idev->dev_tracker);
0267     if (!idev->dead) {
0268         pr_warn("Freeing alive inet6 device %p\n", idev);
0269         return;
0270     }
0271     call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
0272 }
0273 EXPORT_SYMBOL(in6_dev_finish_destroy);