tree:
https://github.com/0day-ci/linux/commits/UPDATE-20201112-234813/Dmytro-Sh...
head: b0c2d7a5f4037f89bed41815642b876706243575
commit: b0c2d7a5f4037f89bed41815642b876706243575 [1/1] net: Variable SLAAC: SLAAC with
prefixes of arbitrary length in PIO
config: i386-randconfig-m021-20201113 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
New smatch warnings:
net/ipv6/addrconf.c:2888 addrconf_prefix_rcv() warn: inconsistent indenting
net/ipv6/addrconf.c:2888 addrconf_prefix_rcv() warn: ignoring unreachable code.
Old smatch warnings:
net/ipv6/addrconf.c:3757 addrconf_notify() error: potential null dereference
'idev'. (ipv6_add_dev returns null)
vim +2888 net/ipv6/addrconf.c
2763
2764 void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
2765 {
2766 struct prefix_info *pinfo;
2767 __u32 valid_lft;
2768 __u32 prefered_lft;
2769 int addr_type, err;
2770 u32 addr_flags = 0;
2771 struct inet6_dev *in6_dev;
2772 struct net *net = dev_net(dev);
2773
2774 pinfo = (struct prefix_info *) opt;
2775
2776 if (len < sizeof(struct prefix_info)) {
2777 netdev_dbg(dev, "addrconf: prefix option too short\n");
2778 return;
2779 }
2780
2781 /*
2782 * Validation checks ([ADDRCONF], page 19)
2783 */
2784
2785 addr_type = ipv6_addr_type(&pinfo->prefix);
2786
2787 if (addr_type & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL))
2788 return;
2789
2790 valid_lft = ntohl(pinfo->valid);
2791 prefered_lft = ntohl(pinfo->prefered);
2792
2793 if (prefered_lft > valid_lft) {
2794 net_warn_ratelimited("addrconf: prefix option has invalid
lifetime\n");
2795 return;
2796 }
2797
2798 in6_dev = in6_dev_get(dev);
2799
2800 if (!in6_dev) {
2801 net_dbg_ratelimited("addrconf: device %s not configured\n",
2802 dev->name);
2803 return;
2804 }
2805
2806 /*
2807 * Two things going on here:
2808 * 1) Add routes for on-link prefixes
2809 * 2) Configure prefixes with the auto flag set
2810 */
2811
2812 if (pinfo->onlink) {
2813 struct fib6_info *rt;
2814 unsigned long rt_expires;
2815
2816 /* Avoid arithmetic overflow. Really, we could
2817 * save rt_expires in seconds, likely valid_lft,
2818 * but it would require division in fib gc, that it
2819 * not good.
2820 */
2821 if (HZ > USER_HZ)
2822 rt_expires = addrconf_timeout_fixup(valid_lft, HZ);
2823 else
2824 rt_expires = addrconf_timeout_fixup(valid_lft, USER_HZ);
2825
2826 if (addrconf_finite_timeout(rt_expires))
2827 rt_expires *= HZ;
2828
2829 rt = addrconf_get_prefix_route(&pinfo->prefix,
2830 pinfo->prefix_len,
2831 dev,
2832 RTF_ADDRCONF | RTF_PREFIX_RT,
2833 RTF_DEFAULT, true);
2834
2835 if (rt) {
2836 /* Autoconf prefix route */
2837 if (valid_lft == 0) {
2838 ip6_del_rt(net, rt, false);
2839 rt = NULL;
2840 } else if (addrconf_finite_timeout(rt_expires)) {
2841 /* not infinity */
2842 fib6_set_expires(rt, jiffies + rt_expires);
2843 } else {
2844 fib6_clean_expires(rt);
2845 }
2846 } else if (valid_lft) {
2847 clock_t expires = 0;
2848 int flags = RTF_ADDRCONF | RTF_PREFIX_RT;
2849 if (addrconf_finite_timeout(rt_expires)) {
2850 /* not infinity */
2851 flags |= RTF_EXPIRES;
2852 expires = jiffies_to_clock_t(rt_expires);
2853 }
2854 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
2855 0, dev, expires, flags,
2856 GFP_ATOMIC);
2857 }
2858 fib6_info_release(rt);
2859 }
2860
2861 /* Try to figure out our local address for this prefix */
2862
2863 if (pinfo->autoconf && in6_dev->cnf.autoconf) {
2864 struct in6_addr addr;
2865 bool tokenized = false, dev_addr_generated = false;
2866
2867 if (pinfo->prefix_len == 64) {
2868 memcpy(&addr, &pinfo->prefix, 8);
2869
2870 if (!ipv6_addr_any(&in6_dev->token)) {
2871 read_lock_bh(&in6_dev->lock);
2872 memcpy(addr.s6_addr + 8,
2873 in6_dev->token.s6_addr + 8, 8);
2874 read_unlock_bh(&in6_dev->lock);
2875 tokenized = true;
2876 } else if (is_addr_mode_generate_stable(in6_dev) &&
2877 !ipv6_generate_stable_address(&addr, 0,
2878 in6_dev)) {
2879 addr_flags |= IFA_F_STABLE_PRIVACY;
2880 goto ok;
2881 } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
2882 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
2883 goto put;
2884 } else {
2885 dev_addr_generated = true;
2886 }
2887 goto ok;
2888 goto put;
2889 } else if (((in6_dev->if_flags
& IF_RA_VAR_PLEN) == IF_RA_VAR_PLEN) &&
2890 pinfo->prefix_len > 0 && pinfo->prefix_len <= 128) {
2891 /* SLAAC with prefixes of arbitrary length (Variable SLAAC).
2892 * draft-mishra-6man-variable-slaac
2893 * draft-mishra-v6ops-variable-slaac-problem-stmt
2894 * Contact: Dmytro Shytyi.
2895 */
2896 memcpy(&addr, &pinfo->prefix, 16);
2897 if (in6_dev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY) {
2898 if (!ipv6_generate_address_variable_plen(&addr,
2899 0,
2900 in6_dev,
2901 pinfo->prefix_len,
2902 true)) {
2903 addr_flags |= IFA_F_STABLE_PRIVACY;
2904 goto ok;
2905 }
2906 } else if (!ipv6_generate_address_variable_plen(&addr,
2907 0,
2908 in6_dev,
2909 pinfo->prefix_len,
2910 false)) {
2911 goto ok;
2912 }
2913 } else {
2914 net_dbg_ratelimited("IPv6: Prefix with unexpected length %d\n",
2915 pinfo->prefix_len);
2916 }
2917 goto put;
2918
2919 ok:
2920 err = addrconf_prefix_rcv_add_addr(net, dev, pinfo, in6_dev,
2921 &addr, addr_type,
2922 addr_flags, sllao,
2923 tokenized, valid_lft,
2924 prefered_lft);
2925 if (err)
2926 goto put;
2927
2928 /* Ignore error case here because previous prefix add addr was
2929 * successful which will be notified.
2930 */
2931 ndisc_ops_prefix_rcv_add_addr(net, dev, pinfo, in6_dev, &addr,
2932 addr_type, addr_flags, sllao,
2933 tokenized, valid_lft,
2934 prefered_lft,
2935 dev_addr_generated);
2936 }
2937 inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo);
2938 put:
2939 in6_dev_put(in6_dev);
2940 }
2941
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org