head 1.183; access; symbols netbsd-10-0-RELEASE:1.183 netbsd-10-0-RC6:1.183 netbsd-10-0-RC5:1.183 netbsd-10-0-RC4:1.183 netbsd-10-0-RC3:1.183 netbsd-10-0-RC2:1.183 thorpej-ifq:1.183.0.8 thorpej-ifq-base:1.183 thorpej-altq-separation:1.183.0.6 thorpej-altq-separation-base:1.183 netbsd-10-0-RC1:1.183 netbsd-10:1.183.0.4 netbsd-10-base:1.183 bouyer-sunxi-drm:1.183.0.2 bouyer-sunxi-drm-base:1.183 netbsd-9-3-RELEASE:1.147.4.2 thorpej-i2c-spi-conf2:1.177.0.6 thorpej-i2c-spi-conf2-base:1.177 thorpej-futex2:1.177.0.4 thorpej-futex2-base:1.177 thorpej-cfargs2:1.177.0.2 thorpej-cfargs2-base:1.177 cjep_sun2x-base1:1.176 cjep_sun2x:1.176.0.2 cjep_sun2x-base:1.176 cjep_staticlib_x-base1:1.176 netbsd-9-2-RELEASE:1.147.4.1 cjep_staticlib_x:1.170.0.4 cjep_staticlib_x-base:1.170 thorpej-i2c-spi-conf:1.170.0.2 thorpej-i2c-spi-conf-base:1.177 thorpej-cfargs:1.158.0.2 thorpej-cfargs-base:1.169 thorpej-futex:1.153.0.2 thorpej-futex-base:1.158 netbsd-9-1-RELEASE:1.147.4.1 bouyer-xenpvh-base2:1.149 phil-wifi-20200421:1.149 bouyer-xenpvh-base1:1.149 phil-wifi-20200411:1.149 bouyer-xenpvh:1.149.0.4 bouyer-xenpvh-base:1.149 is-mlppp:1.149.0.2 is-mlppp-base:1.149 phil-wifi-20200406:1.149 netbsd-8-2-RELEASE:1.125.6.10 ad-namecache-base3:1.149 netbsd-9-0-RELEASE:1.147.4.1 netbsd-9-0-RC2:1.147 ad-namecache-base2:1.147 ad-namecache-base1:1.147 ad-namecache:1.147.0.6 ad-namecache-base:1.147 netbsd-9-0-RC1:1.147 phil-wifi-20191119:1.147 netbsd-9:1.147.0.4 netbsd-9-base:1.147 phil-wifi-20190609:1.147 netbsd-8-1-RELEASE:1.125.6.9 netbsd-8-1-RC1:1.125.6.9 isaki-audio2:1.147.0.2 isaki-audio2-base:1.147 pgoyette-compat-merge-20190127:1.134.2.7 pgoyette-compat-20190127:1.146 pgoyette-compat-20190118:1.146 pgoyette-compat-1226:1.146 pgoyette-compat-1126:1.146 pgoyette-compat-1020:1.144 pgoyette-compat-0930:1.143 pgoyette-compat-0906:1.143 netbsd-7-2-RELEASE:1.101 pgoyette-compat-0728:1.141 netbsd-8-0-RELEASE:1.125.6.9 phil-wifi:1.141.0.2 phil-wifi-base:1.141 pgoyette-compat-0625:1.140 netbsd-8-0-RC2:1.125.6.8 pgoyette-compat-0521:1.137 pgoyette-compat-0502:1.136 pgoyette-compat-0422:1.136 netbsd-8-0-RC1:1.125.6.7 pgoyette-compat-0415:1.134 pgoyette-compat-0407:1.134 pgoyette-compat-0330:1.134 pgoyette-compat-0322:1.134 pgoyette-compat-0315:1.134 netbsd-7-1-2-RELEASE:1.101 pgoyette-compat:1.134.0.2 pgoyette-compat-base:1.134 netbsd-7-1-1-RELEASE:1.101 tls-maxphys-base-20171202:1.132 matt-nb8-mediatek:1.125.6.2.0.2 matt-nb8-mediatek-base:1.125.6.2 nick-nhusb-base-20170825:1.126 perseant-stdc-iso10646:1.125.0.8 perseant-stdc-iso10646-base:1.125 netbsd-8:1.125.0.6 netbsd-8-base:1.125 prg-localcount2-base3:1.125 prg-localcount2-base2:1.125 prg-localcount2-base1:1.125 prg-localcount2:1.125.0.4 prg-localcount2-base:1.125 pgoyette-localcount-20170426:1.125 bouyer-socketcan-base1:1.125 jdolecek-ncq:1.125.0.2 jdolecek-ncq-base:1.125 pgoyette-localcount-20170320:1.125 netbsd-7-1:1.101.0.10 netbsd-7-1-RELEASE:1.101 netbsd-7-1-RC2:1.101 nick-nhusb-base-20170204:1.124 netbsd-7-nhusb-base-20170116:1.101 bouyer-socketcan:1.123.0.2 bouyer-socketcan-base:1.123 pgoyette-localcount-20170107:1.123 netbsd-7-1-RC1:1.101 nick-nhusb-base-20161204:1.119 pgoyette-localcount-20161104:1.118 netbsd-7-0-2-RELEASE:1.101 nick-nhusb-base-20161004:1.118 localcount-20160914:1.117 netbsd-7-nhusb:1.101.0.8 netbsd-7-nhusb-base:1.101 pgoyette-localcount-20160806:1.111 pgoyette-localcount-20160726:1.111 pgoyette-localcount:1.111.0.2 pgoyette-localcount-base:1.111 nick-nhusb-base-20160907:1.111 nick-nhusb-base-20160529:1.106 netbsd-7-0-1-RELEASE:1.101 nick-nhusb-base-20160422:1.105 nick-nhusb-base-20160319:1.104 nick-nhusb-base-20151226:1.104 netbsd-7-0:1.101.0.6 netbsd-7-0-RELEASE:1.101 nick-nhusb-base-20150921:1.104 netbsd-7-0-RC3:1.101 netbsd-7-0-RC2:1.101 netbsd-7-0-RC1:1.101 nick-nhusb-base-20150606:1.102 nick-nhusb-base-20150406:1.102 nick-nhusb:1.102.0.2 nick-nhusb-base:1.102 netbsd-5-2-3-RELEASE:1.93.4.1 netbsd-5-1-5-RELEASE:1.93.4.1 netbsd-6-0-6-RELEASE:1.98 netbsd-6-1-5-RELEASE:1.98 netbsd-7:1.101.0.4 netbsd-7-base:1.101 yamt-pagecache-base9:1.101 yamt-pagecache-tag8:1.98 netbsd-6-1-4-RELEASE:1.98 netbsd-6-0-5-RELEASE:1.98 tls-earlyentropy:1.101.0.2 tls-earlyentropy-base:1.101 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.101 riastradh-drm2-base3:1.101 netbsd-6-1-3-RELEASE:1.98 netbsd-6-0-4-RELEASE:1.98 netbsd-5-2-2-RELEASE:1.93.4.1 netbsd-5-1-4-RELEASE:1.93.4.1 netbsd-6-1-2-RELEASE:1.98 netbsd-6-0-3-RELEASE:1.98 netbsd-5-2-1-RELEASE:1.93.4.1 netbsd-5-1-3-RELEASE:1.93.4.1 rmind-smpnet-nbase:1.101 netbsd-6-1-1-RELEASE:1.98 riastradh-drm2-base2:1.100 riastradh-drm2-base1:1.100 riastradh-drm2:1.100.0.2 riastradh-drm2-base:1.100 rmind-smpnet:1.98.0.16 rmind-smpnet-base:1.101 netbsd-6-1:1.98.0.22 netbsd-6-0-2-RELEASE:1.98 netbsd-6-1-RELEASE:1.98 khorben-n900:1.98.0.20 netbsd-6-1-RC4:1.98 netbsd-6-1-RC3:1.98 agc-symver:1.98.0.18 agc-symver-base:1.98 netbsd-6-1-RC2:1.98 netbsd-6-1-RC1:1.98 yamt-pagecache-base8:1.98 netbsd-5-2:1.93.4.1.0.10 netbsd-6-0-1-RELEASE:1.98 yamt-pagecache-base7:1.98 netbsd-5-2-RELEASE:1.93.4.1 netbsd-5-2-RC1:1.93.4.1 matt-nb6-plus-nbase:1.98 yamt-pagecache-base6:1.98 netbsd-6-0:1.98.0.14 netbsd-6-0-RELEASE:1.98 netbsd-6-0-RC2:1.98 tls-maxphys:1.98.0.12 tls-maxphys-base:1.101 matt-nb6-plus:1.98.0.10 matt-nb6-plus-base:1.98 netbsd-6-0-RC1:1.98 jmcneill-usbmp-base10:1.98 yamt-pagecache-base5:1.98 jmcneill-usbmp-base9:1.98 yamt-pagecache-base4:1.98 jmcneill-usbmp-base8:1.98 jmcneill-usbmp-base7:1.98 jmcneill-usbmp-base6:1.98 jmcneill-usbmp-base5:1.98 jmcneill-usbmp-base4:1.98 jmcneill-usbmp-base3:1.98 jmcneill-usbmp-pre-base2:1.98 jmcneill-usbmp-base2:1.98 netbsd-6:1.98.0.8 netbsd-6-base:1.98 netbsd-5-1-2-RELEASE:1.93.4.1 netbsd-5-1-1-RELEASE:1.93.4.1 jmcneill-usbmp:1.98.0.6 jmcneill-usbmp-base:1.98 jmcneill-audiomp3:1.98.0.4 jmcneill-audiomp3-base:1.98 yamt-pagecache-base3:1.98 yamt-pagecache-base2:1.98 yamt-pagecache:1.98.0.2 yamt-pagecache-base:1.98 rmind-uvmplock-nbase:1.96 cherry-xenmp:1.96.0.6 cherry-xenmp-base:1.96 bouyer-quota2-nbase:1.96 bouyer-quota2:1.96.0.4 bouyer-quota2-base:1.96 jruoho-x86intr:1.96.0.2 jruoho-x86intr-base:1.96 matt-mips64-premerge-20101231:1.96 matt-nb5-mips64-premerge-20101231:1.93.4.1 matt-nb5-pq3:1.93.4.1.0.8 matt-nb5-pq3-base:1.93.4.1 netbsd-5-1:1.93.4.1.0.6 netbsd-5-1-RELEASE:1.93.4.1 uebayasi-xip-base4:1.96 uebayasi-xip-base3:1.96 yamt-nfs-mp-base11:1.96 netbsd-5-1-RC4:1.93.4.1 matt-nb5-mips64-k15:1.93.4.1 uebayasi-xip-base2:1.96 yamt-nfs-mp-base10:1.96 netbsd-5-1-RC3:1.93.4.1 netbsd-5-1-RC2:1.93.4.1 uebayasi-xip-base1:1.96 netbsd-5-1-RC1:1.93.4.1 rmind-uvmplock:1.95.0.4 rmind-uvmplock-base:1.96 yamt-nfs-mp-base9:1.95 uebayasi-xip:1.95.0.2 uebayasi-xip-base:1.95 netbsd-5-0-2-RELEASE:1.93.4.1 matt-nb5-mips64-premerge-20091211:1.93.4.1 matt-premerge-20091211:1.94 yamt-nfs-mp-base8:1.94 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.93.4.1 matt-nb4-mips64-k7-u2a-k9b:1.93.4.1 matt-nb5-mips64-u1-k1-k5:1.93.4.1 yamt-nfs-mp-base7:1.94 matt-nb5-mips64:1.93.4.1.0.4 netbsd-5-0-1-RELEASE:1.93.4.1 jymxensuspend-base:1.94 yamt-nfs-mp-base6:1.94 yamt-nfs-mp-base5:1.94 yamt-nfs-mp-base4:1.94 jym-xensuspend-nbase:1.94 yamt-nfs-mp-base3:1.94 nick-hppapmap-base4:1.94 nick-hppapmap-base3:1.94 netbsd-5-0:1.93.4.1.0.2 netbsd-5-0-RELEASE:1.93.4.1 netbsd-5-0-RC4:1.93.4.1 netbsd-5-0-RC3:1.93.4.1 nick-hppapmap-base2:1.94 netbsd-5-0-RC2:1.93 jym-xensuspend:1.93.0.8 jym-xensuspend-base:1.94 netbsd-5-0-RC1:1.93 haad-dm-base2:1.93 haad-nbase2:1.93 ad-audiomp2:1.93.0.6 ad-audiomp2-base:1.93 netbsd-5:1.93.0.4 netbsd-5-base:1.93 nick-hppapmap:1.93.0.2 nick-hppapmap-base:1.94 matt-mips64-base2:1.93 matt-mips64:1.79.0.10 haad-dm-base1:1.93 wrstuden-revivesa-base-4:1.92 netbsd-4-0-1-RELEASE:1.76.2.1.4.1 wrstuden-revivesa-base-3:1.92 wrstuden-revivesa-base-2:1.92 wrstuden-fixsa-newbase:1.76.2.3 nick-csl-alignment-base5:1.80 haad-dm:1.87.0.2 haad-dm-base:1.93 wrstuden-revivesa-base-1:1.87 simonb-wapbl-nbase:1.87 yamt-pf42-base4:1.87 simonb-wapbl:1.86.0.4 simonb-wapbl-base:1.87 yamt-pf42-base3:1.86 hpcarm-cleanup-nbase:1.86 yamt-pf42-baseX:1.84 yamt-pf42-base2:1.86 yamt-nfs-mp-base2:1.86 wrstuden-revivesa:1.86.0.2 wrstuden-revivesa-base:1.87 yamt-nfs-mp:1.85.0.2 yamt-nfs-mp-base:1.85 yamt-pf42:1.84.0.8 yamt-pf42-base:1.84 ad-socklock-base1:1.84 yamt-lazymbuf-base15:1.84 yamt-lazymbuf-base14:1.84 keiichi-mipv6-nbase:1.84 mjf-devfs2:1.84.0.6 mjf-devfs2-base:1.93 nick-net80211-sync:1.84.0.4 nick-net80211-sync-base:1.84 keiichi-mipv6:1.84.0.2 keiichi-mipv6-base:1.84 bouyer-xeni386-merge1:1.81.10.1 matt-armv6-prevmlocking:1.79.8.1 wrstuden-fixsa-base-1:1.76.2.1 vmlocking2-base3:1.82 netbsd-4-0:1.76.2.1.0.4 netbsd-4-0-RELEASE:1.76.2.1 bouyer-xeni386-nbase:1.82 yamt-kmem-base3:1.81 cube-autoconf:1.81.0.12 cube-autoconf-base:1.81 yamt-kmem-base2:1.81 bouyer-xeni386:1.81.0.10 bouyer-xeni386-base:1.82 yamt-kmem:1.81.0.8 yamt-kmem-base:1.81 vmlocking2-base2:1.81 reinoud-bufcleanup-nbase:1.81 vmlocking2:1.81.0.6 vmlocking2-base1:1.81 netbsd-4-0-RC5:1.76.2.1 matt-nb4-arm:1.76.2.1.0.2 matt-nb4-arm-base:1.76.2.1 matt-armv6-nbase:1.84 jmcneill-base:1.81 netbsd-4-0-RC4:1.76.2.1 mjf-devfs:1.81.0.4 mjf-devfs-base:1.83 bouyer-xenamd64-base2:1.81 vmlocking-nbase:1.81 yamt-x86pmap-base4:1.81 bouyer-xenamd64:1.81.0.2 bouyer-xenamd64-base:1.81 netbsd-4-0-RC3:1.76.2.1 yamt-x86pmap-base3:1.81 yamt-x86pmap-base2:1.80 netbsd-4-0-RC2:1.76.2.1 yamt-x86pmap:1.80.0.2 yamt-x86pmap-base:1.80 netbsd-4-0-RC1:1.76 matt-armv6:1.79.0.8 matt-armv6-base:1.82 matt-mips64-base:1.79 jmcneill-pm:1.79.0.6 jmcneill-pm-base:1.81 hpcarm-cleanup:1.79.0.4 hpcarm-cleanup-base:1.84 nick-csl-alignment:1.79.0.2 nick-csl-alignment-base:1.79 netbsd-3-1-1-RELEASE:1.59.2.2.2.1 netbsd-3-0-3-RELEASE:1.59.4.1 yamt-idlelwp-base8:1.78 wrstuden-fixsa:1.76.0.8 wrstuden-fixsa-base:1.76.2.3 thorpej-atomic:1.78.0.2 thorpej-atomic-base:1.78 reinoud-bufcleanup:1.77.0.6 reinoud-bufcleanup-base:1.81 mjf-ufs-trans:1.77.0.4 mjf-ufs-trans-base:1.79 vmlocking:1.77.0.2 vmlocking-base:1.81 ad-audiomp:1.76.0.6 ad-audiomp-base:1.76 yamt-idlelwp:1.76.0.4 post-newlock2-merge:1.76 newlock2-nbase:1.76 yamt-splraiseipl-base5:1.76 yamt-splraiseipl-base4:1.76 yamt-splraiseipl-base3:1.76 abandoned-netbsd-4-base:1.71 abandoned-netbsd-4:1.71.0.2 netbsd-3-1:1.59.2.2.0.2 netbsd-3-1-RELEASE:1.59.2.2 netbsd-3-0-2-RELEASE:1.59 yamt-splraiseipl-base2:1.73 netbsd-3-1-RC4:1.59.2.2 yamt-splraiseipl:1.72.0.4 yamt-splraiseipl-base:1.72 netbsd-3-1-RC3:1.59.2.2 yamt-pdpolicy-base9:1.72 newlock2:1.72.0.2 newlock2-base:1.76 yamt-pdpolicy-base8:1.72 netbsd-3-1-RC2:1.59.2.2 netbsd-3-1-RC1:1.59.2.2 yamt-pdpolicy-base7:1.71 netbsd-4:1.76.0.2 netbsd-4-base:1.76 yamt-pdpolicy-base6:1.69 chap-midi-nbase:1.69 netbsd-3-0-1-RELEASE:1.59 gdamore-uart:1.69.0.2 gdamore-uart-base:1.69 simonb-timcounters-final:1.64.4.3 yamt-pdpolicy-base5:1.68 chap-midi:1.68.0.2 chap-midi-base:1.69 yamt-pdpolicy-base4:1.64 yamt-pdpolicy-base3:1.64 peter-altq-base:1.64 peter-altq:1.64.0.10 yamt-pdpolicy-base2:1.64 elad-kernelauth-base:1.67 elad-kernelauth:1.64.0.8 yamt-pdpolicy:1.64.0.6 yamt-pdpolicy-base:1.64 yamt-uio_vmspace-base5:1.64 simonb-timecounters:1.64.0.4 simonb-timecounters-base:1.68 rpaulo-netinet-merge-pcb:1.64.0.2 rpaulo-netinet-merge-pcb-base:1.72 yamt-uio_vmspace:1.63.0.2 netbsd-3-0:1.59.0.4 netbsd-3-0-RELEASE:1.59 netbsd-3-0-RC6:1.59 yamt-readahead-base3:1.61 netbsd-3-0-RC5:1.59 netbsd-3-0-RC4:1.59 netbsd-3-0-RC3:1.59 yamt-readahead-base2:1.61 netbsd-3-0-RC2:1.59 yamt-readahead-pervnode:1.61 yamt-readahead-perfile:1.61 yamt-readahead:1.61.0.6 yamt-readahead-base:1.61 netbsd-3-0-RC1:1.59 yamt-vop-base3:1.61 netbsd-2-0-3-RELEASE:1.51 netbsd-2-1:1.51.0.6 yamt-vop-base2:1.61 thorpej-vnode-attr:1.61.0.4 thorpej-vnode-attr-base:1.61 netbsd-2-1-RELEASE:1.51 yamt-vop:1.61.0.2 yamt-vop-base:1.61 netbsd-2-1-RC6:1.51 netbsd-2-1-RC5:1.51 netbsd-2-1-RC4:1.51 netbsd-2-1-RC3:1.51 netbsd-2-1-RC2:1.51 netbsd-2-1-RC1:1.51 yamt-lazymbuf:1.60.0.2 yamt-km-base4:1.59 netbsd-2-0-2-RELEASE:1.51 yamt-km-base3:1.59 netbsd-3:1.59.0.2 netbsd-3-base:1.59 yamt-km-base2:1.58 yamt-km:1.58.0.2 yamt-km-base:1.58 kent-audio2:1.57.0.2 kent-audio2-base:1.59 netbsd-2-0-1-RELEASE:1.51 kent-audio1-beforemerge:1.57 netbsd-2:1.51.0.4 netbsd-2-base:1.51 kent-audio1:1.56.0.2 kent-audio1-base:1.56 netbsd-2-0-RELEASE:1.51 netbsd-2-0-RC5:1.51 netbsd-2-0-RC4:1.51 netbsd-2-0-RC3:1.51 netbsd-2-0-RC2:1.51 netbsd-2-0-RC1:1.51 netbsd-2-0:1.51.0.2 netbsd-2-0-base:1.51 netbsd-1-6-PATCH002-RELEASE:1.24.4.16 netbsd-1-6-PATCH002:1.24.4.16 netbsd-1-6-PATCH002-RC4:1.24.4.16 netbsd-1-6-PATCH002-RC3:1.24.4.16 netbsd-1-6-PATCH002-RC2:1.24.4.16 netbsd-1-6-PATCH002-RC1:1.24.4.16 ktrace-lwp:1.44.0.2 ktrace-lwp-base:1.61 netbsd-1-6-PATCH001:1.24.4.15 netbsd-1-6-PATCH001-RELEASE:1.24.4.15 netbsd-1-6-PATCH001-RC3:1.24.4.15 netbsd-1-6-PATCH001-RC2:1.24.4.15 netbsd-1-6-PATCH001-RC1:1.24.4.14 nathanw_sa_end:1.3.2.18 nathanw_sa_before_merge:1.37 fvdl_fs64_base:1.36 gmcgarry_ctxsw:1.35.0.4 gmcgarry_ctxsw_base:1.35 gmcgarry_ucred:1.35.0.2 gmcgarry_ucred_base:1.35 nathanw_sa_base:1.37 kqueue-aftermerge:1.35 kqueue-beforemerge:1.35 netbsd-1-6-RELEASE:1.24 netbsd-1-6-RC3:1.24 netbsd-1-6-RC2:1.24 netbsd-1-6-RC1:1.24 netbsd-1-6:1.24.0.4 netbsd-1-6-base:1.24 gehenna-devsw:1.24.0.2 gehenna-devsw-base:1.33 eeh-devprop:1.23.0.4 eeh-devprop-base:1.23 newlock:1.23.0.2 newlock-base:1.23 ifpoll-base:1.22 thorpej-mips-cache:1.5.0.4 thorpej-mips-cache-base:1.6 thorpej-devvp-base3:1.5 thorpej-devvp-base2:1.5 post-chs-ubcperf:1.5 pre-chs-ubcperf:1.5 thorpej-devvp:1.5.0.2 thorpej-devvp-base:1.5 kqueue:1.4.0.2 kqueue-base:1.35 nathanw_sa:1.3.0.2; locks; strict; comment @ * @; 1.183 date 2022.08.15.08.28.41; author knakahara; state Exp; branches; next 1.182; commitid y6KoKCGlaNJE2XPD; 1.182 date 2022.08.12.06.24.03; author knakahara; state Exp; branches; next 1.181; commitid HwJWvE4IH826syPD; 1.181 date 2022.05.23.21.46.12; author andvar; state Exp; branches; next 1.180; commitid uTIEPi7gX64a9eFD; 1.180 date 2022.05.10.09.05.03; author knakahara; state Exp; branches; next 1.179; commitid fJXWZSngLFeCmuDD; 1.179 date 2022.05.04.14.30.04; author martin; state Exp; branches; next 1.178; commitid 4xlQA3A3BXH8mKCD; 1.178 date 2021.10.11.05.13.11; author knakahara; state Exp; branches; next 1.177; commitid XtwcpcwCe61wRlcD; 1.177 date 2021.06.16.00.21.19; author riastradh; state Exp; branches; next 1.176; commitid iD8ua5Jd5N5x0iXC; 1.176 date 2021.05.19.03.44.46; author yamaguchi; state Exp; branches; next 1.175; commitid vo8CunZOKeNd2ITC; 1.175 date 2021.05.19.03.35.27; author yamaguchi; state Exp; branches; next 1.174; commitid pkANHNiU1eJXYHTC; 1.174 date 2021.05.18.01.46.29; author yamaguchi; state Exp; branches; next 1.173; commitid n0QFDOpxQmdBpzTC; 1.173 date 2021.05.13.03.48.55; author yamaguchi; state Exp; branches; next 1.172; commitid firIbETeZhDifWSC; 1.172 date 2021.05.13.03.28.36; author yamaguchi; state Exp; branches; next 1.171; commitid m53zRXsMtYYs8WSC; 1.171 date 2021.05.13.01.01.10; author yamaguchi; state Exp; branches; next 1.170; commitid GIJU5nw0wkN3kVSC; 1.170 date 2021.04.22.10.26.24; author yamaguchi; state Exp; branches 1.170.2.1 1.170.4.1; next 1.169; commitid il6OJQbcs1WI7hQC; 1.169 date 2021.04.16.02.23.25; author yamaguchi; state Exp; branches; next 1.168; commitid Kfbqp4FPIY5SDsPC; 1.168 date 2021.04.16.02.12.00; author yamaguchi; state Exp; branches; next 1.167; commitid mt2MR6xQIE0QysPC; 1.167 date 2021.04.16.01.59.50; author yamaguchi; state Exp; branches; next 1.166; commitid Rva3FfoTcx2ivsPC; 1.166 date 2021.04.16.01.44.35; author yamaguchi; state Exp; branches; next 1.165; commitid 2lSkmYFbdB0BqsPC; 1.165 date 2021.04.16.01.32.04; author yamaguchi; state Exp; branches; next 1.164; commitid 213afk07geG8msPC; 1.164 date 2021.04.16.01.28.51; author yamaguchi; state Exp; branches; next 1.163; commitid J5XL8lzSzcoilsPC; 1.163 date 2021.04.16.01.24.35; author yamaguchi; state Exp; branches; next 1.162; commitid G8KiiQ76gRuKjsPC; 1.162 date 2021.04.13.05.04.54; author yamaguchi; state Exp; branches; next 1.161; commitid qoUUx6JAg57RC5PC; 1.161 date 2021.04.13.05.00.06; author yamaguchi; state Exp; branches; next 1.160; commitid jsMipeoBnmEFB5PC; 1.160 date 2021.04.13.04.57.15; author yamaguchi; state Exp; branches; next 1.159; commitid FuOmKmID2bWvA5PC; 1.159 date 2021.04.13.04.53.22; author yamaguchi; state Exp; branches; next 1.158; commitid WxNPheHttEIez5PC; 1.158 date 2020.11.25.10.42.35; author yamaguchi; state Exp; branches 1.158.2.1; next 1.157; commitid OAEi43EFXdZlYfxC; 1.157 date 2020.11.25.10.39.47; author yamaguchi; state Exp; branches; next 1.156; commitid phcCHvhTNceiXfxC; 1.156 date 2020.11.25.10.38.10; author yamaguchi; state Exp; branches; next 1.155; commitid 6cJoybBwhB3RWfxC; 1.155 date 2020.11.25.10.37.04; author yamaguchi; state Exp; branches; next 1.154; commitid pxhQhdlXTnZoWfxC; 1.154 date 2020.11.25.10.18.49; author yamaguchi; state Exp; branches; next 1.153; commitid CHRP98jfFV2VPfxC; 1.153 date 2020.09.25.06.22.33; author yamaguchi; state Exp; branches 1.153.2.1; next 1.152; commitid 7xUVgfs6F6nHtopC; 1.152 date 2020.09.25.06.12.33; author yamaguchi; state Exp; branches; next 1.151; commitid 3VxVbOeinUddropC; 1.151 date 2020.09.18.09.53.50; author yamaguchi; state Exp; branches; next 1.150; commitid yX90wFonPbXQSvoC; 1.150 date 2020.09.18.09.48.56; author yamaguchi; state Exp; branches; next 1.149; commitid k3Y9wDwPCqobRvoC; 1.149 date 2020.02.10.22.38.10; author mlelstv; state Exp; branches; next 1.148; commitid mdoHITUWS3dFdbWB; 1.148 date 2020.01.29.04.28.27; author thorpej; state Exp; branches; next 1.147; commitid 5uH8WW48hxhUzxUB; 1.147 date 2019.03.18.11.38.03; author msaitoh; state Exp; branches 1.147.4.1 1.147.6.1; next 1.146; commitid 5tTVE7PxYXdW8QfB; 1.146 date 2018.10.27.06.46.43; author maxv; state Exp; branches; next 1.145; commitid Yol2BQ95liW36zXA; 1.145 date 2018.10.27.05.56.10; author maxv; state Exp; branches; next 1.144; commitid BtnGzh4AYggMOyXA; 1.144 date 2018.09.30.10.00.24; author maxv; state Exp; branches; next 1.143; commitid D1oRXJEMFQti27UA; 1.143 date 2018.08.24.17.06.29; author maxv; state Exp; branches; next 1.142; commitid 4RTTcFV7WM1gAoPA; 1.142 date 2018.08.13.09.29.13; author maxv; state Exp; branches; next 1.141; commitid jc1CZ6llswNkpWNA; 1.141 date 2018.06.26.06.48.02; author msaitoh; state Exp; branches 1.141.2.1; next 1.140; commitid BGd0EgCdw1Br3LHA; 1.140 date 2018.06.18.09.53.45; author yamaguchi; state Exp; branches; next 1.139; commitid UKRkuGENWhnLkKGA; 1.139 date 2018.06.18.09.49.05; author yamaguchi; state Exp; branches; next 1.138; commitid Ly39yPR0UO18jKGA; 1.138 date 2018.05.25.04.40.27; author ozaki-r; state Exp; branches; next 1.137; commitid Yp9fQmlkpbQHnDDA; 1.137 date 2018.05.03.16.52.42; author maxv; state Exp; branches; next 1.136; commitid JVB8xgqaTdsI8SAA; 1.136 date 2018.04.18.07.40.40; author knakahara; state Exp; branches; next 1.135; commitid 0yYcHI3JcggfzTyA; 1.135 date 2018.04.18.07.36.26; author knakahara; state Exp; branches; next 1.134; commitid Hk0WAFvQ7RKHxTyA; 1.134 date 2018.02.12.15.38.14; author maxv; state Exp; branches 1.134.2.1; next 1.133; commitid J5uwx6ly40pDiAqA; 1.133 date 2017.12.07.10.22.04; author ozaki-r; state Exp; branches; next 1.132; commitid DQ0uDHkGmCWHHWhA; 1.132 date 2017.11.17.07.37.12; author ozaki-r; state Exp; branches; next 1.131; commitid 1NQBDXAUtBTZqmfA; 1.131 date 2017.11.16.03.07.18; author ozaki-r; state Exp; branches; next 1.130; commitid CEIZkYvAZzuoYcfA; 1.130 date 2017.11.15.07.52.58; author knakahara; state Exp; branches; next 1.129; commitid BB8fkBHgWowlA6fA; 1.129 date 2017.10.23.09.32.33; author msaitoh; state Exp; branches; next 1.128; commitid H2fTjPHj77nlS9cA; 1.128 date 2017.10.12.09.49.43; author knakahara; state Exp; branches; next 1.127; commitid nBiF2SRIC1u7kKaA; 1.127 date 2017.10.12.09.47.21; author knakahara; state Exp; branches; next 1.126; commitid ADF0xZZdUb1fjKaA; 1.126 date 2017.07.20.02.34.24; author knakahara; state Exp; branches; next 1.125; 1.125 date 2017.02.07.02.33.54; author ozaki-r; state Exp; branches 1.125.6.1; next 1.124; 1.124 date 2017.02.01.17.58.47; author maxv; state Exp; branches; next 1.123; 1.123 date 2016.12.27.01.31.06; author christos; state Exp; branches 1.123.2.1; next 1.122; 1.122 date 2016.12.26.23.21.49; author christos; state Exp; branches; next 1.121; 1.121 date 2016.12.16.08.47.36; author knakahara; state Exp; branches; next 1.120; 1.120 date 2016.12.13.00.35.11; author knakahara; state Exp; branches; next 1.119; 1.119 date 2016.11.18.08.13.02; author knakahara; state Exp; branches; next 1.118; 1.118 date 2016.10.03.11.06.06; author ozaki-r; state Exp; branches; next 1.117; 1.117 date 2016.08.11.15.16.07; author christos; state Exp; branches; next 1.116; 1.116 date 2016.08.08.07.23.27; author roy; state Exp; branches; next 1.115; 1.115 date 2016.08.08.02.50.05; author pgoyette; state Exp; branches; next 1.114; 1.114 date 2016.08.07.17.38.34; author christos; state Exp; branches; next 1.113; 1.113 date 2016.08.07.01.59.43; author pgoyette; state Exp; branches; next 1.112; 1.112 date 2016.08.06.23.46.30; author pgoyette; state Exp; branches; next 1.111; 1.111 date 2016.07.07.06.55.43; author msaitoh; state Exp; branches 1.111.2.1; next 1.110; 1.110 date 2016.06.28.02.02.56; author ozaki-r; state Exp; branches; next 1.109; 1.109 date 2016.06.20.06.46.37; author knakahara; state Exp; branches; next 1.108; 1.108 date 2016.06.10.13.31.44; author ozaki-r; state Exp; branches; next 1.107; 1.107 date 2016.06.10.13.27.16; author ozaki-r; state Exp; branches; next 1.106; 1.106 date 2016.04.24.16.59.15; author christos; state Exp; branches; next 1.105; 1.105 date 2016.04.15.01.31.29; author ozaki-r; state Exp; branches; next 1.104; 1.104 date 2015.08.24.22.21.26; author pooka; state Exp; branches; next 1.103; 1.103 date 2015.08.20.14.40.19; author christos; state Exp; branches; next 1.102; 1.102 date 2014.10.18.08.33.29; author snj; state Exp; branches 1.102.2.1; next 1.101; 1.101 date 2013.09.13.21.09.40; author martin; state Exp; branches; next 1.100; 1.100 date 2013.07.17.10.16.58; author oki; state Exp; branches; next 1.99; 1.99 date 2013.06.29.21.06.58; author rmind; state Exp; branches; next 1.98; 1.98 date 2011.09.05.12.19.09; author rjs; state Exp; branches 1.98.2.1 1.98.12.1 1.98.16.1; next 1.97; 1.97 date 2011.08.30.22.23.06; author rjs; state Exp; branches; next 1.96; 1.96 date 2010.04.05.07.22.23; author joerg; state Exp; branches; next 1.95; 1.95 date 2010.01.19.22.08.01; author pooka; state Exp; branches 1.95.2.1 1.95.4.1; next 1.94; 1.94 date 2009.02.19.15.17.50; author christos; state Exp; branches; next 1.93; 1.93 date 2008.10.15.20.08.33; author scw; state Exp; branches 1.93.2.1 1.93.4.1 1.93.8.1; next 1.92; 1.92 date 2008.08.19.22.03.05; author martin; state Exp; branches; next 1.91; 1.91 date 2008.08.19.10.41.10; author simonb; state Exp; branches; next 1.90; 1.90 date 2008.08.18.21.43.49; author martin; state Exp; branches; next 1.89; 1.89 date 2008.08.18.20.43.50; author martin; state Exp; branches; next 1.88; 1.88 date 2008.08.08.14.31.00; author martin; state Exp; branches; next 1.87; 1.87 date 2008.06.15.16.37.21; author christos; state Exp; branches 1.87.2.1; next 1.86; 1.86 date 2008.04.28.20.24.09; author martin; state Exp; branches 1.86.2.1 1.86.4.1; next 1.85; 1.85 date 2008.04.24.11.38.37; author ad; state Exp; branches 1.85.2.1; next 1.84; 1.84 date 2008.02.20.17.05.53; author matt; state Exp; branches 1.84.6.1 1.84.8.1; next 1.83; 1.83 date 2008.02.07.01.22.01; author dyoung; state Exp; branches; next 1.82; 1.82 date 2007.12.25.18.33.45; author perry; state Exp; branches; next 1.81; 1.81 date 2007.10.08.16.18.05; author ad; state Exp; branches 1.81.4.1 1.81.6.1 1.81.10.1; next 1.80; 1.80 date 2007.09.09.09.58.55; author martin; state Exp; branches 1.80.2.1; next 1.79; 1.79 date 2007.07.09.21.11.00; author ad; state Exp; branches 1.79.2.1 1.79.6.1 1.79.8.1; next 1.78; 1.78 date 2007.03.31.11.00.23; author martin; state Exp; branches; next 1.77; 1.77 date 2007.03.04.06.03.16; author christos; state Exp; branches 1.77.2.1 1.77.4.1; next 1.76; 1.76 date 2006.11.16.01.33.40; author christos; state Exp; branches 1.76.2.1 1.76.4.1 1.76.8.1; next 1.75; 1.75 date 2006.11.01.12.10.06; author martin; state Exp; branches; next 1.74; 1.74 date 2006.10.25.20.28.45; author elad; state Exp; branches; next 1.73; 1.73 date 2006.10.12.01.32.28; author christos; state Exp; branches; next 1.72; 1.72 date 2006.08.30.16.57.59; author christos; state Exp; branches 1.72.2.1 1.72.4.1; next 1.71; 1.71 date 2006.08.05.17.20.54; author pavel; state Exp; branches; next 1.70; 1.70 date 2006.07.23.22.06.12; author ad; state Exp; branches; next 1.69; 1.69 date 2006.06.07.22.33.42; author kardel; state Exp; branches; next 1.68; 1.68 date 2006.05.14.21.19.33; author elad; state Exp; branches 1.68.2.1; next 1.67; 1.67 date 2006.04.27.20.04.26; author tron; state Exp; branches; next 1.66; 1.66 date 2006.04.27.13.19.04; author tron; state Exp; branches; next 1.65; 1.65 date 2006.04.15.02.22.44; author christos; state Exp; branches; next 1.64; 1.64 date 2006.01.31.23.50.15; author martin; state Exp; branches 1.64.2.1 1.64.4.1 1.64.6.1 1.64.8.1 1.64.10.1; next 1.63; 1.63 date 2005.12.11.23.05.25; author thorpej; state Exp; branches 1.63.2.1; next 1.62; 1.62 date 2005.12.11.12.24.51; author christos; state Exp; branches; next 1.61; 1.61 date 2005.08.31.00.00.26; author martin; state Exp; branches; next 1.60; 1.60 date 2005.05.29.21.22.53; author christos; state Exp; branches 1.60.2.1; next 1.59; 1.59 date 2005.02.26.22.45.09; author perry; state Exp; branches 1.59.2.1 1.59.4.1; next 1.58; 1.58 date 2005.01.19.15.05.55; author martin; state Exp; branches 1.58.2.1; next 1.57; 1.57 date 2004.12.08.07.43.29; author martin; state Exp; branches 1.57.2.1; next 1.56; 1.56 date 2004.12.04.18.31.43; author peter; state Exp; branches; next 1.55; 1.55 date 2004.11.28.17.16.10; author skrll; state Exp; branches; next 1.54; 1.54 date 2004.11.28.11.44.36; author martin; state Exp; branches; next 1.53; 1.53 date 2004.04.21.18.40.40; author itojun; state Exp; branches; next 1.52; 1.52 date 2004.03.30.06.00.13; author oki; state Exp; branches; next 1.51; 1.51 date 2003.11.28.08.56.48; author keihan; state Exp; branches 1.51.4.1; next 1.50; 1.50 date 2003.10.30.01.43.08; author simonb; state Exp; branches; next 1.49; 1.49 date 2003.10.25.18.29.12; author christos; state Exp; branches; next 1.48; 1.48 date 2003.09.26.22.23.58; author wiz; state Exp; branches; next 1.47; 1.47 date 2003.09.16.20.59.04; author martin; state Exp; branches; next 1.46; 1.46 date 2003.09.03.21.36.31; author martin; state Exp; branches; next 1.45; 1.45 date 2003.08.23.16.42.41; author martin; state Exp; branches; next 1.44; 1.44 date 2003.06.27.16.24.32; author oki; state Exp; branches 1.44.2.1; next 1.43; 1.43 date 2003.06.18.08.12.51; author oki; state Exp; branches; next 1.42; 1.42 date 2003.03.01.15.50.15; author martin; state Exp; branches; next 1.41; 1.41 date 2003.03.01.15.24.36; author martin; state Exp; branches; next 1.40; 1.40 date 2003.03.01.15.10.13; author aymeric; state Exp; branches; next 1.39; 1.39 date 2003.02.04.20.52.23; author martin; state Exp; branches; next 1.38; 1.38 date 2003.02.03.23.51.03; author thorpej; state Exp; branches; next 1.37; 1.37 date 2003.01.07.20.02.10; author martin; state Exp; branches; next 1.36; 1.36 date 2002.12.25.11.54.33; author martin; state Exp; branches; next 1.35; 1.35 date 2002.09.01.18.06.59; author martin; state Exp; branches; next 1.34; 1.34 date 2002.09.01.17.21.40; author martin; state Exp; branches; next 1.33; 1.33 date 2002.08.25.19.21.47; author tron; state Exp; branches; next 1.32; 1.32 date 2002.06.22.17.41.23; author yamt; state Exp; branches; next 1.31; 1.31 date 2002.06.22.16.56.11; author yamt; state Exp; branches; next 1.30; 1.30 date 2002.06.22.11.46.16; author itojun; state Exp; branches; next 1.29; 1.29 date 2002.06.22.11.37.48; author itojun; state Exp; branches; next 1.28; 1.28 date 2002.06.22.05.59.27; author itojun; state Exp; branches; next 1.27; 1.27 date 2002.06.22.05.54.14; author itojun; state Exp; branches; next 1.26; 1.26 date 2002.06.22.05.52.00; author itojun; state Exp; branches; next 1.25; 1.25 date 2002.06.22.05.33.42; author itojun; state Exp; branches; next 1.24; 1.24 date 2002.04.14.12.24.28; author martin; state Exp; branches 1.24.2.1 1.24.4.1; next 1.23; 1.23 date 2002.03.04.15.15.05; author martin; state Exp; branches; next 1.22; 1.22 date 2002.02.24.17.11.53; author martin; state Exp; branches; next 1.21; 1.21 date 2002.02.10.15.13.43; author martin; state Exp; branches; next 1.20; 1.20 date 2002.02.01.13.50.00; author martin; state Exp; branches; next 1.19; 1.19 date 2002.02.01.13.40.16; author martin; state Exp; branches; next 1.18; 1.18 date 2002.01.14.16.10.33; author kleink; state Exp; branches; next 1.17; 1.17 date 2002.01.14.16.04.44; author aymeric; state Exp; branches; next 1.16; 1.16 date 2002.01.13.10.57.57; author aymeric; state Exp; branches; next 1.15; 1.15 date 2002.01.04.12.21.25; author martin; state Exp; branches; next 1.14; 1.14 date 2001.12.16.23.53.31; author martin; state Exp; branches; next 1.13; 1.13 date 2001.12.16.11.40.52; author martin; state Exp; branches; next 1.12; 1.12 date 2001.12.15.20.43.31; author martin; state Exp; branches; next 1.11; 1.11 date 2001.12.10.23.23.24; author martin; state Exp; branches; next 1.10; 1.10 date 2001.12.10.00.24.12; author martin; state Exp; branches; next 1.9; 1.9 date 2001.12.01.18.25.23; author martin; state Exp; branches; next 1.8; 1.8 date 2001.11.13.00.49.35; author lukem; state Exp; branches; next 1.7; 1.7 date 2001.11.12.23.49.42; author lukem; state Exp; branches; next 1.6; 1.6 date 2001.10.28.09.48.20; author martin; state Exp; branches; next 1.5; 1.5 date 2001.09.04.20.41.32; author martin; state Exp; branches 1.5.4.1; next 1.4; 1.4 date 2001.06.24.20.35.50; author martin; state Exp; branches 1.4.2.1; next 1.3; 1.3 date 2001.06.18.12.32.47; author martin; state Exp; branches 1.3.2.1; next 1.2; 1.2 date 2001.06.14.05.44.24; author itojun; state Exp; branches; next 1.1; 1.1 date 2001.04.29.09.50.37; author martin; state Exp; branches; next ; 1.170.2.1 date 2021.06.17.04.46.35; author thorpej; state Exp; branches; next ; commitid d7CrUzY34skBrrXC; 1.170.4.1 date 2021.05.31.22.15.21; author cjep; state Exp; branches; next ; commitid eWz9SBW0XqKjJlVC; 1.158.2.1 date 2021.04.17.17.26.21; author thorpej; state Exp; branches; next ; commitid bct79XL9ibnNBFPC; 1.153.2.1 date 2020.12.14.14.38.15; author thorpej; state Exp; branches; next ; commitid S4HwP6n7zzL3FIzC; 1.147.4.1 date 2020.02.13.19.40.05; author martin; state Exp; branches; next 1.147.4.2; commitid hQasXZcEX7dO8yWB; 1.147.4.2 date 2022.05.04.15.08.47; author sborrill; state Exp; branches; next ; commitid PbdoiwcX0s3jzKCD; 1.147.6.1 date 2020.02.29.20.21.06; author ad; state Exp; branches; next ; commitid OjSb8ro7YQETQBYB; 1.141.2.1 date 2019.06.10.22.09.45; author christos; state Exp; branches; next 1.141.2.2; commitid jtc8rnCzWiEEHGqB; 1.141.2.2 date 2020.04.08.14.08.57; author martin; state Exp; branches; next ; commitid Qli2aW9E74UFuA3C; 1.134.2.1 date 2018.04.22.07.20.27; author pgoyette; state Exp; branches; next 1.134.2.2; commitid W6xykws0Zbl4kpzA; 1.134.2.2 date 2018.05.21.04.36.15; author pgoyette; state Exp; branches; next 1.134.2.3; commitid X5L8kSrBWQcDt7DA; 1.134.2.3 date 2018.06.25.07.26.06; author pgoyette; state Exp; branches; next 1.134.2.4; commitid 8PtAu9af7VvhiDHA; 1.134.2.4 date 2018.07.28.04.38.10; author pgoyette; state Exp; branches; next 1.134.2.5; commitid 1UP1xAIUxv1ZgRLA; 1.134.2.5 date 2018.09.06.06.56.44; author pgoyette; state Exp; branches; next 1.134.2.6; commitid HCi1bXD317XIK0RA; 1.134.2.6 date 2018.10.20.06.58.46; author pgoyette; state Exp; branches; next 1.134.2.7; commitid mTSoqZEZ4arHnFWA; 1.134.2.7 date 2018.11.26.01.52.50; author pgoyette; state Exp; branches; next ; commitid Zj4q5SspGdKXto1B; 1.125.6.1 date 2017.07.25.02.07.11; author snj; state Exp; branches; next 1.125.6.2; 1.125.6.2 date 2017.11.02.20.28.24; author snj; state Exp; branches; next 1.125.6.3; commitid V9y762IcICjVavdA; 1.125.6.3 date 2017.12.08.06.12.35; author msaitoh; state Exp; branches; next 1.125.6.4; commitid iqUUQ0r9Aj18i3iA; 1.125.6.4 date 2017.12.10.10.10.25; author snj; state Exp; branches; next 1.125.6.5; commitid GuBc4alt52ToxkiA; 1.125.6.5 date 2018.01.02.10.20.33; author snj; state Exp; branches; next 1.125.6.6; commitid 07oy8c4rjfdaRhlA; 1.125.6.6 date 2018.03.08.13.22.25; author martin; state Exp; branches; next 1.125.6.7; commitid jdkM8ZEG3p1eMEtA; 1.125.6.7 date 2018.04.18.14.16.57; author martin; state Exp; branches; next 1.125.6.8; commitid 80DPoMYEKaWdLVyA; 1.125.6.8 date 2018.06.07.17.42.25; author martin; state Exp; branches; next 1.125.6.9; commitid ZSliDILKr3M3inFA; 1.125.6.9 date 2018.07.12.15.11.56; author martin; state Exp; branches; next 1.125.6.10; commitid wQENiy5pDTLGkRJA; 1.125.6.10 date 2020.02.13.19.37.39; author martin; state Exp; branches; next 1.125.6.11; commitid 5hffLiJxvMpY7yWB; 1.125.6.11 date 2022.05.04.15.36.35; author sborrill; state Exp; branches; next ; commitid uMB4h5EE4pUPIKCD; 1.123.2.1 date 2017.04.21.16.54.05; author bouyer; state Exp; branches; next ; 1.111.2.1 date 2016.11.04.14.49.20; author pgoyette; state Exp; branches; next 1.111.2.2; 1.111.2.2 date 2017.01.07.08.56.50; author pgoyette; state Exp; branches; next 1.111.2.3; 1.111.2.3 date 2017.03.20.06.57.50; author pgoyette; state Exp; branches; next ; 1.102.2.1 date 2015.09.22.12.06.10; author skrll; state Exp; branches; next 1.102.2.2; 1.102.2.2 date 2016.04.22.15.44.17; author skrll; state Exp; branches; next 1.102.2.3; 1.102.2.3 date 2016.05.29.08.44.38; author skrll; state Exp; branches; next 1.102.2.4; 1.102.2.4 date 2016.07.09.20.25.21; author skrll; state Exp; branches; next 1.102.2.5; 1.102.2.5 date 2016.10.05.20.56.08; author skrll; state Exp; branches; next 1.102.2.6; 1.102.2.6 date 2016.12.05.10.55.27; author skrll; state Exp; branches; next 1.102.2.7; 1.102.2.7 date 2017.02.05.13.40.58; author skrll; state Exp; branches; next 1.102.2.8; 1.102.2.8 date 2017.08.28.17.53.11; author skrll; state Exp; branches; next ; commitid UQQpnjvcNkUZn05A; 1.98.2.1 date 2014.05.22.11.41.09; author yamt; state Exp; branches; next ; 1.98.12.1 date 2014.08.20.00.04.34; author tls; state Exp; branches; next 1.98.12.2; 1.98.12.2 date 2017.12.03.11.39.02; author jdolecek; state Exp; branches; next ; commitid XcIYRZTAh1LmerhA; 1.98.16.1 date 2013.08.28.23.59.36; author rmind; state Exp; branches; next 1.98.16.2; 1.98.16.2 date 2014.05.18.17.46.12; author rmind; state Exp; branches; next ; 1.95.2.1 date 2010.04.30.14.44.19; author uebayasi; state Exp; branches; next ; 1.95.4.1 date 2010.05.30.05.18.01; author rmind; state Exp; branches; next ; 1.93.2.1 date 2009.03.03.18.33.38; author skrll; state Exp; branches; next ; 1.93.4.1 date 2009.02.25.03.15.32; author snj; state Exp; branches; next ; 1.93.8.1 date 2009.05.13.17.22.19; author jym; state Exp; branches; next ; 1.87.2.1 date 2008.10.19.22.17.41; author haad; state Exp; branches; next ; 1.86.2.1 date 2008.06.23.04.31.58; author wrstuden; state Exp; branches; next 1.86.2.2; 1.86.2.2 date 2008.09.18.04.36.59; author wrstuden; state Exp; branches; next ; 1.86.4.1 date 2008.06.18.16.33.50; author simonb; state Exp; branches; next ; 1.85.2.1 date 2008.05.16.02.25.40; author yamt; state Exp; branches; next 1.85.2.2; 1.85.2.2 date 2009.05.04.08.14.15; author yamt; state Exp; branches; next 1.85.2.3; 1.85.2.3 date 2010.03.11.15.04.27; author yamt; state Exp; branches; next 1.85.2.4; 1.85.2.4 date 2010.08.11.22.54.54; author yamt; state Exp; branches; next ; 1.84.6.1 date 2008.06.02.13.24.22; author mjf; state Exp; branches; next 1.84.6.2; 1.84.6.2 date 2008.06.29.09.33.18; author mjf; state Exp; branches; next 1.84.6.3; 1.84.6.3 date 2008.09.28.10.40.56; author mjf; state Exp; branches; next 1.84.6.4; 1.84.6.4 date 2009.01.17.13.29.31; author mjf; state Exp; branches; next ; 1.84.8.1 date 2008.05.18.12.35.27; author yamt; state Exp; branches; next 1.84.8.2; 1.84.8.2 date 2008.06.17.09.15.13; author yamt; state Exp; branches; next ; 1.81.4.1 date 2008.02.18.21.07.01; author mjf; state Exp; branches; next ; 1.81.6.1 date 2007.12.26.19.57.33; author ad; state Exp; branches; next ; 1.81.10.1 date 2008.01.02.21.57.08; author bouyer; state Exp; branches; next ; 1.80.2.1 date 2007.10.14.11.49.00; author yamt; state Exp; branches; next ; 1.79.2.1 date 2007.09.10.10.56.12; author skrll; state Exp; branches; next ; 1.79.6.1 date 2007.10.02.18.29.15; author joerg; state Exp; branches; next 1.79.6.2; 1.79.6.2 date 2007.10.26.15.49.02; author joerg; state Exp; branches; next ; 1.79.8.1 date 2007.11.06.23.33.33; author matt; state Exp; branches; next 1.79.8.2; 1.79.8.2 date 2008.01.09.01.57.12; author matt; state Exp; branches; next 1.79.8.3; 1.79.8.3 date 2008.03.23.02.05.05; author matt; state Exp; branches; next ; 1.77.2.1 date 2007.04.10.13.26.47; author ad; state Exp; branches; next 1.77.2.2; 1.77.2.2 date 2007.06.17.21.31.51; author ad; state Exp; branches; next 1.77.2.3; 1.77.2.3 date 2007.07.01.21.50.44; author ad; state Exp; branches; next 1.77.2.4; 1.77.2.4 date 2007.07.15.15.53.00; author ad; state Exp; branches; next 1.77.2.5; 1.77.2.5 date 2007.10.09.15.22.26; author ad; state Exp; branches; next ; 1.77.4.1 date 2007.07.11.20.10.58; author mjf; state Exp; branches; next ; 1.76.2.1 date 2007.09.11.09.19.17; author xtraeme; state Exp; branches 1.76.2.1.4.1; next 1.76.2.2; 1.76.2.2 date 2008.08.08.14.41.07; author jdc; state Exp; branches; next 1.76.2.3; 1.76.2.3 date 2008.08.20.20.52.30; author bouyer; state Exp; branches; next 1.76.2.4; 1.76.2.4 date 2009.03.16.06.12.38; author snj; state Exp; branches; next ; 1.76.2.1.4.1 date 2008.08.08.14.41.21; author jdc; state Exp; branches; next ; 1.76.4.1 date 2007.03.12.05.59.12; author rmind; state Exp; branches; next 1.76.4.2; 1.76.4.2 date 2007.04.15.16.03.57; author yamt; state Exp; branches; next ; 1.76.8.1 date 2007.09.23.21.36.34; author wrstuden; state Exp; branches; next 1.76.8.2; 1.76.8.2 date 2008.09.04.08.46.45; author skrll; state Exp; branches; next ; 1.72.2.1 date 2006.11.18.21.39.29; author ad; state Exp; branches; next ; 1.72.4.1 date 2006.10.22.06.07.24; author yamt; state Exp; branches; next 1.72.4.2; 1.72.4.2 date 2006.12.10.07.19.00; author yamt; state Exp; branches; next ; 1.68.2.1 date 2006.06.19.04.09.12; author chap; state Exp; branches; next ; 1.64.2.1 date 2006.09.09.02.58.06; author rpaulo; state Exp; branches; next ; 1.64.4.1 date 2006.02.04.14.18.52; author simonb; state Exp; branches; next 1.64.4.2; 1.64.4.2 date 2006.04.22.11.40.06; author simonb; state Exp; branches; next 1.64.4.3; 1.64.4.3 date 2006.06.01.22.38.37; author kardel; state Exp; branches; next ; 1.64.6.1 date 2006.05.24.10.58.56; author yamt; state Exp; branches; next 1.64.6.2; 1.64.6.2 date 2006.06.26.12.53.39; author yamt; state Exp; branches; next 1.64.6.3; 1.64.6.3 date 2006.08.11.15.46.14; author yamt; state Exp; branches; next 1.64.6.4; 1.64.6.4 date 2006.09.03.15.25.35; author yamt; state Exp; branches; next ; 1.64.8.1 date 2006.03.08.01.11.55; author elad; state Exp; branches; next 1.64.8.2; 1.64.8.2 date 2006.03.10.15.05.22; author elad; state Exp; branches; next 1.64.8.3; 1.64.8.3 date 2006.04.19.04.46.10; author elad; state Exp; branches; next 1.64.8.4; 1.64.8.4 date 2006.05.06.23.31.59; author christos; state Exp; branches; next 1.64.8.5; 1.64.8.5 date 2006.05.11.23.31.08; author elad; state Exp; branches; next ; 1.64.10.1 date 2006.05.24.15.50.44; author tron; state Exp; branches; next ; 1.63.2.1 date 2006.02.01.14.52.37; author yamt; state Exp; branches; next ; 1.60.2.1 date 2006.06.21.15.10.27; author yamt; state Exp; branches; next 1.60.2.2; 1.60.2.2 date 2006.12.30.20.50.20; author yamt; state Exp; branches; next 1.60.2.3; 1.60.2.3 date 2007.09.03.14.42.10; author yamt; state Exp; branches; next 1.60.2.4; 1.60.2.4 date 2007.10.27.11.36.02; author yamt; state Exp; branches; next 1.60.2.5; 1.60.2.5 date 2008.01.21.09.47.05; author yamt; state Exp; branches; next 1.60.2.6; 1.60.2.6 date 2008.02.11.14.59.59; author yamt; state Exp; branches; next 1.60.2.7; 1.60.2.7 date 2008.02.27.08.37.00; author yamt; state Exp; branches; next ; 1.59.2.1 date 2006.02.01.20.43.25; author tron; state Exp; branches; next 1.59.2.2; 1.59.2.2 date 2006.05.03.16.47.09; author ghen; state Exp; branches 1.59.2.2.2.1; next 1.59.2.3; 1.59.2.3 date 2006.11.19.17.51.38; author bouyer; state Exp; branches; next 1.59.2.4; 1.59.2.4 date 2008.08.08.15.05.22; author jdc; state Exp; branches; next ; 1.59.2.2.2.1 date 2006.11.19.17.52.57; author bouyer; state Exp; branches; next 1.59.2.2.2.2; 1.59.2.2.2.2 date 2008.08.08.15.05.37; author jdc; state Exp; branches; next ; 1.59.4.1 date 2006.11.19.17.52.18; author bouyer; state Exp; branches; next 1.59.4.2; 1.59.4.2 date 2008.08.08.15.05.59; author jdc; state Exp; branches; next ; 1.58.2.1 date 2005.03.19.08.36.31; author yamt; state Exp; branches; next ; 1.57.2.1 date 2005.04.29.11.29.31; author kent; state Exp; branches; next ; 1.51.4.1 date 2006.02.01.20.51.20; author tron; state Exp; branches; next ; 1.44.2.1 date 2004.08.03.10.54.16; author skrll; state Exp; branches; next 1.44.2.2; 1.44.2.2 date 2004.09.18.14.54.16; author skrll; state Exp; branches; next 1.44.2.3; 1.44.2.3 date 2004.09.21.13.36.38; author skrll; state Exp; branches; next 1.44.2.4; 1.44.2.4 date 2004.11.29.07.24.51; author skrll; state Exp; branches; next 1.44.2.5; 1.44.2.5 date 2004.12.18.09.32.50; author skrll; state Exp; branches; next 1.44.2.6; 1.44.2.6 date 2005.01.24.08.35.53; author skrll; state Exp; branches; next 1.44.2.7; 1.44.2.7 date 2005.03.04.16.52.58; author skrll; state Exp; branches; next 1.44.2.8; 1.44.2.8 date 2005.11.10.14.10.32; author skrll; state Exp; branches; next ; 1.24.2.1 date 2002.07.15.10.36.49; author gehenna; state Exp; branches; next 1.24.2.2; 1.24.2.2 date 2002.08.29.00.56.42; author gehenna; state Exp; branches; next ; 1.24.4.1 date 2003.02.07.18.44.32; author tron; state Exp; branches; next 1.24.4.2; 1.24.4.2 date 2003.02.07.19.20.56; author tron; state Exp; branches; next 1.24.4.3; 1.24.4.3 date 2003.02.07.19.56.56; author tron; state Exp; branches; next 1.24.4.4; 1.24.4.4 date 2003.02.07.19.58.08; author tron; state Exp; branches; next 1.24.4.5; 1.24.4.5 date 2003.02.07.19.59.19; author tron; state Exp; branches; next 1.24.4.6; 1.24.4.6 date 2003.02.07.20.04.22; author tron; state Exp; branches; next 1.24.4.7; 1.24.4.7 date 2003.02.07.20.06.26; author tron; state Exp; branches; next 1.24.4.8; 1.24.4.8 date 2003.02.07.20.07.20; author tron; state Exp; branches; next 1.24.4.9; 1.24.4.9 date 2003.02.07.20.08.45; author tron; state Exp; branches; next 1.24.4.10; 1.24.4.10 date 2003.02.07.20.10.28; author tron; state Exp; branches; next 1.24.4.11; 1.24.4.11 date 2003.02.07.20.13.08; author tron; state Exp; branches; next 1.24.4.12; 1.24.4.12 date 2003.02.07.20.15.02; author tron; state Exp; branches; next 1.24.4.13; 1.24.4.13 date 2003.02.07.20.16.37; author tron; state Exp; branches; next 1.24.4.14; 1.24.4.14 date 2003.02.07.20.19.11; author tron; state Exp; branches; next 1.24.4.15; 1.24.4.15 date 2003.03.04.05.49.44; author jmc; state Exp; branches; next 1.24.4.16; 1.24.4.16 date 2003.08.26.14.41.37; author tron; state Exp; branches; next ; 1.5.4.1 date 2001.11.12.21.19.18; author thorpej; state Exp; branches; next ; 1.4.2.1 date 2001.09.13.01.16.21; author thorpej; state Exp; branches; next 1.4.2.2; 1.4.2.2 date 2002.01.10.20.02.09; author thorpej; state Exp; branches; next 1.4.2.3; 1.4.2.3 date 2002.02.11.20.10.29; author jdolecek; state Exp; branches; next 1.4.2.4; 1.4.2.4 date 2002.03.16.16.02.06; author jdolecek; state Exp; branches; next 1.4.2.5; 1.4.2.5 date 2002.06.23.17.50.26; author jdolecek; state Exp; branches; next 1.4.2.6; 1.4.2.6 date 2002.09.06.08.48.56; author jdolecek; state Exp; branches; next ; 1.3.2.1 date 2001.06.18.12.32.47; author nathanw; state dead; branches; next 1.3.2.2; 1.3.2.2 date 2001.06.21.20.08.10; author nathanw; state Exp; branches; next 1.3.2.3; 1.3.2.3 date 2001.08.24.00.12.13; author nathanw; state Exp; branches; next 1.3.2.4; 1.3.2.4 date 2001.09.21.22.36.45; author nathanw; state Exp; branches; next 1.3.2.5; 1.3.2.5 date 2001.11.14.19.17.24; author nathanw; state Exp; branches; next 1.3.2.6; 1.3.2.6 date 2002.01.08.00.33.52; author nathanw; state Exp; branches; next 1.3.2.7; 1.3.2.7 date 2002.01.09.02.54.45; author nathanw; state Exp; branches; next 1.3.2.8; 1.3.2.8 date 2002.01.11.23.39.44; author nathanw; state Exp; branches; next 1.3.2.9; 1.3.2.9 date 2002.02.28.04.15.01; author nathanw; state Exp; branches; next 1.3.2.10; 1.3.2.10 date 2002.04.01.07.48.22; author nathanw; state Exp; branches; next 1.3.2.11; 1.3.2.11 date 2002.04.17.00.06.24; author nathanw; state Exp; branches; next 1.3.2.12; 1.3.2.12 date 2002.06.24.22.11.34; author nathanw; state Exp; branches; next 1.3.2.13; 1.3.2.13 date 2002.07.12.01.40.29; author nathanw; state Exp; branches; next 1.3.2.14; 1.3.2.14 date 2002.08.01.02.46.39; author nathanw; state Exp; branches; next 1.3.2.15; 1.3.2.15 date 2002.08.27.23.47.54; author nathanw; state Exp; branches; next 1.3.2.16; 1.3.2.16 date 2002.09.17.21.22.50; author nathanw; state Exp; branches; next 1.3.2.17; 1.3.2.17 date 2002.12.29.20.55.43; author thorpej; state Exp; branches; next 1.3.2.18; 1.3.2.18 date 2003.01.15.18.59.04; author thorpej; state Exp; branches; next ; desc @@ 1.183 log @Fix stall on PPPOE_STATE_PADR_SENT, suggested by martin@@n.o, thanks. Just drop such large PADO frames, ok'ed by yamaguchi@@n.o. I left if_pppoe.c:r1.182 code because that fixes other issues such as pppoe(4) stall in PPPOE_STATE_PADR_SENT when the PADO sender never replys. @ text @/* $NetBSD: if_pppoe.c,v 1.182 2022/08/12 06:24:03 knakahara Exp $ */ /* * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Martin Husemann . * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.182 2022/08/12 06:24:03 knakahara Exp $"); #ifdef _KERNEL_OPT #include "pppoe.h" #include "opt_pppoe.h" #include "opt_net_mpsafe.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ioconf.h" #ifdef NET_MPSAFE #define PPPOE_MPSAFE 1 #endif #ifndef PPPOE_DEQUEUE_MAXLEN #define PPPOE_DEQUEUE_MAXLEN IFQ_MAXLEN #endif struct pppoehdr { uint8_t vertype; uint8_t code; uint16_t session; uint16_t plen; } __packed; struct pppoetag { uint16_t tag; uint16_t len; } __packed; #define PPPOE_HEADERLEN sizeof(struct pppoehdr) #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) #define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ #define PPPOE_TAG_EOL 0x0000 /* end of list */ #define PPPOE_TAG_SNAME 0x0101 /* service name */ #define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ #define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ #define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ #define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ #define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ #define PPPOE_TAG_MAX_PAYLOAD 0x0120 /* max payload */ #define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ #define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ #define PPPOE_TAG_GENERIC_ERR 0x0203 /* generic error */ #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ #define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ /* two byte PPP protocol discriminator, then IP data */ #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ #define PPPOE_ADD_16(PTR, VAL) \ *(PTR)++ = (VAL) / 256; \ *(PTR)++ = (VAL) % 256 /* Add a complete PPPoE header to the buffer pointed to by PTR */ #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ *(PTR)++ = PPPOE_VERTYPE; \ *(PTR)++ = (CODE); \ PPPOE_ADD_16(PTR, SESS); \ PPPOE_ADD_16(PTR, LEN) #define PPPOE_DISC_TIMEOUT (hz*5) /* base for quick timeout calculation */ #define PPPOE_SLOW_RETRY (hz*60) /* persistent retry interval */ #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_RECON_PADTRCVD (hz*5) /* reconnect delay after PADT received */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ #ifdef PPPOE_SERVER /* from if_spppsubr.c */ #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ #endif #define PPPOE_LOCK(_sc, _op) rw_enter(&(_sc)->sc_lock, (_op)) #define PPPOE_UNLOCK(_sc) rw_exit(&(_sc)->sc_lock) #define PPPOE_WLOCKED(_sc) rw_write_held(&(_sc)->sc_lock) #ifdef PPPOE_MPSAFE #define DECLARE_SPLNET_VARIABLE #define ACQUIRE_SPLNET() do { } while (0) #define RELEASE_SPLNET() do { } while (0) #else #define DECLARE_SPLNET_VARIABLE int __s #define ACQUIRE_SPLNET() do { \ __s = splnet(); \ } while (0) #define RELEASE_SPLNET() do { \ splx(__s); \ } while (0) #endif #ifdef PPPOE_DEBUG #define DPRINTF(_sc, _fmt, _arg...) pppoe_printf((_sc), (_fmt), ##_arg) #else #define DPRINTF(_sc, _fmt, _arg...) __nothing #endif struct pppoe_softc { struct sppp sc_sppp; /* contains a struct ifnet as first element */ LIST_ENTRY(pppoe_softc) sc_list; struct ifnet *sc_eth_if; /* ethernet interface we are using */ uint64_t sc_id; /* id of this softc, our hunique */ int sc_state; /* discovery phase or session connected */ struct ether_addr sc_dest; /* hardware address of concentrator */ uint16_t sc_session; /* PPPoE session id */ char *sc_service_name; /* if != NULL: requested name of service */ char *sc_concentrator_name; /* if != NULL: requested concentrator id */ uint8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ size_t sc_ac_cookie_len; /* length of cookie data */ uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ #ifdef PPPOE_SERVER uint8_t *sc_hunique; /* content of host unique we must echo back */ size_t sc_hunique_len; /* length of host unique */ #endif callout_t sc_timeout; /* timeout while not in session state */ struct workqueue *sc_timeout_wq; /* workqueue for timeout */ struct work sc_timeout_wk; u_int sc_timeout_scheduled; int sc_padi_retried; /* number of PADI retries already done */ int sc_padr_retried; /* number of PADR retries already done */ krwlock_t sc_lock; /* lock of sc_state, sc_session, and sc_eth_if */ bool sc_detaching; }; /* incoming traffic will be queued here */ struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN }; struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN }; void *pppoe_softintr = NULL; static void pppoe_softintr_handler(void *); extern int sppp_ioctl(struct ifnet *, unsigned long, void *); /* input routines */ static void pppoeintr(void); static void pppoe_disc_input(struct mbuf *); static void pppoe_dispatch_disc_pkt(struct mbuf *, int); static void pppoe_data_input(struct mbuf *); static void pppoe_enqueue(struct ifqueue *, struct mbuf *); /* management routines */ static int pppoe_connect(struct pppoe_softc *); static int pppoe_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static int pppoe_ioctl(struct ifnet *, unsigned long, void *); static void pppoe_tls(struct sppp *); static void pppoe_tlf(struct sppp *); static void pppoe_start(struct ifnet *); #ifdef PPPOE_MPSAFE static int pppoe_transmit(struct ifnet *, struct mbuf *); #endif static void pppoe_clear_softc(struct pppoe_softc *, const char *); static void pppoe_printf(struct pppoe_softc *, const char *, ...); /* internal timeout handling */ static void pppoe_timeout_co(void *); static void pppoe_timeout_co_halt(void *); static void pppoe_timeout_wk(struct work *, void *); static void pppoe_timeout(struct pppoe_softc *); /* sending actual protocol control packets */ static int pppoe_send_padi(struct pppoe_softc *); static int pppoe_send_padr(struct pppoe_softc *); #ifdef PPPOE_SERVER static int pppoe_send_pado(struct pppoe_softc *); static int pppoe_send_pads(struct pppoe_softc *); #endif static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *); /* raw output */ static int pppoe_output(struct pppoe_softc *, struct mbuf *); /* internal helper functions */ static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *, krw_t); static struct mbuf *pppoe_get_mbuf(size_t len); static void pppoe_ifattach_hook(void *, unsigned long, void *); static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; static krwlock_t pppoe_softc_list_lock; static int pppoe_clone_create(struct if_clone *, int); static int pppoe_clone_destroy(struct ifnet *); static bool pppoe_term_unknown = false; static int pppoe_term_unknown_pps = 1; static struct sysctllog *pppoe_sysctl_clog; static void sysctl_net_pppoe_setup(struct sysctllog **); static struct if_clone pppoe_cloner = IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy); /* ARGSUSED */ void pppoeattach(int count) { /* * Nothing to do here, initialization is handled by the * module initialization code in pppoeinit() below). */ } static void pppoeinit(void) { LIST_INIT(&pppoe_softc_list); rw_init(&pppoe_softc_list_lock); if_clone_attach(&pppoe_cloner); pppoe_softintr = softint_establish(SOFTINT_MPSAFE|SOFTINT_NET, pppoe_softintr_handler, NULL); sysctl_net_pppoe_setup(&pppoe_sysctl_clog); IFQ_LOCK_INIT(&ppoediscinq); IFQ_LOCK_INIT(&ppoeinq); } static int pppoedetach(void) { int error = 0; rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); error = EBUSY; } if (error == 0) { if_clone_detach(&pppoe_cloner); softint_disestablish(pppoe_softintr); /* Remove our sysctl sub-tree */ sysctl_teardown(&pppoe_sysctl_clog); } return error; } static void pppoe_softc_genid(uint64_t *id) { struct pppoe_softc *sc; uint64_t rndid; rw_enter(&pppoe_softc_list_lock, RW_READER); while (1) { rndid = cprng_strong64(); sc = NULL; LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_id == rndid) break; } if (sc == NULL) { break; } } rw_exit(&pppoe_softc_list_lock); *id = rndid; } static int pppoe_clone_create(struct if_clone *ifc, int unit) { struct pppoe_softc *sc; struct ifnet *ifp; int rv; sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); ifp = &sc->sc_sppp.pp_if; rw_init(&sc->sc_lock); pppoe_softc_genid(&sc->sc_id); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if_initname(ifp, "pppoe", unit); ifp->if_softc = sc; ifp->if_mtu = PPPOE_MAXMTU; ifp->if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; #ifdef PPPOE_MPSAFE ifp->if_extflags = IFEF_MPSAFE; #endif ifp->if_type = IFT_PPP; ifp->if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; ifp->if_dlt = DLT_PPP_ETHER; ifp->if_ioctl = pppoe_ioctl; ifp->if_start = pppoe_start; #ifdef PPPOE_MPSAFE ifp->if_transmit = pppoe_transmit; #endif IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ PP_NOFRAMING; /* no serial encapsulation */ sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ rv = workqueue_create(&sc->sc_timeout_wq, ifp->if_xname, pppoe_timeout_wk, sc, PRI_SOFTNET, IPL_SOFTNET, 0); if (rv != 0) goto destroy_sclock; callout_init(&sc->sc_timeout, CALLOUT_MPSAFE); callout_setfunc(&sc->sc_timeout, pppoe_timeout_co, sc); if_initialize(ifp); ifp->if_percpuq = if_percpuq_create(ifp); rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); rw_exit(&pppoe_softc_list_lock); sppp_attach(ifp); bpf_attach(ifp, DLT_PPP_ETHER, 0); if_register(ifp); return 0; destroy_sclock: rw_destroy(&sc->sc_lock); kmem_free(sc, sizeof(*sc)); return rv; } static int pppoe_clone_destroy(struct ifnet *ifp) { struct pppoe_softc * sc = ifp->if_softc; PPPOE_LOCK(sc, RW_WRITER); /* stop ioctls */ sc->sc_detaching = true; if (ifp->if_flags & IFF_RUNNING) { pppoe_clear_softc(sc, "destroy interface"); sc->sc_eth_if = NULL; } PPPOE_UNLOCK(sc); rw_enter(&pppoe_softc_list_lock, RW_WRITER); LIST_REMOVE(sc, sc_list); if (LIST_EMPTY(&pppoe_softc_list)) { pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } rw_exit(&pppoe_softc_list_lock); bpf_detach(ifp); sppp_detach(&sc->sc_sppp.pp_if); if_detach(ifp); callout_setfunc(&sc->sc_timeout, pppoe_timeout_co_halt, sc); workqueue_wait(sc->sc_timeout_wq, &sc->sc_timeout_wk); workqueue_destroy(sc->sc_timeout_wq); callout_halt(&sc->sc_timeout, NULL); callout_destroy(&sc->sc_timeout); #ifdef PPPOE_SERVER if (sc->sc_hunique) { free(sc->sc_hunique, M_DEVBUF); sc->sc_hunique = NULL; sc->sc_hunique_len = 0; } #endif if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); rw_destroy(&sc->sc_lock); kmem_free(sc, sizeof(*sc)); return 0; } static void pppoe_printf(struct pppoe_softc *sc, const char *fmt, ...) { va_list ap; bool pppoe_debug; #ifdef PPPOE_DEBUG pppoe_debug = true; #else pppoe_debug = false; #endif if (sc == NULL) { if (!pppoe_debug) return; printf("pppoe: "); } else { if (!ISSET(sc->sc_sppp.pp_if.if_flags, IFF_DEBUG)) return; printf("%s: ", sc->sc_sppp.pp_if.if_xname); } va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } /* * Find the interface handling the specified session. * Note: O(number of sessions open), this is a client-side only, mean * and lean implementation, so number of open sessions typically should * be 1. */ static struct pppoe_softc * pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif, krw_t lock) { struct pppoe_softc *sc = NULL; if (session == 0) return NULL; rw_enter(&pppoe_softc_list_lock, RW_READER); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { PPPOE_LOCK(sc, lock); if ( sc->sc_state == PPPOE_STATE_SESSION && sc->sc_session == session && sc->sc_eth_if == rcvif) break; PPPOE_UNLOCK(sc); } rw_exit(&pppoe_softc_list_lock); return sc; } /* Check host unique token passed and return appropriate softc pointer, * or NULL if token is bogus. */ static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif, krw_t lock) { struct pppoe_softc *sc; uint64_t t; CTASSERT(sizeof(t) == sizeof(sc->sc_id)); rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); return NULL; } if (len != sizeof(sc->sc_id)) { rw_exit(&pppoe_softc_list_lock); return NULL; } memcpy(&t, token, len); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { PPPOE_LOCK(sc, lock); if (sc->sc_id == t && sc->sc_eth_if != NULL) { break; } PPPOE_UNLOCK(sc); } rw_exit(&pppoe_softc_list_lock); if (sc == NULL) { pppoe_printf(NULL, "alien host unique tag" ", no session found\n"); return NULL; } /* should be safe to access *sc now */ if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { pppoe_printf(sc, "host unique tag found" ", but it belongs to a connection in state %d\n", sc->sc_state); PPPOE_UNLOCK(sc); return NULL; } if (sc->sc_eth_if != rcvif) { pppoe_printf(sc, "wrong interface, not accepting host unique\n"); PPPOE_UNLOCK(sc); return NULL; } return sc; } static void pppoe_softintr_handler(void *dummy) { /* called at splsoftnet() */ pppoeintr(); } /* called at appropriate protection level */ static void pppoeintr(void) { struct mbuf *m; int i; SOFTNET_LOCK_UNLESS_NET_MPSAFE(); for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoediscinq); IF_DEQUEUE(&ppoediscinq, m); IFQ_UNLOCK(&ppoediscinq); if (m == NULL) break; pppoe_disc_input(m); } for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoeinq); IF_DEQUEUE(&ppoeinq, m); IFQ_UNLOCK(&ppoeinq); if (m == NULL) break; pppoe_data_input(m); } #if PPPOE_DEQUEUE_MAXLEN < IFQ_MAXLEN if (!IF_IS_EMPTY(&ppoediscinq) || !IF_IS_EMPTY(&ppoeinq)) softint_schedule(pppoe_softintr); #endif SOFTNET_UNLOCK_UNLESS_NET_MPSAFE(); } /* analyze and handle a single received packet while not in session state */ static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) { uint16_t tag, len; uint16_t session, plen; struct pppoe_softc *sc; const char *err_msg; char *error; size_t dlen; uint8_t *ac_cookie; size_t ac_cookie_len; uint8_t *relay_sid; size_t relay_sid_len; uint8_t *hunique; size_t hunique_len; struct pppoehdr *ph; struct pppoetag *pt; struct mbuf *n; int noff, err, errortag; struct ether_header *eh; struct ifnet *rcvif; struct psref psref; if (m->m_len < sizeof(*eh)) { m = m_pullup(m, sizeof(*eh)); if (m == NULL) goto done; } eh = mtod(m, struct ether_header *); off += sizeof(*eh); if (m->m_pkthdr.len - off < PPPOE_HEADERLEN) { goto done; } M_REGION_GET(ph, struct pppoehdr *, m, off, sizeof(*ph)); if (ph == NULL) { goto done; } if (ph->vertype != PPPOE_VERTYPE) { goto done; } ac_cookie = NULL; ac_cookie_len = 0; relay_sid = NULL; relay_sid_len = 0; hunique = NULL; hunique_len = 0; session = ntohs(ph->session); plen = ntohs(ph->plen); off += sizeof(*ph); if (plen + off > m->m_pkthdr.len) { goto done; } m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ tag = 0; len = 0; sc = NULL; err_msg = NULL; errortag = 0; while (off + sizeof(*pt) <= m->m_pkthdr.len) { M_REGION_GET(pt, struct pppoetag *, m, off, sizeof(*pt)); if (pt == NULL) { goto done; } tag = ntohs(pt->tag); len = ntohs(pt->len); if (off + len + sizeof(*pt) > m->m_pkthdr.len) { goto done; } switch (tag) { case PPPOE_TAG_EOL: goto breakbreak; case PPPOE_TAG_SNAME: break; /* ignored */ case PPPOE_TAG_ACNAME: if (len > 0) { dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT); if (error == NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; free(error, M_TEMP); goto done; } strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); pppoe_printf(NULL, "connected to %s\n", error); free(error, M_TEMP); } break; /* ignored */ case PPPOE_TAG_HUNIQUE: if (hunique == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; err_msg = "TAG HUNIQUE ERROR"; break; } hunique = mtod(n, uint8_t *) + noff; hunique_len = len; } break; case PPPOE_TAG_ACCOOKIE: if (ac_cookie == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG ACCOOKIE ERROR"; m = NULL; break; } ac_cookie = mtod(n, char *) + noff; ac_cookie_len = len; } break; case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; case PPPOE_TAG_SNAME_ERR: err_msg = "SERVICE NAME ERROR"; errortag = 1; break; case PPPOE_TAG_ACSYS_ERR: err_msg = "AC SYSTEM ERROR"; errortag = 1; break; case PPPOE_TAG_GENERIC_ERR: err_msg = "GENERIC ERROR"; errortag = 1; break; } if (err_msg) { error = NULL; if (errortag && len) { dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT|M_ZERO); n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; } else if (error) { strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); } } if (error) { pppoe_printf(NULL, "%s: %s\n", err_msg, error); free(error, M_TEMP); } else pppoe_printf(NULL, "%s\n", err_msg); if (errortag || m == NULL) goto done; } off += sizeof(*pt) + len; } breakbreak:; switch (ph->code) { case PPPOE_CODE_PADI: #ifdef PPPOE_SERVER /* * got service name, concentrator name, and/or host unique. * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); goto done; } LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { PPPOE_LOCK(sc, RW_WRITER); if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { PPPOE_UNLOCK(sc); continue; } if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { PPPOE_UNLOCK(sc); continue; } if (sc->sc_state == PPPOE_STATE_INITIAL) break; PPPOE_UNLOCK(sc); } rw_exit(&pppoe_softc_list_lock); if (sc == NULL) { goto done; } if (hunique) { if (sc->sc_hunique) free(sc->sc_hunique, M_DEVBUF); sc->sc_hunique = malloc(hunique_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_hunique == NULL) { PPPOE_UNLOCK(sc); goto done; } sc->sc_hunique_len = hunique_len; memcpy(sc->sc_hunique, hunique, hunique_len); } memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); sc->sc_state = PPPOE_STATE_PADO_SENT; pppoe_send_pado(sc); PPPOE_UNLOCK(sc); break; #endif /* PPPOE_SERVER */ case PPPOE_CODE_PADR: #ifdef PPPOE_SERVER /* * get sc from ac_cookie if IFF_PASSIVE */ if (ac_cookie == NULL) { goto done; } rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) { /* be quiet if there is not a single pppoe instance */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { pppoe_printf(NULL, "received PADR" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); goto done; } if (sc->sc_state != PPPOE_STATE_PADO_SENT) { pppoe_printf(sc, "received unexpected PADR\n"); PPPOE_UNLOCK(sc); goto done; } if (hunique) { if (sc->sc_hunique) free(sc->sc_hunique, M_DEVBUF); sc->sc_hunique = malloc(hunique_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_hunique == NULL) { PPPOE_UNLOCK(sc); goto done; } sc->sc_hunique_len = hunique_len; memcpy(sc->sc_hunique, hunique, hunique_len); } pppoe_send_pads(sc); sc->sc_state = PPPOE_STATE_SESSION; PPPOE_UNLOCK(sc); sc->sc_sppp.pp_up(&sc->sc_sppp); break; #else /* ignore, we are no access concentrator */ goto done; #endif /* PPPOE_SERVER */ case PPPOE_CODE_PADO: rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) { /* be quiet if there is not a single pppoe instance */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { pppoe_printf(NULL, "received PADO" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); goto done; } if (sc->sc_state != PPPOE_STATE_PADI_SENT) { pppoe_printf(sc, "received unexpected PADO\n"); PPPOE_UNLOCK(sc); goto done; } if (ac_cookie) { if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_ac_cookie == NULL) { pppoe_printf(sc, "FATAL: could not allocate memory " "for AC cookie\n"); sc->sc_ac_cookie_len = 0; PPPOE_UNLOCK(sc); goto done; } sc->sc_ac_cookie_len = ac_cookie_len; memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); } else if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; sc->sc_ac_cookie_len = 0; } if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { pppoe_printf(sc, "FATAL: could not allocate memory " "for relay SID\n"); sc->sc_relay_sid_len = 0; PPPOE_UNLOCK(sc); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } else if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; sc->sc_relay_sid_len = 0; } memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); callout_stop(&sc->sc_timeout); sc->sc_padr_retried = 0; sc->sc_state = PPPOE_STATE_PADR_SENT; if ((err = pppoe_send_padr(sc)) != 0) { if (err == ENOBUFS) { pppoe_printf(sc, "PADO is too large, drop it\n"); /* * Cannot send PADR generated by received PADO, * so restart from sending PAD*I*. */ sc->sc_state = PPPOE_STATE_PADI_SENT; callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried)); PPPOE_UNLOCK(sc); goto done; } pppoe_printf(sc, "failed to send PADR, error=%d\n", err); } callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried)); PPPOE_UNLOCK(sc); break; case PPPOE_CODE_PADS: rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) goto done; if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } sc->sc_session = session; callout_stop(&sc->sc_timeout); pppoe_printf(sc, "session 0x%x connected\n", session); sc->sc_state = PPPOE_STATE_SESSION; PPPOE_UNLOCK(sc); sc->sc_sppp.pp_up(&sc->sc_sppp); /* notify upper layers */ break; case PPPOE_CODE_PADT: rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) goto done; if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } pppoe_clear_softc(sc, "received PADT"); if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) { pppoe_printf(sc, "wait for reconnect\n"); callout_schedule(&sc->sc_timeout, PPPOE_RECON_PADTRCVD); } PPPOE_UNLOCK(sc); break; default: rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); pppoe_printf(sc, "unknown code (0x%04x) session = 0x%04x\n", ph->code, session); if (sc == NULL) goto done; PPPOE_UNLOCK(sc); break; } done: if (m) m_freem(m); return; } static void pppoe_disc_input(struct mbuf *m) { KASSERT(m->m_flags & M_PKTHDR); /* * Avoid error messages if there is not a single PPPoE instance. */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); pppoe_dispatch_disc_pkt(m, 0); } else { rw_exit(&pppoe_softc_list_lock); m_freem(m); } } static bool pppoe_is_my_frame(uint8_t *dhost, struct ifnet *rcvif) { if (memcmp(CLLADDR(rcvif->if_sadl), dhost, ETHER_ADDR_LEN) == 0) return true; return false; } static void pppoe_data_input(struct mbuf *m) { uint16_t session, plen; struct pppoe_softc *sc; struct pppoehdr *ph; struct ifnet *rcvif; struct psref psref; uint8_t shost[ETHER_ADDR_LEN]; uint8_t dhost[ETHER_ADDR_LEN]; bool term_unknown = pppoe_term_unknown; KASSERT(m->m_flags & M_PKTHDR); /* * Avoid error messages if there is not a single PPPoE instance. */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); goto drop; } rw_exit(&pppoe_softc_list_lock); if (term_unknown) { memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); memcpy(dhost, mtod(m, struct ether_header*)->ether_dhost, ETHER_ADDR_LEN); } m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { goto drop; } if (m->m_len < sizeof(*ph)) { m = m_pullup(m, sizeof(*ph)); if (m == NULL) { return; } } ph = mtod(m, struct pppoehdr *); if (ph->vertype != PPPOE_VERTYPE) { goto drop; } if (ph->code != 0) { goto drop; } session = ntohs(ph->session); rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto drop; sc = pppoe_find_softc_by_session(session, rcvif, RW_READER); if (sc == NULL) { if (term_unknown) { static struct timeval lasttime = {0, 0}; static int curpps = 0; /* * avoid to send wrong PADT which is response from * session stage packets for other hosts when parent * ethernet is promiscuous mode. */ if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, pppoe_term_unknown_pps)) { pppoe_printf(NULL, "input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); } } m_put_rcvif_psref(rcvif, &psref); goto drop; } m_put_rcvif_psref(rcvif, &psref); plen = ntohs(ph->plen); bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_IN); m_adj(m, PPPOE_HEADERLEN); #ifdef PPPOE_DEBUG { struct mbuf *p; printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } #endif PPPOE_UNLOCK(sc); if (m->m_pkthdr.len < plen) goto drop; /* ignore trailing garbage */ m_adj(m, plen - m->m_pkthdr.len); /* * Fix incoming interface pointer (not the raw ethernet interface * anymore) */ m_set_rcvif(m, &sc->sc_sppp.pp_if); /* pass packet up and account for it */ if_statinc(&sc->sc_sppp.pp_if, if_ipackets); sppp_input(&sc->sc_sppp.pp_if, m); return; drop: m_freem(m); } static int pppoe_output(struct pppoe_softc *sc, struct mbuf *m) { struct sockaddr dst; struct ether_header *eh; uint16_t etype; if (sc->sc_eth_if == NULL) { m_freem(m); return EIO; } memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); DPRINTF(sc, "(%x) state=%d, session=0x%x output -> %s, len=%d\n", etype, sc->sc_state, sc->sc_session, ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len); m->m_flags &= ~(M_BCAST|M_MCAST); if_statinc(&sc->sc_sppp.pp_if, if_opackets); return if_output_lock(sc->sc_eth_if, sc->sc_eth_if, m, &dst, NULL); } static int pppoe_parm_cpyinstr(struct pppoe_softc *sc, char **dst, const void *src, size_t len) { int error = 0; char *next = NULL; size_t bufsiz, cpysiz, strsiz; bufsiz = len + 1; if (src == NULL) goto out; bufsiz = len + 1; next = malloc(bufsiz, M_DEVBUF, M_WAITOK); if (next == NULL) return ENOMEM; error = copyinstr(src, next, bufsiz, &cpysiz); if (error != 0) goto fail; if (cpysiz != bufsiz) { error = EINVAL; goto fail; } strsiz = strnlen(next, bufsiz); if (strsiz == bufsiz) { error = EINVAL; goto fail; } out: PPPOE_LOCK(sc, RW_WRITER); if (*dst != NULL) free(*dst, M_DEVBUF); *dst = next; next = NULL; PPPOE_UNLOCK(sc); fail: if (next != NULL) free(next, M_DEVBUF); return error; } static int pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data) { struct lwp *l = curlwp; /* XXX */ struct pppoe_softc *sc = (struct pppoe_softc*)ifp; struct ifreq *ifr = data; int error = 0; switch (cmd) { case PPPOESETPARMS: { struct pppoediscparms *parms = (struct pppoediscparms*)data; if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, NULL) != 0) return EPERM; if (parms->eth_ifname[0] != 0) { struct ifnet *eth_if; PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_detaching) { PPPOE_UNLOCK(sc); return ENXIO; } eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; PPPOE_UNLOCK(sc); return ENXIO; } if (sc->sc_sppp.pp_if.if_mtu != eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; PPPOE_UNLOCK(sc); } error = pppoe_parm_cpyinstr(sc, &sc->sc_concentrator_name, parms->ac_name, parms->ac_name_len); if (error != 0) return error; error = pppoe_parm_cpyinstr(sc, &sc->sc_service_name, parms->service_name, parms->service_name_len); if (error != 0) return error; return 0; } break; case PPPOEGETPARMS: { struct pppoediscparms *parms = (struct pppoediscparms*)data; memset(parms, 0, sizeof *parms); PPPOE_LOCK(sc, RW_READER); if (sc->sc_eth_if) strlcpy(parms->ifname, sc->sc_eth_if->if_xname, sizeof(parms->ifname)); PPPOE_UNLOCK(sc); return 0; } break; case PPPOEGETSESSION: { struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data; PPPOE_LOCK(sc, RW_READER); state->state = sc->sc_state; state->session_id = sc->sc_session; state->padi_retry_no = sc->sc_padi_retried; state->padr_retry_no = sc->sc_padr_retried; PPPOE_UNLOCK(sc); return 0; } break; case SIOCSIFFLAGS: /* * Prevent running re-establishment timers overriding * administrators choice. */ PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_detaching) { PPPOE_UNLOCK(sc); return ENXIO; } if ((ifr->ifr_flags & IFF_UP) == 0 && sc->sc_state < PPPOE_STATE_SESSION) { callout_stop(&sc->sc_timeout); sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); } PPPOE_UNLOCK(sc); error = sppp_ioctl(ifp, cmd, data); return error; case SIOCSIFMTU: if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { return EINVAL; } /*FALLTHROUGH*/ default: return sppp_ioctl(ifp, cmd, data); } return 0; } /* * Allocate a mbuf/cluster with space to store the given data length * of payload, leaving space for prepending an ethernet header * in front. */ static struct mbuf * pppoe_get_mbuf(size_t len) { struct mbuf *m; if (len + sizeof(struct ether_header) > MCLBYTES) return NULL; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) return NULL; if (len + sizeof(struct ether_header) > MHLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { m_free(m); return NULL; } } m->m_data += sizeof(struct ether_header); m->m_len = len; m->m_pkthdr.len = len; m_reset_rcvif(m); return m; } static int pppoe_send_padi(struct pppoe_softc *sc) { struct mbuf *m0; int len, l1 = 0, l2 = 0; uint8_t *p; if (sc->sc_state > PPPOE_STATE_PADI_SENT) panic("pppoe_send_padi in state %d", sc->sc_state); /* Compute packet length. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { l1 = strlen(sc->sc_service_name); len += l1; } if (sc->sc_concentrator_name != NULL) { l2 = strlen(sc->sc_concentrator_name); len += sizeof(struct pppoetag) + l2; } len += sizeof(struct pppoetag) + sizeof(sc->sc_id); if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) { len += sizeof(struct pppoetag) + 2; } /* Allocate packet. */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (m0 == NULL) return ENOBUFS; /* Fill in packet. */ p = mtod(m0, uint8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); memcpy(p, sc->sc_service_name, l1); p += l1; } else { PPPOE_ADD_16(p, 0); } if (sc->sc_concentrator_name != NULL) { PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); PPPOE_ADD_16(p, l2); memcpy(p, sc->sc_concentrator_name, l2); p += l2; } PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) { PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD); PPPOE_ADD_16(p, 2); PPPOE_ADD_16(p, (uint16_t)sc->sc_sppp.pp_if.if_mtu); } #ifdef PPPOE_DEBUG if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) panic("pppoe_send_padi: garbled output len, should be %ld, is %ld", (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); #endif /* Send packet. */ return pppoe_output(sc, m0); } static void pppoe_timeout_co(void *arg) { struct pppoe_softc *sc = (struct pppoe_softc *)arg; if (atomic_swap_uint(&sc->sc_timeout_scheduled, 1) != 0) return; workqueue_enqueue(sc->sc_timeout_wq, &sc->sc_timeout_wk, NULL); } static void pppoe_timeout_co_halt(void *unused __unused) { /* do nothing to halt callout safely */ } static void pppoe_timeout_wk(struct work *wk __unused, void *arg) { struct pppoe_softc *sc = (struct pppoe_softc *)arg; atomic_swap_uint(&sc->sc_timeout_scheduled, 0); pppoe_timeout(sc); } static void pppoe_timeout(struct pppoe_softc *sc) { int retry_wait, err; DECLARE_SPLNET_VARIABLE; pppoe_printf(sc, "timeout\n"); PPPOE_LOCK(sc, RW_WRITER); switch (sc->sc_state) { case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ if (!sc->sc_detaching) pppoe_connect(sc); break; case PPPOE_STATE_PADI_SENT: /* * We have two basic ways of retrying: * - Quick retry mode: try a few times in short sequence * - Slow retry mode: we already had a connection successfully * established and will try infinitely (without user * intervention) * We only enter slow retry mode if IFF_LINK1 (aka autodial) * is not set. */ /* initialize for quick retry mode */ retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); ACQUIRE_SPLNET(); sc->sc_padi_retried++; if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; } else { pppoe_abort_connect(sc); RELEASE_SPLNET(); PPPOE_UNLOCK(sc); return; } } if ((err = pppoe_send_padi(sc)) != 0) { sc->sc_padi_retried--; pppoe_printf(sc, "failed to transmit PADI, error=%d\n", err); } callout_schedule(&sc->sc_timeout,retry_wait); RELEASE_SPLNET(); break; case PPPOE_STATE_PADR_SENT: ACQUIRE_SPLNET(); sc->sc_padr_retried++; if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_PADI_SENT; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; if ((err = pppoe_send_padi(sc)) != 0) { pppoe_printf(sc, "failed to send PADI, error=%d\n", err); } callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried)); RELEASE_SPLNET(); PPPOE_UNLOCK(sc); return; } if ((err = pppoe_send_padr(sc)) != 0) { pppoe_printf(sc,"failed to send PADR, error=%d", err); } callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried)); RELEASE_SPLNET(); break; case PPPOE_STATE_CLOSING: pppoe_disconnect(sc); break; default: PPPOE_UNLOCK(sc); return; /* all done, work in peace */ } PPPOE_UNLOCK(sc); } /* Start a connection (i.e. initiate discovery phase) */ static int pppoe_connect(struct pppoe_softc *sc) { int err; DECLARE_SPLNET_VARIABLE; KASSERT(PPPOE_WLOCKED(sc)); if (sc->sc_state != PPPOE_STATE_INITIAL) return EBUSY; #ifdef PPPOE_SERVER /* wait PADI if IFF_PASSIVE */ if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) return 0; #endif ACQUIRE_SPLNET(); /* save state, in case we fail to send PADI */ sc->sc_state = PPPOE_STATE_PADI_SENT; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; err = pppoe_send_padi(sc); if (err != 0) pppoe_printf(sc, "failed to send PADI, error=%d\n", err); callout_schedule(&sc->sc_timeout, PPPOE_DISC_TIMEOUT); RELEASE_SPLNET(); return err; } /* disconnect */ static int pppoe_disconnect(struct pppoe_softc *sc) { int err; DECLARE_SPLNET_VARIABLE; KASSERT(PPPOE_WLOCKED(sc)); ACQUIRE_SPLNET(); if (sc->sc_state < PPPOE_STATE_SESSION) err = EBUSY; else { pppoe_printf(sc, "disconnecting\n"); err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); } /* cleanup softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; #ifdef PPPOE_SERVER if (sc->sc_hunique) { free(sc->sc_hunique, M_DEVBUF); sc->sc_hunique = NULL; } sc->sc_hunique_len = 0; #endif sc->sc_session = 0; PPPOE_UNLOCK(sc); /* notify upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); PPPOE_LOCK(sc, RW_WRITER); RELEASE_SPLNET(); return err; } /* Connection attempt aborted */ static void pppoe_abort_connect(struct pppoe_softc *sc) { KASSERT(PPPOE_WLOCKED(sc)); pppoe_printf(sc, "could not establish connection\n"); sc->sc_state = PPPOE_STATE_CLOSING; PPPOE_UNLOCK(sc); /* notify upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); PPPOE_LOCK(sc, RW_WRITER); /* clear connection state */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_INITIAL; } static int pppoe_send_padr(struct pppoe_softc *sc) { struct mbuf *m0; uint8_t *p; size_t len, l1 = 0; if (sc->sc_state != PPPOE_STATE_PADR_SENT) return EIO; /* Compute packet length. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { l1 = strlen(sc->sc_service_name); len += l1; } if (sc->sc_ac_cookie_len > 0) { len += sizeof(struct pppoetag) + sc->sc_ac_cookie_len; } if (sc->sc_relay_sid_len > 0) { len += sizeof(struct pppoetag) + sc->sc_relay_sid_len; } len += sizeof(struct pppoetag) + sizeof(sc->sc_id); if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) { len += sizeof(struct pppoetag) + 2; } /* Allocate packet. */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (m0 == NULL) return ENOBUFS; /* Fill in packet. */ p = mtod(m0, uint8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); memcpy(p, sc->sc_service_name, l1); p += l1; } else { PPPOE_ADD_16(p, 0); } if (sc->sc_ac_cookie_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); PPPOE_ADD_16(p, sc->sc_ac_cookie_len); memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); p += sc->sc_ac_cookie_len; } if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MAXMTU) { PPPOE_ADD_16(p, PPPOE_TAG_MAX_PAYLOAD); PPPOE_ADD_16(p, 2); PPPOE_ADD_16(p, (uint16_t)sc->sc_sppp.pp_if.if_mtu); } #ifdef PPPOE_DEBUG if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) panic("pppoe_send_padr: garbled output len, should be %ld, is %ld", (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); #endif /* Send packet. */ return pppoe_output(sc, m0); } /* send a PADT packet */ static int pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest) { struct ether_header *eh; struct sockaddr dst; struct mbuf *m0; uint8_t *p; m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) return EIO; p = mtod(m0, uint8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOEDISC); memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); return if_output_lock(outgoing_if, outgoing_if, m0, &dst, NULL); } #ifdef PPPOE_SERVER static int pppoe_send_pado(struct pppoe_softc *sc) { struct mbuf *m0; uint8_t *p; size_t len; if (sc->sc_state != PPPOE_STATE_PADO_SENT) return EIO; /* Include AC cookie. */ len = sizeof(struct pppoetag) + sizeof(sc->sc_id); /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return EIO; p = mtod(m0, uint8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sc->sc_hunique_len); memcpy(p, sc->sc_hunique, sc->sc_hunique_len); return pppoe_output(sc, m0); } static int pppoe_send_pads(struct pppoe_softc *sc) { struct bintime bt; struct mbuf *m0; uint8_t *p; size_t len, l1 = 0; /* XXX: gcc */ KASSERT(PPPOE_WLOCKED(sc)); if (sc->sc_state != PPPOE_STATE_PADO_SENT) return EIO; getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; /* Include service name. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { l1 = strlen(sc->sc_service_name); len += l1; } /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, uint8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); memcpy(p, sc->sc_service_name, l1); p += l1; } else { PPPOE_ADD_16(p, 0); } PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sc->sc_hunique_len); memcpy(p, sc->sc_hunique, sc->sc_hunique_len); return pppoe_output(sc, m0); } #endif static void pppoe_tls(struct sppp *sp) { struct pppoe_softc *sc = (void *)sp; int wtime; PPPOE_LOCK(sc, RW_READER); if (sc->sc_state != PPPOE_STATE_INITIAL) { PPPOE_UNLOCK(sc); return; } if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact its radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_schedule(&sc->sc_timeout, wtime); PPPOE_UNLOCK(sc); } static void pppoe_tlf(struct sppp *sp) { struct pppoe_softc *sc = (void *)sp; PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_state < PPPOE_STATE_SESSION) { callout_stop(&sc->sc_timeout); sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); PPPOE_UNLOCK(sc); return; } /* * Do not call pppoe_disconnect here, the upper layer state * machine gets confused by this. We must return from this * function and defer disconnecting to the timeout handler. */ sc->sc_state = PPPOE_STATE_CLOSING; callout_schedule(&sc->sc_timeout, hz/50); PPPOE_UNLOCK(sc); } static void pppoe_start(struct ifnet *ifp) { struct pppoe_softc *sc = (void *)ifp; struct mbuf *m; uint8_t *p; size_t len; if (sppp_isempty(ifp)) return; /* are we ready to process data yet? */ PPPOE_LOCK(sc, RW_READER); if (sc->sc_state < PPPOE_STATE_SESSION) { sppp_flush(&sc->sc_sppp.pp_if); PPPOE_UNLOCK(sc); return; } while ((m = sppp_dequeue(ifp)) != NULL) { len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { if_statinc(ifp, if_oerrors); continue; } p = mtod(m, uint8_t *); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT); pppoe_output(sc, m); } PPPOE_UNLOCK(sc); } #ifdef PPPOE_MPSAFE static int pppoe_transmit(struct ifnet *ifp, struct mbuf *m) { struct pppoe_softc *sc = (void *)ifp; uint8_t *p; size_t len; if (m == NULL) return EINVAL; /* are we ready to process data yet? */ PPPOE_LOCK(sc, RW_READER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_UNLOCK(sc); m_freem(m); return ENOBUFS; } len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { PPPOE_UNLOCK(sc); if_statinc(ifp, if_oerrors); return ENETDOWN; } p = mtod(m, uint8_t *); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT); pppoe_output(sc, m); PPPOE_UNLOCK(sc); return 0; } #endif /* PPPOE_MPSAFE */ static void pppoe_ifattach_hook(void *arg, unsigned long cmd, void *arg2) { struct ifnet *ifp = arg2; struct pppoe_softc *sc; DECLARE_SPLNET_VARIABLE; if (cmd != PFIL_IFNET_DETACH) return; ACQUIRE_SPLNET(); rw_enter(&pppoe_softc_list_lock, RW_READER); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_eth_if != ifp) { PPPOE_UNLOCK(sc); continue; } if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); pppoe_printf(sc, "ethernet interface detached, going down\n"); } sc->sc_eth_if = NULL; pppoe_clear_softc(sc, "ethernet interface detached"); PPPOE_UNLOCK(sc); } rw_exit(&pppoe_softc_list_lock); RELEASE_SPLNET(); } static void pppoe_clear_softc(struct pppoe_softc *sc, const char *message) { KASSERT(PPPOE_WLOCKED(sc)); /* stop timer */ callout_stop(&sc->sc_timeout); pppoe_printf(sc, "session 0x%x terminated, %s\n", sc->sc_session, message); /* fix our state */ sc->sc_state = PPPOE_STATE_INITIAL; PPPOE_UNLOCK(sc); /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); PPPOE_LOCK(sc, RW_WRITER); /* clean up softc */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; } static void pppoe_enqueue(struct ifqueue *inq, struct mbuf *m) { if (m->m_flags & M_PROMISC) { m_freem(m); return; } #ifndef PPPOE_SERVER if (m->m_flags & (M_MCAST | M_BCAST)) { m_freem(m); return; } #endif IFQ_LOCK(inq); if (IF_QFULL(inq)) { IF_DROP(inq); IFQ_UNLOCK(inq); m_freem(m); } else { IF_ENQUEUE(inq, m); IFQ_UNLOCK(inq); softint_schedule(pppoe_softintr); } return; } void pppoe_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoeinq, m); return; } void pppoedisc_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoediscinq, m); return; } static void sysctl_net_pppoe_setup(struct sysctllog **clog) { const struct sysctlnode *node = NULL; extern pktq_rps_hash_func_t sppp_pktq_rps_hash_p; sppp_pktq_rps_hash_p = pktq_rps_hash_default; sysctl_createv(clog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "pppoe", SYSCTL_DESCR("PPPOE protocol"), NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL); if (node == NULL) return; sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_BOOL, "term_unknown", SYSCTL_DESCR("Terminate unknown sessions"), NULL, 0, &pppoe_term_unknown, sizeof(pppoe_term_unknown), CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_STRING, "rps_hash", SYSCTL_DESCR("Interface rps hash function control"), sysctl_pktq_rps_hash_handler, 0, (void *)&sppp_pktq_rps_hash_p, PKTQ_RPS_HASH_NAME_LEN, CTL_CREATE, CTL_EOL); } /* * Module infrastructure */ #include "if_module.h" IF_MODULE(MODULE_CLASS_DRIVER, pppoe, "sppp_subr") @ 1.182 log @Fix stall on PPPOE_STATE_PADR_SENT when received specific PADO, ok'ed by yamaguchi@@n.o. When pppoe receives a PADO frame larger than mbuf cluster size, pppoe_send_padr() fails forever. So, the pppoe interface stall on PPPOE_STATE_PADR_SENT until ifconfig down/up. It should retry from PADI in such case. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.181 2022/05/23 21:46:12 andvar Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.181 2022/05/23 21:46:12 andvar Exp $"); d991 13 @ 1.181 log @s/controll/control/ in comments. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.180 2022/05/10 09:05:03 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.180 2022/05/10 09:05:03 knakahara Exp $"); a1617 1 sc->sc_padr_retried--; @ 1.180 log @Zeroize the length explicitly when malloc failed. Pointed out by yamaguchi@@n.o. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.179 2022/05/04 14:30:04 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.179 2022/05/04 14:30:04 martin Exp $"); d235 1 a235 1 /* sending actual protocol controll packets */ @ 1.179 log @Do not allocate mbuf clusters when the caller (eroneously) asks for more than MCLBYTES size, instead fail the allocation. When we have received multiple PADO offer packets in the discovery phase, do not combine tags from different packets. We are supposed to pick one PADO packet and continue session establishment with that. The second bug could cause code to trigger the first and create invalid response packets and also overwrite data outside of the allocated mbuf cluster. Fixes CVE-2022-29867. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.178 2021/10/11 05:13:11 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.178 2021/10/11 05:13:11 knakahara Exp $"); d956 1 d975 1 @ 1.178 log @Make pktq_rps_hash() pluggable for each interface type. Reviewed by gdt@@n.o, thorpej@@n.o, and riastradh@@n.o, thanks. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.177 2021/06/16 00:21:19 riastradh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.177 2021/06/16 00:21:19 riastradh Exp $"); d961 4 d979 4 d1429 3 @ 1.177 log @if_attach and if_initialize cannot fail, don't test return value These were originally made failable back in 2017 when if_initialize allocated a softint in every interface for link state changes, so that it could fail gracefully instead of panicking: https://mail-index.NetBSD.org/source-changes/2017/10/23/msg089053.html However, this spawned many seldom- or never-tested error branches, which are risky to have around. And that softint in every interface has since been replaced by a single global workqueue, because link state changes require thread context but not low latency or high throughput: https://mail-index.NetBSD.org/source-changes/2020/02/06/msg113759.html So there is no longer any reason for if_initialize to fail. (The subroutine if_stats_init can't fail because percpu_alloc can't fail either.) There is a snag: the softint_establish in if_percpuq_create could fail, potentially leading to bad consequences later on trying to use the softint. This change doesn't introduce any new bugs because of the snag -- if_percpuq_attach was already broken. However, the snag can be better addressed without spawning error branches, either by using a single softint or making softints less scarce. (Separate commit will change the signatures of if_attach and if_initialize to return void, scheduled to ride whatever is the next convenient kernel bump.) Patch and testing on amd64 and evbmips64-eb by maya@@; commit message soliloquy, and compile-testing on evbppc/i386/earmv7hf, by me. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.176 2021/05/19 03:44:46 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.176 2021/05/19 03:44:46 yamaguchi Exp $"); d2149 3 d2169 8 @ 1.176 log @Added a kernel option to change the number of processing packets at one pppoeintr() @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.175 2021/05/19 03:35:27 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.175 2021/05/19 03:35:27 yamaguchi Exp $"); d392 1 a392 3 rv = if_initialize(ifp); if (rv != 0) goto destroy_timeout; a408 3 destroy_timeout: callout_destroy(&sc->sc_timeout); workqueue_destroy(sc->sc_timeout_wq); @ 1.175 log @Added a limitation of the number of processing packets because a enqueuing process can not add packets over IFQ_MAXLEN and removed reschedule at pppoeintr() because it also scheduled at enqueuing process. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.174 2021/05/18 01:46:29 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.174 2021/05/18 01:46:29 yamaguchi Exp $"); d79 4 d605 1 a605 1 for (i = 0; i < IFQ_MAXLEN; i++) { d614 1 a614 1 for (i = 0; i < IFQ_MAXLEN; i++) { d623 5 @ 1.174 log @Added missing PPPOE_UNLOCK() on dropping PADS and PADT @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.173 2021/05/13 03:48:55 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.173 2021/05/13 03:48:55 yamaguchi Exp $"); d597 1 a597 1 int disc_done, data_done; d601 8 a608 12 do { disc_done = 0; data_done = 0; for (;;) { IFQ_LOCK(&ppoediscinq); IF_DEQUEUE(&ppoediscinq, m); IFQ_UNLOCK(&ppoediscinq); if (m == NULL) break; disc_done = 1; pppoe_disc_input(m); } d610 8 a617 13 for (;;) { IFQ_LOCK(&ppoeinq); IF_DEQUEUE(&ppoeinq, m); IFQ_UNLOCK(&ppoeinq); if (m == NULL) break; data_done = 1; pppoe_data_input(m); } } while (disc_done || data_done); if (!IF_IS_EMPTY(&ppoediscinq) || !IF_IS_EMPTY(&ppoeinq)) softint_schedule(pppoe_softintr); @ 1.173 log @Drop PADS and PADT from unknown host for safety @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.172 2021/05/13 03:28:36 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.172 2021/05/13 03:28:36 yamaguchi Exp $"); d1012 1 d1040 1 @ 1.172 log @Change reconnect delay after PADT received (15 sec -> 5 sec) 5 sec is the same as minimum PADI resending interval @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.171 2021/05/13 01:01:10 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.171 2021/05/13 01:01:10 yamaguchi Exp $"); d1010 5 d1037 5 @ 1.171 log @Accept a frame like a PADT just containing PPPoE header @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.170 2021/04/22 10:26:24 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.170 2021/04/22 10:26:24 yamaguchi Exp $"); d132 1 d1033 5 a1037 2 if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) callout_schedule(&sc->sc_timeout, PPPOE_RECON_FAST); @ 1.170 log @Added missing free of sc_hunique to prevent memory leak when using PPPoE server @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.169 2021/04/16 02:23:25 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.169 2021/04/16 02:23:25 yamaguchi Exp $"); d662 1 a662 1 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { @ 1.170.2.1 log @Sync w/ HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.177 2021/06/16 00:21:19 riastradh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.177 2021/06/16 00:21:19 riastradh Exp $"); a78 4 #ifndef PPPOE_DEQUEUE_MAXLEN #define PPPOE_DEQUEUE_MAXLEN IFQ_MAXLEN #endif a131 1 #define PPPOE_RECON_PADTRCVD (hz*5) /* reconnect delay after PADT received */ d387 3 a389 1 if_initialize(ifp); d406 3 d596 1 a596 1 int i; d600 12 a611 8 for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoediscinq); IF_DEQUEUE(&ppoediscinq, m); IFQ_UNLOCK(&ppoediscinq); if (m == NULL) break; pppoe_disc_input(m); } d613 10 a622 8 for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoeinq); IF_DEQUEUE(&ppoeinq, m); IFQ_UNLOCK(&ppoeinq); if (m == NULL) break; pppoe_data_input(m); } a623 1 #if PPPOE_DEQUEUE_MAXLEN < IFQ_MAXLEN a625 1 #endif d662 1 a662 1 if (m->m_pkthdr.len - off < PPPOE_HEADERLEN) { a1008 6 if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } a1030 6 if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } d1032 2 a1033 5 if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) { pppoe_printf(sc, "wait for reconnect\n"); callout_schedule(&sc->sc_timeout, PPPOE_RECON_PADTRCVD); } @ 1.170.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.176 2021/05/19 03:44:46 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.176 2021/05/19 03:44:46 yamaguchi Exp $"); a78 4 #ifndef PPPOE_DEQUEUE_MAXLEN #define PPPOE_DEQUEUE_MAXLEN IFQ_MAXLEN #endif a131 1 #define PPPOE_RECON_PADTRCVD (hz*5) /* reconnect delay after PADT received */ d596 1 a596 1 int i; d600 12 a611 8 for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoediscinq); IF_DEQUEUE(&ppoediscinq, m); IFQ_UNLOCK(&ppoediscinq); if (m == NULL) break; pppoe_disc_input(m); } d613 10 a622 8 for (i = 0; i < PPPOE_DEQUEUE_MAXLEN; i++) { IFQ_LOCK(&ppoeinq); IF_DEQUEUE(&ppoeinq, m); IFQ_UNLOCK(&ppoeinq); if (m == NULL) break; pppoe_data_input(m); } a623 1 #if PPPOE_DEQUEUE_MAXLEN < IFQ_MAXLEN a625 1 #endif d662 1 a662 1 if (m->m_pkthdr.len - off < PPPOE_HEADERLEN) { a1008 6 if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } a1030 6 if (memcmp(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest) != 0) { PPPOE_UNLOCK(sc); goto done; } d1032 2 a1033 5 if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) { pppoe_printf(sc, "wait for reconnect\n"); callout_schedule(&sc->sc_timeout, PPPOE_RECON_PADTRCVD); } @ 1.169 log @Stop and destroy timeout after sppp_detach and if_detach for safety The functions may use resources of pppoe(4) while detaching, so the release should move after it. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.168 2021/04/16 02:12:00 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.168 2021/04/16 02:12:00 yamaguchi Exp $"); d451 7 @ 1.168 log @Remove unnecessaly lock holdings to avoid dead lock The locks were held while callout_halt() and workqueue_wait() without reason. And the locks also were held at callout and workqueue handler so that the handler kicked by those function couldn't acquire the lock. The reasons why those are unneccesary are: - Items of callout_t are protected by callout_lock - Items of struct workqueue and struct work are protected by q_mutex in struct workqueue - Items of struct sppp_work protected by atomic_cas(3) - struct pppoe_softc does not free before workqueue_wait() and callout_halt() even if the locks are not held @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.167 2021/04/16 01:59:50 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.167 2021/04/16 01:59:50 yamaguchi Exp $"); d439 4 d444 1 d446 2 d449 1 a450 3 bpf_detach(ifp); sppp_detach(&sc->sc_sppp.pp_if); if_detach(ifp); a458 2 callout_destroy(&sc->sc_timeout); workqueue_destroy(sc->sc_timeout_wq); @ 1.167 log @Stop ppp layer at first of destroying pppoe interface @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.166 2021/04/16 01:44:35 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.166 2021/04/16 01:44:35 yamaguchi Exp $"); a438 1 PPPOE_LOCK(sc, RW_WRITER); a456 1 PPPOE_UNLOCK(sc); @ 1.166 log @Sort initialization sequence in pppoe_clone_create() out for refactoring It has no functionality impact @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.165 2021/04/16 01:32:04 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.165 2021/04/16 01:32:04 yamaguchi Exp $"); d191 1 d421 3 a423 1 rw_enter(&pppoe_softc_list_lock, RW_WRITER); d425 5 a429 4 PPPOE_LOCK(sc, RW_WRITER); callout_setfunc(&sc->sc_timeout, pppoe_timeout_co_halt, sc); workqueue_wait(sc->sc_timeout_wq, &sc->sc_timeout_wk); callout_halt(&sc->sc_timeout, NULL); d431 1 d439 5 d1298 4 d1360 4 d1527 2 a1528 1 pppoe_connect(sc); @ 1.165 log @Use kmem_zalloc to allocate pppoe_softc @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.164 2021/04/16 01:28:51 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.164 2021/04/16 01:28:51 yamaguchi Exp $"); d342 1 d346 1 d350 2 d353 12 a364 4 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); sc->sc_sppp.pp_if.if_softc = sc; sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU; sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; d366 1 a366 1 sc->sc_sppp.pp_if.if_extflags = IFEF_MPSAFE; d368 5 a372 3 sc->sc_sppp.pp_if.if_type = IFT_PPP; sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; d375 1 a375 6 sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d378 1 a378 1 sc->sc_sppp.pp_if.if_xname, pppoe_timeout_wk, sc, d386 1 a386 9 sc->sc_sppp.pp_if.if_start = pppoe_start; #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_transmit = pppoe_transmit; #endif sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ rv = if_initialize(&sc->sc_sppp.pp_if); d390 1 a390 2 sc->sc_sppp.pp_if.if_percpuq = if_percpuq_create(&sc->sc_sppp.pp_if); sppp_attach(&sc->sc_sppp.pp_if); a391 1 bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d396 1 d399 3 a401 1 if_register(&sc->sc_sppp.pp_if); a402 3 rw_enter(&pppoe_softc_list_lock, RW_WRITER); LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); rw_exit(&pppoe_softc_list_lock); @ 1.164 log @Move initialization of sc_lock in pppoe_softc to first The lock may be held in callbacks for ppp layer or other components so that it should be initialized early. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.163 2021/04/16 01:24:35 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.163 2021/04/16 01:24:35 yamaguchi Exp $"); d344 1 a344 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d411 1 a411 1 free(sc, M_DEVBUF); d452 1 a452 1 free(sc, M_DEVBUF); @ 1.163 log @commonize error handling in pppoe_clone_create() @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.162 2021/04/13 05:04:54 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.162 2021/04/13 05:04:54 yamaguchi Exp $"); d346 1 d372 1 a372 1 goto free_sc; a400 2 rw_init(&sc->sc_lock); d409 2 a410 1 free_sc: d412 1 @ 1.162 log @Reschedule softint to process packets enqueued to ppoediscinq while doing pppoe_data_input And added a empty check for ppoeinq, for safety @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.161 2021/04/13 05:00:06 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.161 2021/04/13 05:00:06 yamaguchi Exp $"); d370 2 a371 4 if (rv != 0) { free(sc, M_DEVBUF); return rv; } d385 3 a387 7 if (rv != 0) { workqueue_destroy(sc->sc_timeout_wq); callout_halt(&sc->sc_timeout, NULL); callout_destroy(&sc->sc_timeout); free(sc, M_DEVBUF); return rv; } d406 7 @ 1.161 log @Added missing counter clear when a pppoe state changes to PADI_SENT @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.160 2021/04/13 04:57:15 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.160 2021/04/13 04:57:15 yamaguchi Exp $"); d605 3 @ 1.160 log @Added a NULL check for parent interface of pppoe @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.159 2021/04/13 04:53:22 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.159 2021/04/13 04:53:22 yamaguchi Exp $"); d1550 1 d1600 1 @ 1.159 log @Hold the lock for pppoe while referencing sc_id that is an item of struct pppoe_softc @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.158 2020/11/25 10:42:35 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.158 2020/11/25 10:42:35 yamaguchi Exp $"); d536 1 a536 1 if (sc->sc_id == t) { @ 1.158 log @Fix to reconnect after PADT received @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.157 2020/11/25 10:39:47 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.157 2020/11/25 10:39:47 yamaguchi Exp $"); d535 1 a536 1 PPPOE_LOCK(sc, lock); d539 1 @ 1.158.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.169 2021/04/16 02:23:25 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.169 2021/04/16 02:23:25 yamaguchi Exp $"); a190 1 bool sc_detaching; a341 1 struct ifnet *ifp; d344 1 a344 2 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); ifp = &sc->sc_sppp.pp_if; a345 1 rw_init(&sc->sc_lock); a346 2 /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d348 4 a351 12 if_initname(ifp, "pppoe", unit); ifp->if_softc = sc; ifp->if_mtu = PPPOE_MAXMTU; ifp->if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; #ifdef PPPOE_MPSAFE ifp->if_extflags = IFEF_MPSAFE; #endif ifp->if_type = IFT_PPP; ifp->if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; ifp->if_dlt = DLT_PPP_ETHER; ifp->if_ioctl = pppoe_ioctl; ifp->if_start = pppoe_start; d353 1 a353 1 ifp->if_transmit = pppoe_transmit; d355 3 a357 5 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; d360 6 a365 1 sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ d368 1 a368 1 ifp->if_xname, pppoe_timeout_wk, sc, d370 4 a373 2 if (rv != 0) goto destroy_sclock; d378 7 a384 3 rv = if_initialize(ifp); if (rv != 0) goto destroy_timeout; d386 10 a395 1 ifp->if_percpuq = if_percpuq_create(ifp); d397 1 a401 1 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); d404 1 a404 3 sppp_attach(ifp); bpf_attach(ifp, DLT_PPP_ETHER, 0); if_register(ifp); d406 5 a411 9 destroy_timeout: callout_destroy(&sc->sc_timeout); workqueue_destroy(sc->sc_timeout_wq); destroy_sclock: rw_destroy(&sc->sc_lock); kmem_free(sc, sizeof(*sc)); return rv; d419 2 d422 3 a424 8 /* stop ioctls */ sc->sc_detaching = true; if (ifp->if_flags & IFF_RUNNING) { pppoe_clear_softc(sc, "destroy interface"); sc->sc_eth_if = NULL; } PPPOE_UNLOCK(sc); a425 1 rw_enter(&pppoe_softc_list_lock, RW_WRITER); a435 9 callout_setfunc(&sc->sc_timeout, pppoe_timeout_co_halt, sc); workqueue_wait(sc->sc_timeout_wq, &sc->sc_timeout_wk); workqueue_destroy(sc->sc_timeout_wq); callout_halt(&sc->sc_timeout, NULL); callout_destroy(&sc->sc_timeout); d444 2 d447 1 d450 1 a450 1 kmem_free(sc, sizeof(*sc)); d535 2 a536 2 PPPOE_LOCK(sc, lock); if (sc->sc_id == t && sc->sc_eth_if != NULL) { a538 1 PPPOE_UNLOCK(sc); a603 3 if (!IF_IS_EMPTY(&ppoediscinq) || !IF_IS_EMPTY(&ppoeinq)) softint_schedule(pppoe_softintr); a1282 4 if (sc->sc_detaching) { PPPOE_UNLOCK(sc); return ENXIO; } a1340 4 if (sc->sc_detaching) { PPPOE_UNLOCK(sc); return ENXIO; } d1504 1 a1504 2 if (!sc->sc_detaching) pppoe_connect(sc); a1548 1 sc->sc_padi_retried = 0; a1597 1 sc->sc_padi_retried = 0; @ 1.157 log @add a logging function used at debugging pppoe(4) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.156 2020/11/25 10:38:10 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.156 2020/11/25 10:38:10 yamaguchi Exp $"); d1009 2 @ 1.156 log @fix to remove trailing garbage @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.155 2020/11/25 10:37:04 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.155 2020/11/25 10:37:04 yamaguchi Exp $"); d158 6 d221 1 d455 29 d543 2 a544 3 #ifdef PPPOE_DEBUG printf("pppoe: alien host unique tag, no session found\n"); #endif d550 3 a552 2 printf("%s: host unique tag found, but it belongs to a connection in state %d\n", sc->sc_sppp.pp_if.if_xname, sc->sc_state); d557 1 a557 2 printf("%s: wrong interface, not accepting host unique\n", sc->sc_sppp.pp_if.if_xname); a614 1 char devname[IF_NAMESIZE]; d706 1 a706 1 printf("pppoe: connected to %s\n", error); d780 1 a780 1 printf("pppoe: %s: %s\n", err_msg, error); d783 1 a783 1 printf("pppoe: %s\n", err_msg); d864 1 a864 1 printf("pppoe: received PADR" d872 1 a872 2 printf("%s: received unexpected PADR\n", sc->sc_sppp.pp_if.if_xname); d916 1 a916 1 printf("pppoe: received PADO" d924 1 a924 2 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); d935 2 a936 3 printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); d949 2 a950 3 printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); d962 2 a963 4 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); d988 1 a988 3 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d1024 5 a1028 9 if (sc != NULL) { strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_UNLOCK(sc); } else strlcpy(devname, "pppoe", sizeof(devname)); printf("%s: unknown code (0x%04x) session = 0x%04x\n", devname, ph->code, session); d1133 1 a1133 1 printf("pppoe: input for unknown session %#x, " d1206 2 a1207 4 #ifdef PPPOE_DEBUG printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, a1208 1 #endif d1496 1 a1496 3 #ifdef PPPOE_DEBUG printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname); #endif d1533 2 a1534 4 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to transmit PADI, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); d1549 2 a1550 4 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI" ", error=%d\n", sc->sc_sppp.pp_if.if_xname, err); d1560 1 a1560 4 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); d1598 2 a1599 3 if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI, error=%d\n", sc->sc_sppp.pp_if.if_xname, err); d1619 1 a1619 3 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); d1664 1 a1664 2 printf("%s: could not establish connection\n", sc->sc_sppp.pp_if.if_xname); d2011 2 a2012 2 printf("%s: ethernet interface detached, going down\n", sc->sc_sppp.pp_if.if_xname); d2029 2 a2030 3 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, %s\n", sc->sc_sppp.pp_if.if_xname, sc->sc_session, message); @ 1.155 log @stop callout even when the state is in PPPOE_STATE_INITIAL @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.154 2020/11/25 10:18:49 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.154 2020/11/25 10:18:49 yamaguchi Exp $"); d1147 2 @ 1.154 log @Close lcp when the lower layer down if the interface is passive or on-demand reivewed by knakahara@@n.o. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.153 2020/09/25 06:22:33 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.153 2020/09/25 06:22:33 yamaguchi Exp $"); a1319 1 && sc->sc_state >= PPPOE_STATE_PADI_SENT @ 1.153 log @Add a function to copy AC-Name and Service-Name @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.152 2020/09/25 06:12:33 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.152 2020/09/25 06:12:33 yamaguchi Exp $"); d1889 6 d1898 1 @ 1.153.2.1 log @Sync w/ HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.158 2020/11/25 10:42:35 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.158 2020/11/25 10:42:35 yamaguchi Exp $"); a157 6 #ifdef PPPOE_DEBUG #define DPRINTF(_sc, _fmt, _arg...) pppoe_printf((_sc), (_fmt), ##_arg) #else #define DPRINTF(_sc, _fmt, _arg...) __nothing #endif a214 1 static void pppoe_printf(struct pppoe_softc *, const char *, ...); a447 29 static void pppoe_printf(struct pppoe_softc *sc, const char *fmt, ...) { va_list ap; bool pppoe_debug; #ifdef PPPOE_DEBUG pppoe_debug = true; #else pppoe_debug = false; #endif if (sc == NULL) { if (!pppoe_debug) return; printf("pppoe: "); } else { if (!ISSET(sc->sc_sppp.pp_if.if_flags, IFF_DEBUG)) return; printf("%s: ", sc->sc_sppp.pp_if.if_xname); } va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } d507 3 a509 2 pppoe_printf(NULL, "alien host unique tag" ", no session found\n"); d515 2 a516 3 pppoe_printf(sc, "host unique tag found" ", but it belongs to a connection in state %d\n", sc->sc_state); d521 2 a522 1 pppoe_printf(sc, "wrong interface, not accepting host unique\n"); d580 1 d672 1 a672 1 pppoe_printf(NULL, "connected to %s\n", error); d746 1 a746 1 pppoe_printf(NULL, "%s: %s\n", err_msg, error); d749 1 a749 1 pppoe_printf(NULL, "%s\n", err_msg); d830 1 a830 1 pppoe_printf(NULL, "received PADR" d838 2 a839 1 pppoe_printf(sc, "received unexpected PADR\n"); d883 1 a883 1 pppoe_printf(NULL, "received PADO" d891 2 a892 1 pppoe_printf(sc, "received unexpected PADO\n"); d903 3 a905 2 pppoe_printf(sc, "FATAL: could not allocate memory " "for AC cookie\n"); d918 3 a920 2 pppoe_printf(sc, "FATAL: could not allocate memory " "for relay SID\n"); d932 4 a935 2 pppoe_printf(sc, "failed to send PADR, error=%d\n", err); d960 3 a962 1 pppoe_printf(sc, "session 0x%x connected\n", session); a982 2 if (sc->sc_sppp.pp_if.if_flags & IFF_RUNNING) callout_schedule(&sc->sc_timeout, PPPOE_RECON_FAST); d998 9 a1006 5 pppoe_printf(sc, "unknown code (0x%04x) session = 0x%04x\n", ph->code, session); if (sc == NULL) goto done; PPPOE_UNLOCK(sc); d1111 1 a1111 1 pppoe_printf(NULL, "input for unknown session %#x, " a1146 2 /* ignore trailing garbage */ m_adj(m, plen - m->m_pkthdr.len); d1182 4 a1185 2 DPRINTF(sc, "(%x) state=%d, session=0x%x output -> %s, len=%d\n", etype, sc->sc_state, sc->sc_session, d1187 1 d1320 1 d1476 3 a1478 1 pppoe_printf(sc, "timeout\n"); d1515 4 a1518 2 pppoe_printf(sc, "failed to transmit PADI, error=%d\n", err); d1533 4 a1536 2 pppoe_printf(sc, "failed to send PADI, error=%d\n", err); d1546 4 a1549 1 pppoe_printf(sc,"failed to send PADR, error=%d", err); d1587 3 a1589 2 if (err != 0) pppoe_printf(sc, "failed to send PADI, error=%d\n", err); d1609 3 a1611 1 pppoe_printf(sc, "disconnecting\n"); d1656 2 a1657 1 pppoe_printf(sc, "could not establish connection\n"); a1888 6 callout_stop(&sc->sc_timeout); sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); a1891 1 d1997 2 a1998 2 pppoe_printf(sc, "ethernet interface detached, going down\n"); d2015 3 a2017 2 pppoe_printf(sc, "session 0x%x terminated, %s\n", sc->sc_session, message); @ 1.152 log @Clear AC-Name and Service-Name if params are not specified @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.151 2020/09/18 09:53:50 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.151 2020/09/18 09:53:50 yamaguchi Exp $"); d1195 46 a1274 16 if (parms->ac_name != NULL) { size_t s; char *b = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK); if (b == NULL) return ENOMEM; error = copyinstr(parms->ac_name, b, parms->ac_name_len+1, &s); if (error != 0) { free(b, M_DEVBUF); return error; } if (s != parms->ac_name_len+1) { free(b, M_DEVBUF); return EINVAL; } d1276 9 a1284 37 PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); sc->sc_concentrator_name = b; PPPOE_UNLOCK(sc); } else { if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); sc->sc_concentrator_name = NULL; } if (parms->service_name != NULL) { size_t s; char *b = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK); if (b == NULL) return ENOMEM; error = copyinstr(parms->service_name, b, parms->service_name_len+1, &s); if (error != 0) { free(b, M_DEVBUF); return error; } if (s != parms->service_name_len+1) { free(b, M_DEVBUF); return EINVAL; } PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); sc->sc_service_name = b; PPPOE_UNLOCK(sc); } else { if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); sc->sc_service_name = NULL; } @ 1.151 log @Do pppoe_timeout() in thread context OKed by knakahara@@n.o fix port-amd64/55661 @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp $"); d1251 4 d1278 4 @ 1.150 log @Use callout_setfunc and callout_schedule @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.149 2020/02/10 22:38:10 mlelstv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.149 2020/02/10 22:38:10 mlelstv Exp $"); d44 1 d61 1 d178 4 a181 1 callout_t sc_timeout; /* timeout while not in session state */ d217 4 a220 1 static void pppoe_timeout(void *); d360 8 d369 1 a369 1 callout_setfunc(&sc->sc_timeout, pppoe_timeout, sc); d381 1 d415 2 d438 1 d1434 28 a1461 1 pppoe_timeout(void *arg) a1463 1 struct pppoe_softc *sc = (struct pppoe_softc*)arg; @ 1.149 log @safely extract character sequences from packet for printing. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.148 2020/01/29 04:28:27 thorpej Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.148 2020/01/29 04:28:27 thorpej Exp $"); d353 1 d917 2 a918 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d1464 1 a1464 2 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d1482 2 a1483 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d1495 2 a1496 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d1534 1 a1534 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d1820 1 a1820 1 callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); d1843 1 a1843 1 callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc); @ 1.148 log @Adopt . @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $"); d561 1 d635 2 a636 1 error = malloc(len + 1, M_TEMP, M_NOWAIT); d648 3 a650 1 strlcpy(error, mtod(n, char*) + noff, len + 1); d711 2 a712 1 error = malloc(len + 1, M_TEMP, d719 3 a721 2 strlcpy(error, mtod(n, char *) + noff, len + 1); @ 1.147 log @ s/pakcet/packet/ in comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.146 2018/10/27 06:46:43 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.146 2018/10/27 06:46:43 maxv Exp $"); d1128 1 a1128 1 sc->sc_sppp.pp_if.if_ipackets++; d1164 1 a1164 1 sc->sc_sppp.pp_if.if_opackets++; d1868 1 a1868 1 ifp->if_oerrors++; d1904 1 a1904 1 ifp->if_oerrors++; @ 1.147.6.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.149 2020/02/10 22:38:10 mlelstv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.149 2020/02/10 22:38:10 mlelstv Exp $"); a560 1 size_t dlen; d634 1 a634 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT); d646 1 a646 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d707 1 a707 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, d714 2 a715 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d1128 1 a1128 1 if_statinc(&sc->sc_sppp.pp_if, if_ipackets); d1164 1 a1164 1 if_statinc(&sc->sc_sppp.pp_if, if_opackets); d1868 1 a1868 1 if_statinc(ifp, if_oerrors); d1904 1 a1904 1 if_statinc(ifp, if_oerrors); @ 1.147.4.1 log @Pull up following revision(s) (requested by mlelstv in ticket #708): sys/net/if_pppoe.c: revision 1.149 safely extract character sequences from packet for printing. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $"); a560 1 size_t dlen; d634 1 a634 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT); d646 1 a646 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d707 1 a707 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, d714 2 a715 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); @ 1.147.4.2 log @Pull up the following revisions(s) (requested by martin in ticket #1442): sys/net/if_pppoe.c: revision 1.179 pppoe(4): fix CVE-2022-29867 - discovery phase local network mbuf corruption. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.147.4.1 2020/02/13 19:40:05 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.147.4.1 2020/02/13 19:40:05 martin Exp $"); a889 4 } else if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; sc->sc_ac_cookie_len = 0; a904 4 } else if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; sc->sc_relay_sid_len = 0; a1326 3 if (len + sizeof(struct ether_header) > MCLBYTES) return NULL; @ 1.146 log @Remove printfs that are too easily reachable, switch to M_REGION_GET, and simplify the initialization. No real functional change. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.145 2018/10/27 05:56:10 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.145 2018/10/27 05:56:10 maxv Exp $"); d1079 1 a1079 1 * session stage pakcets for other hosts when parent @ 1.145 log @style @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.144 2018/09/30 10:00:24 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.144 2018/09/30 10:00:24 maxv Exp $"); a574 5 /* as long as we don't know which instance */ strlcpy(devname, "pppoe", sizeof(devname)); err_msg = NULL; errortag = 0; a582 7 ac_cookie = NULL; ac_cookie_len = 0; relay_sid = NULL; relay_sid_len = 0; hunique = NULL; hunique_len = 0; session = 0; a583 1 printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); d587 2 a588 4 n = m_pulldown(m, off, sizeof(*ph), &noff); if (!n) { printf("pppoe: could not get PPPoE header\n"); m = NULL; a590 1 ph = (struct pppoehdr *)(mtod(n, char *) + noff); a591 2 printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); d594 8 a606 2 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", m->m_pkthdr.len - off, plen); d614 2 d617 2 a618 4 n = m_pulldown(m, off, sizeof(*pt), &noff); if (!n) { printf("%s: parse error\n", devname); m = NULL; d621 1 a621 1 pt = (struct pppoetag *)(mtod(n, char *) + noff); a624 2 printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); d719 1 a719 2 printf("%s: %s: %s\n", devname, err_msg, error); d722 1 a722 1 printf("%s: %s\n", devname, err_msg); a789 2 /* be quiet if there is not a single pppoe instance */ printf("pppoe: received PADR but not includes ac_cookie\n"); a1049 2 printf("pppoe (data): dropping too short packet: %d bytes\n", m->m_pkthdr.len); a1055 1 printf("pppoe: could not get PPPoE header\n"); a1061 2 printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); d1064 1 a1064 1 if (ph->code != 0) d1066 1 @ 1.144 log @remove hardcoded bullshit, probably fixes PR/53644 @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.143 2018/08/24 17:06:29 maxv Exp $ */ d3 1 a3 1 /*- d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.143 2018/08/24 17:06:29 maxv Exp $"); d531 2 a532 1 if (m == NULL) break; d541 2 a542 1 if (m == NULL) break; d582 1 a582 1 if (!m) d622 1 d744 1 a776 1 /* printf("pppoe: free passive interface is not found\n");*/ d798 1 d813 1 a813 3 ac_cookie_len, rcvif, RW_WRITER); d856 1 d864 1 a864 3 hunique_len, rcvif, RW_WRITER); d933 1 d941 1 a941 3 hunique_len, rcvif, RW_WRITER); d959 1 d976 1 d984 1 a984 3 hunique_len, rcvif, RW_READER); d1074 1 a1074 1 if (!m) { d1103 2 a1104 2 if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, d1143 1 a1143 1 * Fix incoming interface pointer (not the raw ethernet interface d1206 1 a1206 1 struct ifnet *eth_if; @ 1.143 log @Use a random hunique, instead of sending the pointer of the interface. Tested via ATF. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.142 2018/08/13 09:29:13 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.142 2018/08/13 09:29:13 maxv Exp $"); d1746 5 a1750 6 /* calc length */ len = 0; /* include ac_cookie */ len += 2 + 2 + sizeof(sc); /* include hunique */ len += 2 + 2 + sc->sc_hunique_len; d1755 1 d1782 4 a1785 5 /* calc length */ len = 0; /* include hunique */ len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ d1789 3 d1796 1 @ 1.142 log @Clarify two functions. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.141 2018/06/26 06:48:02 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.141 2018/06/26 06:48:02 msaitoh Exp $"); d59 1 d161 1 d298 25 d331 2 d460 4 a463 1 struct pppoe_softc *sc, *t; d471 1 a471 1 if (len != sizeof sc) { d478 1 a478 1 if (sc == t) { d1380 1 a1380 1 len += sizeof(struct pppoetag) + sizeof(sc); d1408 3 a1410 3 PPPOE_ADD_16(p, sizeof(sc)); memcpy(p, &sc, sizeof(sc)); p += sizeof(sc); d1656 1 a1656 1 len += sizeof(struct pppoetag) + sizeof(sc); d1690 3 a1692 3 PPPOE_ADD_16(p, sizeof(sc)); memcpy(p, &sc, sizeof(sc)); p += sizeof(sc); d1758 3 a1760 3 PPPOE_ADD_16(p, sizeof(sc)); memcpy(p, &sc, sizeof(sc)); p += sizeof(sc); @ 1.141 log @ Implement the BPF direction filter (BIOC[GS]DIRECTION). It provides backward compatibility with BIOC[GS]SEESENT ioctl. The userland interface is the same as FreeBSD. This change also fixes a bug that the direction is misunderstand on some environment by passing the direction to bpf_mtap*() instead of checking m->m_pkthdr.rcvif. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.140 2018/06/18 09:53:45 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.140 2018/06/18 09:53:45 yamaguchi Exp $"); d1332 1 a1332 1 int len, l1 = 0, l2 = 0; /* XXX: gcc */ d1335 1 a1335 1 if (sc->sc_state >PPPOE_STATE_PADI_SENT) d1338 2 a1339 2 /* calculate length of frame (excluding ethernet header + pppoe header) */ len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ d1346 1 a1346 1 len += 2 + 2 + l2; d1348 1 d1350 1 a1350 1 len += 2 + 2 + 2; d1353 3 a1355 3 /* allocate a buffer */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) d1358 1 a1358 1 /* fill in pkt */ d1377 1 a1377 1 memcpy(p, &sc, sizeof sc); d1392 1 a1392 1 /* send pkt */ a1601 1 /* Send a PADR packet */ d1607 1 a1607 1 size_t len, l1 = 0; /* XXX: gcc */ d1612 3 a1614 2 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ d1618 7 a1624 4 if (sc->sc_ac_cookie_len > 0) len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ d1626 1 a1626 1 len += 2 + 2 + 2; d1628 2 d1631 1 a1631 1 if (!m0) d1633 2 d1659 1 a1659 1 memcpy(p, &sc, sizeof sc); d1674 1 @ 1.141.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $ */ d3 1 a3 1 /* d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.147 2019/03/18 11:38:03 msaitoh Exp $"); a58 1 #include a159 1 uint64_t sc_id; /* id of this softc, our hunique */ a295 25 static void pppoe_softc_genid(uint64_t *id) { struct pppoe_softc *sc; uint64_t rndid; rw_enter(&pppoe_softc_list_lock, RW_READER); while (1) { rndid = cprng_strong64(); sc = NULL; LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_id == rndid) break; } if (sc == NULL) { break; } } rw_exit(&pppoe_softc_list_lock); *id = rndid; } a303 2 pppoe_softc_genid(&sc->sc_id); d431 1 a431 4 struct pppoe_softc *sc; uint64_t t; CTASSERT(sizeof(t) == sizeof(sc->sc_id)); d439 1 a439 1 if (len != sizeof(sc->sc_id)) { d446 1 a446 1 if (sc->sc_id == t) { d499 1 a499 2 if (m == NULL) break; d508 1 a508 2 if (m == NULL) break; d541 5 d548 1 a548 1 if (m == NULL) d554 7 d562 1 d566 4 a569 2 M_REGION_GET(ph, struct pppoehdr *, m, off, sizeof(*ph)); if (ph == NULL) { d572 1 d574 2 a577 8 ac_cookie = NULL; ac_cookie_len = 0; relay_sid = NULL; relay_sid_len = 0; hunique = NULL; hunique_len = 0; d583 2 a587 1 a590 2 err_msg = NULL; errortag = 0; d592 4 a595 2 M_REGION_GET(pt, struct pppoetag *, m, off, sizeof(*pt)); if (pt == NULL) { d598 1 a598 1 d602 2 d698 2 a699 1 printf("pppoe: %s: %s\n", err_msg, error); d702 1 a702 1 printf("pppoe: %s\n", err_msg); a708 1 d741 1 a762 1 d769 2 d777 3 a779 1 ac_cookie_len, rcvif, RW_WRITER); a821 1 d829 3 a831 1 hunique_len, rcvif, RW_WRITER); a899 1 d907 3 a909 1 hunique_len, rcvif, RW_WRITER); a926 1 a942 1 d950 3 a952 1 hunique_len, rcvif, RW_READER); d1035 2 d1042 2 a1043 1 if (m == NULL) { d1050 2 d1054 1 a1054 1 if (ph->code != 0) { a1055 1 } d1068 1 a1068 1 * session stage packets for other hosts when parent d1071 2 a1072 2 if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, d1111 1 a1111 1 * Fix incoming interface pointer (not the raw ethernet interface d1174 1 a1174 1 struct ifnet *eth_if; d1332 1 a1332 1 int len, l1 = 0, l2 = 0; d1335 1 a1335 1 if (sc->sc_state > PPPOE_STATE_PADI_SENT) d1338 2 a1339 2 /* Compute packet length. */ len = sizeof(struct pppoetag); d1346 1 a1346 1 len += sizeof(struct pppoetag) + l2; a1347 1 len += sizeof(struct pppoetag) + sizeof(sc->sc_id); d1349 1 a1349 1 len += sizeof(struct pppoetag) + 2; d1352 3 a1354 3 /* Allocate packet. */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (m0 == NULL) d1357 1 a1357 1 /* Fill in packet. */ d1375 3 a1377 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); d1391 1 a1391 1 /* Send packet. */ d1601 1 d1607 1 a1607 1 size_t len, l1 = 0; d1612 2 a1613 3 /* Compute packet length. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { d1617 4 a1620 7 if (sc->sc_ac_cookie_len > 0) { len += sizeof(struct pppoetag) + sc->sc_ac_cookie_len; } if (sc->sc_relay_sid_len > 0) { len += sizeof(struct pppoetag) + sc->sc_relay_sid_len; } len += sizeof(struct pppoetag) + sizeof(sc->sc_id); d1622 1 a1622 1 len += sizeof(struct pppoetag) + 2; a1623 2 /* Allocate packet. */ d1625 1 a1625 1 if (m0 == NULL) a1626 2 /* Fill in packet. */ d1650 3 a1652 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); a1665 1 /* Send packet. */ d1705 6 a1710 5 /* Include AC cookie. */ len = sizeof(struct pppoetag) + sizeof(sc->sc_id); /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; a1714 1 d1717 3 a1719 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); d1741 5 a1745 4 /* Include service name. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { a1748 3 /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; a1752 1 @ 1.141.2.2 log @Merge changes from current as of 20200406 @ text @d1 1 a1 1 /* $NetBSD$ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD$"); a560 1 size_t dlen; d634 1 a634 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT); d646 1 a646 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d707 1 a707 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, d714 2 a715 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d1128 1 a1128 1 if_statinc(&sc->sc_sppp.pp_if, if_ipackets); d1164 1 a1164 1 if_statinc(&sc->sc_sppp.pp_if, if_opackets); d1868 1 a1868 1 if_statinc(ifp, if_oerrors); d1904 1 a1904 1 if_statinc(ifp, if_oerrors); @ 1.140 log @Fix to aquire pppoe_softc_list_lock before read and write the list ok by knakahara@@n.o @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.139 2018/06/18 09:49:05 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.139 2018/06/18 09:49:05 yamaguchi Exp $"); d1087 1 a1087 1 bpf_mtap(&sc->sc_sppp.pp_if, m); d1851 1 a1851 1 bpf_mtap(&sc->sc_sppp.pp_if, m); d1887 1 a1887 1 bpf_mtap(&sc->sc_sppp.pp_if, m); @ 1.139 log @Fix not to use PPPOE_UNLOCK before acccess to pppoe_softc to avoid a race condition According to the locking order of pppoe(4), the access to pppoe_softc has to follow 5 steps as below. 1. aquire pppoe_softc_list_lock 2. aquire pppoe_softc lock 3. release pppoe_softc_list_lock 4. access to pppoe_softc 5. release pppoe_softc lock However, pppoe_dispatch_disc_pkt() releases the lock of pppoe_softc temporarily, and then re-aquires it before step 4 of the adove. So, it is possible for other contexts to destroy a pppoe_softc in the interim. To fix this condition, avoid PPPOE_UNLOCK with the problem. ok by knakahara@@n.o @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.138 2018/05/25 04:40:27 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.138 2018/05/25 04:40:27 ozaki-r Exp $"); d280 3 a282 1 if (!LIST_EMPTY(&pppoe_softc_list)) d284 1 d344 1 d348 2 d433 3 a435 1 if (LIST_EMPTY(&pppoe_softc_list)) d437 1 d439 2 a440 1 if (len != sizeof sc) d442 1 a444 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d716 3 a718 1 if (LIST_EMPTY(&pppoe_softc_list)) d720 2 a721 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d784 6 a789 2 if (!LIST_EMPTY(&pppoe_softc_list)) printf("pppoe: received PADR but could not find request for it\n"); d838 6 a843 2 if (!LIST_EMPTY(&pppoe_softc_list)) printf("pppoe: received PADO but could not find request for it\n"); d983 1 d985 1 d988 1 d1020 1 d1022 1 d1025 1 @ 1.138 log @Ensure to call if_register after interface initializations finish @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.137 2018/05/03 16:52:42 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.137 2018/05/03 16:52:42 maxv Exp $"); a520 1 #ifdef PPPOE_SERVER a522 1 #endif d528 2 a547 1 #ifdef PPPOE_SERVER a549 1 #endif d602 1 a602 2 error = NULL; if (sc != NULL && len > 0) { d616 1 a616 1 printf("%s: connected to %s\n", devname, error); d620 9 a628 3 case PPPOE_TAG_HUNIQUE: { struct ifnet *rcvif; struct psref psref; d630 2 a631 23 if (sc != NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; err_msg = "TAG HUNIQUE ERROR"; break; } #ifdef PPPOE_SERVER hunique = mtod(n, uint8_t *) + noff; hunique_len = len; #endif rcvif = m_get_rcvif_psref(m, &psref); if (rcvif != NULL) { sc = pppoe_find_softc_by_hunique( mtod(n, char *) + noff, len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); if (sc != NULL) { strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_UNLOCK(sc); a633 1 } a751 3 { struct ifnet *rcvif; struct psref psref; a800 1 } d806 13 a825 2 PPPOE_LOCK(sc, RW_WRITER); d880 13 a895 2 PPPOE_LOCK(sc, RW_WRITER); d906 7 a912 3 case PPPOE_CODE_PADT: { struct ifnet *rcvif; struct psref psref; a913 5 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); } d915 1 a921 1 } d923 13 a936 1 PPPOE_LOCK(sc, RW_READER); @ 1.137 log @Drop early if there's no PPPoE interface. Otherwise it is easy for someone to flood dmesg over the local subnet. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $"); a338 1 if_register(&sc->sc_sppp.pp_if); d344 1 @ 1.136 log @Fix sending PADT to unexpected hosts when net.pppoe.term_unknown is enabled. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.135 2018/04/18 07:36:26 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.135 2018/04/18 07:36:26 knakahara Exp $"); d947 1 d949 3 a951 1 /* avoid error messages if there is not a single pppoe instance */ a952 1 KASSERT(m->m_flags & M_PKTHDR); d954 1 a954 1 } else d956 1 d983 7 @ 1.135 log @net.pppoe.term_unknown can be written safely now. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.134 2018/02/12 15:38:14 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.134 2018/02/12 15:38:14 maxv Exp $"); d66 1 d240 1 d956 10 d975 1 d980 1 a980 1 if (term_unknown) d983 3 d1017 14 a1030 3 printf("pppoe: input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); @ 1.134 log @Use m_freem instead of m_free. Otherwise we're leaking the next mbufs in the chain. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.133 2017/12/07 10:22:04 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.133 2017/12/07 10:22:04 ozaki-r Exp $"); d963 1 d967 1 a967 1 if (pppoe_term_unknown) d1000 1 a1000 1 if (pppoe_term_unknown) { d1945 1 a1945 1 CTLFLAG_PERMANENT | CTLFLAG_READONLY, @ 1.134.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $"); a65 1 #include a238 1 static int pppoe_term_unknown_pps = 1; a953 10 static bool pppoe_is_my_frame(uint8_t *dhost, struct ifnet *rcvif) { if (memcmp(CLLADDR(rcvif->if_sadl), dhost, ETHER_ADDR_LEN) == 0) return true; return false; } a962 2 uint8_t dhost[ETHER_ADDR_LEN]; bool term_unknown = pppoe_term_unknown; d966 1 a966 1 if (term_unknown) { a968 3 memcpy(dhost, mtod(m, struct ether_header*)->ether_dhost, ETHER_ADDR_LEN); } d999 4 a1002 15 if (term_unknown) { static struct timeval lasttime = {0, 0}; static int curpps = 0; /* * avoid to send wrong PADT which is response from * session stage pakcets for other hosts when parent * ethernet is promiscuous mode. */ if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, pppoe_term_unknown_pps)) { printf("pppoe: input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); } d1944 1 a1944 1 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, @ 1.134.2.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.137 2018/05/03 16:52:42 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.137 2018/05/03 16:52:42 maxv Exp $"); a946 1 KASSERT(m->m_flags & M_PKTHDR); d948 1 a948 3 /* * Avoid error messages if there is not a single PPPoE instance. */ d950 1 d952 1 a952 1 } else { a953 1 } a979 7 /* * Avoid error messages if there is not a single PPPoE instance. */ if (LIST_EMPTY(&pppoe_softc_list)) { goto drop; } @ 1.134.2.3 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.140 2018/06/18 09:53:45 yamaguchi Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.140 2018/06/18 09:53:45 yamaguchi Exp $"); d280 1 a280 3 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); a281 1 } d339 1 a341 1 rw_enter(&pppoe_softc_list_lock, RW_READER); a344 3 rw_exit(&pppoe_softc_list_lock); if_register(&sc->sc_sppp.pp_if); d427 1 a427 3 rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); a428 1 } d430 1 a430 2 if (len != sizeof sc) { rw_exit(&pppoe_softc_list_lock); a431 1 } d434 1 d521 1 d524 1 a529 2 struct ifnet *rcvif; struct psref psref; d548 1 d551 1 d604 2 a605 1 if (len > 0) { d619 1 a619 1 printf("pppoe: connected to %s\n", error); d623 3 a625 9 case PPPOE_TAG_HUNIQUE: if (hunique == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; err_msg = "TAG HUNIQUE ERROR"; break; } d627 23 a649 2 hunique = mtod(n, uint8_t *) + noff; hunique_len = len; d652 1 d725 2 a727 5 if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); goto done; } d771 3 d793 2 a794 6 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { printf("pppoe: received PADR" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); d823 1 a828 13 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); d831 2 a832 6 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { printf("pppoe: received PADO" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); d836 2 d892 1 a892 2 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) d895 1 a895 11 if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) goto done; d907 4 a910 1 case PPPOE_CODE_PADT: d912 4 a915 6 if (__predict_false(rcvif == NULL)) goto done; sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); a916 1 d923 1 a924 13 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); d926 1 a951 1 rw_enter(&pppoe_softc_list_lock, RW_READER); a952 1 rw_exit(&pppoe_softc_list_lock); a954 1 rw_exit(&pppoe_softc_list_lock); a985 1 rw_enter(&pppoe_softc_list_lock, RW_READER); a986 1 rw_exit(&pppoe_softc_list_lock); a988 1 rw_exit(&pppoe_softc_list_lock); @ 1.134.2.4 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.141 2018/06/26 06:48:02 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.141 2018/06/26 06:48:02 msaitoh Exp $"); d1087 1 a1087 1 bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_IN); d1851 1 a1851 1 bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT); d1887 1 a1887 1 bpf_mtap(&sc->sc_sppp.pp_if, m, BPF_D_OUT); @ 1.134.2.5 log @Sync with HEAD Resolve a couple of conflicts (result of the uimin/uimax changes) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.143 2018/08/24 17:06:29 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.143 2018/08/24 17:06:29 maxv Exp $"); a58 1 #include a159 1 uint64_t sc_id; /* id of this softc, our hunique */ a295 25 static void pppoe_softc_genid(uint64_t *id) { struct pppoe_softc *sc; uint64_t rndid; rw_enter(&pppoe_softc_list_lock, RW_READER); while (1) { rndid = cprng_strong64(); sc = NULL; LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_id == rndid) break; } if (sc == NULL) { break; } } rw_exit(&pppoe_softc_list_lock); *id = rndid; } a303 2 pppoe_softc_genid(&sc->sc_id); d431 1 a431 4 struct pppoe_softc *sc; uint64_t t; CTASSERT(sizeof(t) == sizeof(sc->sc_id)); d439 1 a439 1 if (len != sizeof(sc->sc_id)) { d446 1 a446 1 if (sc->sc_id == t) { d1332 1 a1332 1 int len, l1 = 0, l2 = 0; d1335 1 a1335 1 if (sc->sc_state > PPPOE_STATE_PADI_SENT) d1338 2 a1339 2 /* Compute packet length. */ len = sizeof(struct pppoetag); d1346 1 a1346 1 len += sizeof(struct pppoetag) + l2; a1347 1 len += sizeof(struct pppoetag) + sizeof(sc->sc_id); d1349 1 a1349 1 len += sizeof(struct pppoetag) + 2; d1352 3 a1354 3 /* Allocate packet. */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (m0 == NULL) d1357 1 a1357 1 /* Fill in packet. */ d1375 3 a1377 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); d1391 1 a1391 1 /* Send packet. */ d1601 1 d1607 1 a1607 1 size_t len, l1 = 0; d1612 2 a1613 3 /* Compute packet length. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { d1617 4 a1620 7 if (sc->sc_ac_cookie_len > 0) { len += sizeof(struct pppoetag) + sc->sc_ac_cookie_len; } if (sc->sc_relay_sid_len > 0) { len += sizeof(struct pppoetag) + sc->sc_relay_sid_len; } len += sizeof(struct pppoetag) + sizeof(sc->sc_id); d1622 1 a1622 1 len += sizeof(struct pppoetag) + 2; a1623 2 /* Allocate packet. */ d1625 1 a1625 1 if (m0 == NULL) a1626 2 /* Fill in packet. */ d1650 3 a1652 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); a1665 1 /* Send packet. */ d1717 3 a1719 3 PPPOE_ADD_16(p, sizeof(sc->sc_id)); memcpy(p, &sc->sc_id, sizeof(sc->sc_id)); p += sizeof(sc->sc_id); @ 1.134.2.6 log @Sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.144 2018/09/30 10:00:24 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.144 2018/09/30 10:00:24 maxv Exp $"); d1746 6 a1751 5 /* Include AC cookie. */ len = sizeof(struct pppoetag) + sizeof(sc->sc_id); /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; a1755 1 d1782 5 a1786 4 /* Include service name. */ len = sizeof(struct pppoetag); if (sc->sc_service_name != NULL) { a1789 3 /* Include hunique. */ len += sizeof(struct pppoetag) + sc->sc_hunique_len; a1793 1 @ 1.134.2.7 log @Sync with HEAD, resolve a couple of conflicts @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.146 2018/10/27 06:46:43 maxv Exp $ */ d3 1 a3 1 /* d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.146 2018/10/27 06:46:43 maxv Exp $"); d531 1 a531 2 if (m == NULL) break; d540 1 a540 2 if (m == NULL) break; d573 5 d580 1 a580 1 if (m == NULL) d586 7 d594 1 d598 4 a601 2 M_REGION_GET(ph, struct pppoehdr *, m, off, sizeof(*ph)); if (ph == NULL) { d604 1 d606 2 a609 8 ac_cookie = NULL; ac_cookie_len = 0; relay_sid = NULL; relay_sid_len = 0; hunique = NULL; hunique_len = 0; d615 2 a619 1 a622 2 err_msg = NULL; errortag = 0; d624 4 a627 2 M_REGION_GET(pt, struct pppoetag *, m, off, sizeof(*pt)); if (pt == NULL) { d630 1 a630 1 d634 2 d730 2 a731 1 printf("pppoe: %s: %s\n", err_msg, error); d734 1 a734 1 printf("pppoe: %s\n", err_msg); a740 1 d773 1 a794 1 d801 2 d809 3 a811 1 ac_cookie_len, rcvif, RW_WRITER); a853 1 d861 3 a863 1 hunique_len, rcvif, RW_WRITER); a931 1 d939 3 a941 1 hunique_len, rcvif, RW_WRITER); a958 1 a974 1 d982 3 a984 1 hunique_len, rcvif, RW_READER); d1067 2 d1074 2 a1075 1 if (m == NULL) { d1082 2 d1086 1 a1086 1 if (ph->code != 0) { a1087 1 } d1103 2 a1104 2 if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, d1143 1 a1143 1 * Fix incoming interface pointer (not the raw ethernet interface d1206 1 a1206 1 struct ifnet *eth_if; @ 1.133 log @Remove wrong assertions rw_lock_held() returns true when any context holds the lock. However, in if_pppoe.c, the function was used wrongly as it returns true only if the lock is held in the same context. From s-yamaguchi@@IIJ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.132 2017/11/17 07:37:12 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.132 2017/11/17 07:37:12 ozaki-r Exp $"); d1798 1 a1798 1 m_free(m); d1890 1 a1890 1 m_free(m); d1896 1 a1896 1 m_free(m); @ 1.132 log @Provide macros for softnet_lock and KERNEL_LOCK hiding NET_MPSAFE switch It reduces C&P codes such as "#ifndef NET_MPSAFE KERNEL_LOCK(1, NULL); ..." scattered all over the source code and makes it easy to identify remaining KERNEL_LOCK and/or softnet_lock that are held even if NET_MPSAFE. No functional change @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.131 2017/11/16 03:07:18 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.131 2017/11/16 03:07:18 ozaki-r Exp $"); a137 1 #define PPPOE_LOCKED(_sc) rw_lock_held(&(_sc)->sc_lock) a138 1 #define PPPOE_RLOCKED(_sc) rw_read_held(&(_sc)->sc_lock) a1056 2 KASSERT(PPPOE_LOCKED(sc)); a1259 2 KASSERT(PPPOE_LOCKED(sc)); a1533 2 KASSERT(PPPOE_LOCKED(sc)); a1626 2 KASSERT(PPPOE_LOCKED(sc)); /* required by pppoe_output(). */ a1699 2 KASSERT(!PPPOE_LOCKED(sc)); a1728 2 KASSERT(!PPPOE_LOCKED(sc)); @ 1.131 log @Unify IFEF_*_MPSAFE into IFEF_MPSAFE There are already two flags for if_output and if_start, however, it seems such MPSAFE flags are eventually needed for all if_XXX operations. Having discrete flags for each operation is wasteful of if_extflags bits. So let's unify the flags into one: IFEF_MPSAFE. Fortunately IFEF_*_MPSAFE flags have never been included in any releases, so we can change them without breaking backward compatibility of the releases (though the kernel version of -current should be bumped). Note that if an interface have both MP-safe and non-MP-safe operations at a time, we have to set the IFEF_MPSAFE flag and let callees of non-MP-safe opeartions take the kernel lock. Proposed on tech-kern@@ and tech-net@@ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.130 2017/11/15 07:52:58 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.130 2017/11/15 07:52:58 knakahara Exp $"); d480 1 a480 3 #ifndef PPPOE_MPSAFE mutex_enter(softnet_lock); #endif d503 2 a504 3 #ifndef PPPOE_MPSAFE mutex_exit(softnet_lock); #endif @ 1.130 log @Mark callouts of pppoe(4) CALLOUT_MPSAFE. Suggested by ozaki-r@@n.o. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.129 2017/10/23 09:32:33 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.129 2017/10/23 09:32:33 msaitoh Exp $"); d306 1 a306 1 sc->sc_sppp.pp_if.if_extflags = IFEF_OUTPUT_MPSAFE; @ 1.129 log @ - If if_initialize() failed in the attach function, free resources and return. - KNF @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.128 2017/10/12 09:49:43 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.128 2017/10/12 09:49:43 knakahara Exp $"); d320 1 a320 1 callout_init(&sc->sc_timeout, 0); @ 1.128 log @sppp_lock is changed from mutex to rwlock now. Contributed by s-yamaguchi@@IIJ. Add locking notes later. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.127 2017/10/12 09:47:21 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.127 2017/10/12 09:47:21 knakahara Exp $"); d226 2 a227 1 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); d297 1 d330 7 a336 1 if_initialize(&sc->sc_sppp.pp_if); a370 1 d389 1 a389 1 return (0); d644 3 a646 2 sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, len, rcvif, RW_READER); d1026 1 a1026 2 sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); d1040 4 a1043 1 /* fix incoming interface pointer (not the raw ethernet interface anymore) */ d1072 2 a1073 1 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; d1104 1 a1104 1 return (EPERM); d1397 1 a1397 2 sc->sc_sppp.pp_if.if_xname, err); d1475 2 a1476 1 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); @ 1.127 log @Integrate two locks used to protect PPPoE softc. Contributed by s-yamaguchi@@IIJ. PPPOE_SESSION_LOCK protects variables used in PPP packet processing, on the other hand PPPOE_PARAM_LOCK protects the other variables used to establish a PPPoE session id. Those locks isn't acquired in the same time because the PPP packet processing doesn't work without PPPoE session id. By the reason, the locks can be integrated into PPPOE_LOCK. Add locking notes later. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.126 2017/07/20 02:34:24 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.126 2017/07/20 02:34:24 knakahara Exp $"); a815 1 sppp_lock_enter(&sc->sc_sppp); a816 1 sppp_lock_exit(&sc->sc_sppp); a899 1 sppp_lock_enter(&sc->sc_sppp); a900 1 sppp_lock_exit(&sc->sc_sppp); a1493 1 sppp_lock_enter(&sc->sc_sppp); a1494 1 sppp_lock_exit(&sc->sc_sppp); a1514 1 sppp_lock_enter(&sc->sc_sppp); a1515 1 sppp_lock_exit(&sc->sc_sppp); a1843 1 sppp_lock_enter(&sc->sc_sppp); a1848 1 sppp_lock_exit(&sc->sc_sppp); a1873 1 sppp_lock_enter(&sc->sc_sppp); a1874 1 sppp_lock_exit(&sc->sc_sppp); @ 1.126 log @fix panic when PPPOE_DEBUG enabled. implemented by s-yamaguchi@@IIJ, thanks. XXX need pullup to -8 branch @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $"); d136 6 a141 12 #define PPPOE_SESSION_LOCK(_sc, _op) rw_enter(&(_sc)->sc_session_lock, (_op)) #define PPPOE_SESSION_UNLOCK(_sc) rw_exit(&(_sc)->sc_session_lock) #define PPPOE_SESSION_LOCKED(_sc) rw_lock_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_WLOCKED(_sc) rw_write_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_RLOCKED(_sc) rw_read_held(&(_sc)->sc_session_lock) #define PPPOE_PARAM_LOCK(_sc) if ((_sc)->sc_lock) \ mutex_enter((_sc)->sc_lock) #define PPPOE_PARAM_UNLOCK(_sc) if ((_sc)->sc_lock) \ mutex_exit((_sc)->sc_lock) #define PPPOE_PARAM_LOCKED(_sc) (!(_sc)->sc_lock || \ mutex_owned((_sc)->sc_lock)) a161 1 bool sc_state_updating; /* state update in other components */ d178 1 a178 2 krwlock_t sc_session_lock; /* lock of sc_state, sc_session, and sc_eth_if */ kmutex_t *sc_lock; /* lock of other parameters */ d338 1 a338 2 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); rw_init(&sc->sc_session_lock); d353 1 a353 1 PPPOE_PARAM_LOCK(sc); a362 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d377 2 a378 5 PPPOE_PARAM_UNLOCK(sc); if (sc->sc_lock) mutex_obj_free(sc->sc_lock); PPPOE_SESSION_UNLOCK(sc); rw_destroy(&sc->sc_session_lock); d400 2 a401 3 PPPOE_SESSION_LOCK(sc, lock); if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_SESSION d406 1 a406 1 PPPOE_SESSION_UNLOCK(sc); d430 1 a430 1 PPPOE_SESSION_LOCK(sc, lock); a442 9 if (sc->sc_state_updating) { #ifdef PPPOE_DEBUG printf("%s: host unique tag found, but its state is updating\n", sc->sc_sppp.pp_if.if_xname); #endif PPPOE_SESSION_UNLOCK(sc); return NULL; } d447 1 a447 1 PPPOE_SESSION_UNLOCK(sc); d453 1 a453 1 PPPOE_SESSION_UNLOCK(sc); d644 1 a644 1 PPPOE_SESSION_UNLOCK(sc); d724 1 a724 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d726 1 a726 1 PPPOE_SESSION_UNLOCK(sc); d730 1 a730 1 PPPOE_SESSION_UNLOCK(sc); d734 1 a734 2 if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_INITIAL) d737 1 a737 1 PPPOE_SESSION_UNLOCK(sc); a745 1 PPPOE_PARAM_LOCK(sc); d752 1 a752 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d761 1 a761 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d793 1 a793 2 if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADO_SENT) { d796 1 a796 1 PPPOE_SESSION_UNLOCK(sc); d799 1 a799 1 PPPOE_PARAM_LOCK(sc); d806 1 a806 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d814 1 a814 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d833 1 a833 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d835 1 a835 2 if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADI_SENT) { d838 1 a838 1 PPPOE_SESSION_UNLOCK(sc); a841 1 PPPOE_PARAM_LOCK(sc); d851 1 a851 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d866 1 a866 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d886 1 a886 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d892 1 a892 8 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); if (sc->sc_state_updating) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); goto done; } d900 1 a900 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a918 1 PPPOE_PARAM_LOCK(sc); d920 1 a920 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d925 1 a925 1 PPPOE_SESSION_LOCK(sc, RW_READER); d928 1 a928 1 PPPOE_SESSION_UNLOCK(sc); d1032 1 a1032 1 PPPOE_SESSION_UNLOCK(sc); d1056 1 a1056 2 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1101 1 a1101 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d1105 1 a1105 1 PPPOE_SESSION_UNLOCK(sc); d1115 1 a1115 1 PPPOE_SESSION_UNLOCK(sc); d1134 1 a1134 1 PPPOE_PARAM_LOCK(sc); d1138 1 a1138 1 PPPOE_PARAM_UNLOCK(sc); d1157 1 a1157 1 PPPOE_PARAM_LOCK(sc); d1161 1 a1161 1 PPPOE_PARAM_UNLOCK(sc); d1170 1 a1170 1 PPPOE_SESSION_LOCK(sc, RW_READER); d1174 1 a1174 1 PPPOE_SESSION_UNLOCK(sc); d1181 1 a1181 2 PPPOE_SESSION_LOCK(sc, RW_READER); PPPOE_PARAM_LOCK(sc); d1186 1 a1186 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1195 1 a1195 2 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); a1205 1 sc->sc_state_updating = 1; d1208 1 a1208 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1211 4 PPPOE_SESSION_LOCK(sc, RW_WRITER); sc->sc_state_updating = 0; PPPOE_SESSION_UNLOCK(sc); d1260 1 a1260 2 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1333 1 a1333 2 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); d1362 1 a1362 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1397 1 a1397 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1416 1 a1416 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1419 1 a1419 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1429 1 a1429 2 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1459 1 a1459 2 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1473 1 sc->sc_state_updating = 1; d1495 1 a1495 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1502 1 a1502 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; d1512 1 a1512 2 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1516 1 sc->sc_state_updating = 1; d1518 1 a1518 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1525 1 a1525 4 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; d1540 1 a1540 2 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1635 1 a1635 2 KASSERT(PPPOE_SESSION_LOCKED(sc)); /* required by pppoe_output(). */ KASSERT(PPPOE_PARAM_LOCKED(sc)); d1669 1 a1669 2 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1710 1 a1710 2 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); d1712 1 a1712 1 PPPOE_SESSION_LOCK(sc, RW_READER); d1715 1 a1715 1 PPPOE_SESSION_UNLOCK(sc); a1718 2 PPPOE_PARAM_LOCK(sc); d1733 1 a1733 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1741 1 a1741 2 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); d1743 1 a1743 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d1746 1 a1746 1 PPPOE_SESSION_UNLOCK(sc); a1754 1 PPPOE_PARAM_LOCK(sc); d1758 1 a1758 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1773 1 d1776 1 a1787 1 PPPOE_SESSION_LOCK(sc, RW_READER); a1791 1 PPPOE_PARAM_LOCK(sc); a1792 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1794 1 d1809 1 a1809 1 PPPOE_SESSION_LOCK(sc, RW_READER); d1811 1 a1811 1 PPPOE_SESSION_UNLOCK(sc); d1819 1 a1819 1 PPPOE_SESSION_UNLOCK(sc); a1827 1 PPPOE_PARAM_LOCK(sc); d1829 1 a1829 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1847 1 a1847 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); d1849 1 a1849 1 PPPOE_SESSION_UNLOCK(sc); a1859 1 PPPOE_PARAM_LOCK(sc); d1861 1 a1861 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1870 1 a1870 2 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1879 1 sc->sc_state_updating = 1; d1881 1 a1881 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1888 1 a1888 4 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; @ 1.125 log @Use m_get_rcvif_psref instead of m_get_rcvif Because the critical sections are now sleepable. Reviewed by knakahara@@ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.124 2017/02/01 17:58:47 maxv Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.124 2017/02/01 17:58:47 maxv Exp $"); a1368 1 p += sizeof sc; a1667 1 p += sizeof sc; @ 1.125.6.1 log @Pull up following revision(s) (requested by knakahara in ticket #149): sys/net/if_pppoe.c: revision 1.126 fix panic when PPPOE_DEBUG enabled. implemented by s-yamaguchi@@IIJ, thanks. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $"); d1369 1 d1669 1 @ 1.125.6.2 log @Pull up following revision(s) (requested by knakahara in ticket #332): sys/net/if_pppoe.c: 1.127-1.128 sys/net/if_pppoe.h: 1.15 sys/net/if_spppsubr.c: 1.170-1.171 sys/net/if_spppvar.h: 1.21-1.22 Integrate two locks used to protect PPPoE softc. Contributed by s-yamaguchi@@IIJ. PPPOE_SESSION_LOCK protects variables used in PPP packet processing, on the other hand PPPOE_PARAM_LOCK protects the other variables used to establish a PPPoE session id. Those locks isn't acquired in the same time because the PPP packet processing doesn't work without PPPoE session id. By the reason, the locks can be integrated into PPPOE_LOCK. Add locking notes later. -- sppp_lock is changed from mutex to rwlock now. Contributed by s-yamaguchi@@IIJ. Add locking notes later. -- Add a locking notes for if_pppoe -- Add a locking notes for if_spppsubr -- fix no INET6 build. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.1 2017/07/25 02:07:11 snj Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.1 2017/07/25 02:07:11 snj Exp $"); d136 12 a147 6 #define PPPOE_LOCK(_sc, _op) rw_enter(&(_sc)->sc_lock, (_op)) #define PPPOE_UNLOCK(_sc) rw_exit(&(_sc)->sc_lock) #define PPPOE_LOCKED(_sc) rw_lock_held(&(_sc)->sc_lock) #define PPPOE_WLOCKED(_sc) rw_write_held(&(_sc)->sc_lock) #define PPPOE_RLOCKED(_sc) rw_read_held(&(_sc)->sc_lock) d168 1 d185 2 a186 1 krwlock_t sc_lock; /* lock of sc_state, sc_session, and sc_eth_if */ d346 2 a347 1 rw_init(&sc->sc_lock); d362 1 a362 1 PPPOE_LOCK(sc, RW_WRITER); d372 1 d387 5 a391 2 PPPOE_UNLOCK(sc); rw_destroy(&sc->sc_lock); d413 3 a415 2 PPPOE_LOCK(sc, lock); if ( sc->sc_state == PPPOE_STATE_SESSION d420 1 a420 1 PPPOE_UNLOCK(sc); d444 1 a444 1 PPPOE_LOCK(sc, lock); d457 9 d470 1 a470 1 PPPOE_UNLOCK(sc); d476 1 a476 1 PPPOE_UNLOCK(sc); d667 1 a667 1 PPPOE_UNLOCK(sc); d747 1 a747 1 PPPOE_LOCK(sc, RW_WRITER); d749 1 a749 1 PPPOE_UNLOCK(sc); d753 1 a753 1 PPPOE_UNLOCK(sc); d757 2 a758 1 if (sc->sc_state == PPPOE_STATE_INITIAL) d761 1 a761 1 PPPOE_UNLOCK(sc); d770 1 d777 2 a778 1 PPPOE_UNLOCK(sc); d787 2 a788 1 PPPOE_UNLOCK(sc); d820 2 a821 1 if (sc->sc_state != PPPOE_STATE_PADO_SENT) { d824 1 a824 1 PPPOE_UNLOCK(sc); d827 1 a827 1 d834 2 a835 1 PPPOE_UNLOCK(sc); d843 2 a844 1 PPPOE_UNLOCK(sc); d846 1 d848 1 d863 1 a863 1 PPPOE_LOCK(sc, RW_WRITER); d865 2 a866 1 if (sc->sc_state != PPPOE_STATE_PADI_SENT) { d869 1 a869 1 PPPOE_UNLOCK(sc); d873 1 d883 2 a884 1 PPPOE_UNLOCK(sc); d899 2 a900 1 PPPOE_UNLOCK(sc); d920 2 a921 1 PPPOE_UNLOCK(sc); d927 8 a934 1 PPPOE_LOCK(sc, RW_WRITER); d942 2 a943 1 PPPOE_UNLOCK(sc); d945 1 d947 1 d962 1 d964 2 a965 1 PPPOE_UNLOCK(sc); d970 1 a970 1 PPPOE_LOCK(sc, RW_READER); d973 1 a973 1 PPPOE_UNLOCK(sc); d1077 1 a1077 1 PPPOE_UNLOCK(sc); d1101 2 a1102 1 KASSERT(PPPOE_LOCKED(sc)); d1147 1 a1147 1 PPPOE_LOCK(sc, RW_WRITER); d1151 1 a1151 1 PPPOE_UNLOCK(sc); d1161 1 a1161 1 PPPOE_UNLOCK(sc); d1180 1 a1180 1 PPPOE_LOCK(sc, RW_WRITER); d1184 1 a1184 1 PPPOE_UNLOCK(sc); d1203 1 a1203 1 PPPOE_LOCK(sc, RW_WRITER); d1207 1 a1207 1 PPPOE_UNLOCK(sc); d1216 1 a1216 1 PPPOE_LOCK(sc, RW_READER); d1220 1 a1220 1 PPPOE_UNLOCK(sc); d1227 2 a1228 1 PPPOE_LOCK(sc, RW_READER); d1233 2 a1234 1 PPPOE_UNLOCK(sc); d1243 2 a1244 1 PPPOE_LOCK(sc, RW_WRITER); d1255 1 d1258 2 a1259 1 PPPOE_UNLOCK(sc); d1263 4 d1315 2 a1316 1 KASSERT(PPPOE_LOCKED(sc)); d1389 2 a1390 1 PPPOE_LOCK(sc, RW_WRITER); d1419 2 a1420 1 PPPOE_UNLOCK(sc); d1455 2 a1456 1 PPPOE_UNLOCK(sc); d1475 2 a1476 1 PPPOE_UNLOCK(sc); d1479 2 a1480 1 PPPOE_UNLOCK(sc); d1490 2 a1491 1 KASSERT(PPPOE_WLOCKED(sc)); d1521 2 a1522 1 KASSERT(PPPOE_WLOCKED(sc)); d1537 1 d1559 2 a1560 1 PPPOE_UNLOCK(sc); d1563 1 d1565 1 d1567 3 a1569 1 PPPOE_LOCK(sc, RW_WRITER); d1579 2 a1580 1 KASSERT(PPPOE_WLOCKED(sc)); d1585 1 d1587 2 a1588 1 PPPOE_UNLOCK(sc); d1591 1 d1593 1 d1595 4 a1598 1 PPPOE_LOCK(sc, RW_WRITER); d1613 2 a1614 1 KASSERT(PPPOE_LOCKED(sc)); d1709 2 a1710 1 KASSERT(PPPOE_LOCKED(sc)); /* required by pppoe_output(). */ d1744 2 a1745 1 KASSERT(PPPOE_WLOCKED(sc)); d1786 2 a1787 1 KASSERT(!PPPOE_LOCKED(sc)); d1789 1 a1789 1 PPPOE_LOCK(sc, RW_READER); d1792 1 a1792 1 PPPOE_UNLOCK(sc); d1796 2 d1812 2 a1813 1 PPPOE_UNLOCK(sc); d1821 2 a1822 1 KASSERT(!PPPOE_LOCKED(sc)); d1824 1 a1824 1 PPPOE_LOCK(sc, RW_WRITER); d1827 1 a1827 1 PPPOE_UNLOCK(sc); d1836 1 d1840 2 a1841 1 PPPOE_UNLOCK(sc); a1855 1 PPPOE_LOCK(sc, RW_READER); a1857 1 PPPOE_UNLOCK(sc); d1869 1 d1874 1 d1876 2 a1878 1 PPPOE_UNLOCK(sc); d1893 1 a1893 1 PPPOE_LOCK(sc, RW_READER); d1895 1 a1895 1 PPPOE_UNLOCK(sc); d1903 1 a1903 1 PPPOE_UNLOCK(sc); d1912 1 d1914 2 a1915 1 PPPOE_UNLOCK(sc); d1933 1 a1933 1 PPPOE_LOCK(sc, RW_WRITER); d1935 1 a1935 1 PPPOE_UNLOCK(sc); d1938 1 d1944 1 d1946 1 d1948 2 a1949 1 PPPOE_UNLOCK(sc); d1958 2 a1959 1 KASSERT(PPPOE_WLOCKED(sc)); d1969 1 d1971 2 a1972 1 PPPOE_UNLOCK(sc); d1975 1 d1977 4 d1982 1 a1982 1 PPPOE_LOCK(sc, RW_WRITER); @ 1.125.6.3 log @Pull up following revision(s) (requested by ozaki-r in ticket #431): sys/net/if_pppoe.c: revision 1.133 Remove wrong assertions rw_lock_held() returns true when any context holds the lock. However, in if_pppoe.c, the function was used wrongly as it returns true only if the lock is held in the same context. From s-yamaguchi@@IIJ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.2 2017/11/02 20:28:24 snj Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.2 2017/11/02 20:28:24 snj Exp $"); d138 1 d140 1 d1052 2 d1256 2 d1532 2 d1627 2 d1702 2 d1733 2 @ 1.125.6.4 log @Pull up following revision(s) (requested by msaitoh in ticket #427): sys/arch/amiga/dev/if_bah_zbus.c: 1.17 sys/arch/arm/broadcom/bcm53xx_eth.c: 1.30 sys/arch/powerpc/booke/dev/pq3etsec.c: 1.32 sys/arch/usermode/dev/if_veth.c: 1.9 sys/dev/ic/an.c: 1.66 sys/dev/ic/athn.c: 1.17 sys/dev/ic/atw.c: 1.162 sys/dev/ic/bwi.c: 1.33 sys/dev/ic/dwc_gmac.c: 1.41-1.42 sys/dev/ic/malo.c: 1.10 sys/dev/ic/rt2560.c: 1.31 sys/dev/ic/rt2661.c: 1.36 sys/dev/ic/rt2860.c: 1.29 sys/dev/ic/rtw.c: 1.127 sys/dev/ic/rtwvar.h: 1.46 sys/dev/ic/smc90cx6.c: 1.71 sys/dev/ic/smc90cx6var.h: 1.12 sys/dev/ic/wi.c: 1.244 sys/dev/pci/if_ipw.c: 1.66 sys/dev/pci/if_iwi.c: 1.104 sys/dev/pci/if_iwm.c: 1.76 sys/dev/pci/if_iwn.c: 1.86 sys/dev/pci/if_rtwn.c: 1.13 sys/dev/pci/if_wm.c: 1.541 sys/dev/pci/if_wpi.c: 1.79 sys/dev/pci/ixgbe/ixgbe.c: 1.106 sys/dev/pci/ixgbe/ixv.c: 1.73 via patch sys/dev/pcmcia/if_malo_pcmcia.c: 1.15 sys/dev/scsipi/if_se.c: 1.95 sys/dev/usb/if_upl.c: 1.60 sys/net/if.c: 1.396 sys/net/if.h: 1.241 sys/net/if_arc.h: 1.23 sys/net/if_arcsubr.c: 1.78 sys/net/if_bridge.c: 1.136-1.137 sys/net/if_etherip.c: 1.39 sys/net/if_faith.c: 1.56 sys/net/if_gif.c: 1.131 sys/net/if_loop.c: 1.96 sys/net/if_mpls.c: 1.30 sys/net/if_pppoe.c: 1.129 sys/net/if_srt.c: 1.27 sys/net/if_stf.c: 1.102 sys/net/if_tap.c: 1.100 sys/net/if_vlan.c: 1.105 sys/netinet/ip_carp.c: 1.91 sys/rump/net/lib/libshmif/if_shmem.c: 1.73-1.74 sys/rump/net/lib/libvirtif/if_virt.c: 1.55-1.56 if_initalize() and if_attach() failed when resource allocation failed (e.g. allocating softint). Without this change, it panics. It's bad because resource shortage really occured when a lot of pseudo interface is created. To avoid this problem, don't panic and change return value of if_initialize() and if_attach() to int. Caller fanction will be recover from error cleanly by checking the return value. Return if bah_attach_subr() failed. If if_attach() failed in the attach function, return. - If if_initialize() failed in the attach function, free resources and return. - Add some missing frees in bridge_clone_destroy(). - KNF If error occured in bcmeth_ccb_attach(), free resources and return. If error occured in pq3etsec_attach(), free resources and return. If error occured in the attach function, free resources and return. - If if_initialize() failed in athn_attach(), free resources and return. - Add missing pmf_event_deregister() in athn_detach(). - Free resources correctly on some errors in atw_attach(). - Use apint*() insread of printf() in the attach function. If if_initialize() failed in the attach function, return. - If if_initialize() failed in the attach function, free resources and return. - Add missing dwc_gmac_free_dma_rings() and mutex_destroy() when attach failed. - If if_initialize() failed in the attach function, free resources and return. - ifp is always not NULL in iwi_detach(). Check correctly with ifp->if_softc. - If if_initialize() failed in the attach function, free resources and return. - Fix error path in the attach function correctly. If if_initialize() failed in the attach function, free resources and return. If if_attach() failed in the attach function, free resources and return. - If if_initialize() failed in the attach function, free resources and return. - KNF - If if_attach() failed in the attach function, free resources and return. - KNF Fix compile error. Fix compile error. We don't need '&mii', but just 'mii' for mii_detach(). Don't free sc_rthash twice @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.3 2017/12/08 06:12:35 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.3 2017/12/08 06:12:35 msaitoh Exp $"); d224 1 a224 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); a293 1 int rv; d326 1 a326 7 rv = if_initialize(&sc->sc_sppp.pp_if); if (rv != 0) { callout_halt(&sc->sc_timeout, NULL); callout_destroy(&sc->sc_timeout); free(sc, M_DEVBUF); return rv; } d361 1 d380 1 a380 1 return 0; d635 2 a636 3 sc = pppoe_find_softc_by_hunique( mtod(n, char *) + noff, len, rcvif, RW_READER); d1016 2 a1017 1 sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); d1031 1 a1031 4 /* * Fix incoming interface pointer (not the raw ethernet interface * anymore) */ d1058 1 a1058 2 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; d1089 1 a1089 1 return EPERM; d1380 2 a1381 1 sc->sc_sppp.pp_if.if_xname, err); d1459 1 a1459 2 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); @ 1.125.6.5 log @Pull up following revision(s) (requested by ozaki-r in ticket #456): sys/arch/arm/sunxi/sunxi_emac.c: 1.9 sys/dev/ic/dwc_gmac.c: 1.43-1.44 sys/dev/pci/if_iwm.c: 1.75 sys/dev/pci/if_wm.c: 1.543 sys/dev/pci/ixgbe/ixgbe.c: 1.112 sys/dev/pci/ixgbe/ixv.c: 1.74 sys/kern/sys_socket.c: 1.75 sys/net/agr/if_agr.c: 1.43 sys/net/bpf.c: 1.219 sys/net/if.c: 1.397, 1.399, 1.401-1.403, 1.406-1.410, 1.412-1.416 sys/net/if.h: 1.242-1.247, 1.250, 1.252-1.257 sys/net/if_bridge.c: 1.140 via patch, 1.142-1.146 sys/net/if_etherip.c: 1.40 sys/net/if_ethersubr.c: 1.243, 1.246 sys/net/if_faith.c: 1.57 sys/net/if_gif.c: 1.132 sys/net/if_l2tp.c: 1.15, 1.17 sys/net/if_loop.c: 1.98-1.101 sys/net/if_media.c: 1.35 sys/net/if_pppoe.c: 1.131-1.132 sys/net/if_spppsubr.c: 1.176-1.177 sys/net/if_tun.c: 1.142 sys/net/if_vlan.c: 1.107, 1.109, 1.114-1.121 sys/net/npf/npf_ifaddr.c: 1.3 sys/net/npf/npf_os.c: 1.8-1.9 sys/net/rtsock.c: 1.230 sys/netcan/if_canloop.c: 1.3-1.5 sys/netinet/if_arp.c: 1.255 sys/netinet/igmp.c: 1.65 sys/netinet/in.c: 1.210-1.211 sys/netinet/in_pcb.c: 1.180 sys/netinet/ip_carp.c: 1.92, 1.94 sys/netinet/ip_flow.c: 1.81 sys/netinet/ip_input.c: 1.362 sys/netinet/ip_mroute.c: 1.147 sys/netinet/ip_output.c: 1.283, 1.285, 1.287 sys/netinet6/frag6.c: 1.61 sys/netinet6/in6.c: 1.251, 1.255 sys/netinet6/in6_pcb.c: 1.162 sys/netinet6/ip6_flow.c: 1.35 sys/netinet6/ip6_input.c: 1.183 sys/netinet6/ip6_output.c: 1.196 sys/netinet6/mld6.c: 1.90 sys/netinet6/nd6.c: 1.239-1.240 sys/netinet6/nd6_nbr.c: 1.139 sys/netinet6/nd6_rtr.c: 1.136 sys/netipsec/ipsec_output.c: 1.65 sys/rump/net/lib/libnetinet/netinet_component.c: 1.9-1.10 kmem_intr_free kmem_intr_[z]alloced memory the underlying pools are the same but api-wise those should match Unify IFEF_*_MPSAFE into IFEF_MPSAFE There are already two flags for if_output and if_start, however, it seems such MPSAFE flags are eventually needed for all if_XXX operations. Having discrete flags for each operation is wasteful of if_extflags bits. So let's unify the flags into one: IFEF_MPSAFE. Fortunately IFEF_*_MPSAFE flags have never been included in any releases, so we can change them without breaking backward compatibility of the releases (though the kernel version of -current should be bumped). Note that if an interface have both MP-safe and non-MP-safe operations at a time, we have to set the IFEF_MPSAFE flag and let callees of non-MP-safe opeartions take the kernel lock. Proposed on tech-kern@@ and tech-net@@ Provide macros for softnet_lock and KERNEL_LOCK hiding NET_MPSAFE switch It reduces C&P codes such as "#ifndef NET_MPSAFE KERNEL_LOCK(1, NULL); ..." scattered all over the source code and makes it easy to identify remaining KERNEL_LOCK and/or softnet_lock that are held even if NET_MPSAFE. No functional change Hold KERNEL_LOCK on if_ioctl selectively based on IFEF_MPSAFE If IFEF_MPSAFE is set, hold the lock and otherwise don't hold. This change requires additions of KERNEL_LOCK to subsequence functions from if_ioctl such as ifmedia_ioctl and ifioctl_common to protect non-MP-safe components. Proposed on tech-kern@@ and tech-net@@ Ensure to hold if_ioctl_lock when calling if_flags_set Fix locking against myself on ifpromisc vlan_unconfig_locked could be called with holding if_ioctl_lock. Ensure to not turn on IFF_RUNNING of an interface until its initialization completes And ensure to turn off it before destruction as per IFF_RUNNING's description "resource allocated". (The description is a bit doubtful though, I believe the change is still proper.) Ensure to hold if_ioctl_lock on if_up and if_down One exception for if_down is if_detach; in the case the lock isn't needed because it's guaranteed that no other one can access ifp at that point. Make if_link_queue MP-safe if IFEF_MPSAFE if_link_queue is a queue to store events of link state changes, which is used to pass events from (typically) an interrupt handler to if_link_state_change softint. The queue was protected by KERNEL_LOCK so far, but if IFEF_MPSAFE is enabled, it becomes unsafe because (perhaps) an interrupt handler of an interface with IFEF_MPSAFE doesn't take KERNEL_LOCK. Protect it by a spin mutex. Additionally with this change KERNEL_LOCK of if_link_state_change softint is omitted if NET_MPSAFE is enabled. Note that the spin mutex is now ifp->if_snd.ifq_lock as well as the case of if_timer (see the comment). Use IFADDR_WRITER_FOREACH instead of IFADDR_READER_FOREACH At that point no other one modifies the list so IFADDR_READER_FOREACH is unnecessary. Use of IFADDR_READER_FOREACH is harmless in general though, if we try to detect contract violations of pserialize, using it violates the contract. So avoid using it makes life easy. Ensure to call if_addr_init with holding if_ioctl_lock Get rid of outdated comments Fix build of kernels without ether By throwing out if_enable_vlan_mtu and if_disable_vlan_mtu that created a unnecessary dependency from if.c to if_ethersubr.c. PR kern/52790 Rename IFNET_LOCK to IFNET_GLOBAL_LOCK IFNET_LOCK will be used in another lock, if_ioctl_lock (might be renamed then). Wrap if_ioctl_lock with IFNET_* macros (NFC) Also if_ioctl_lock perhaps needs to be renamed to something because it's now not just for ioctl... Reorder some destruction routines in if_detach - Destroy if_ioctl_lock at the end of the if_detach because it's used in various destruction routines - Move psref_target_destroy after pr_purgeif because we want to use psref in pr_purgeif (otherwise destruction procedures can be tricky) Ensure to call if_mcast_op with holding IFNET_LOCK Note that CARP doesn't deal with IFNET_LOCK yet. Remove IFNET_GLOBAL_LOCK where it's unnecessary because IFNET_LOCK is held Describe which lock is used to protect each member variable of struct ifnet Requested by skrll@@ Write a guideline for converting an interface to IFEF_MPSAFE Requested by skrll@@ Note that IFNET_LOCK must not be held in softint Don't set IFEF_MPSAFE unless NET_MPSAFE at this point Because recent investigations show that interfaces with IFEF_MPSAFE need to follow additional restrictions to work with the flag safely. We should enable it on an interface by default only if the interface surely satisfies the restrictions, which are described in if.h. Note that enabling IFEF_MPSAFE solely gains a few benefit on performance because the network stack is still serialized by the big kernel locks by default. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.4 2017/12/10 10:10:25 snj Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.4 2017/12/10 10:10:25 snj Exp $"); d304 1 a304 1 sc->sc_sppp.pp_if.if_extflags = IFEF_MPSAFE; d478 3 a480 1 SOFTNET_LOCK_UNLESS_NET_MPSAFE(); d503 3 a505 2 SOFTNET_UNLOCK_UNLESS_NET_MPSAFE(); @ 1.125.6.6 log @Pull up following revision(s) (requested by knakahara in ticket #613): sys/net/if_pppoe.c: revision 1.130,1.134 sys/net/if_spppsubr.c: revision 1.172,1.175,1.179 sys/net/if_gif.c: revision 1.138,1.139 Mark callouts of pppoe(4) CALLOUT_MPSAFE. Suggested by ozaki-r@@n.o. fix non-diagnostic compilation Fix spl leak. ifconfig gif0 create ifconfig gif0 destroy WARNING: SPL NOT LOWERED ON ... Fix breaking character limit. Pointed out by ozaki-r@@n.o, thanks. Use m_freem instead of m_free. Otherwise we're leaking the next mbufs in the chain. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.5 2018/01/02 10:20:33 snj Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.5 2018/01/02 10:20:33 snj Exp $"); d318 1 a318 1 callout_init(&sc->sc_timeout, CALLOUT_MPSAFE); d1798 1 a1798 1 m_freem(m); d1890 1 a1890 1 m_freem(m); d1896 1 a1896 1 m_freem(m); @ 1.125.6.7 log @Pull up following revision(s) (requested by knakahara in ticket #779): sys/net/if_pppoe.c: revision 1.135,1.136 net.pppoe.term_unknown can be written safely now. Fix sending PADT to unexpected hosts when net.pppoe.term_unknown is enabled. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.6 2018/03/08 13:22:25 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.6 2018/03/08 13:22:25 martin Exp $"); a65 1 #include a238 1 static int pppoe_term_unknown_pps = 1; a953 10 static bool pppoe_is_my_frame(uint8_t *dhost, struct ifnet *rcvif) { if (memcmp(CLLADDR(rcvif->if_sadl), dhost, ETHER_ADDR_LEN) == 0) return true; return false; } a962 2 uint8_t dhost[ETHER_ADDR_LEN]; bool term_unknown = pppoe_term_unknown; d966 1 a966 1 if (term_unknown) { a968 3 memcpy(dhost, mtod(m, struct ether_header*)->ether_dhost, ETHER_ADDR_LEN); } d999 4 a1002 15 if (term_unknown) { static struct timeval lasttime = {0, 0}; static int curpps = 0; /* * avoid to send wrong PADT which is response from * session stage pakcets for other hosts when parent * ethernet is promiscuous mode. */ if (pppoe_is_my_frame(dhost, rcvif) && ppsratecheck(&lasttime, &curpps, pppoe_term_unknown_pps)) { printf("pppoe: input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); } d1944 1 a1944 1 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, @ 1.125.6.8 log @Pull up following revision(s) (requested by ozaki-r in ticket #843): sys/dev/pci/ixgbe/ixv.c: revision 1.101 sys/net/if_bridge.c: revision 1.156 sys/net/if_pppoe.c: revision 1.138 sys/dev/pci/if_wm.c: revision 1.580 sys/dev/pci/ixgbe/ixgbe.c: revision 1.156 sys/net/if_gif.c: revision 1.142 Ensure to call if_register after interface initializations finish @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.7 2018/04/18 14:16:57 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.7 2018/04/18 14:16:57 martin Exp $"); d339 1 a344 1 if_register(&sc->sc_sppp.pp_if); @ 1.125.6.9 log @Pull up following revision(s) (requested by yamaguchi in ticket #890): sys/net/if_pppoe.c: revision 1.137 sys/net/if_pppoe.c: revision 1.139 sys/net/if_pppoe.c: revision 1.140 Drop early if there's no PPPoE interface. Otherwise it is easy for someone to flood dmesg over the local subnet. Fix not to use PPPOE_UNLOCK before acccess to pppoe_softc to avoid a race condition According to the locking order of pppoe(4), the access to pppoe_softc has to follow 5 steps as below. 1. aquire pppoe_softc_list_lock 2. aquire pppoe_softc lock 3. release pppoe_softc_list_lock 4. access to pppoe_softc 5. release pppoe_softc lock However, pppoe_dispatch_disc_pkt() releases the lock of pppoe_softc temporarily, and then re-aquires it before step 4 of the adove. So, it is possible for other contexts to destroy a pppoe_softc in the interim. To fix this condition, avoid PPPOE_UNLOCK with the problem. ok by knakahara@@n.o Fix to aquire pppoe_softc_list_lock before read and write the list ok by knakahara@@n.o @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.8 2018/06/07 17:42:25 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.8 2018/06/07 17:42:25 martin Exp $"); d280 1 a280 3 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); a281 1 } a340 1 rw_enter(&pppoe_softc_list_lock, RW_READER); a343 2 rw_exit(&pppoe_softc_list_lock); d427 1 a427 3 rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); a428 1 } d430 1 a430 2 if (len != sizeof sc) { rw_exit(&pppoe_softc_list_lock); a431 1 } d434 1 d521 1 d524 1 a529 2 struct ifnet *rcvif; struct psref psref; d548 1 d551 1 d604 2 a605 1 if (len > 0) { d619 1 a619 1 printf("pppoe: connected to %s\n", error); d623 3 a625 9 case PPPOE_TAG_HUNIQUE: if (hunique == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; err_msg = "TAG HUNIQUE ERROR"; break; } d627 23 a649 2 hunique = mtod(n, uint8_t *) + noff; hunique_len = len; d652 1 d725 2 a727 5 if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); goto done; } d771 3 d793 2 a794 6 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { printf("pppoe: received PADR" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); d823 1 a828 13 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); d831 2 a832 6 rw_enter(&pppoe_softc_list_lock, RW_READER); if (!LIST_EMPTY(&pppoe_softc_list)) { printf("pppoe: received PADO" " but could not find request for it\n"); } rw_exit(&pppoe_softc_list_lock); d836 2 d892 1 a892 2 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) d895 1 a895 11 if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); if (sc == NULL) goto done; d907 4 a910 1 case PPPOE_CODE_PADT: d912 4 a915 6 if (__predict_false(rcvif == NULL)) goto done; sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); a916 1 d923 1 a924 13 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto done; if (hunique != NULL) { sc = pppoe_find_softc_by_hunique(hunique, hunique_len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); d926 1 a946 1 KASSERT(m->m_flags & M_PKTHDR); d948 1 a948 4 /* * Avoid error messages if there is not a single PPPoE instance. */ rw_enter(&pppoe_softc_list_lock, RW_READER); d950 1 a950 1 rw_exit(&pppoe_softc_list_lock); d952 1 a952 2 } else { rw_exit(&pppoe_softc_list_lock); a953 1 } a979 10 /* * Avoid error messages if there is not a single PPPoE instance. */ rw_enter(&pppoe_softc_list_lock, RW_READER); if (LIST_EMPTY(&pppoe_softc_list)) { rw_exit(&pppoe_softc_list_lock); goto drop; } rw_exit(&pppoe_softc_list_lock); @ 1.125.6.10 log @Pull up following revision(s) (requested by mlelstv in ticket #1505): sys/net/if_pppoe.c: revision 1.149 safely extract character sequences from packet for printing. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.9 2018/07/12 15:11:56 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.9 2018/07/12 15:11:56 martin Exp $"); a526 1 size_t dlen; d613 1 a613 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, M_NOWAIT); d625 1 a625 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); d686 1 a686 2 dlen = 4 * len + 1; error = malloc(dlen, M_TEMP, d693 2 a694 3 strnvisx(error, dlen, mtod(n, char*) + noff, len, VIS_SAFE | VIS_OCTAL); @ 1.125.6.11 log @Pull up the following revisions(s) (requested by martin in ticket #1740): sys/net/if_pppoe.c: revision 1.179 pppoe(4): fix CVE-2022-29867 - discovery phase local network mbuf corruption. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125.6.10 2020/02/13 19:37:39 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125.6.10 2020/02/13 19:37:39 martin Exp $"); a873 4 } else if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; sc->sc_ac_cookie_len = 0; a888 4 } else if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; sc->sc_relay_sid_len = 0; a1315 3 if (len + sizeof(struct ether_header) > MCLBYTES) return NULL; @ 1.124 log @Not sure what we are trying to achieve here, but there are two issues; error can be printed while it is not initialized, and if m_pulldown fails m is freed and reused. Quickly reviewed by christos and martin @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.123 2016/12/27 01:31:06 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.123 2016/12/27 01:31:06 christos Exp $"); d58 1 d644 2 a645 1 int s; d658 6 a663 4 rcvif = m_get_rcvif(m, &s); sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, len, rcvif, RW_READER); m_put_rcvif(rcvif, &s); d793 3 d804 9 a812 4 sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, m_get_rcvif_NOMPSAFE(m), RW_WRITER); d850 1 d951 1 a951 1 int s; d953 6 a958 3 rcvif = m_get_rcvif(m, &s); sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); m_put_rcvif(rcvif, &s); @ 1.123 log @fix merge conflict. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.122 2016/12/26 23:21:49 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.122 2016/12/26 23:21:49 christos Exp $"); d624 8 a631 11 error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strlcpy(error, mtod(n, char*) + noff, len); } printf("%s: connected to %s\n", devname, error); d633 1 d635 4 d709 2 a710 1 error = malloc(len+1, M_TEMP, M_NOWAIT); d713 5 a717 3 if (n && error) { strlcpy(error, mtod(n, char *) + noff, len); @ 1.123.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $"); a57 1 #include d624 11 a634 8 error = malloc(len + 1, M_TEMP, M_NOWAIT); if (error == NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; a635 1 goto done; a636 4 strlcpy(error, mtod(n, char*) + noff, len + 1); printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); d641 1 a641 2 struct psref psref; d654 4 a657 6 rcvif = m_get_rcvif_psref(m, &psref); if (rcvif != NULL) { sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); d707 1 a707 2 error = malloc(len + 1, M_TEMP, M_NOWAIT|M_ZERO); d710 3 a712 5 if (!n) { m = NULL; } else if (error) { strlcpy(error, mtod(n, char *) + noff, len + 1); a783 3 { struct ifnet *rcvif; struct psref psref; d792 4 a795 9 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); a832 1 } d933 1 a933 1 struct psref psref; d935 3 a937 6 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); @ 1.122 log @pfil(9) improvements to handle address changes: Add: PFIL_IFADDR call on interface reconfig (mbuf is ioctl #) PFIL_IFNET call on interface attach/detach (mbuf is PFIL_IFNET_*) from rmind@@ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.121 2016/12/16 08:47:36 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.121 2016/12/16 08:47:36 knakahara Exp $"); d238 1 a238 1 static void pppoe_ifattach_hook(void *, u_long, void *); d1901 2 a1902 2 static int pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) d1904 1 d1908 2 a1909 2 if (mp != (struct mbuf **)PFIL_IFNET_DETACH) return 0; a1933 2 return 0; @ 1.121 log @fix unlock and splx inversion. Currently, this doesn't cause problem because either one is used. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.120 2016/12/13 00:35:11 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.120 2016/12/13 00:35:11 knakahara Exp $"); d238 1 a238 1 static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int); d342 1 a342 1 pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); d367 1 a367 1 pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); @ 1.120 log @MP-safe pppoe(4). Nearly all parts is implemented by Shoichi YAMAGUCHI, thanks. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.119 2016/11/18 08:13:02 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.119 2016/11/18 08:13:02 knakahara Exp $"); d1398 1 a1400 1 RELEASE_SPLNET(); @ 1.119 log @if_register() must be called after ifp->if_dl initialized. There may be similar problems. I will fix step by step... @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $"); d38 1 d56 2 d70 4 d135 26 d167 1 d184 2 d212 3 d233 3 a235 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *); static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *); d241 1 d270 1 d273 2 a274 2 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); d310 3 d328 3 d344 5 d350 1 d359 5 a363 1 callout_stop(&sc->sc_timeout); d365 1 d369 4 d385 7 d404 1 a404 1 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif) d406 1 a406 1 struct pppoe_softc *sc; d410 1 a410 1 d412 3 a414 1 if (sc->sc_state == PPPOE_STATE_SESSION d417 3 a419 1 return sc; d421 2 a422 1 return NULL; d428 2 a429 1 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif) d440 8 a447 2 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) if (sc == t) break; d456 9 d469 1 d475 1 a484 1 mutex_enter(softnet_lock); a485 1 mutex_exit(softnet_lock); d495 4 d520 3 d532 2 a533 1 const char *err_msg, *devname; d549 3 a551 1 devname = "pppoe"; /* as long as we don't know which instance */ d656 1 a656 1 len, rcvif); d658 5 a662 2 if (sc != NULL) devname = sc->sc_sppp.pp_if.if_xname; d736 1 d738 3 a740 1 if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) d742 3 a744 1 if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) d746 4 a749 1 if (sc->sc_state == PPPOE_STATE_INITIAL) d751 2 d754 2 d760 2 d767 3 a769 1 if (sc->sc_hunique == NULL) d771 1 d778 2 d794 2 a795 1 m_get_rcvif_NOMPSAFE(m)); d802 3 a804 1 if (sc->sc_state != PPPOE_STATE_PADO_SENT) { d807 1 d810 1 d816 3 a818 1 if (sc->sc_hunique == NULL) d820 1 d826 4 d831 1 d844 5 a848 1 if (sc->sc_state != PPPOE_STATE_PADI_SENT) { d851 1 d854 2 d865 2 d881 2 d901 3 d908 10 d924 4 d929 1 d936 1 a936 1 sc = pppoe_find_softc_by_session(session, rcvif); d940 2 d943 2 d948 8 d957 1 a957 2 sc? sc->sc_sppp.pp_if.if_xname : "pppoe", ph->code, session); d1022 1 a1022 1 sc = pppoe_find_softc_by_session(session, rcvif); d1032 1 d1056 1 d1080 3 d1126 1 d1130 1 d1140 1 d1158 2 d1163 1 d1181 2 d1186 1 d1195 1 d1199 1 d1206 2 d1212 2 d1222 3 d1234 1 d1236 11 a1246 1 return sppp_ioctl(ifp, cmd, data); d1294 3 d1361 1 a1361 1 int x, retry_wait, err; d1363 1 d1369 2 d1390 1 a1390 1 x = splnet(); d1398 3 a1400 1 splx(x); d1413 1 a1413 1 splx(x); d1417 1 a1417 1 x = splnet(); d1434 3 a1436 1 splx(x); d1449 1 a1449 1 splx(x); d1455 2 d1459 2 d1467 5 a1471 1 int x, err; d1481 1 a1481 1 x = splnet(); d1490 1 a1490 1 splx(x); d1498 5 a1502 1 int err, x; d1504 1 a1504 1 x = splnet(); d1517 2 d1539 3 d1543 1 d1545 1 d1547 3 a1549 1 splx(x); d1551 1 d1559 3 d1565 4 d1571 1 d1573 6 d1593 3 d1690 3 d1725 3 d1767 7 a1773 1 if (sc->sc_state != PPPOE_STATE_INITIAL) d1775 3 d1792 3 d1801 8 a1808 1 if (sc->sc_state < PPPOE_STATE_SESSION) d1810 1 d1817 2 d1820 3 d1850 1 d1855 1 d1857 2 d1862 38 d1905 1 a1905 1 int s; d1910 2 a1911 1 s = splnet(); d1913 3 a1915 1 if (sc->sc_eth_if != ifp) d1917 2 d1924 1 d1926 1 d1928 2 d1931 2 a1932 1 splx(s); d1940 3 d1951 4 d1957 1 d1959 6 @ 1.118 log @Fix race condition on ifqueue used by traditional netisr If a underlying network device driver supports MSI/MSI-X, RX interrupts can be delivered to arbitrary CPUs. This means that Layer 2 subroutines such as ether_input (softint) and subsequent Layer 3 subroutines (softint) which are called via traditional netisr can be dispatched on an arbitrary CPU. Layer 2 subroutines now run without any locks (expected) and so a Layer 2 subroutine and a Layer 3 subroutine can run in parallel. There is a shared data between a Layer 2 routine and a Layer 3 routine, that is ifqueue and IF_ENQUEUE (from L2) and IF_DEQUEUE (from L3) on it are racy now. To fix the race condition, use ifqueue#ifq_lock to protect ifqueue instead of splnet that is meaningless now. The same race condition exists in route_intr. Fix it as well. Reviewed by knakahara@@ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.117 2016/08/11 15:16:07 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.117 2016/08/11 15:16:07 christos Exp $"); d287 2 a288 1 if_attach(&sc->sc_sppp.pp_if); d290 1 @ 1.117 log @kill unknown sessions ifdef, link set for sysctl. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.116 2016/08/08 07:23:27 roy Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.116 2016/08/08 07:23:27 roy Exp $"); d234 3 d400 1 a400 1 int s, disc_done, data_done; d406 1 a406 1 s = splnet(); d408 1 a408 1 splx(s); d415 1 a415 1 s = splnet(); d417 1 a417 1 splx(s); d1637 1 d1640 1 d1644 1 @ 1.116 log @Fix compile without modules. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.115 2016/08/08 02:50:05 pgoyette Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.115 2016/08/08 02:50:05 pgoyette Exp $"); a66 3 #undef PPPOE_DEBUG /* XXX - remove this or make it an option */ /* #define PPPOE_DEBUG 1 */ a204 1 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS a205 1 #endif a206 1 #ifdef _MODULE d208 1 a208 3 #endif SYSCTL_SETUP_PROTO(sysctl_net_pppoe_setup); a232 1 #ifdef _MODULE a233 1 #endif a247 1 #ifdef _MODULE a248 1 #endif a805 1 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS a806 1 #endif d810 3 a812 3 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); #endif a842 1 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS d844 1 a844 1 printf("pppoe: input for unknown session 0x%x, " a847 1 #endif d1658 2 a1659 1 SYSCTL_SETUP(sysctl_net_pppoe_setup, "sysctl net.pppoe subtree setup") a1672 1 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS a1678 1 #endif @ 1.115 log @Don't try to set-up our sysctl sub-tree if we're built-in - this will happen automatically (via "registration" of the setup function in a link-set), and if we're not a module, the SYSCTL_SETUP_PROTO() will not have declared a function prototype! @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.114 2016/08/07 17:38:34 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.114 2016/08/07 17:38:34 christos Exp $"); d258 1 d260 1 @ 1.114 log @modularize some more drivers and merge the module glue @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.113 2016/08/07 01:59:43 pgoyette Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.113 2016/08/07 01:59:43 pgoyette Exp $"); d241 1 d243 1 @ 1.113 log @For modular configurations, always build with PPPOE_TERM_UNKNOWN_SESSIONS defined, and provide a sysctl variable for enabling/disabling the option. Update man page accordingly. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.112 2016/08/06 23:46:30 pgoyette Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.112 2016/08/06 23:46:30 pgoyette Exp $"); d227 2 a228 2 * Nothing to do here - all initialization happens as part * of module init. d241 1 d247 4 d252 6 a257 2 softint_disestablish(pppoe_softintr); if_clone_detach(&pppoe_cloner); d259 1 a259 1 return 0; a1669 65 /* * Module glue */ MODULE(MODULE_CLASS_DRIVER, if_pppoe, "sppp_subr"); #ifdef _MODULE CFDRIVER_DECL(pppoe, DV_IFNET, NULL); #endif static int if_pppoe_modcmd(modcmd_t cmd, void *arg) { int error = 0; switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE error = config_cfdriver_attach(&pppoe_cd); if (error) { aprint_error("%s: unable to register cfdriver for" "%s, error %d\n", __func__, pppoe_cd.cd_name, error); break; } #endif /* Init the cloner etc. */ pppoeinit(); #ifdef _MODULE /* Create our sysctl subtree */ sysctl_net_pppoe_setup(&pppoe_sysctl_clog); #endif break; case MODULE_CMD_FINI: /* * Make sure it's ok to detach - no units left, and * line discipline is removed */ if (!LIST_EMPTY(&pppoe_softc_list)) { error = EBUSY; break; } if ((error = pppoedetach()) != 0) break; #ifdef _MODULE /* Remove device from autoconf database */ if ((error = config_cfdriver_detach(&pppoe_cd)) != 0) { aprint_error("%s: failed to detach %s cfdriver, error " "%d\n", __func__, pppoe_cd.cd_name, error); break; } /* Remove our sysctl sub-tree */ sysctl_teardown(&pppoe_sysctl_clog); #endif break; case MODULE_CMD_STAT: case MODULE_CMD_AUTOUNLOAD: default: error = ENOTTY; } return error; } d1693 7 @ 1.112 log @Modularize the pppoe driver @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.111 2016/07/07 06:55:43 msaitoh Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.111 2016/07/07 06:55:43 msaitoh Exp $"); d54 1 d208 10 d845 5 a849 3 printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); d1688 5 d1713 2 d1716 1 d1726 23 @ 1.111 log @KNF. Remove extra spaces. No functional change. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.110 2016/06/28 02:02:56 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.110 2016/06/28 02:02:56 ozaki-r Exp $"); d35 1 a36 2 #ifdef _KERNEL_OPT d52 2 d214 11 d233 10 d1647 58 @ 1.111.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $ */ d33 3 a35 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $"); a217 22 sysctl_net_pppoe_setup(&pppoe_sysctl_clog); IFQ_LOCK_INIT(&ppoediscinq); IFQ_LOCK_INIT(&ppoeinq); } static int pppoedetach(void) { int error = 0; if (!LIST_EMPTY(&pppoe_softc_list)) error = EBUSY; if (error == 0) { if_clone_detach(&pppoe_cloner); softint_disestablish(pppoe_softintr); /* Remove our sysctl sub-tree */ sysctl_teardown(&pppoe_sysctl_clog); } return error; d363 1 a363 1 int disc_done, data_done; d369 1 a369 1 IFQ_LOCK(&ppoediscinq); d371 1 a371 1 IFQ_UNLOCK(&ppoediscinq); d378 1 a378 1 IFQ_LOCK(&ppoeinq); d380 1 a380 1 IFQ_UNLOCK(&ppoeinq); a1601 1 IFQ_LOCK(inq); a1603 1 IFQ_UNLOCK(inq); a1606 1 IFQ_UNLOCK(inq); @ 1.111.2.2 log @Sync with HEAD. (Note that most of these changes are simply $NetBSD$ tag issues.) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.123 2016/12/27 01:31:06 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.123 2016/12/27 01:31:06 christos Exp $"); a36 1 #include "opt_net_mpsafe.h" a50 5 #include #include #include #include #include d63 2 a64 3 #ifdef NET_MPSAFE #define PPPOE_MPSAFE 1 #endif a126 26 #define PPPOE_SESSION_LOCK(_sc, _op) rw_enter(&(_sc)->sc_session_lock, (_op)) #define PPPOE_SESSION_UNLOCK(_sc) rw_exit(&(_sc)->sc_session_lock) #define PPPOE_SESSION_LOCKED(_sc) rw_lock_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_WLOCKED(_sc) rw_write_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_RLOCKED(_sc) rw_read_held(&(_sc)->sc_session_lock) #define PPPOE_PARAM_LOCK(_sc) if ((_sc)->sc_lock) \ mutex_enter((_sc)->sc_lock) #define PPPOE_PARAM_UNLOCK(_sc) if ((_sc)->sc_lock) \ mutex_exit((_sc)->sc_lock) #define PPPOE_PARAM_LOCKED(_sc) (!(_sc)->sc_lock || \ mutex_owned((_sc)->sc_lock)) #ifdef PPPOE_MPSAFE #define DECLARE_SPLNET_VARIABLE #define ACQUIRE_SPLNET() do { } while (0) #define RELEASE_SPLNET() do { } while (0) #else #define DECLARE_SPLNET_VARIABLE int __s #define ACQUIRE_SPLNET() do { \ __s = splnet(); \ } while (0) #define RELEASE_SPLNET() do { \ splx(__s); \ } while (0) #endif a132 1 bool sc_state_updating; /* state update in other components */ a148 2 krwlock_t sc_session_lock; /* lock of sc_state, sc_session, and sc_eth_if */ kmutex_t *sc_lock; /* lock of other parameters */ a174 3 #ifdef PPPOE_MPSAFE static int pppoe_transmit(struct ifnet *, struct mbuf *); #endif d193 2 a194 3 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *, krw_t); d197 1 a197 1 static void pppoe_ifattach_hook(void *, unsigned long, void *); a199 1 static krwlock_t pppoe_softc_list_lock; a211 1 rw_init(&pppoe_softc_list_lock); d214 2 a215 2 pppoe_softintr = softint_establish(SOFTINT_MPSAFE|SOFTINT_NET, pppoe_softintr_handler, NULL); a250 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_extflags = IFEF_OUTPUT_MPSAFE; #endif a265 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_transmit = pppoe_transmit; #endif d270 1 a270 2 if_initialize(&sc->sc_sppp.pp_if); sc->sc_sppp.pp_if.if_percpuq = if_percpuq_create(&sc->sc_sppp.pp_if); a271 1 if_register(&sc->sc_sppp.pp_if); d275 1 a275 1 pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a276 5 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); rw_init(&sc->sc_session_lock); rw_enter(&pppoe_softc_list_lock, RW_WRITER); a277 1 rw_exit(&pppoe_softc_list_lock); d286 1 a286 5 rw_enter(&pppoe_softc_list_lock, RW_WRITER); PPPOE_PARAM_LOCK(sc); callout_halt(&sc->sc_timeout, NULL); a287 1 d289 1 a289 1 pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a290 4 rw_exit(&pppoe_softc_list_lock); PPPOE_SESSION_LOCK(sc, RW_WRITER); a302 7 PPPOE_PARAM_UNLOCK(sc); if (sc->sc_lock) mutex_obj_free(sc->sc_lock); PPPOE_SESSION_UNLOCK(sc); rw_destroy(&sc->sc_session_lock); d315 1 a315 1 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif, krw_t lock) d317 1 a317 1 struct pppoe_softc *sc = NULL; d321 1 a321 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d323 1 a323 3 PPPOE_SESSION_LOCK(sc, lock); if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_SESSION d326 1 a326 3 break; PPPOE_SESSION_UNLOCK(sc); d328 1 a328 2 rw_exit(&pppoe_softc_list_lock); return sc; d334 1 a334 2 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif, krw_t lock) d345 2 a346 8 rw_enter(&pppoe_softc_list_lock, RW_READER); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc == t) { PPPOE_SESSION_LOCK(sc, lock); break; } } rw_exit(&pppoe_softc_list_lock); a354 9 if (sc->sc_state_updating) { #ifdef PPPOE_DEBUG printf("%s: host unique tag found, but its state is updating\n", sc->sc_sppp.pp_if.if_xname); #endif PPPOE_SESSION_UNLOCK(sc); return NULL; } a358 1 PPPOE_SESSION_UNLOCK(sc); a363 1 PPPOE_SESSION_UNLOCK(sc); d373 1 d375 1 a384 4 #ifndef PPPOE_MPSAFE mutex_enter(softnet_lock); #endif a405 3 #ifndef PPPOE_MPSAFE mutex_exit(softnet_lock); #endif d415 1 a415 2 const char *err_msg; char devname[IF_NAMESIZE]; d431 1 a431 3 /* as long as we don't know which instance */ strlcpy(devname, "pppoe", sizeof(devname)); d536 1 a536 1 len, rcvif, RW_READER); d538 2 a539 5 if (sc != NULL) { strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_SESSION_UNLOCK(sc); } a612 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d614 1 a614 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { PPPOE_SESSION_UNLOCK(sc); d616 1 a616 3 } if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { PPPOE_SESSION_UNLOCK(sc); d618 1 a618 4 } if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_INITIAL) a619 2 PPPOE_SESSION_UNLOCK(sc); a620 2 rw_exit(&pppoe_softc_list_lock); a624 2 PPPOE_PARAM_LOCK(sc); d630 1 a630 3 if (sc->sc_hunique == NULL) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a631 1 } a637 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d652 1 a652 2 m_get_rcvif_NOMPSAFE(m), RW_WRITER); d659 1 a659 3 if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADO_SENT) { a661 1 PPPOE_SESSION_UNLOCK(sc); a663 1 PPPOE_PARAM_LOCK(sc); d669 1 a669 3 if (sc->sc_hunique == NULL) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a670 1 } a675 4 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); sppp_lock_enter(&sc->sc_sppp); a676 1 sppp_lock_exit(&sc->sc_sppp); d689 1 a689 5 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADI_SENT) { a691 1 PPPOE_SESSION_UNLOCK(sc); a693 2 PPPOE_PARAM_LOCK(sc); a702 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a716 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a734 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a738 10 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); if (sc->sc_state_updating) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); goto done; } a744 4 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); sppp_lock_enter(&sc->sc_sppp); a745 1 sppp_lock_exit(&sc->sc_sppp); d752 1 a752 1 sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); a755 2 PPPOE_PARAM_LOCK(sc); a756 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a759 8 if (sc != NULL) { PPPOE_SESSION_LOCK(sc, RW_READER); strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_SESSION_UNLOCK(sc); } else strlcpy(devname, "pppoe", sizeof(devname)); d761 2 a762 1 devname, ph->code, session); d829 1 a829 1 sc = pppoe_find_softc_by_session(session, rcvif, RW_READER); a838 1 a861 1 PPPOE_SESSION_UNLOCK(sc); a884 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a927 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); a930 1 PPPOE_SESSION_UNLOCK(sc); a939 1 PPPOE_SESSION_UNLOCK(sc); a956 2 PPPOE_PARAM_LOCK(sc); a959 1 PPPOE_PARAM_UNLOCK(sc); a976 2 PPPOE_PARAM_LOCK(sc); a979 1 PPPOE_PARAM_UNLOCK(sc); a987 1 PPPOE_SESSION_LOCK(sc, RW_READER); a990 1 PPPOE_SESSION_UNLOCK(sc); a996 2 PPPOE_SESSION_LOCK(sc, RW_READER); PPPOE_PARAM_LOCK(sc); a1000 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1008 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); a1017 1 sc->sc_state_updating = 1; d1019 1 a1019 11 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); error = sppp_ioctl(ifp, cmd, data); PPPOE_SESSION_LOCK(sc, RW_WRITER); sc->sc_state_updating = 0; PPPOE_SESSION_UNLOCK(sc); return error; a1066 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1131 1 a1131 1 int retry_wait, err; a1132 1 DECLARE_SPLNET_VARIABLE; a1137 2 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); d1157 1 a1157 1 ACQUIRE_SPLNET(); d1165 1 a1165 3 RELEASE_SPLNET(); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1178 1 a1178 1 RELEASE_SPLNET(); d1182 1 a1182 1 ACQUIRE_SPLNET(); d1199 1 a1199 3 RELEASE_SPLNET(); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1212 1 a1212 1 RELEASE_SPLNET(); a1217 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1219 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1226 1 a1226 5 int err; DECLARE_SPLNET_VARIABLE; KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1236 1 a1236 1 ACQUIRE_SPLNET(); d1245 1 a1245 1 RELEASE_SPLNET(); d1253 1 a1253 2 int err; DECLARE_SPLNET_VARIABLE; d1255 1 a1255 4 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); ACQUIRE_SPLNET(); a1267 2 sc->sc_state_updating = 1; a1287 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1288 1 sppp_lock_enter(&sc->sc_sppp); a1289 1 sppp_lock_exit(&sc->sc_sppp); d1291 1 a1291 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; a1292 1 RELEASE_SPLNET(); a1299 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1302 4 sc->sc_state_updating = 1; PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1304 1 sppp_lock_enter(&sc->sc_sppp); a1305 6 sppp_lock_exit(&sc->sc_sppp); PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; a1319 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1413 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); /* required by pppoe_output(). */ KASSERT(PPPOE_PARAM_LOCKED(sc)); a1445 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1485 1 a1485 7 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); PPPOE_SESSION_LOCK(sc, RW_READER); if (sc->sc_state != PPPOE_STATE_INITIAL) { PPPOE_SESSION_UNLOCK(sc); a1486 3 } PPPOE_PARAM_LOCK(sc); a1500 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1507 1 a1507 8 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_SESSION_UNLOCK(sc); a1508 1 } a1514 2 PPPOE_PARAM_LOCK(sc); a1515 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1542 1 PPPOE_SESSION_LOCK(sc, RW_READER); a1546 1 PPPOE_PARAM_LOCK(sc); a1547 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1551 1 a1551 1 #ifdef PPPOE_MPSAFE d1553 1 a1553 1 pppoe_transmit(struct ifnet *ifp, struct mbuf *m) a1554 39 struct pppoe_softc *sc = (void *)ifp; uint8_t *p; size_t len; if (m == NULL) return EINVAL; /* are we ready to process data yet? */ PPPOE_SESSION_LOCK(sc, RW_READER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_SESSION_UNLOCK(sc); m_free(m); return ENOBUFS; } len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { PPPOE_SESSION_UNLOCK(sc); ifp->if_oerrors++; return ENETDOWN; } p = mtod(m, uint8_t *); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); bpf_mtap(&sc->sc_sppp.pp_if, m); PPPOE_PARAM_LOCK(sc); pppoe_output(sc, m); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); return 0; } #endif /* PPPOE_MPSAFE */ static void pppoe_ifattach_hook(void *arg, unsigned long cmd, void *arg2) { struct ifnet *ifp = arg2; d1556 1 a1556 1 DECLARE_SPLNET_VARIABLE; d1558 2 a1559 2 if (cmd != PFIL_IFNET_DETACH) return; d1561 1 a1561 2 ACQUIRE_SPLNET(); rw_enter(&pppoe_softc_list_lock, RW_READER); d1563 1 a1563 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_eth_if != ifp) { PPPOE_SESSION_UNLOCK(sc); a1564 2 } sppp_lock_enter(&sc->sc_sppp); a1569 1 sppp_lock_exit(&sc->sc_sppp); a1570 1 PPPOE_PARAM_LOCK(sc); a1571 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1573 3 a1575 2 rw_exit(&pppoe_softc_list_lock); RELEASE_SPLNET(); a1580 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1588 4 sc->sc_state_updating = 1; PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1590 1 sppp_lock_enter(&sc->sc_sppp); a1591 6 sppp_lock_exit(&sc->sc_sppp); PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; @ 1.111.2.3 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.125 2017/02/07 02:33:54 ozaki-r Exp $"); a56 1 #include d607 11 a617 8 error = malloc(len + 1, M_TEMP, M_NOWAIT); if (error == NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; a618 1 goto done; a619 4 strlcpy(error, mtod(n, char*) + noff, len + 1); printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); d624 1 a624 2 struct psref psref; d637 4 a640 6 rcvif = m_get_rcvif_psref(m, &psref); if (rcvif != NULL) { sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); d690 1 a690 2 error = malloc(len + 1, M_TEMP, M_NOWAIT|M_ZERO); d693 3 a695 5 if (!n) { m = NULL; } else if (error) { strlcpy(error, mtod(n, char *) + noff, len + 1); a766 3 { struct ifnet *rcvif; struct psref psref; d775 4 a778 9 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); a815 1 } d916 1 a916 1 struct psref psref; d918 3 a920 6 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); @ 1.110 log @Add missing NULL checks for m_get_rcvif_psref @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.109 2016/06/20 06:46:37 knakahara Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.109 2016/06/20 06:46:37 knakahara Exp $"); d216 2 a217 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); @ 1.109 log @apply if_output_lock() to L3 callers which call ifp->if_output() of L2(or L3 tunneling). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.108 2016/06/10 13:31:44 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.108 2016/06/10 13:31:44 ozaki-r Exp $"); d806 2 @ 1.108 log @Avoid storing a pointer of an interface in a mbuf Having a pointer of an interface in a mbuf isn't safe if we remove big kernel locks; an interface object (ifnet) can be destroyed anytime in any packet processing and accessing such object via a pointer is racy. Instead we have to get an object from the interface collection (ifindex2ifnet) via an interface index (if_index) that is stored to a mbuf instead of an pointer. The change provides two APIs: m_{get,put}_rcvif_psref that use psref(9) for sleep-able critical sections and m_{get,put}_rcvif that use pserialize(9) for other critical sections. The change also adds another API called m_get_rcvif_NOMPSAFE, that is NOT MP-safe and for transition moratorium, i.e., it is intended to be used for places where are not planned to be MP-ified soon. The change adds some overhead due to psref to performance sensitive paths, however the overhead is not serious, 2% down at worst. Proposed on tech-kern and tech-net. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.107 2016/06/10 13:27:16 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.107 2016/06/10 13:27:16 ozaki-r Exp $"); d883 1 a883 1 return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL); d1380 1 a1380 1 return outgoing_if->if_output(outgoing_if, m0, &dst, NULL); @ 1.107 log @Introduce m_set_rcvif and m_reset_rcvif The API is used to set (or reset) a received interface of a mbuf. They are counterpart of m_get_rcvif, which will come in another commit, hide internal of rcvif operation, and reduce the diff of the upcoming change. No functional change. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.106 2016/04/24 16:59:15 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.106 2016/04/24 16:59:15 christos Exp $"); d498 3 a500 1 case PPPOE_TAG_HUNIQUE: d513 1 d515 2 a516 1 len, m->m_pkthdr.rcvif); d520 1 d631 1 a631 1 m->m_pkthdr.rcvif); d726 7 a732 2 case PPPOE_CODE_PADT: sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); d737 1 d769 2 d805 2 a806 1 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); d811 1 a811 1 pppoe_send_padt(m->m_pkthdr.rcvif, session, shost); d813 1 d816 1 @ 1.106 log @CID 980057, 980058, use strlcpy() @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.105 2016/04/15 01:31:29 ozaki-r Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.105 2016/04/15 01:31:29 ozaki-r Exp $"); d828 1 a828 1 m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; d1016 1 a1016 1 m->m_pkthdr.rcvif = NULL; @ 1.105 log @Hide PPPoE variables from if_ethersubr.c This improves modularity of if_pppoe. From s-yamaguchi@@IIJ @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.104 2015/08/24 22:21:26 pooka Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.104 2015/08/24 22:21:26 pooka Exp $"); d488 1 a488 1 strncpy(error, a490 1 error[len] = '\0'; d562 1 a562 1 strncpy(error, a563 1 error[len] = '\0'; d950 2 a951 1 strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ); @ 1.104 log @sprinkle _KERNEL_OPT @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.103 2015/08/20 14:40:19 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.103 2015/08/20 14:40:19 christos Exp $"); d163 1 a163 1 static void pppoe_input(void); d167 1 d353 1 a353 1 pppoe_input(); d359 1 a359 1 pppoe_input(void) d1568 39 @ 1.103 log @include "ioconf.h" to get the 'void attach(int count);' prototype. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102 2014/10/18 08:33:29 snj Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102 2014/10/18 08:33:29 snj Exp $"); d36 2 d39 1 @ 1.102 log @src is too big these days to tolerate superfluous apostrophes. It's "its", people! @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.101 2013/09/13 21:09:40 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.101 2013/09/13 21:09:40 martin Exp $"); d60 1 a165 1 void pppoeattach(int); @ 1.102.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.104 2015/08/24 22:21:26 pooka Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.104 2015/08/24 22:21:26 pooka Exp $"); a35 2 #ifdef _KERNEL_OPT a36 1 #endif a59 1 #include "ioconf.h" d165 1 @ 1.102.2.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.1 2015/09/22 12:06:10 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.1 2015/09/22 12:06:10 skrll Exp $"); d163 1 a163 1 static void pppoeintr(void); a166 1 static void pppoe_enqueue(struct ifqueue *, struct mbuf *); d352 1 a352 1 pppoeintr(); d358 1 a358 1 pppoeintr(void) a1566 39 static void pppoe_enqueue(struct ifqueue *inq, struct mbuf *m) { if (m->m_flags & M_PROMISC) { m_free(m); return; } #ifndef PPPOE_SERVER if (m->m_flags & (M_MCAST | M_BCAST)) { m_free(m); return; } #endif if (IF_QFULL(inq)) { IF_DROP(inq); m_freem(m); } else { IF_ENQUEUE(inq, m); softint_schedule(pppoe_softintr); } return; } void pppoe_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoeinq, m); return; } void pppoedisc_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoediscinq, m); return; } @ 1.102.2.3 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.2 2016/04/22 15:44:17 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.2 2016/04/22 15:44:17 skrll Exp $"); d488 1 a488 1 strlcpy(error, d491 1 d563 1 a563 1 strlcpy(error, d565 1 d952 1 a952 2 strlcpy(parms->ifname, sc->sc_eth_if->if_xname, sizeof(parms->ifname)); @ 1.102.2.4 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.3 2016/05/29 08:44:38 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.3 2016/05/29 08:44:38 skrll Exp $"); d216 1 a216 2 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); d498 1 a498 3 case PPPOE_TAG_HUNIQUE: { struct ifnet *rcvif; int s; a510 1 rcvif = m_get_rcvif(m, &s); d512 1 a512 2 len, rcvif); m_put_rcvif(rcvif, &s); a515 1 } d626 1 a626 1 m_get_rcvif_NOMPSAFE(m)); d721 2 a722 7 case PPPOE_CODE_PADT: { struct ifnet *rcvif; int s; rcvif = m_get_rcvif(m, &s); sc = pppoe_find_softc_by_session(session, rcvif); m_put_rcvif(rcvif, &s); a726 1 } a757 2 struct ifnet *rcvif; struct psref psref; d792 1 a792 4 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto drop; sc = pppoe_find_softc_by_session(session, rcvif); d797 1 a797 1 pppoe_send_padt(rcvif, session, shost); a798 1 m_put_rcvif_psref(rcvif, &psref); a800 1 m_put_rcvif_psref(rcvif, &psref); d828 1 a828 1 m_set_rcvif(m, &sc->sc_sppp.pp_if); d867 1 a867 1 return if_output_lock(sc->sc_eth_if, sc->sc_eth_if, m, &dst, NULL); d1016 1 a1016 1 m_reset_rcvif(m); d1364 1 a1364 1 return if_output_lock(outgoing_if, outgoing_if, m0, &dst, NULL); @ 1.102.2.5 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.4 2016/07/09 20:25:21 skrll Exp $ */ d33 3 a35 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.4 2016/07/09 20:25:21 skrll Exp $"); a37 1 #include "pppoe.h" a52 3 #include #include #include d65 3 a205 5 static bool pppoe_term_unknown = false; static struct sysctllog *pppoe_sysctl_clog; static void sysctl_net_pppoe_setup(struct sysctllog **); a212 11 /* * Nothing to do here, initialization is handled by the * module initialization code in pppoeinit() below). */ } static void pppoeinit(void) { a217 22 sysctl_net_pppoe_setup(&pppoe_sysctl_clog); IFQ_LOCK_INIT(&ppoediscinq); IFQ_LOCK_INIT(&ppoeinq); } static int pppoedetach(void) { int error = 0; if (!LIST_EMPTY(&pppoe_softc_list)) error = EBUSY; if (error == 0) { if_clone_detach(&pppoe_cloner); softint_disestablish(pppoe_softintr); /* Remove our sysctl sub-tree */ sysctl_teardown(&pppoe_sysctl_clog); } return error; d363 1 a363 1 int disc_done, data_done; d369 1 a369 1 IFQ_LOCK(&ppoediscinq); d371 1 a371 1 IFQ_UNLOCK(&ppoediscinq); d378 1 a378 1 IFQ_LOCK(&ppoeinq); d380 1 a380 1 IFQ_UNLOCK(&ppoeinq); d568 1 a568 1 strlcpy(error, d772 1 d774 1 d778 3 a780 3 if (pppoe_term_unknown) memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); d811 5 a815 5 if (pppoe_term_unknown) { printf("pppoe: input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); } a1601 1 IFQ_LOCK(inq); a1603 1 IFQ_UNLOCK(inq); a1606 1 IFQ_UNLOCK(inq); a1624 30 static void sysctl_net_pppoe_setup(struct sysctllog **clog) { const struct sysctlnode *node = NULL; sysctl_createv(clog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "pppoe", SYSCTL_DESCR("PPPOE protocol"), NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL); if (node == NULL) return; sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_BOOL, "term_unknown", SYSCTL_DESCR("Terminate unknown sessions"), NULL, 0, &pppoe_term_unknown, sizeof(pppoe_term_unknown), CTL_CREATE, CTL_EOL); } /* * Module infrastructure */ #include "if_module.h" IF_MODULE(MODULE_CLASS_DRIVER, pppoe, "sppp_subr") @ 1.102.2.6 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.5 2016/10/05 20:56:08 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.5 2016/10/05 20:56:08 skrll Exp $"); d287 1 a287 2 if_initialize(&sc->sc_sppp.pp_if); sc->sc_sppp.pp_if.if_percpuq = if_percpuq_create(&sc->sc_sppp.pp_if); a288 1 if_register(&sc->sc_sppp.pp_if); @ 1.102.2.7 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.6 2016/12/05 10:55:27 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.6 2016/12/05 10:55:27 skrll Exp $"); a37 1 #include "opt_net_mpsafe.h" a54 2 #include #include a66 4 #ifdef NET_MPSAFE #define PPPOE_MPSAFE 1 #endif a127 26 #define PPPOE_SESSION_LOCK(_sc, _op) rw_enter(&(_sc)->sc_session_lock, (_op)) #define PPPOE_SESSION_UNLOCK(_sc) rw_exit(&(_sc)->sc_session_lock) #define PPPOE_SESSION_LOCKED(_sc) rw_lock_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_WLOCKED(_sc) rw_write_held(&(_sc)->sc_session_lock) #define PPPOE_SESSION_RLOCKED(_sc) rw_read_held(&(_sc)->sc_session_lock) #define PPPOE_PARAM_LOCK(_sc) if ((_sc)->sc_lock) \ mutex_enter((_sc)->sc_lock) #define PPPOE_PARAM_UNLOCK(_sc) if ((_sc)->sc_lock) \ mutex_exit((_sc)->sc_lock) #define PPPOE_PARAM_LOCKED(_sc) (!(_sc)->sc_lock || \ mutex_owned((_sc)->sc_lock)) #ifdef PPPOE_MPSAFE #define DECLARE_SPLNET_VARIABLE #define ACQUIRE_SPLNET() do { } while (0) #define RELEASE_SPLNET() do { } while (0) #else #define DECLARE_SPLNET_VARIABLE int __s #define ACQUIRE_SPLNET() do { \ __s = splnet(); \ } while (0) #define RELEASE_SPLNET() do { \ splx(__s); \ } while (0) #endif a133 1 bool sc_state_updating; /* state update in other components */ a149 2 krwlock_t sc_session_lock; /* lock of sc_state, sc_session, and sc_eth_if */ kmutex_t *sc_lock; /* lock of other parameters */ a175 3 #ifdef PPPOE_MPSAFE static int pppoe_transmit(struct ifnet *, struct mbuf *); #endif d194 2 a195 3 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *, krw_t); d198 1 a198 1 static void pppoe_ifattach_hook(void *, unsigned long, void *); a200 1 static krwlock_t pppoe_softc_list_lock; a228 1 rw_init(&pppoe_softc_list_lock); d231 2 a232 2 pppoe_softintr = softint_establish(SOFTINT_MPSAFE|SOFTINT_NET, pppoe_softintr_handler, NULL); a267 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_extflags = IFEF_OUTPUT_MPSAFE; #endif a282 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_transmit = pppoe_transmit; #endif d294 1 a294 1 pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a295 5 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); rw_init(&sc->sc_session_lock); rw_enter(&pppoe_softc_list_lock, RW_WRITER); a296 1 rw_exit(&pppoe_softc_list_lock); d305 1 a305 5 rw_enter(&pppoe_softc_list_lock, RW_WRITER); PPPOE_PARAM_LOCK(sc); callout_halt(&sc->sc_timeout, NULL); a306 1 d308 1 a308 1 pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a309 4 rw_exit(&pppoe_softc_list_lock); PPPOE_SESSION_LOCK(sc, RW_WRITER); a321 7 PPPOE_PARAM_UNLOCK(sc); if (sc->sc_lock) mutex_obj_free(sc->sc_lock); PPPOE_SESSION_UNLOCK(sc); rw_destroy(&sc->sc_session_lock); d334 1 a334 1 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif, krw_t lock) d336 1 a336 1 struct pppoe_softc *sc = NULL; d340 1 a340 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d342 1 a342 3 PPPOE_SESSION_LOCK(sc, lock); if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_SESSION d345 1 a345 3 break; PPPOE_SESSION_UNLOCK(sc); d347 1 a347 2 rw_exit(&pppoe_softc_list_lock); return sc; d353 1 a353 2 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif, krw_t lock) d364 2 a365 8 rw_enter(&pppoe_softc_list_lock, RW_READER); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc == t) { PPPOE_SESSION_LOCK(sc, lock); break; } } rw_exit(&pppoe_softc_list_lock); a373 9 if (sc->sc_state_updating) { #ifdef PPPOE_DEBUG printf("%s: host unique tag found, but its state is updating\n", sc->sc_sppp.pp_if.if_xname); #endif PPPOE_SESSION_UNLOCK(sc); return NULL; } a377 1 PPPOE_SESSION_UNLOCK(sc); a382 1 PPPOE_SESSION_UNLOCK(sc); d392 1 d394 1 a403 4 #ifndef PPPOE_MPSAFE mutex_enter(softnet_lock); #endif a424 3 #ifndef PPPOE_MPSAFE mutex_exit(softnet_lock); #endif d434 1 a434 2 const char *err_msg; char devname[IF_NAMESIZE]; d450 1 a450 3 /* as long as we don't know which instance */ strlcpy(devname, "pppoe", sizeof(devname)); d523 11 a533 8 error = malloc(len + 1, M_TEMP, M_NOWAIT); if (error == NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; a534 1 goto done; a535 4 strlcpy(error, mtod(n, char*) + noff, len + 1); printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); d555 1 a555 1 len, rcvif, RW_READER); d557 2 a558 5 if (sc != NULL) { strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_SESSION_UNLOCK(sc); } d603 1 a603 2 error = malloc(len + 1, M_TEMP, M_NOWAIT|M_ZERO); d606 3 a608 5 if (!n) { m = NULL; } else if (error) { strlcpy(error, mtod(n, char *) + noff, len + 1); a631 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d633 1 a633 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { PPPOE_SESSION_UNLOCK(sc); d635 1 a635 3 } if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { PPPOE_SESSION_UNLOCK(sc); d637 1 a637 4 } if (!sc->sc_state_updating && sc->sc_state == PPPOE_STATE_INITIAL) a638 2 PPPOE_SESSION_UNLOCK(sc); a639 2 rw_exit(&pppoe_softc_list_lock); a643 2 PPPOE_PARAM_LOCK(sc); d649 1 a649 3 if (sc->sc_hunique == NULL) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a650 1 } a656 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d671 1 a671 2 m_get_rcvif_NOMPSAFE(m), RW_WRITER); d678 1 a678 3 if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADO_SENT) { a680 1 PPPOE_SESSION_UNLOCK(sc); a682 1 PPPOE_PARAM_LOCK(sc); d688 1 a688 3 if (sc->sc_hunique == NULL) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a689 1 } a694 4 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); sppp_lock_enter(&sc->sc_sppp); a695 1 sppp_lock_exit(&sc->sc_sppp); d708 1 a708 5 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_state_updating || sc->sc_state != PPPOE_STATE_PADI_SENT) { a710 1 PPPOE_SESSION_UNLOCK(sc); a712 2 PPPOE_PARAM_LOCK(sc); a721 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a735 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a753 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a757 10 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); if (sc->sc_state_updating) { PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); goto done; } a763 4 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); sppp_lock_enter(&sc->sc_sppp); a764 1 sppp_lock_exit(&sc->sc_sppp); d771 1 a771 1 sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); a774 2 PPPOE_PARAM_LOCK(sc); a775 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a778 8 if (sc != NULL) { PPPOE_SESSION_LOCK(sc, RW_READER); strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_SESSION_UNLOCK(sc); } else strlcpy(devname, "pppoe", sizeof(devname)); d780 2 a781 1 devname, ph->code, session); d846 1 a846 1 sc = pppoe_find_softc_by_session(session, rcvif, RW_READER); a855 1 a878 1 PPPOE_SESSION_UNLOCK(sc); a901 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a944 1 PPPOE_SESSION_LOCK(sc, RW_WRITER); a947 1 PPPOE_SESSION_UNLOCK(sc); a956 1 PPPOE_SESSION_UNLOCK(sc); a973 2 PPPOE_PARAM_LOCK(sc); a976 1 PPPOE_PARAM_UNLOCK(sc); a993 2 PPPOE_PARAM_LOCK(sc); a996 1 PPPOE_PARAM_UNLOCK(sc); a1004 1 PPPOE_SESSION_LOCK(sc, RW_READER); a1007 1 PPPOE_SESSION_UNLOCK(sc); a1013 2 PPPOE_SESSION_LOCK(sc, RW_READER); PPPOE_PARAM_LOCK(sc); a1017 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1025 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); a1034 1 sc->sc_state_updating = 1; d1036 1 a1036 11 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); error = sppp_ioctl(ifp, cmd, data); PPPOE_SESSION_LOCK(sc, RW_WRITER); sc->sc_state_updating = 0; PPPOE_SESSION_UNLOCK(sc); return error; a1083 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1148 1 a1148 1 int retry_wait, err; a1149 1 DECLARE_SPLNET_VARIABLE; a1154 2 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); d1174 1 a1174 1 ACQUIRE_SPLNET(); d1182 1 a1182 3 RELEASE_SPLNET(); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1195 1 a1195 1 RELEASE_SPLNET(); d1199 1 a1199 1 ACQUIRE_SPLNET(); d1216 1 a1216 3 RELEASE_SPLNET(); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1229 1 a1229 1 RELEASE_SPLNET(); a1234 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1236 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1243 1 a1243 5 int err; DECLARE_SPLNET_VARIABLE; KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1253 1 a1253 1 ACQUIRE_SPLNET(); d1262 1 a1262 1 RELEASE_SPLNET(); d1270 1 a1270 2 int err; DECLARE_SPLNET_VARIABLE; d1272 1 a1272 4 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); ACQUIRE_SPLNET(); a1284 2 sc->sc_state_updating = 1; a1304 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1305 1 sppp_lock_enter(&sc->sc_sppp); a1306 1 sppp_lock_exit(&sc->sc_sppp); d1308 1 a1308 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; a1309 1 RELEASE_SPLNET(); a1316 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1319 4 sc->sc_state_updating = 1; PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1321 1 sppp_lock_enter(&sc->sc_sppp); a1322 6 sppp_lock_exit(&sc->sc_sppp); PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; a1336 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1430 3 KASSERT(PPPOE_SESSION_LOCKED(sc)); /* required by pppoe_output(). */ KASSERT(PPPOE_PARAM_LOCKED(sc)); a1462 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); d1502 1 a1502 7 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); PPPOE_SESSION_LOCK(sc, RW_READER); if (sc->sc_state != PPPOE_STATE_INITIAL) { PPPOE_SESSION_UNLOCK(sc); a1503 3 } PPPOE_PARAM_LOCK(sc); a1517 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1524 1 a1524 8 KASSERT(!PPPOE_SESSION_LOCKED(sc)); KASSERT(!PPPOE_PARAM_LOCKED(sc)); PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_SESSION_UNLOCK(sc); a1525 1 } a1531 2 PPPOE_PARAM_LOCK(sc); a1532 3 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1559 1 PPPOE_SESSION_LOCK(sc, RW_READER); a1563 1 PPPOE_PARAM_LOCK(sc); a1564 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1568 1 a1568 1 #ifdef PPPOE_MPSAFE d1570 1 a1570 39 pppoe_transmit(struct ifnet *ifp, struct mbuf *m) { struct pppoe_softc *sc = (void *)ifp; uint8_t *p; size_t len; if (m == NULL) return EINVAL; /* are we ready to process data yet? */ PPPOE_SESSION_LOCK(sc, RW_READER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_SESSION_UNLOCK(sc); m_free(m); return ENOBUFS; } len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { PPPOE_SESSION_UNLOCK(sc); ifp->if_oerrors++; return ENETDOWN; } p = mtod(m, uint8_t *); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); bpf_mtap(&sc->sc_sppp.pp_if, m); PPPOE_PARAM_LOCK(sc); pppoe_output(sc, m); PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); return 0; } #endif /* PPPOE_MPSAFE */ static void pppoe_ifattach_hook(void *arg, unsigned long cmd, void *arg2) a1571 1 struct ifnet *ifp = arg2; d1573 1 a1573 1 DECLARE_SPLNET_VARIABLE; d1575 2 a1576 2 if (cmd != PFIL_IFNET_DETACH) return; d1578 1 a1578 2 ACQUIRE_SPLNET(); rw_enter(&pppoe_softc_list_lock, RW_READER); d1580 1 a1580 3 PPPOE_SESSION_LOCK(sc, RW_WRITER); if (sc->sc_eth_if != ifp) { PPPOE_SESSION_UNLOCK(sc); a1581 2 } sppp_lock_enter(&sc->sc_sppp); a1586 1 sppp_lock_exit(&sc->sc_sppp); a1587 1 PPPOE_PARAM_LOCK(sc); a1588 2 PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); d1590 3 a1592 2 rw_exit(&pppoe_softc_list_lock); RELEASE_SPLNET(); a1597 3 KASSERT(PPPOE_SESSION_WLOCKED(sc)); KASSERT(PPPOE_PARAM_LOCKED(sc)); a1605 4 sc->sc_state_updating = 1; PPPOE_PARAM_UNLOCK(sc); PPPOE_SESSION_UNLOCK(sc); a1607 1 sppp_lock_enter(&sc->sc_sppp); a1608 6 sppp_lock_exit(&sc->sc_sppp); PPPOE_SESSION_LOCK(sc, RW_WRITER); PPPOE_PARAM_LOCK(sc); sc->sc_state_updating = 0; @ 1.102.2.8 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.102.2.7 2017/02/05 13:40:58 skrll Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.102.2.7 2017/02/05 13:40:58 skrll Exp $"); a57 1 #include d643 1 a643 2 struct psref psref; d656 4 a659 6 rcvif = m_get_rcvif_psref(m, &psref); if (rcvif != NULL) { sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); a788 3 { struct ifnet *rcvif; struct psref psref; d797 4 a800 9 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); a837 1 } d938 1 a938 1 struct psref psref; d940 3 a942 6 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); d1353 1 d1653 1 @ 1.101 log @Remove unused variable @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.100 2013/07/17 10:16:58 oki Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.100 2013/07/17 10:16:58 oki Exp $"); d1450 1 a1450 1 * might have failed to contact it's radius server. @ 1.100 log @if received PADT, get correct sc related with session id. RFC2516 5.5 says, no tags required in PADT packet. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.99 2013/06/29 21:06:58 rmind Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.99 2013/06/29 21:06:58 rmind Exp $"); d1006 2 a1007 3 struct mbuf *n; MFREE(m, n); return 0; @ 1.99 log @- Rewrite parts of pfil(9): use array to store hooks and thus be more cache friendly (there are only few hooks in the system). Make the structures opaque and the interface more strict. - Remove PFIL_HOOKS option by making pfil(9) mandatory. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $"); d720 1 @ 1.98 log @Add support for RFC 4638 to pppoe(4). The change to if_spppsubr.c moves the test for whether LCP should request a mru change until after the pppoe device has picked up the mtu of the underlying ethernet device. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.97 2011/08/30 22:23:06 rjs Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.97 2011/08/30 22:23:06 rjs Exp $"); a35 1 #include "opt_pfil_hooks.h" a194 1 #ifdef PFIL_HOOKS a195 1 #endif d249 3 a251 5 #ifdef PFIL_HOOKS if (LIST_EMPTY(&pppoe_softc_list)) pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET|PFIL_WAITOK, &if_pfil); #endif d263 3 a265 5 #ifdef PFIL_HOOKS if (LIST_EMPTY(&pppoe_softc_list)) pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET|PFIL_WAITOK, &if_pfil); #endif a1509 1 #ifdef PFIL_HOOKS d1511 1 a1511 2 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) a1534 1 #endif @ 1.98.12.1 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 /* $NetBSD$ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD$"); d36 1 d196 1 d198 1 d252 5 a256 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } d268 5 a272 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } a726 1 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); d1012 3 a1014 2 m_free(m); return NULL; d1517 1 d1519 2 a1520 1 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) d1544 1 @ 1.98.12.2 log @update from HEAD @ text @a34 1 #ifdef _KERNEL_OPT a36 2 #include "opt_net_mpsafe.h" #endif a49 6 #include #include #include #include #include #include a59 1 #include "ioconf.h" d61 2 a62 3 #ifdef NET_MPSAFE #define PPPOE_MPSAFE 1 #endif a124 20 #define PPPOE_LOCK(_sc, _op) rw_enter(&(_sc)->sc_lock, (_op)) #define PPPOE_UNLOCK(_sc) rw_exit(&(_sc)->sc_lock) #define PPPOE_LOCKED(_sc) rw_lock_held(&(_sc)->sc_lock) #define PPPOE_WLOCKED(_sc) rw_write_held(&(_sc)->sc_lock) #define PPPOE_RLOCKED(_sc) rw_read_held(&(_sc)->sc_lock) #ifdef PPPOE_MPSAFE #define DECLARE_SPLNET_VARIABLE #define ACQUIRE_SPLNET() do { } while (0) #define RELEASE_SPLNET() do { } while (0) #else #define DECLARE_SPLNET_VARIABLE int __s #define ACQUIRE_SPLNET() do { \ __s = splnet(); \ } while (0) #define RELEASE_SPLNET() do { \ splx(__s); \ } while (0) #endif a146 1 krwlock_t sc_lock; /* lock of sc_state, sc_session, and sc_eth_if */ d159 1 a159 1 static void pppoeintr(void); a162 1 static void pppoe_enqueue(struct ifqueue *, struct mbuf *); d165 1 a172 3 #ifdef PPPOE_MPSAFE static int pppoe_transmit(struct ifnet *, struct mbuf *); #endif d191 2 a192 4 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *, krw_t); static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *, krw_t); d195 1 a195 1 static void pppoe_ifattach_hook(void *, unsigned long, void *); a197 1 static krwlock_t pppoe_softc_list_lock; a201 5 static bool pppoe_term_unknown = false; static struct sysctllog *pppoe_sysctl_clog; static void sysctl_net_pppoe_setup(struct sysctllog **); a208 11 /* * Nothing to do here, initialization is handled by the * module initialization code in pppoeinit() below). */ } static void pppoeinit(void) { a209 1 rw_init(&pppoe_softc_list_lock); d212 1 a212 24 pppoe_softintr = softint_establish(SOFTINT_MPSAFE|SOFTINT_NET, pppoe_softintr_handler, NULL); sysctl_net_pppoe_setup(&pppoe_sysctl_clog); IFQ_LOCK_INIT(&ppoediscinq); IFQ_LOCK_INIT(&ppoeinq); } static int pppoedetach(void) { int error = 0; if (!LIST_EMPTY(&pppoe_softc_list)) error = EBUSY; if (error == 0) { if_clone_detach(&pppoe_cloner); softint_disestablish(pppoe_softintr); /* Remove our sysctl sub-tree */ sysctl_teardown(&pppoe_sysctl_clog); } return error; a218 1 int rv; a225 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_extflags = IFEF_MPSAFE; #endif d238 1 a238 1 callout_init(&sc->sc_timeout, CALLOUT_MPSAFE); a240 3 #ifdef PPPOE_MPSAFE sc->sc_sppp.pp_if.if_transmit = pppoe_transmit; #endif d245 1 a245 8 rv = if_initialize(&sc->sc_sppp.pp_if); if (rv != 0) { callout_halt(&sc->sc_timeout, NULL); callout_destroy(&sc->sc_timeout); free(sc, M_DEVBUF); return rv; } sc->sc_sppp.pp_if.if_percpuq = if_percpuq_create(&sc->sc_sppp.pp_if); a246 1 if_register(&sc->sc_sppp.pp_if); d250 1 a250 1 pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a251 4 rw_init(&sc->sc_lock); rw_enter(&pppoe_softc_list_lock, RW_WRITER); a252 1 rw_exit(&pppoe_softc_list_lock); d261 1 a261 5 rw_enter(&pppoe_softc_list_lock, RW_WRITER); PPPOE_LOCK(sc, RW_WRITER); callout_halt(&sc->sc_timeout, NULL); a262 1 d264 1 a264 1 pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); a265 2 rw_exit(&pppoe_softc_list_lock); a277 4 PPPOE_UNLOCK(sc); rw_destroy(&sc->sc_lock); d280 1 a280 1 return 0; d290 1 a290 1 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif, krw_t lock) d292 1 a292 1 struct pppoe_softc *sc = NULL; d296 1 a296 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d298 1 a298 2 PPPOE_LOCK(sc, lock); if ( sc->sc_state == PPPOE_STATE_SESSION d301 1 a301 3 break; PPPOE_UNLOCK(sc); d303 1 a303 2 rw_exit(&pppoe_softc_list_lock); return sc; d309 1 a309 2 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif, krw_t lock) d320 2 a321 8 rw_enter(&pppoe_softc_list_lock, RW_READER); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc == t) { PPPOE_LOCK(sc, lock); break; } } rw_exit(&pppoe_softc_list_lock); a333 1 PPPOE_UNLOCK(sc); a338 1 PPPOE_UNLOCK(sc); d348 3 a350 1 pppoeintr(); d355 1 a355 1 pppoeintr(void) d358 1 a358 3 int disc_done, data_done; SOFTNET_LOCK_UNLESS_NET_MPSAFE(); d364 1 a364 1 IFQ_LOCK(&ppoediscinq); d366 1 a366 1 IFQ_UNLOCK(&ppoediscinq); d373 1 a373 1 IFQ_LOCK(&ppoeinq); d375 1 a375 1 IFQ_UNLOCK(&ppoeinq); a380 2 SOFTNET_UNLOCK_UNLESS_NET_MPSAFE(); d390 1 a390 2 const char *err_msg; char devname[IF_NAMESIZE]; d406 1 a406 3 /* as long as we don't know which instance */ strlcpy(devname, "pppoe", sizeof(devname)); d479 12 a490 8 error = malloc(len + 1, M_TEMP, M_NOWAIT); if (error == NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { m = NULL; a491 1 goto done; a492 4 strlcpy(error, mtod(n, char*) + noff, len + 1); printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); d495 1 a495 4 case PPPOE_TAG_HUNIQUE: { struct ifnet *rcvif; struct psref psref; d508 4 a511 12 rcvif = m_get_rcvif_psref(m, &psref); if (rcvif != NULL) { sc = pppoe_find_softc_by_hunique( mtod(n, char *) + noff, len, rcvif, RW_READER); } m_put_rcvif_psref(rcvif, &psref); if (sc != NULL) { strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_UNLOCK(sc); } a512 1 } d555 1 a555 2 error = malloc(len + 1, M_TEMP, M_NOWAIT|M_ZERO); d558 4 a561 5 if (!n) { m = NULL; } else if (error) { strlcpy(error, mtod(n, char *) + noff, len + 1); a584 1 rw_enter(&pppoe_softc_list_lock, RW_READER); d586 1 a586 3 PPPOE_LOCK(sc, RW_WRITER); if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { PPPOE_UNLOCK(sc); d588 1 a588 3 } if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { PPPOE_UNLOCK(sc); a589 2 } a591 2 PPPOE_UNLOCK(sc); a592 2 rw_exit(&pppoe_softc_list_lock); a596 1 d602 1 a602 2 if (sc->sc_hunique == NULL) { PPPOE_UNLOCK(sc); a603 1 } a609 1 PPPOE_UNLOCK(sc); a613 3 { struct ifnet *rcvif; struct psref psref; d622 3 a624 9 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); a630 1 a633 1 PPPOE_UNLOCK(sc); a635 1 d641 1 a641 2 if (sc->sc_hunique == NULL) { PPPOE_UNLOCK(sc); a642 1 } a647 2 PPPOE_UNLOCK(sc); a649 1 } a660 3 PPPOE_LOCK(sc, RW_WRITER); a663 1 PPPOE_UNLOCK(sc); a665 1 a674 1 PPPOE_UNLOCK(sc); a688 1 PPPOE_UNLOCK(sc); a706 2 PPPOE_UNLOCK(sc); a710 3 PPPOE_LOCK(sc, RW_WRITER); a716 2 PPPOE_UNLOCK(sc); d719 2 a720 10 case PPPOE_CODE_PADT: { struct ifnet *rcvif; struct psref psref; rcvif = m_get_rcvif_psref(m, &psref); if (__predict_true(rcvif != NULL)) { sc = pppoe_find_softc_by_session(session, rcvif, RW_WRITER); } m_put_rcvif_psref(rcvif, &psref); a722 1 a723 1 PPPOE_UNLOCK(sc); a724 1 } a725 8 if (sc != NULL) { PPPOE_LOCK(sc, RW_READER); strlcpy(devname, sc->sc_sppp.pp_if.if_xname, sizeof(devname)); PPPOE_UNLOCK(sc); } else strlcpy(devname, "pppoe", sizeof(devname)); d727 2 a728 1 devname, ph->code, session); d756 1 a756 2 struct ifnet *rcvif; struct psref psref; d758 1 d762 3 a764 3 if (pppoe_term_unknown) memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); d790 1 a790 4 rcvif = m_get_rcvif_psref(m, &psref); if (__predict_false(rcvif == NULL)) goto drop; sc = pppoe_find_softc_by_session(session, rcvif, RW_READER); d792 5 a796 6 if (pppoe_term_unknown) { printf("pppoe: input for unknown session %#x, " "sending PADT\n", session); pppoe_send_padt(rcvif, session, shost); } m_put_rcvif_psref(rcvif, &psref); a799 2 m_put_rcvif_psref(rcvif, &psref); d811 2 a812 1 sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); a820 1 PPPOE_UNLOCK(sc); d825 2 a826 5 /* * Fix incoming interface pointer (not the raw ethernet interface * anymore) */ m_set_rcvif(m, &sc->sc_sppp.pp_if); a843 2 KASSERT(PPPOE_LOCKED(sc)); d852 1 a852 2 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; d865 1 a865 1 return if_output_lock(sc->sc_eth_if, sc->sc_eth_if, m, &dst, NULL); d883 1 a883 1 return EPERM; a886 1 PPPOE_LOCK(sc, RW_WRITER); a889 1 PPPOE_UNLOCK(sc); a898 1 PPPOE_UNLOCK(sc); a915 2 PPPOE_LOCK(sc, RW_WRITER); a918 1 PPPOE_UNLOCK(sc); a935 2 PPPOE_LOCK(sc, RW_WRITER); a938 1 PPPOE_UNLOCK(sc); a946 1 PPPOE_LOCK(sc, RW_READER); d948 1 a948 3 strlcpy(parms->ifname, sc->sc_eth_if->if_xname, sizeof(parms->ifname)); PPPOE_UNLOCK(sc); a954 1 PPPOE_LOCK(sc, RW_READER); a958 1 PPPOE_UNLOCK(sc); a966 2 PPPOE_LOCK(sc, RW_WRITER); d977 1 a977 6 PPPOE_UNLOCK(sc); error = sppp_ioctl(ifp, cmd, data); return error; d1013 1 a1013 1 m_reset_rcvif(m); a1024 2 KASSERT(PPPOE_LOCKED(sc)); d1076 1 d1089 1 a1089 1 int retry_wait, err; a1090 1 DECLARE_SPLNET_VARIABLE; a1095 1 PPPOE_LOCK(sc, RW_WRITER); d1115 1 a1115 1 ACQUIRE_SPLNET(); d1123 1 a1123 2 RELEASE_SPLNET(); PPPOE_UNLOCK(sc); d1136 1 a1136 1 RELEASE_SPLNET(); d1140 1 a1140 1 ACQUIRE_SPLNET(); d1151 2 a1152 1 sc->sc_sppp.pp_if.if_xname, err); d1157 1 a1157 2 RELEASE_SPLNET(); PPPOE_UNLOCK(sc); d1170 1 a1170 1 RELEASE_SPLNET(); a1175 1 PPPOE_UNLOCK(sc); a1177 1 PPPOE_UNLOCK(sc); d1184 1 a1184 4 int err; DECLARE_SPLNET_VARIABLE; KASSERT(PPPOE_WLOCKED(sc)); d1194 1 a1194 1 ACQUIRE_SPLNET(); d1203 1 a1203 1 RELEASE_SPLNET(); d1211 1 a1211 2 int err; DECLARE_SPLNET_VARIABLE; d1213 1 a1213 3 KASSERT(PPPOE_WLOCKED(sc)); ACQUIRE_SPLNET(); d1221 1 a1221 2 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); a1225 1 a1245 2 PPPOE_UNLOCK(sc); d1249 1 a1249 1 PPPOE_LOCK(sc, RW_WRITER); a1250 1 RELEASE_SPLNET(); a1257 2 KASSERT(PPPOE_WLOCKED(sc)); a1261 2 PPPOE_UNLOCK(sc); a1264 2 PPPOE_LOCK(sc, RW_WRITER); a1277 2 KASSERT(PPPOE_LOCKED(sc)); d1330 1 d1361 1 a1361 1 return if_output_lock(outgoing_if, outgoing_if, m0, &dst, NULL); a1371 2 KASSERT(PPPOE_LOCKED(sc)); /* required by pppoe_output(). */ a1403 2 KASSERT(PPPOE_WLOCKED(sc)); d1443 1 a1443 6 KASSERT(!PPPOE_LOCKED(sc)); PPPOE_LOCK(sc, RW_READER); if (sc->sc_state != PPPOE_STATE_INITIAL) { PPPOE_UNLOCK(sc); a1444 1 } d1450 1 a1450 1 * might have failed to contact its radius server. a1458 2 PPPOE_UNLOCK(sc); d1465 1 a1465 7 KASSERT(!PPPOE_LOCKED(sc)); PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_UNLOCK(sc); a1466 1 } a1472 1 a1473 2 PPPOE_UNLOCK(sc); a1487 1 PPPOE_LOCK(sc, RW_READER); a1489 1 PPPOE_UNLOCK(sc); a1506 1 PPPOE_UNLOCK(sc); d1509 1 a1509 1 #ifdef PPPOE_MPSAFE d1511 1 a1511 37 pppoe_transmit(struct ifnet *ifp, struct mbuf *m) { struct pppoe_softc *sc = (void *)ifp; uint8_t *p; size_t len; if (m == NULL) return EINVAL; /* are we ready to process data yet? */ PPPOE_LOCK(sc, RW_READER); if (sc->sc_state < PPPOE_STATE_SESSION) { PPPOE_UNLOCK(sc); m_free(m); return ENOBUFS; } len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { PPPOE_UNLOCK(sc); ifp->if_oerrors++; return ENETDOWN; } p = mtod(m, uint8_t *); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); bpf_mtap(&sc->sc_sppp.pp_if, m); pppoe_output(sc, m); PPPOE_UNLOCK(sc); return 0; } #endif /* PPPOE_MPSAFE */ static void pppoe_ifattach_hook(void *arg, unsigned long cmd, void *arg2) a1512 1 struct ifnet *ifp = arg2; d1514 1 a1514 1 DECLARE_SPLNET_VARIABLE; d1516 2 a1517 2 if (cmd != PFIL_IFNET_DETACH) return; d1519 1 a1519 2 ACQUIRE_SPLNET(); rw_enter(&pppoe_softc_list_lock, RW_READER); d1521 1 a1521 3 PPPOE_LOCK(sc, RW_WRITER); if (sc->sc_eth_if != ifp) { PPPOE_UNLOCK(sc); a1522 1 } a1529 1 PPPOE_UNLOCK(sc); d1531 3 a1533 2 rw_exit(&pppoe_softc_list_lock); RELEASE_SPLNET(); a1538 2 KASSERT(PPPOE_WLOCKED(sc)); a1547 2 PPPOE_UNLOCK(sc); a1550 2 PPPOE_LOCK(sc, RW_WRITER); a1563 72 static void pppoe_enqueue(struct ifqueue *inq, struct mbuf *m) { if (m->m_flags & M_PROMISC) { m_free(m); return; } #ifndef PPPOE_SERVER if (m->m_flags & (M_MCAST | M_BCAST)) { m_free(m); return; } #endif IFQ_LOCK(inq); if (IF_QFULL(inq)) { IF_DROP(inq); IFQ_UNLOCK(inq); m_freem(m); } else { IF_ENQUEUE(inq, m); IFQ_UNLOCK(inq); softint_schedule(pppoe_softintr); } return; } void pppoe_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoeinq, m); return; } void pppoedisc_input(struct ifnet *ifp, struct mbuf *m) { pppoe_enqueue(&ppoediscinq, m); return; } static void sysctl_net_pppoe_setup(struct sysctllog **clog) { const struct sysctlnode *node = NULL; sysctl_createv(clog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "pppoe", SYSCTL_DESCR("PPPOE protocol"), NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL); if (node == NULL) return; sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_BOOL, "term_unknown", SYSCTL_DESCR("Terminate unknown sessions"), NULL, 0, &pppoe_term_unknown, sizeof(pppoe_term_unknown), CTL_CREATE, CTL_EOL); } /* * Module infrastructure */ #include "if_module.h" IF_MODULE(MODULE_CLASS_DRIVER, pppoe, "sppp_subr") @ 1.98.2.1 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $"); d36 1 d196 1 d198 1 d252 5 a256 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } d268 5 a272 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } a726 1 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); d1012 3 a1014 2 m_free(m); return NULL; d1517 1 d1519 2 a1520 1 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) d1544 1 @ 1.98.16.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD$ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD$"); d36 1 d196 1 d198 1 d252 5 a256 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } d268 5 a272 3 if (LIST_EMPTY(&pppoe_softc_list)) { pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil); } a726 1 sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); d1517 1 d1519 2 a1520 1 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) d1544 1 @ 1.98.16.2 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.98.16.1 2013/08/28 23:59:36 rmind Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.98.16.1 2013/08/28 23:59:36 rmind Exp $"); d1006 3 a1008 2 m_free(m); return NULL; @ 1.97 log @Typo in comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.96 2010/04/05 07:22:23 joerg Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.96 2010/04/05 07:22:23 joerg Exp $"); d88 1 d899 1 a899 1 if (sc->sc_sppp.pp_if.if_mtu > d1045 3 d1074 7 d1297 3 d1328 7 @ 1.96 log @Push the bpf_ops usage back into bpf.h. Push the common ifp->if_bpf check into the inline functions as well the fourth argument for bpf_attach. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.95 2010/01/19 22:08:01 pooka Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.95 2010/01/19 22:08:01 pooka Exp $"); d90 1 a90 1 #define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ @ 1.95 log @Redefine bpf linkage through an always present op vector, i.e. #if NBPFILTER is no longer required in the client. This change doesn't yet add support for loading bpf as a module, since drivers can register before bpf is attached. However, callers of bpf can now be modularized. Dynamically loadable bpf could probably be done fairly easily with coordination from the stub driver and the real driver by registering attachments in the stub before the real driver is loaded and doing a handoff. ... and I'm not going to ponder the depths of unload here. Tested with i386/MONOLITHIC, modified MONOLITHIC without bpf and rump. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $"); d250 1 a250 2 bpf_ops->bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0, &sc->sc_sppp.pp_if.if_bpf); d272 1 a272 1 bpf_ops->bpf_detach(ifp); d807 1 a807 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_ops->bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d1489 1 a1489 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_ops->bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); @ 1.95.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.95 2010/01/19 22:08:01 pooka Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.95 2010/01/19 22:08:01 pooka Exp $"); d250 2 a251 1 bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d273 1 a273 1 bpf_detach(ifp); d808 2 a809 1 bpf_mtap(&sc->sc_sppp.pp_if, m); d1491 2 a1492 1 bpf_mtap(&sc->sc_sppp.pp_if, m); @ 1.95.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD$"); d250 2 a251 1 bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d273 1 a273 1 bpf_detach(ifp); d808 2 a809 1 bpf_mtap(&sc->sc_sppp.pp_if, m); d1491 2 a1492 1 bpf_mtap(&sc->sc_sppp.pp_if, m); @ 1.94 log @PR/40690: Jordan Gordeev: pppoe(4) doesn't work when PPPoE relays are present Add support for sending the session id tag back. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $"); a35 1 #include "bpfilter.h" a58 1 #if NBPFILTER > 0 a59 1 #endif d250 2 a251 3 #if NBPFILTER > 0 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); #endif d273 1 a273 3 #if NBPFILTER > 0 bpfdetach(ifp); #endif a807 1 #if NBPFILTER > 0 d809 1 a809 2 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); #endif a1490 1 #if NBPFILTER > 0 d1492 1 a1492 2 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); #endif @ 1.93 log @Reduce the scope of PPPoE session IDs from globally unique to per-interface unique. Some brands of ADSL modems pick a hard-coded session ID which would otherwise make it impossible to use two of them in the same system simultaneously. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.92 2008/08/19 22:03:05 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.92 2008/08/19 22:03:05 martin Exp $"); d141 2 d288 2 d407 2 d432 2 d539 13 d693 14 d1238 5 d1294 2 d1315 6 d1559 4 @ 1.93.8.1 log @Sync with HEAD. Commit is split, to avoid a "too many arguments" protocol error. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $"); a140 2 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ a285 2 if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); a402 2 uint8_t *relay_sid; size_t relay_sid_len; a425 2 relay_sid = NULL; relay_sid_len = 0; a530 13 case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; a671 14 if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } a1202 5 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; a1253 2 if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ a1272 6 if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } a1510 4 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } @ 1.93.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $"); a140 2 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ a285 2 if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); a402 2 uint8_t *relay_sid; size_t relay_sid_len; a425 2 relay_sid = NULL; relay_sid_len = 0; a530 13 case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; a671 14 if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } a1202 5 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; a1253 2 if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ a1272 6 if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } a1510 4 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } @ 1.93.4.1 log @Pull up following revision(s) (requested by christos in ticket #478): sys/net/if_pppoe.c: revision 1.94 PR/40690: Jordan Gordeev: pppoe(4) doesn't work when PPPoE relays are present Add support for sending the session id tag back. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $"); a140 2 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ a285 2 if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); a402 2 uint8_t *relay_sid; size_t relay_sid_len; a425 2 relay_sid = NULL; relay_sid_len = 0; a530 13 case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; a671 14 if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } a1202 5 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; a1253 2 if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ a1272 6 if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } a1510 4 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } @ 1.92 log @Simplify auth failure reconnect a bit and make it more similar to the session establishment timeout handling. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.91 2008/08/19 10:41:10 simonb Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.91 2008/08/19 10:41:10 simonb Exp $"); d308 3 a310 6 && sc->sc_session == session) { if (sc->sc_eth_if == rcvif) return sc; else return NULL; } @ 1.91 log @Fix a tyop in a comment and a few #define nits while here. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.90 2008/08/18 21:43:49 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.90 2008/08/18 21:43:49 martin Exp $"); d119 1 a119 1 #define PPPOE_RECON_SLOW (hz*45) /* after more auth failures */ d1403 3 a1405 6 if (sc->sc_sppp.pp_auth_failures == 1) { wtime = PPPOE_RECON_FAST; } else { wtime = PPPOE_RECON_SLOW * sc->sc_sppp.pp_auth_failures; } d1407 1 a1407 1 wtime = hz / 10; @ 1.90 log @When upper layer asks us to re-establish a connection, don't do so synchronously, but insert a (varying) delay. Before we have only been decoupled from the peer via network latency - now we introduce some explicit delay. This, at least, creates batter serialized debug output. However, if we have to reconnect because of an authentication failure, the peer may have just been unable to access it's radius server. (I have a setup where this seems to happen every now and then, depending on time of day.) Backoff reconnect in this cases seriously longer - this is better than hitting the max-auth-failure limit within a few seconds. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.89 2008/08/18 20:43:50 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.89 2008/08/18 20:43:50 martin Exp $"); d80 1 a80 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d95 1 a95 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d110 1 a110 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d119 2 a120 2 #define PPPOE_RECON_SLOW (hz*45) /* after more auht failures */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d125 1 a125 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ @ 1.89 log @Test and handle memory allocation failure for the access concentrator cookie. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.88 2008/08/08 14:31:00 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.88 2008/08/08 14:31:00 martin Exp $"); d118 2 d1071 4 d1392 2 d1396 17 a1412 1 pppoe_connect(sc); @ 1.88 log @Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.87 2008/06/15 16:37:21 christos Exp $ */ d4 1 a4 1 * Copyright (c) 2002 The NetBSD Foundation, Inc. d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.87 2008/06/15 16:37:21 christos Exp $"); d664 4 a667 1 if (sc->sc_ac_cookie == NULL) d669 1 @ 1.87 log @- add if_alloc (ours just mallocs), and if_initname and use them (from FreeBSD) - kill memsets where M_ZERO can be used. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.86 2008/04/28 20:24:09 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.86 2008/04/28 20:24:09 martin Exp $"); d472 1 a472 1 if (off + len > m->m_pkthdr.len) { d563 1 a563 1 if (errortag) @ 1.87.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $ */ d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93 2008/10/15 20:08:33 scw Exp $"); d80 1 a80 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d95 1 a95 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d110 1 a110 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d118 1 a118 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d123 1 a123 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ d306 6 a311 3 && sc->sc_session == session && sc->sc_eth_if == rcvif) return sc; d472 1 a472 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d563 1 a563 1 if (errortag || m == NULL) d664 1 a664 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a665 1 } a1064 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1381 2 int wtime; d1384 1 a1384 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); @ 1.86 log @Remove clause 3 and 4 from TNF licenses @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $"); d221 1 a221 2 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK); memset(sc, 0, sizeof(struct pppoe_softc)); d223 1 a223 2 snprintf(sc->sc_sppp.pp_if.if_xname, sizeof(sc->sc_sppp.pp_if.if_xname), "pppoe%d", unit); @ 1.86.2.1 log @Sync w/ -current. 34 merge conflicts to follow. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.86 2008/04/28 20:24:09 martin Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.86 2008/04/28 20:24:09 martin Exp $"); d221 2 a222 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d224 2 a225 1 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); @ 1.86.2.2 log @Sync with wrstuden-revivesa-base-2. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.86.2.1 2008/06/23 04:31:58 wrstuden Exp $ */ d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.86.2.1 2008/06/23 04:31:58 wrstuden Exp $"); d80 1 a80 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d95 1 a95 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d110 1 a110 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d118 1 a118 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d123 1 a123 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ d472 1 a472 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d563 1 a563 1 if (errortag || m == NULL) d664 1 a664 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a665 1 } a1064 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1381 2 int wtime; d1384 1 a1384 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); @ 1.86.4.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.87 2008/06/15 16:37:21 christos Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.87 2008/06/15 16:37:21 christos Exp $"); d221 2 a222 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d224 2 a225 1 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); @ 1.85 log @Merge the socket locking patch: - Socket layer becomes MP safe. - Unix protocols become MP safe. - Allows protocol processing interrupts to safely block on locks. - Fixes a number of race conditions. With much feedback from matt@@ and plunky@@. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $ */ a17 7 * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $"); @ 1.85.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $ */ d18 7 d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $"); @ 1.85.2.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.85.2.1 2008/05/16 02:25:40 yamt Exp $ */ d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85.2.1 2008/05/16 02:25:40 yamt Exp $"); d80 1 a80 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d95 1 a95 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d110 1 a110 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d118 1 a118 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d123 1 a123 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ a138 2 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ d221 2 a222 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d224 2 a225 1 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); a285 2 if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); d308 6 a313 3 && sc->sc_session == session && sc->sc_eth_if == rcvif) return sc; a405 2 uint8_t *relay_sid; size_t relay_sid_len; a428 2 relay_sid = NULL; relay_sid_len = 0; d474 1 a474 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { a533 13 case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; d565 1 a565 1 if (errortag || m == NULL) d666 1 a666 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a667 1 } a670 14 if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } a1066 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1197 5 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; a1248 2 if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ a1267 6 if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } a1383 2 int wtime; d1386 1 a1386 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); a1490 4 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } @ 1.85.2.3 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.85.2.2 2009/05/04 08:14:15 yamt Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85.2.2 2009/05/04 08:14:15 yamt Exp $"); d36 1 d60 1 d62 1 d253 3 a255 2 bpf_ops->bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0, &sc->sc_sppp.pp_if.if_bpf); d277 3 a279 1 bpf_ops->bpf_detach(ifp); d814 1 d816 2 a817 1 bpf_ops->bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d1499 1 d1501 2 a1502 1 bpf_ops->bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); @ 1.85.2.4 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.85.2.3 2010/03/11 15:04:27 yamt Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85.2.3 2010/03/11 15:04:27 yamt Exp $"); d250 2 a251 1 bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d273 1 a273 1 bpf_detach(ifp); d808 2 a809 1 bpf_mtap(&sc->sc_sppp.pp_if, m); d1491 2 a1492 1 bpf_mtap(&sc->sc_sppp.pp_if, m); @ 1.84 log @s/u_\(int[0-9]*_t\)/u\1/g (change u_int*_t to uint*_t) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.83 2008/02/07 01:22:01 dyoung Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.83 2008/02/07 01:22:01 dyoung Exp $"); d58 1 d367 1 d369 1 @ 1.84.6.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d18 7 d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); a57 1 #include a365 1 mutex_enter(softnet_lock); a366 1 mutex_exit(softnet_lock); @ 1.84.6.2 log @Sync with HEAD. @ text @d221 2 a222 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d224 2 a225 1 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); @ 1.84.6.3 log @Sync with HEAD. @ text @d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d80 1 a80 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d95 1 a95 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d110 1 a110 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d118 1 a118 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d123 1 a123 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ d472 1 a472 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d563 1 a563 1 if (errortag || m == NULL) d664 1 a664 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a665 1 } a1064 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1381 2 int wtime; d1384 1 a1384 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); @ 1.84.6.4 log @Sync with HEAD. @ text @d308 6 a313 3 && sc->sc_session == session && sc->sc_eth_if == rcvif) return sc; @ 1.84.8.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $ */ d18 7 d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $"); a57 1 #include a365 1 mutex_enter(softnet_lock); a366 1 mutex_exit(softnet_lock); @ 1.84.8.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.84.8.1 2008/05/18 12:35:27 yamt Exp $ */ d33 1 a33 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.84.8.1 2008/05/18 12:35:27 yamt Exp $"); d221 2 a222 1 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO); d224 2 a225 1 if_initname(&sc->sc_sppp.pp_if, "pppoe", unit); @ 1.83 log @Start patching up the kernel so that a network driver always has the opportunity to handle an ioctl before generic ifioctl handling occurs. This will ease extending the kernel and sharing of code between drivers. First steps: Make the signature of ifioctl_common() match struct ifinet->if_ioctl. Convert SIOCSIFCAP and SIOCSIFMTU to the new ifioctl() regime, throughout the kernel. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.82 2007/12/25 18:33:45 perry Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.82 2007/12/25 18:33:45 perry Exp $"); d75 4 a78 4 u_int8_t vertype; u_int8_t code; u_int16_t session; u_int16_t plen; d82 2 a83 2 u_int16_t tag; u_int16_t len; d139 1 a139 1 u_int16_t sc_session; /* PPPoE session id */ d143 1 a143 1 u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ d146 1 a146 1 u_int8_t *sc_hunique; /* content of host unique we must echo back */ d190 1 a190 1 static int pppoe_send_padt(struct ifnet *, u_int, const u_int8_t *); d197 1 a197 1 static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *); d327 1 a327 1 pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif) d403 2 a404 2 u_int16_t tag, len; u_int16_t session, plen; d408 1 a408 1 u_int8_t *ac_cookie; d411 1 a411 1 u_int8_t *hunique; d517 1 a517 1 hunique = mtod(n, u_int8_t *) + noff; d733 1 a733 1 u_int16_t session, plen; d737 1 a737 1 u_int8_t shost[ETHER_ADDR_LEN]; d825 1 a825 1 u_int16_t etype; d1007 1 a1007 1 u_int8_t *p; d1029 1 a1029 1 p = mtod(m0, u_int8_t *); d1051 1 a1051 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d1053 1 a1053 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1191 1 a1191 1 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const u_int8_t *)&sc->sc_dest); d1240 1 a1240 1 u_int8_t *p; d1256 1 a1256 1 p = mtod(m0, u_int8_t *); d1278 1 a1278 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d1280 1 a1280 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1288 1 a1288 1 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const u_int8_t *dest) d1293 1 a1293 1 u_int8_t *p; d1298 1 a1298 1 p = mtod(m0, u_int8_t *); d1316 1 a1316 1 u_int8_t *p; d1331 1 a1331 1 p = mtod(m0, u_int8_t *); d1348 1 a1348 1 u_int8_t *p; d1367 1 a1367 1 p = mtod(m0, u_int8_t *); d1413 1 a1413 1 u_int8_t *p; d1432 1 a1432 1 p = mtod(m, u_int8_t *); @ 1.82 log @Convert many of the uses of __attribute__ to equivalent __packed, __unused and __dead macros from cdefs.h @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.81 2007/10/08 16:18:05 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.81 2007/10/08 16:18:05 ad Exp $"); d856 1 a945 2 { struct ifreq *ifr = (struct ifreq*) data; a960 1 } a961 3 { struct ifreq *ifr = (struct ifreq *)data; d966 1 a966 2 return sppp_ioctl(ifp, cmd, data); } @ 1.81 log @Use the softint API. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $"); d79 1 a79 1 } __attribute__((__packed__)); d84 1 a84 1 } __attribute__((__packed__)); @ 1.81.4.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.83 2008/02/07 01:22:01 dyoung Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.83 2008/02/07 01:22:01 dyoung Exp $"); d79 1 a79 1 } __packed; d84 1 a84 1 } __packed; a855 1 struct ifreq *ifr = data; d945 2 d962 1 d964 3 d971 2 a972 1 /*FALLTHROUGH*/ @ 1.81.10.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d79 1 a79 1 } __packed; d84 1 a84 1 } __packed; @ 1.81.6.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.82 2007/12/25 18:33:45 perry Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.82 2007/12/25 18:33:45 perry Exp $"); d79 1 a79 1 } __packed; d84 1 a84 1 } __packed; @ 1.80 log @Print the access concentrator name when a session is established. This seems to be usefull to identify peers with known broken firmware (e.g. that can only do IPv4 reliably). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.79 2007/07/09 21:11:00 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.79 2007/07/09 21:11:00 ad Exp $"); d57 2 a69 1 #include d219 1 a219 1 pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); @ 1.80.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $"); a56 2 #include d68 1 d218 1 a218 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); @ 1.79 log @Merge some of the less invasive changes from the vmlocking branch: - kthread, callout, devsw API changes - select()/poll() improvements - miscellaneous MT safety improvements @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.78 2007/03/31 11:00:23 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.78 2007/03/31 11:00:23 martin Exp $"); d488 17 @ 1.79.8.1 log @sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.81 2007/10/08 16:18:05 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.81 2007/10/08 16:18:05 ad Exp $"); a56 2 #include d68 1 d218 1 a218 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); a487 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, char*) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.79.8.2 log @sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.79.8.1 2007/11/06 23:33:33 matt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.79.8.1 2007/11/06 23:33:33 matt Exp $"); d79 1 a79 1 } __packed; d84 1 a84 1 } __packed; @ 1.79.8.3 log @sync with HEAD @ text @d1 1 a1 1 /* if_pppoe.c,v 1.79.8.2 2008/01/09 01:57:12 matt Exp */ d40 1 a40 1 __KERNEL_RCSID(0, "if_pppoe.c,v 1.79.8.2 2008/01/09 01:57:12 matt Exp"); d75 4 a78 4 uint8_t vertype; uint8_t code; uint16_t session; uint16_t plen; d82 2 a83 2 uint16_t tag; uint16_t len; d139 1 a139 1 uint16_t sc_session; /* PPPoE session id */ d143 1 a143 1 uint8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ d146 1 a146 1 uint8_t *sc_hunique; /* content of host unique we must echo back */ d190 1 a190 1 static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *); d197 1 a197 1 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *); d327 1 a327 1 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif) d403 2 a404 2 uint16_t tag, len; uint16_t session, plen; d408 1 a408 1 uint8_t *ac_cookie; d411 1 a411 1 uint8_t *hunique; d517 1 a517 1 hunique = mtod(n, uint8_t *) + noff; d733 1 a733 1 uint16_t session, plen; d737 1 a737 1 uint8_t shost[ETHER_ADDR_LEN]; d825 1 a825 1 uint16_t etype; a855 1 struct ifreq *ifr = data; d945 2 d962 1 d964 3 d971 2 a972 1 /*FALLTHROUGH*/ d1013 1 a1013 1 uint8_t *p; d1035 1 a1035 1 p = mtod(m0, uint8_t *); d1057 1 a1057 1 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) d1059 1 a1059 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); d1197 1 a1197 1 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); d1246 1 a1246 1 uint8_t *p; d1262 1 a1262 1 p = mtod(m0, uint8_t *); d1284 1 a1284 1 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) d1286 1 a1286 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); d1294 1 a1294 1 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest) d1299 1 a1299 1 uint8_t *p; d1304 1 a1304 1 p = mtod(m0, uint8_t *); d1322 1 a1322 1 uint8_t *p; d1337 1 a1337 1 p = mtod(m0, uint8_t *); d1354 1 a1354 1 uint8_t *p; d1373 1 a1373 1 p = mtod(m0, uint8_t *); d1419 1 a1419 1 uint8_t *p; d1438 1 a1438 1 p = mtod(m, uint8_t *); @ 1.79.6.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $"); a487 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, char*) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.79.6.2 log @Sync with HEAD. Follow the merge of pmap.c on i386 and amd64 and move pmap_init_tmp_pgtbl into arch/x86/x86/pmap.c. Modify the ACPI wakeup code to restore CR4 before jumping back into kernel space as the large page option might cover that. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.79.6.1 2007/10/02 18:29:15 joerg Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.79.6.1 2007/10/02 18:29:15 joerg Exp $"); a56 2 #include d68 1 d218 1 a218 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); @ 1.79.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.80 2007/09/09 09:58:55 martin Exp $"); a487 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, char*) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.78 log @caddr_t fallout (only visible with options PPPOE_SERVER) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77 2007/03/04 06:03:16 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77 2007/03/04 06:03:16 christos Exp $"); d148 1 a148 1 struct callout sc_timeout; /* timeout while not in session state */ a156 1 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS a158 4 #else struct callout pppoe_softintr = CALLOUT_INITIALIZER; void pppoe_softintr_handler(void *); #endif a217 1 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS a218 1 #endif d246 1 a246 1 callout_init(&sc->sc_timeout); d291 1 a360 1 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS a366 9 #else void pppoe_softintr_handler(void *dummy) { int s = splnet(); pppoe_input(); splx(s); } #endif @ 1.77 log @Kill caddr_t; there will be some MI fallout, but it will be fixed shortly. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $"); d515 1 a515 1 hunique = mtod(n, void *) + noff; @ 1.77.4.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.79 2007/07/09 21:11:00 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.79 2007/07/09 21:11:00 ad Exp $"); d148 1 a148 1 callout_t sc_timeout; /* timeout while not in session state */ d157 1 d160 4 d223 1 d225 1 d253 1 a253 1 callout_init(&sc->sc_timeout, 0); a297 1 callout_destroy(&sc->sc_timeout); d367 1 d374 9 d515 1 a515 1 hunique = mtod(n, u_int8_t *) + noff; @ 1.77.2.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77 2007/03/04 06:03:16 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77 2007/03/04 06:03:16 christos Exp $"); d515 1 a515 1 hunique = mtod(n, u_int8_t *) + noff; @ 1.77.2.2 log @- Increase the number of thread priorities from 128 to 256. How the space is set up is to be revisited. - Implement soft interrupts as kernel threads. A generic implementation is provided, with hooks for fast-path MD code that can run the interrupt threads over the top of other threads executing in the kernel. - Split vnode::v_flag into three fields, depending on how the flag is locked (by the interlock, by the vnode lock, by the file system). - Miscellaneous locking fixes and improvements. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77.2.1 2007/04/10 13:26:47 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77.2.1 2007/04/10 13:26:47 ad Exp $"); a56 2 #include d68 1 d224 1 a224 1 pppoe_softintr = softint_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); @ 1.77.2.3 log @Adapt to callout API change. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77.2.2 2007/06/17 21:31:51 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77.2.2 2007/06/17 21:31:51 ad Exp $"); d149 1 a149 1 callout_t sc_timeout; /* timeout while not in session state */ d158 1 d161 4 d224 1 d226 1 d254 1 a254 1 callout_init(&sc->sc_timeout, 0); a298 1 callout_destroy(&sc->sc_timeout); d368 1 d375 9 @ 1.77.2.4 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77.2.3 2007/07/01 21:50:44 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77.2.3 2007/07/01 21:50:44 ad Exp $"); d219 1 a219 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); @ 1.77.2.5 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.77.2.4 2007/07/15 15:53:00 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.77.2.4 2007/07/15 15:53:00 ad Exp $"); a488 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, char*) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.76 log @__unused removal on arguments; approved by core. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.75 2006/11/01 12:10:06 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.75 2006/11/01 12:10:06 martin Exp $"); d158 1 a158 1 void * pppoe_softintr = NULL; d178 1 a178 1 static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t); d464 1 a464 1 ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); d490 1 a490 1 pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); d515 1 a515 1 hunique = mtod(n, caddr_t) + noff; d518 1 a518 1 sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, d532 1 a532 1 ac_cookie = mtod(n, caddr_t) + noff; d557 1 a557 1 mtod(n, caddr_t) + noff, len); d850 1 a850 1 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) @ 1.76.8.1 log @Sync with somewhat-recent netbsd-4. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $"); a503 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.76.8.2 log @Sync with netbsd-4. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76.8.1 2007/09/23 21:36:34 wrstuden Exp $ */ d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.8.1 2007/09/23 21:36:34 wrstuden Exp $"); d85 1 a85 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d100 1 a100 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d115 1 a115 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d123 1 a123 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d128 1 a128 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ d493 1 a493 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d584 1 a584 1 if (errortag || m == NULL) d685 1 a685 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a686 1 } a1091 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1408 2 int wtime; d1411 1 a1411 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); @ 1.76.2.1 log @Pull up following revision(s) (requested by martin in ticket #873): sys/net/if_pppoe.c: revision 1.80 (via patch) Print the access concentrator name when a session is established. This seems to be usefull to identify peers with known broken firmware (e.g. that can only do IPv4 reliably). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $"); a503 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.76.2.1.4.1 log @ncvs ci src/sys/net/if_pppoe.c Pull up revision 1.88 (requested by martin in ticket #1179). Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $"); d493 1 a493 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d584 1 a584 1 if (errortag || m == NULL) @ 1.76.2.2 log @ncvs ci src/sys/net/if_pppoe.c Pull up revision 1.88 (requested by martin in ticket #1179). Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.2.1 2007/09/11 09:19:17 xtraeme Exp $"); d493 1 a493 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d584 1 a584 1 if (errortag || m == NULL) @ 1.76.2.3 log @Pull up following revision(s) (requested by martin in ticket #1186): sys/net/if_pppoe.c: revision 1.89 - 1.92 Test and handle memory allocation failure for the access concentrator cookie. When upper layer asks us to re-establish a connection, don't do so synchronously, but insert a (varying) delay. Before we have only been decoupled from the peer via network latency - now we introduce some explicit delay. This, at least, creates batter serialized debug output. However, if we have to reconnect because of an authentication failure, the peer may have just been unable to access it's radius server. (I have a setup where this seems to happen every now and then, depending on time of day.) Backoff reconnect in this cases seriously longer - this is better than hitting the max-auth-failure limit within a few seconds. Simplify auth failure reconnect a bit and make it more similar to the session establishment timeout handling. Fix a tyop in a comment and a few #define nits while here. @ text @d1 1 a1 1 /* $NetBSD$ */ d4 1 a4 1 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d85 1 a85 1 #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d100 1 a100 1 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ d115 1 a115 1 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ d123 1 a123 3 #define PPPOE_RECON_FAST (hz*15) /* first retry after auth failure */ #define PPPOE_RECON_IMMEDIATE (hz/10) /* "no delay" reconnect */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ d128 1 a128 1 #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ d685 1 a685 4 if (sc->sc_ac_cookie == NULL) { printf("%s: FATAL: could not allocate memory " "for AC cookie\n", sc->sc_sppp.pp_if.if_xname); a686 1 } a1091 4 case PPPOE_STATE_INITIAL: /* delayed connect from pppoe_tls() */ pppoe_connect(sc); break; a1408 2 int wtime; d1411 1 a1411 14 if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH && sc->sc_sppp.pp_auth_failures > 0) { /* * Delay trying to reconnect a bit more - the peer * might have failed to contact it's radius server. */ wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures; if (wtime > PPPOE_SLOW_RETRY) wtime = PPPOE_SLOW_RETRY; } else { wtime = PPPOE_RECON_IMMEDIATE; } callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc); @ 1.76.2.4 log @Pull up following revision(s) (requested by christos in ticket #1279): sys/net/if_pppoe.c: revision 1.94 via patch PR/40690: Jordan Gordeev: pppoe(4) doesn't work when PPPoE relays are present Add support for sending the session id tag back. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.94 2009/02/19 15:17:50 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.2.3 2008/08/20 20:52:30 bouyer Exp $"); a145 2 uint8_t *sc_relay_sid; /* content of relay SID we must echo back */ size_t sc_relay_sid_len; /* length of relay SID data */ a299 2 if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); a426 2 uint8_t *relay_sid; size_t relay_sid_len; a449 2 relay_sid = NULL; relay_sid_len = 0; a554 13 case PPPOE_TAG_RELAYSID: if (relay_sid == NULL) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG RELAYSID ERROR"; m = NULL; break; } relay_sid = mtod(n, char *) + noff; relay_sid_len = len; } break; a695 14 if (relay_sid) { if (sc->sc_relay_sid) free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_relay_sid == NULL) { printf("%s: FATAL: could not allocate memory " "for relay SID\n", sc->sc_sppp.pp_if.if_xname); goto done; } sc->sc_relay_sid_len = relay_sid_len; memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len); } a1232 5 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } sc->sc_relay_sid_len = 0; a1283 2 if (sc->sc_relay_sid_len > 0) len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */ a1302 6 if (sc->sc_relay_sid_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID); PPPOE_ADD_16(p, sc->sc_relay_sid_len); memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len); p += sc->sc_relay_sid_len; } a1540 4 if (sc->sc_relay_sid) { free(sc->sc_relay_sid, M_DEVBUF); sc->sc_relay_sid = NULL; } @ 1.76.4.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $"); d158 1 a158 1 void *pppoe_softintr = NULL; d178 1 a178 1 static int pppoe_ioctl(struct ifnet *, unsigned long, void *); d464 1 a464 1 ph = (struct pppoehdr *)(mtod(n, char *) + noff); d490 1 a490 1 pt = (struct pppoetag *)(mtod(n, char *) + noff); d515 1 a515 1 hunique = mtod(n, void *) + noff; d518 1 a518 1 sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, d532 1 a532 1 ac_cookie = mtod(n, char *) + noff; d557 1 a557 1 mtod(n, char *) + noff, len); d850 1 a850 1 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data) @ 1.76.4.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76.4.1 2007/03/12 05:59:12 rmind Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76.4.1 2007/03/12 05:59:12 rmind Exp $"); d515 1 a515 1 hunique = mtod(n, u_int8_t *) + noff; @ 1.75 log @Do not truncate the last char from a remote error message @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.74 2006/10/25 20:28:45 elad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.74 2006/10/25 20:28:45 elad Exp $"); d218 1 a218 1 pppoeattach(int count __unused) d229 1 a229 1 pppoe_clone_create(struct if_clone *ifc __unused, int unit) d369 1 a369 1 pppoe_softintr_handler(void *dummy __unused) d1451 2 a1452 2 pppoe_ifattach_hook(void *arg __unused, struct mbuf **mp, struct ifnet *ifp, int dir __unused) @ 1.74 log @Kill some KAUTH_GENERIC_ISSUSER uses. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.73 2006/10/12 01:32:28 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.73 2006/10/12 01:32:28 christos Exp $"); d558 1 a558 1 error[len-1] = '\0'; @ 1.73 log @- sprinkle __unused on function decls. - fix a couple of unused bugs - no more -Wno-unused for i386 @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $"); d860 4 a863 3 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0) return error; @ 1.72 log @Fix initializers. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.71 2006/08/05 17:20:54 pavel Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.71 2006/08/05 17:20:54 pavel Exp $"); d218 1 a218 1 pppoeattach(int count) d229 1 a229 1 pppoe_clone_create(struct if_clone *ifc, int unit) d369 1 a369 1 pppoe_softintr_handler(void *dummy) d1450 2 a1451 1 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) @ 1.72.2.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.76 2006/11/16 01:33:40 christos Exp $"); d558 1 a558 1 error[len] = '\0'; d860 3 a862 4 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, NULL) != 0) return (EPERM); d1450 1 a1450 2 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) @ 1.72.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $"); d218 1 a218 1 pppoeattach(int count __unused) d229 1 a229 1 pppoe_clone_create(struct if_clone *ifc __unused, int unit) d369 1 a369 1 pppoe_softintr_handler(void *dummy __unused) d1450 1 a1450 2 pppoe_ifattach_hook(void *arg __unused, struct mbuf **mp, struct ifnet *ifp, int dir __unused) @ 1.72.4.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.72.4.1 2006/10/22 06:07:24 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.72.4.1 2006/10/22 06:07:24 yamt Exp $"); d218 1 a218 1 pppoeattach(int count) d229 1 a229 1 pppoe_clone_create(struct if_clone *ifc, int unit) d369 1 a369 1 pppoe_softintr_handler(void *dummy) d558 1 a558 1 error[len] = '\0'; d860 3 a862 4 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, NULL) != 0) return (EPERM); d1450 2 a1451 2 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) @ 1.71 log @defflag PPPOE_SERVER and PPPOE_TERM_UNKNOWN_SESSIONS. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.70 2006/07/23 22:06:12 ad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.70 2006/07/23 22:06:12 ad Exp $"); d154 2 a155 2 struct ifqueue ppoediscinq = { NULL }; struct ifqueue ppoeinq = { NULL }; a222 3 ppoediscinq.ifq_maxlen = IFQ_MAXLEN; ppoeinq.ifq_maxlen = IFQ_MAXLEN; @ 1.70 log @Use the LWP cached credentials where sane. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.69 2006/06/07 22:33:42 kardel Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.69 2006/06/07 22:33:42 kardel Exp $"); d45 1 @ 1.69 log @merge FreeBSD timecounters from branch simonb-timecounters - struct timeval time is gone time.tv_sec -> time_second - struct timeval mono_time is gone mono_time.tv_sec -> time_uptime - access to time via {get,}{micro,nano,bin}time() get* versions are fast but less precise - support NTP nanokernel implementation (NTP API 4) - further reading: Timecounter Paper: http://phk.freebsd.dk/pubs/timecounter.pdf NTP Nanokernel: http://www.eecis.udel.edu/~mills/ntp/html/kern.html @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.68 2006/05/14 21:19:33 elad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.68 2006/05/14 21:19:33 elad Exp $"); d854 1 a854 1 struct proc *p = curproc; /* XXX */ d862 2 a863 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) @ 1.68 log @integrate kauth. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d1350 1 d1358 2 a1359 1 sc->sc_session = mono_time.tv_sec % 0xff + 1; @ 1.68.2.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.69 2006/06/07 22:33:42 kardel Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.69 2006/06/07 22:33:42 kardel Exp $"); a1349 1 struct bintime bt; d1357 1 a1357 2 getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; @ 1.67 log @Adapt maximum MTU permitted on pppoe(4) interfaces to the MTU of the connected ethernet interface. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.66 2006/04/27 13:19:04 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.66 2006/04/27 13:19:04 tron Exp $"); d55 1 d862 1 a862 1 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) @ 1.66 log @Don't allow to connect a non ethernet interface to a PPPoE interface. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.65 2006/04/15 02:22:44 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.65 2006/04/15 02:22:44 christos Exp $"); d84 1 d105 1 a105 1 #define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) d864 4 a867 3 sc->sc_eth_if = ifunit(parms->eth_ifname); if (sc->sc_eth_if == NULL || sc->sc_eth_if->if_dlt != DLT_EN10MB) { d871 7 d962 1 a962 1 struct ifreq *ifr = (struct ifreq*) data; d964 2 a965 1 if (ifr->ifr_mtu > PPPOE_MAXMTU) d967 1 @ 1.65 log @Don't try to free a NULL mbuf. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $"); d864 3 a866 1 if (sc->sc_eth_if == NULL) d868 1 d870 1 a870 1 if (parms->ac_name) { d890 1 a890 1 if (parms->service_name) { @ 1.64 log @Make sure error messages (received from the access concentrator) are zero terminated. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.63 2005/12/11 23:05:25 thorpej Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.63 2005/12/11 23:05:25 thorpej Exp $"); d711 2 a712 1 m_freem(m); @ 1.64.2.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.72 2006/08/30 16:57:59 christos Exp $"); a44 1 #include "opt_pppoe.h" a54 1 #include a83 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d104 1 a104 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d151 2 a152 2 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN }; struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN }; d220 3 d711 1 a711 2 if (m) m_freem(m); d851 1 a851 1 struct lwp *l = curlwp; /* XXX */ d859 1 a859 2 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0) d862 2 a863 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a864 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d866 1 a866 1 if (parms->ac_name != NULL) { d886 1 a886 1 if (parms->service_name != NULL) { d949 1 a949 1 struct ifreq *ifr = (struct ifreq *)data; d951 1 a951 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a952 1 } a1333 1 struct bintime bt; d1341 1 a1341 2 getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; @ 1.64.10.1 log @Merge 2006-05-24 NetBSD-current into the "peter-altq" branch. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); a54 1 #include a83 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d104 1 a104 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d711 1 a711 2 if (m) m_freem(m); d859 1 a859 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) d862 2 a863 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a864 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d866 1 a866 1 if (parms->ac_name != NULL) { d886 1 a886 1 if (parms->service_name != NULL) { d949 1 a949 1 struct ifreq *ifr = (struct ifreq *)data; d951 1 a951 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a952 1 } @ 1.64.6.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $"); a54 1 #include a83 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d104 1 a104 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d711 1 a711 2 if (m) m_freem(m); d859 1 a859 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) d862 2 a863 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a864 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d866 1 a866 1 if (parms->ac_name != NULL) { d886 1 a886 1 if (parms->service_name != NULL) { d949 1 a949 1 struct ifreq *ifr = (struct ifreq *)data; d951 1 a951 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a952 1 } @ 1.64.6.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.6.1 2006/05/24 10:58:56 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.6.1 2006/05/24 10:58:56 yamt Exp $"); a1349 1 struct bintime bt; d1357 1 a1357 2 getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; @ 1.64.6.3 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.6.2 2006/06/26 12:53:39 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.6.2 2006/06/26 12:53:39 yamt Exp $"); a44 1 #include "opt_pppoe.h" d854 1 a854 1 struct lwp *l = curlwp; /* XXX */ d862 1 a862 2 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0) @ 1.64.6.4 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.6.3 2006/08/11 15:46:14 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.6.3 2006/08/11 15:46:14 yamt Exp $"); d154 2 a155 2 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN }; struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN }; d223 3 @ 1.64.8.1 log @Adapt to kernel authorization KPI. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $"); d859 1 a859 1 if ((error = generic_authorize(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) @ 1.64.8.2 log @generic_authorize() -> kauth_authorize_generic(). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.8.1 2006/03/08 01:11:55 elad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.8.1 2006/03/08 01:11:55 elad Exp $"); d859 1 a859 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) @ 1.64.8.3 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.8.2 2006/03/10 15:05:22 elad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.8.2 2006/03/10 15:05:22 elad Exp $"); d711 1 a711 2 if (m) m_freem(m); @ 1.64.8.4 log @- Move kauth_cred_t declaration to - Cleanup struct ucred; forward declarations that are unused. - Don't include in any header, but include it in the c files that need it. Approved by core. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.8.3 2006/04/19 04:46:10 elad Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.8.3 2006/04/19 04:46:10 elad Exp $"); a54 1 #include @ 1.64.8.5 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.8.4 2006/05/06 23:31:59 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.8.4 2006/05/06 23:31:59 christos Exp $"); a84 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d105 1 a105 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d864 2 a865 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a866 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d868 1 a868 1 if (parms->ac_name != NULL) { d888 1 a888 1 if (parms->service_name != NULL) { d951 1 a951 1 struct ifreq *ifr = (struct ifreq *)data; d953 1 a953 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a954 1 } @ 1.64.4.1 log @Adapt for timecounters: mostly use get*time(), use bintime's for timeout calculations and use "time_second" instead of "time.tv_sec". @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp $"); a1333 1 struct bintime bt; d1341 1 a1341 2 getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; @ 1.64.4.2 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.65 2006/04/15 02:22:44 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.65 2006/04/15 02:22:44 christos Exp $"); d711 1 a711 2 if (m) m_freem(m); @ 1.64.4.3 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.64.4.2 2006/04/22 11:40:06 simonb Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.64.4.2 2006/04/22 11:40:06 simonb Exp $"); a54 1 #include a83 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d104 1 a104 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d860 1 a860 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) d863 2 a864 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a865 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d867 1 a867 1 if (parms->ac_name != NULL) { d887 1 a887 1 if (parms->service_name != NULL) { d950 1 a950 1 struct ifreq *ifr = (struct ifreq *)data; d952 1 a952 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a953 1 } @ 1.63 log @ANSI function decls and application of static. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.62 2005/12/11 12:24:51 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.62 2005/12/11 12:24:51 christos Exp $"); d421 2 a422 1 const char *err_msg, *err_txt; d435 2 a436 1 err_msg = err_txt = NULL; d486 1 a486 2 printf("%s: parse error\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); d520 2 d550 1 a550 1 err_txt = ""; d552 1 d555 5 a559 2 if (n) err_txt = mtod(n, caddr_t) + noff; d561 6 a566 3 printf("%s: %s: %*s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe*", err_msg, len, err_txt); @ 1.63.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.63 2005/12/11 23:05:25 thorpej Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.63 2005/12/11 23:05:25 thorpej Exp $"); d421 1 a421 2 const char *err_msg, *devname; char *error; d434 1 a434 2 devname = "pppoe"; /* as long as we don't know which instance */ err_msg = NULL; d484 2 a485 1 printf("%s: parse error\n", devname); a518 2 if (sc != NULL) devname = sc->sc_sppp.pp_if.if_xname; d547 1 a547 1 error = NULL; a548 1 error = malloc(len+1, M_TEMP, M_NOWAIT); d551 2 a552 5 if (n && error) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len-1] = '\0'; } d554 3 a556 6 if (error) { printf("%s: %s: %s\n", devname, err_msg, error); free(error, M_TEMP); } else printf("%s: %s\n", devname, err_msg); @ 1.62 log @merge ktrace-lwp. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.8 2005/11/10 14:10:32 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.8 2005/11/10 14:10:32 skrll Exp $"); d205 1 a205 1 LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; d207 2 a208 2 int pppoe_clone_create __P((struct if_clone *, int)); int pppoe_clone_destroy __P((struct ifnet *)); d210 1 a210 1 struct if_clone pppoe_cloner = d215 1 a215 2 pppoeattach(count) int count; d228 2 a229 4 int pppoe_clone_create(ifc, unit) struct if_clone *ifc; int unit; d275 2 a276 3 int pppoe_clone_destroy(ifp) struct ifnet *ifp; d368 2 a369 1 static void pppoe_softintr_handler(void *dummy) d375 2 a376 1 void pppoe_softintr_handler(void *dummy) d386 1 a386 1 pppoe_input() d415 2 a416 1 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) @ 1.61 log @Fix bogus uninitialized variable warning ifdef PPPOE_SERVER. Noticed by Marcin Jessa on current-users. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60 2005/05/29 21:22:53 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60 2005/05/29 21:22:53 christos Exp $"); @ 1.60 log @- sprinkle const - remove unneeded casts - use more mem*() instead of b*() funcs. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.59 2005/02/26 22:45:09 perry Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.59 2005/02/26 22:45:09 perry Exp $"); d1327 1 a1327 1 size_t len, l1; @ 1.60.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60 2005/05/29 21:22:53 christos Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60 2005/05/29 21:22:53 christos Exp $"); a54 1 #include a83 1 #define PPPOE_OVERHEAD (PPPOE_HEADERLEN + 2) d104 1 a104 1 #define PPPOE_MAXMTU (ETHERMTU - PPPOE_OVERHEAD) d205 1 a205 1 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; d207 2 a208 2 static int pppoe_clone_create(struct if_clone *, int); static int pppoe_clone_destroy(struct ifnet *); d210 1 a210 1 static struct if_clone pppoe_cloner = d215 2 a216 1 pppoeattach(int count) d229 4 a232 2 static int pppoe_clone_create(struct if_clone *ifc, int unit) d278 3 a280 2 static int pppoe_clone_destroy(struct ifnet *ifp) d372 1 a372 2 static void pppoe_softintr_handler(void *dummy) d378 1 a378 2 void pppoe_softintr_handler(void *dummy) d388 1 a388 1 pppoe_input(void) d417 1 a417 2 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) d422 1 a422 2 const char *err_msg, *devname; char *error; d435 1 a435 2 devname = "pppoe"; /* as long as we don't know which instance */ err_msg = NULL; d485 2 a486 1 printf("%s: parse error\n", devname); a519 2 if (sc != NULL) devname = sc->sc_sppp.pp_if.if_xname; d548 1 a548 1 error = NULL; a549 1 error = malloc(len+1, M_TEMP, M_NOWAIT); d552 2 a553 5 if (n && error) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len-1] = '\0'; } d555 3 a557 6 if (error) { printf("%s: %s: %s\n", devname, err_msg, error); free(error, M_TEMP); } else printf("%s: %s\n", devname, err_msg); d702 1 a702 2 if (m) m_freem(m); d850 1 a850 1 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) d853 2 a854 5 struct ifnet *eth_if; eth_if = ifunit(parms->eth_ifname); if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a855 8 } if (sc->sc_sppp.pp_if.if_mtu > eth_if->if_mtu - PPPOE_OVERHEAD) { sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu - PPPOE_OVERHEAD; } sc->sc_eth_if = eth_if; d857 1 a857 1 if (parms->ac_name != NULL) { d877 1 a877 1 if (parms->service_name != NULL) { d940 1 a940 1 struct ifreq *ifr = (struct ifreq *)data; d942 1 a942 2 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ? PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) { a943 1 } a1324 1 struct bintime bt; d1327 1 a1327 1 size_t len, l1 = 0; /* XXX: gcc */ d1332 1 a1332 2 getbinuptime(&bt); sc->sc_session = bt.sec % 0xff + 1; @ 1.60.2.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.1 2006/06/21 15:10:27 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.1 2006/06/21 15:10:27 yamt Exp $"); a44 1 #include "opt_pppoe.h" d153 2 a154 2 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN }; struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN }; d222 3 d560 1 a560 1 error[len] = '\0'; d854 1 a854 1 struct lwp *l = curlwp; /* XXX */ d862 2 a863 4 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, NULL) != 0) return (EPERM); d1451 1 a1451 2 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) @ 1.60.2.3 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.2 2006/12/30 20:50:20 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.2 2006/12/30 20:50:20 yamt Exp $"); d148 1 a148 1 callout_t sc_timeout; /* timeout while not in session state */ d157 2 a158 1 void *pppoe_softintr = NULL; d160 4 d178 1 a178 1 static int pppoe_ioctl(struct ifnet *, unsigned long, void *); d223 1 d225 1 d253 1 a253 1 callout_init(&sc->sc_timeout, 0); a297 1 callout_destroy(&sc->sc_timeout); d367 1 d374 9 d464 1 a464 1 ph = (struct pppoehdr *)(mtod(n, char *) + noff); d490 1 a490 1 pt = (struct pppoetag *)(mtod(n, char *) + noff); d515 1 a515 1 hunique = mtod(n, u_int8_t *) + noff; d518 1 a518 1 sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff, d532 1 a532 1 ac_cookie = mtod(n, char *) + noff; d557 1 a557 1 mtod(n, char *) + noff, len); d850 1 a850 1 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data) @ 1.60.2.4 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.3 2007/09/03 14:42:10 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.3 2007/09/03 14:42:10 yamt Exp $"); a56 2 #include d68 1 d218 1 a218 1 pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL); a487 17 error = NULL; if (sc != NULL && len > 0) { error = malloc(len+1, M_TEMP, M_NOWAIT); if (error) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) { strncpy(error, mtod(n, char*) + noff, len); error[len] = '\0'; } printf("%s: connected to %s\n", devname, error); free(error, M_TEMP); } } @ 1.60.2.5 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.4 2007/10/27 11:36:02 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.4 2007/10/27 11:36:02 yamt Exp $"); d79 1 a79 1 } __packed; d84 1 a84 1 } __packed; @ 1.60.2.6 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.5 2008/01/21 09:47:05 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.5 2008/01/21 09:47:05 yamt Exp $"); a855 1 struct ifreq *ifr = data; d945 2 d962 1 d964 3 d971 2 a972 1 /*FALLTHROUGH*/ @ 1.60.2.7 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.60.2.6 2008/02/11 14:59:59 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.60.2.6 2008/02/11 14:59:59 yamt Exp $"); d75 4 a78 4 uint8_t vertype; uint8_t code; uint16_t session; uint16_t plen; d82 2 a83 2 uint16_t tag; uint16_t len; d139 1 a139 1 uint16_t sc_session; /* PPPoE session id */ d143 1 a143 1 uint8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ d146 1 a146 1 uint8_t *sc_hunique; /* content of host unique we must echo back */ d190 1 a190 1 static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *); d197 1 a197 1 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *); d327 1 a327 1 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif) d403 2 a404 2 uint16_t tag, len; uint16_t session, plen; d408 1 a408 1 uint8_t *ac_cookie; d411 1 a411 1 uint8_t *hunique; d517 1 a517 1 hunique = mtod(n, uint8_t *) + noff; d733 1 a733 1 uint16_t session, plen; d737 1 a737 1 uint8_t shost[ETHER_ADDR_LEN]; d825 1 a825 1 uint16_t etype; d1007 1 a1007 1 uint8_t *p; d1029 1 a1029 1 p = mtod(m0, uint8_t *); d1051 1 a1051 1 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) d1053 1 a1053 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); d1191 1 a1191 1 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest); d1240 1 a1240 1 uint8_t *p; d1256 1 a1256 1 p = mtod(m0, uint8_t *); d1278 1 a1278 1 if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN) d1280 1 a1280 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *))); d1288 1 a1288 1 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest) d1293 1 a1293 1 uint8_t *p; d1298 1 a1298 1 p = mtod(m0, uint8_t *); d1316 1 a1316 1 uint8_t *p; d1331 1 a1331 1 p = mtod(m0, uint8_t *); d1348 1 a1348 1 uint8_t *p; d1367 1 a1367 1 p = mtod(m0, uint8_t *); d1413 1 a1413 1 uint8_t *p; d1432 1 a1432 1 p = mtod(m, uint8_t *); @ 1.59 log @nuke trailing whitespace @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.58 2005/01/19 15:05:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.58 2005/01/19 15:05:55 martin Exp $"); d859 1 a859 1 char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, d861 1 a861 1 if (p == NULL) d863 1 a863 1 error = copyinstr(parms->ac_name, p, d866 1 a866 1 free(p, M_DEVBUF); d870 1 a870 1 free(p, M_DEVBUF); d875 1 a875 1 sc->sc_concentrator_name = p; d879 1 a879 1 char * p = malloc(parms->service_name_len + 1, M_DEVBUF, d881 1 a881 1 if (p == NULL) d883 1 a883 1 error = copyinstr(parms->service_name, p, d886 1 a886 1 free(p, M_DEVBUF); d890 1 a890 1 free(p, M_DEVBUF); d895 1 a895 1 sc->sc_service_name = p; @ 1.59.4.1 log @Pull up following revision(s) (requested by martin in ticket #1588): sys/net/if_pppoe.c: revision 1.61 Fix bogus uninitialized variable warning ifdef PPPOE_SERVER. Noticed by Marcin Jessa on current-users. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d1327 1 a1327 1 size_t len, l1 = 0; /* XXX: gcc */ @ 1.59.4.2 log @Pull up revision 1.88 via patch (requested by martin in ticket #1953). Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.59.4.1 2006/11/19 17:52:18 bouyer Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.59.4.1 2006/11/19 17:52:18 bouyer Exp $"); d493 1 a493 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d702 1 a702 2 if (m) m_freem(m); @ 1.59.2.1 log @Pull up following revision(s) (requested by martin in ticket #1152): sys/net/if_pppoe.c: revision 1.64 Make sure error messages (received from the access concentrator) are zero terminated. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d422 1 a422 2 const char *err_msg, *devname; char *error; d435 1 a435 2 devname = "pppoe"; /* as long as we don't know which instance */ err_msg = NULL; d485 2 a486 1 printf("%s: parse error\n", devname); a519 2 if (sc != NULL) devname = sc->sc_sppp.pp_if.if_xname; d548 1 a548 1 error = NULL; a549 1 error = malloc(len+1, M_TEMP, M_NOWAIT); d552 2 a553 5 if (n && error) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len-1] = '\0'; } d555 3 a557 6 if (error) { printf("%s: %s: %s\n", devname, err_msg, error); free(error, M_TEMP); } else printf("%s: %s\n", devname, err_msg); @ 1.59.2.2 log @Pull up following revision(s) (requested by 1297): sys/net/if_pppoe.c: revision 1.66 Don't allow to connect a non ethernet interface to a PPPoE interface. @ text @d864 1 a864 3 if (sc->sc_eth_if == NULL || sc->sc_eth_if->if_dlt != DLT_EN10MB) { sc->sc_eth_if = NULL; a865 1 } d867 1 a867 1 if (parms->ac_name != NULL) { d887 1 a887 1 if (parms->service_name != NULL) { @ 1.59.2.2.2.1 log @Pull up following revision(s) (requested by martin in ticket #1588): sys/net/if_pppoe.c: revision 1.61 Fix bogus uninitialized variable warning ifdef PPPOE_SERVER. Noticed by Marcin Jessa on current-users. @ text @d1340 1 a1340 1 size_t len, l1 = 0; /* XXX: gcc */ @ 1.59.2.2.2.2 log @Pull up revision 1.88 (requested by martin in ticket #1953). Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.59.2.2.2.1 2006/11/19 17:52:57 bouyer Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.59.2.2.2.1 2006/11/19 17:52:57 bouyer Exp $"); d494 1 a494 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d568 1 a568 1 if (errortag || m == NULL) @ 1.59.2.3 log @Pull up following revision(s) (requested by martin in ticket #1588): sys/net/if_pppoe.c: revision 1.61 Fix bogus uninitialized variable warning ifdef PPPOE_SERVER. Noticed by Marcin Jessa on current-users. @ text @d1340 1 a1340 1 size_t len, l1 = 0; /* XXX: gcc */ @ 1.59.2.4 log @Pull up revision 1.88 (requested by martin in ticket #1953). Apply patch from Yasuoka Masahiko in PR kern/39321: fix length check when parsing pppoe discovery phase packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.59.2.3 2006/11/19 17:51:38 bouyer Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.59.2.3 2006/11/19 17:51:38 bouyer Exp $"); d494 1 a494 1 if (off + len + sizeof(*pt) > m->m_pkthdr.len) { d568 1 a568 1 if (errortag || m == NULL) @ 1.58 log @Remove deleted interfaces from the instance list (inspired by an OpenBSD change). While there, fix a comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.57 2004/12/08 07:43:29 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.57 2004/12/08 07:43:29 martin Exp $"); d955 1 a955 1 * in front. @ 1.58.2.1 log @sync with head. xen and whitespace. xen part is not finished. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.58 2005/01/19 15:05:55 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.58 2005/01/19 15:05:55 martin Exp $"); d955 1 a955 1 * in front. @ 1.57 log @Factor out softc cleanup after loss of session into pppoe_clear_softc. Use this when loosing the ethernet interface (when it deataches). Fixes PR kern/28375. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.56 2004/12/04 18:31:43 peter Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.56 2004/12/04 18:31:43 peter Exp $"); d284 1 d1453 1 a1453 1 /* stop timer (we might be about to transmit a PADT ourself) */ @ 1.57.2.1 log @sync with -current @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.59 2005/02/26 22:45:09 perry Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.59 2005/02/26 22:45:09 perry Exp $"); a283 1 callout_stop(&sc->sc_timeout); d954 1 a954 1 * in front. d1452 1 a1452 1 /* stop timer */ @ 1.56 log @Change ifc_destroy to return an int instead of void, so that it can pass back errors to ifconfig. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.55 2004/11/28 17:16:10 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.55 2004/11/28 17:16:10 skrll Exp $"); d179 1 d691 1 a691 16 /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); d1441 1 d1448 25 @ 1.55 log @Re-order the inclusion of opt_pfil_hooks so PFIL_HOOKS gets set properly. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.54 2004/11/28 11:44:36 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.54 2004/11/28 11:44:36 martin Exp $"); d207 1 a207 1 void pppoe_clone_destroy __P((struct ifnet *)); d277 1 a277 1 void d301 2 @ 1.54 log @Add a pfil(9) hook to get notified when interfaces detach. When the ethernet interface of a pppoe pseudo-interface detaches, remove the association and mark the pppoe interface down. This should fix PR kern/28375. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.53 2004/04/21 18:40:40 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.53 2004/04/21 18:40:40 itojun Exp $"); d44 1 a60 1 #include "opt_pfil_hooks.h" @ 1.53 log @kill sprintf, use snprintf @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.52 2004/03/30 06:00:13 oki Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.52 2004/03/30 06:00:13 oki Exp $"); d60 1 d200 4 d268 5 d284 5 d1431 28 @ 1.52 log @fixed mbuf leak if up pppoe but not connected an ether i/f. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $"); d233 2 a234 1 sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", unit); @ 1.51 log @s/netbsd.org/NetBSD.org/g @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.50 2003/10/30 01:43:08 simonb Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.50 2003/10/30 01:43:08 simonb Exp $"); d810 2 a811 1 if (sc->sc_eth_if == NULL) d813 1 @ 1.51.4.1 log @Pull up following revision(s) (requested by martin in ticket #10239): sys/net/if_pppoe.c: revision 1.64 Make sure error messages (received from the access concentrator) are zero terminated. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d402 1 a402 2 const char *err_msg, *devname; char *error; d415 1 a415 2 devname = "pppoe"; /* as long as we don't know which instance */ err_msg = NULL; d465 2 a466 1 printf("%s: parse error\n", devname); a499 2 if (sc != NULL) devname = sc->sc_sppp.pp_if.if_xname; d528 1 a528 1 error = NULL; a529 1 error = malloc(len+1, M_TEMP, M_NOWAIT); d532 2 a533 5 if (n && error) { strncpy(error, mtod(n, caddr_t) + noff, len); error[len-1] = '\0'; } d535 3 a537 6 if (error) { printf("%s: %s: %s\n", devname, err_msg, error); free(error, M_TEMP); } else printf("%s: %s\n", devname, err_msg); @ 1.50 log @Remove some assigned-to but otherwise unused variables. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.49 2003/10/25 18:29:12 christos Exp $ */ d8 1 a8 1 * by Martin Husemann . d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.49 2003/10/25 18:29:12 christos Exp $"); @ 1.49 log @Fix uninitialized variable warnings @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.48 2003/09/26 22:23:58 wiz Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.48 2003/09/26 22:23:58 wiz Exp $"); d1126 1 a1126 1 int x, err, retry; a1137 1 retry = sc->sc_padr_retried; @ 1.48 log @Process has only one c. From miod@@openbsd. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.47 2003/09/16 20:59:04 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.47 2003/09/16 20:59:04 martin Exp $"); d978 1 a978 1 int len, l1, l2; d1214 1 a1214 1 size_t len, l1; @ 1.47 log @Tell copyinstr about the real buffer size (not one byte to few). Add more error checking. Noticed by Quentin Garnier. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.46 2003/09/03 21:36:31 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.46 2003/09/03 21:36:31 martin Exp $"); d1390 1 a1390 1 /* are we ready to proccess data yet? */ @ 1.46 log @If the peer cares to send us error messages, actually display them. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.45 2003/08/23 16:42:41 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.45 2003/08/23 16:42:41 martin Exp $"); d852 14 a865 2 char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK); copyinstr(parms->ac_name, p, parms->ac_name_len, &s); d872 14 a885 2 char * p = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK); copyinstr(parms->service_name, p, parms->service_name_len, &s); @ 1.45 log @When trying to (re-)establish a session cope with intermediate output failures of the underlying ethernet interface - just keep trying. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44 2003/06/27 16:24:32 oki Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44 2003/06/27 16:24:32 oki Exp $"); d402 1 a402 1 const char *err_msg = NULL; d412 1 a412 1 int noff, err; d415 2 d490 1 d492 1 a492 2 m = NULL; goto done; d516 1 d520 1 d524 1 d528 12 a539 4 printf("%s: %s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); goto done; @ 1.44 log @Put correct dest ether address on PPPoE server mode. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.43 2003/06/18 08:12:51 oki Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.43 2003/06/18 08:12:51 oki Exp $"); d412 1 a412 1 int noff; d635 9 a643 6 if (pppoe_send_padr(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); d998 1 a998 1 int x, retry_wait; d1032 9 a1040 5 if (pppoe_send_padi(sc) == 0) callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); else pppoe_abort_connect(sc); d1052 10 a1061 6 if (pppoe_send_padi(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); d1065 10 a1074 6 if (pppoe_send_padr(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); d1105 4 a1108 14 if (err != 0) { /* * We failed to send a single PADI packet. * This is unfortunate, because we have no good way to recover * from here. */ /* recover state and return the error */ sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padr_retried = retry; } else { callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); } @ 1.44.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.53 2004/04/21 18:40:40 itojun Exp $ */ d8 1 a8 1 * by Martin Husemann . d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.53 2004/04/21 18:40:40 itojun Exp $"); d233 1 a233 2 snprintf(sc->sc_sppp.pp_if.if_xname, sizeof(sc->sc_sppp.pp_if.if_xname), "pppoe%d", unit); d402 1 a402 1 const char *err_msg, *err_txt; d412 1 a412 1 int noff, err, errortag; a414 2 err_msg = err_txt = NULL; errortag = 0; d488 1 d490 1 a490 2 err_msg = "TAG HUNIQUE ERROR"; break; a513 1 errortag = 1; a516 1 errortag = 1; a519 1 errortag = 1; d523 4 a526 12 err_txt = ""; if (errortag && len) { n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (n) err_txt = mtod(n, caddr_t) + noff; } printf("%s: %s: %*s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe*", err_msg, len, err_txt); if (errortag) goto done; d635 6 a640 9 if ((err = pppoe_send_padr(sc)) != 0) { if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d794 1 a794 2 if (sc->sc_eth_if == NULL) { m_freem(m); a795 1 } d836 2 a837 14 char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK); if (p == NULL) return ENOMEM; error = copyinstr(parms->ac_name, p, parms->ac_name_len+1, &s); if (error != 0) { free(p, M_DEVBUF); return error; } if (s != parms->ac_name_len+1) { free(p, M_DEVBUF); return EINVAL; } d844 2 a845 14 char * p = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK); if (p == NULL) return ENOMEM; error = copyinstr(parms->service_name, p, parms->service_name_len+1, &s); if (error != 0) { free(p, M_DEVBUF); return error; } if (s != parms->service_name_len+1) { free(p, M_DEVBUF); return EINVAL; } d938 1 a938 1 int len, l1 = 0, l2 = 0; /* XXX: gcc */ d995 1 a995 1 int x, retry_wait, err; d1029 5 a1033 9 if ((err = pppoe_send_padi(sc)) != 0) { sc->sc_padi_retried--; if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to transmit PADI, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d1045 6 a1050 10 if ((err = pppoe_send_padi(sc)) != 0) { if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI" ", error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d1054 6 a1059 10 if ((err = pppoe_send_padr(sc)) != 0) { sc->sc_padr_retried--; if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d1074 1 a1074 1 int x, err; d1086 1 d1090 14 a1103 4 if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI, error=%d\n", sc->sc_sppp.pp_if.if_xname, err); callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d1172 1 a1172 1 size_t len, l1 = 0; /* XXX: gcc */ d1348 1 a1348 1 /* are we ready to process data yet? */ @ 1.44.2.2 log @Sync with HEAD. @ text @@ 1.44.2.3 log @Fix the sync with head I botched. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.1 2004/08/03 10:54:16 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.1 2004/08/03 10:54:16 skrll Exp $"); @ 1.44.2.4 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.3 2004/09/21 13:36:38 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.3 2004/09/21 13:36:38 skrll Exp $"); a43 1 #include "opt_pfil_hooks.h" a198 4 #ifdef PFIL_HOOKS static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int); #endif a262 5 #ifdef PFIL_HOOKS if (LIST_EMPTY(&pppoe_softc_list)) pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET|PFIL_WAITOK, &if_pfil); #endif a273 5 #ifdef PFIL_HOOKS if (LIST_EMPTY(&pppoe_softc_list)) pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET|PFIL_WAITOK, &if_pfil); #endif a1415 28 #ifdef PFIL_HOOKS static int pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) { struct pppoe_softc *sc; int s; if (mp != (struct mbuf **)PFIL_IFNET_DETACH) return 0; s = splnet(); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_eth_if != ifp) continue; if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); printf("%s: ethernet interface detached, going down\n", sc->sc_sppp.pp_if.if_xname); } sc->sc_eth_if = NULL; } splx(s); return 0; } #endif @ 1.44.2.5 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.4 2004/11/29 07:24:51 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.4 2004/11/29 07:24:51 skrll Exp $"); a178 1 static void pppoe_clear_softc(struct pppoe_softc *, const char *); d207 1 a207 1 int pppoe_clone_destroy __P((struct ifnet *)); d277 1 a277 1 int a300 2 return (0); d688 16 a703 1 pppoe_clear_softc(sc, "received PADT"); a1452 1 pppoe_clear_softc(sc, "ethernet interface detached"); a1458 25 static void pppoe_clear_softc(struct pppoe_softc *sc, const char *message) { /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, %s\n", sc->sc_sppp.pp_if.if_xname, sc->sc_session, message); /* fix our state */ sc->sc_state = PPPOE_STATE_INITIAL; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); /* clean up softc */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; } @ 1.44.2.6 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.5 2004/12/18 09:32:50 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.5 2004/12/18 09:32:50 skrll Exp $"); a283 1 callout_stop(&sc->sc_timeout); d1452 1 a1452 1 /* stop timer */ @ 1.44.2.7 log @Sync with HEAD. Hi Perry! @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.6 2005/01/24 08:35:53 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.6 2005/01/24 08:35:53 skrll Exp $"); d955 1 a955 1 * in front. @ 1.44.2.8 log @Sync with HEAD. Here we go again... @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.44.2.7 2005/03/04 16:52:58 skrll Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.44.2.7 2005/03/04 16:52:58 skrll Exp $"); d859 1 a859 1 char *b = malloc(parms->ac_name_len + 1, M_DEVBUF, d861 1 a861 1 if (b == NULL) d863 1 a863 1 error = copyinstr(parms->ac_name, b, d866 1 a866 1 free(b, M_DEVBUF); d870 1 a870 1 free(b, M_DEVBUF); d875 1 a875 1 sc->sc_concentrator_name = b; d879 1 a879 1 char *b = malloc(parms->service_name_len + 1, M_DEVBUF, d881 1 a881 1 if (b == NULL) d883 1 a883 1 error = copyinstr(parms->service_name, b, d886 1 a886 1 free(b, M_DEVBUF); d890 1 a890 1 free(b, M_DEVBUF); d895 1 a895 1 sc->sc_service_name = b; d1327 1 a1327 1 size_t len, l1 = 0; /* XXX: gcc */ @ 1.43 log @Add support in-kernel PPPoE server. This may work with one PPPoE session. If you want to use it, #define PPPOE_SERVER in somewhere, or add options PPPOE_SERVER in kernel config file. This is experimental code, and good start point for future development. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.42 2003/03/01 15:50:15 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.42 2003/03/01 15:50:15 martin Exp $"); d562 1 @ 1.42 log @Backout previous, I'm on crack obviously. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.41 2003/03/01 15:24:36 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.41 2003/03/01 15:24:36 martin Exp $"); d122 5 d140 4 d185 4 d405 4 d425 4 d492 4 d533 33 d567 38 d607 1 d1078 5 d1132 7 d1240 71 @ 1.41 log @Initialize sc to NULL, it could be used uninitialized otherwise when searching for our sc by host unique tag. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.40 2003/03/01 15:10:13 aymeric Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.40 2003/03/01 15:10:13 aymeric Exp $"); a313 1 sc = NULL; @ 1.40 log @when looking up a Host-Uniq tag, do not consider NULL as a valid (struct pppoe_softc *). Although we do not generate such tags, other hosts could and some actually do. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.39 2003/02/04 20:52:23 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.39 2003/02/04 20:52:23 martin Exp $"); d314 1 @ 1.39 log @PADT is always send with ethertype PPPOE_DISCOVERY, no matter if we have reached session state or not. Fixes PR kern/20203 by Shoichi Miyake. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.38 2003/02/03 23:51:03 thorpej Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.38 2003/02/03 23:51:03 thorpej Exp $"); d317 1 a317 1 if (sc != t) { @ 1.38 log @Test callout_pending(), not callout_active(), and eliminate now-unnecessary callout_deactivate() calls. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.37 2003/01/07 20:02:10 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.37 2003/01/07 20:02:10 martin Exp $"); d176 1 a176 1 static int pppoe_send_padt(struct pppoe_softc *); a641 5 struct mbuf *m0; struct sockaddr dst; struct ether_header *eh; u_int8_t *p; d644 1 a644 15 m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) goto drop; p = mtod(m0, u_int8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOE); memcpy(&eh->ether_dhost, shost, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); m->m_pkthdr.rcvif->if_output(m->m_pkthdr.rcvif, m0, &dst, NULL); d1019 1 a1019 1 err = pppoe_send_padt(sc); d1109 1 a1109 1 pppoe_send_padt(struct pppoe_softc *sc) d1111 2 a1115 6 if (sc->sc_state < PPPOE_STATE_SESSION) return EIO; #ifdef PPPOE_DEBUG printf("%s: sending PADT\n", sc->sc_sppp.pp_if.if_xname); #endif d1118 1 a1118 1 return ENOBUFS; d1120 10 a1129 2 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, sc->sc_session, 0); return pppoe_output(sc, m0); @ 1.37 log @Fix broken error handling in case M_PREPEND fails. Noticed by Matthias Scheeler. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.36 2002/12/25 11:54:33 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.36 2002/12/25 11:54:33 martin Exp $"); a348 1 callout_deactivate(&pppoe_softintr); @ 1.36 log @In do not call pppoe_abort_connect if we fail to send the initial PADI packet - there is nothing to abort. In pppoe_abort_connect rearange state handling slightly to avoid calls to the PPP LCP state machine get into an infinite recursion. This should fix the symptoms of PR kern/19500, but does not touch the real cause for the lossage described there. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.35 2002/09/01 18:06:59 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.35 2002/09/01 18:06:59 martin Exp $"); d1193 2 a1194 2 m_free(m); break; @ 1.35 log @Apply patch from Todd Vierling in PR kern/17665: remove a test that has been obsoleted by the authentication failure counter - enter slow retry mode always, not only if we already transfered data successfully (the test was designed to disable retries when the initial authentication setting was not correct, the auth failure counter does this job better). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.34 2002/09/01 17:21:40 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.34 2002/09/01 17:21:40 martin Exp $"); d996 1 a996 1 int x, err; d1002 2 d1007 11 a1017 1 if (err == 0) d1020 1 a1020 2 else pppoe_abort_connect(sc); d1066 1 a1066 2 sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d1070 4 @ 1.34 log @Add an option PPPOE_TERM_UNKNOWN_SESSIONS to forcefully disconnect sessions we don't know anything about with a PADT packet. Use with care, this is pretty dangerous and will kill all userland PPPoE implementations. Therefore it is not enabled by default nor added as a commented out option to GENERIC kernels. But it is highly usefull if you have a fixed IP, an ISP that does not use LCP echo requests for link monitoring and you want to recover quickly after a crash or otherwise ungracefull disconnect. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.33 2002/08/25 19:21:47 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.33 2002/08/25 19:21:47 tron Exp $"); d933 1 a933 1 * is not set and we already had a successfull connection. d942 1 a942 2 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { @ 1.33 log @Fix typo in a comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.32 2002/06/22 17:41:23 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.32 2002/06/22 17:41:23 yamt Exp $"); d184 1 d606 3 d612 3 d641 25 a665 1 if (sc == NULL) d667 1 @ 1.32 log @- free buf when unneeded. - pass a consistent type to free(9). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.31 2002/06/22 16:56:11 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.31 2002/06/22 16:56:11 yamt Exp $"); d513 1 a513 1 /* be quiete if there is not a single pppoe instance */ @ 1.31 log @fix loop condition. (don't skip last tag) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.30 2002/06/22 11:46:16 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.30 2002/06/22 11:46:16 itojun Exp $"); d264 6 d524 2 d567 1 a567 1 free(sc->sc_ac_cookie, M_MBUF); d1004 1 a1004 1 free(sc->sc_ac_cookie, M_MBUF); @ 1.30 log @avoid unneeded call to m_pullup @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.29 2002/06/22 11:37:48 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.29 2002/06/22 11:37:48 itojun Exp $"); d433 1 a433 1 while (off + sizeof(*pt) < m->m_pkthdr.len) { @ 1.29 log @do not require PPPoE control packet to be put into a single mbuf. reviewed/tested by ymmt @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.28 2002/06/22 05:59:27 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.28 2002/06/22 05:59:27 itojun Exp $"); d531 1 a531 1 PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), d607 6 a612 4 m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; d897 1 a897 1 retry_wait = PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried); @ 1.28 log @more style @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.27 2002/06/22 05:54:14 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.27 2002/06/22 05:54:14 itojun Exp $"); d70 13 a82 1 #define PPPOE_HEADERLEN 6 a104 5 /* Read a 16 bit unsigned value from a buffer */ #define PPPOE_READ_16(PTR, VAL) \ (VAL) = ((PTR)[0] << 8) | (PTR)[1]; \ (PTR)+=2 d157 2 a158 2 static void pppoe_dispatch_disc_pkt(u_int8_t *, size_t, struct ifnet *, struct ether_header *); static void pppoe_data_input(struct mbuf *m); d378 1 a378 1 static void pppoe_dispatch_disc_pkt(u_int8_t *p, size_t size, struct ifnet *rcvif, struct ether_header *eh) a380 1 u_int8_t vertype, code; d384 1 a384 1 u_int8_t * ac_cookie; d386 13 d403 25 a427 3 if (size <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %ld\n", (long)size); return; d429 1 a429 16 vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", vertype); return; } code = *p++; PPPOE_READ_16(p, session); PPPOE_READ_16(p, plen); size -= PPPOE_HEADERLEN; if (plen > size) { printf("pppoe: packet content does not fit: data available = %ld, packet size = %ld\n", (long)size, (long)plen); return; } size = plen; /* ignore trailing garbage */ d433 12 a444 4 while (size > 4) { PPPOE_READ_16(p, tag); PPPOE_READ_16(p, len); if (len > size) { d447 1 a447 1 return; d451 1 a451 1 size = 0; break; d457 10 a466 2 if (sc == NULL) sc = pppoe_find_softc_by_hunique(p, len, rcvif); d470 8 a477 1 ac_cookie = p; d495 1 a495 6 return; } if (size >= 0) { size -= 4 + len; if (len > 0) p += len; d497 1 d499 2 a500 1 switch (code) { d504 1 a504 1 return; d510 1 a510 1 return; d515 1 a515 1 return; d518 2 a519 1 sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); d521 1 a521 1 return; d530 3 a532 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), pppoe_timeout, sc); d538 1 a538 1 return; d549 1 a549 1 return; d570 1 a570 1 code, session); d573 4 a581 2 u_int8_t *p; struct ether_header *eh; a584 4 /* XXX it is not valid to pass pointer outside of mbuf */ eh = mtod(m, struct ether_header *); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t *); d586 3 a588 3 pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); } m_free(m); d594 1 a594 2 u_int8_t *p, vertype; u_int16_t session, plen, code; d596 1 d602 2 a603 1 printf("pppoe (data): dropping too short packet: %ld bytes\n", (long)m->m_pkthdr.len); d607 6 a612 1 p = mtod(m, u_int8_t *); d614 3 a616 3 vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", vertype); d619 1 a619 3 code = *p++; if (code != 0) d622 1 a622 1 PPPOE_READ_16(p, session); d627 1 a627 1 PPPOE_READ_16(p, plen); d664 1 a664 1 m_free(m); d900 2 a901 2 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { @ 1.27 log @style @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.26 2002/06/22 05:52:00 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.26 2002/06/22 05:52:00 itojun Exp $"); d217 1 a217 1 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header)+PPPOE_HEADERLEN; d219 1 a219 1 sc->sc_sppp.pp_flags |= PP_KEEPALIVE| /* use LCP keepalive */ d411 2 a412 1 printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); d443 3 a445 2 printf("%s: %s\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); d467 2 a468 1 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); d493 2 a494 1 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d504 2 a505 1 printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); d629 1 a629 1 etype = sc->sc_state == PPPOE_STATE_SESSION? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; d715 2 a716 1 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d851 2 a852 2 /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; d854 3 a856 3 pppoe_abort_connect(sc); splx(x); return; d860 2 a861 1 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d871 2 a872 1 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d876 3 a878 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried), pppoe_timeout, sc); d885 3 a887 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), pppoe_timeout, sc); d914 2 a915 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d934 2 a935 1 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); @ 1.26 log @more KNF. warn about mbuf misuse (passing pointer outside of mbuf is dangerous) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.25 2002/06/22 05:33:42 itojun Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.25 2002/06/22 05:33:42 itojun Exp $"); d532 1 a532 1 p = mtod(m, u_int8_t*); d554 1 a554 1 p = mtod(m, u_int8_t*); d784 1 a784 1 p = mtod(m0, u_int8_t*); d806 1 a806 1 if (p - mtod(m0, u_int8_t*) != len + PPPOE_HEADERLEN) d808 1 a808 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t*))); d977 1 a977 1 p = mtod(m0, u_int8_t*); d999 1 a999 1 if (p - mtod(m0, u_int8_t*) != len + PPPOE_HEADERLEN) d1001 1 a1001 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t*))); d1023 1 a1023 1 p = mtod(m0, u_int8_t*); d1076 1 a1076 1 p = mtod(m, u_int8_t*); @ 1.25 log @tabify. minor KNF @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24 2002/04/14 12:24:28 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24 2002/04/14 12:24:28 martin Exp $"); d119 1 a119 1 d154 1 a154 1 void pppoeattach(int count); d164 1 a164 1 static void pppoe_timeout(void*); d172 1 a172 1 static int pppoe_output(struct pppoe_softc *sc, struct mbuf *m); d234 1 a234 1 d271 2 a272 1 if (session == 0) return NULL; d293 2 a294 1 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d296 2 a297 1 if (len != sizeof sc) return NULL; d401 1 a401 1 return; d529 2 a530 1 eh = mtod(m, struct ether_header*); d595 1 a595 1 d741 1 a741 1 if (len+sizeof(struct ether_header) > MHLEN) { d768 1 a768 1 len = 2+2+2+2+sizeof sc; /* service name tag is required, host unique is send too */ d775 1 a775 1 len += 2+2+l2; d779 3 a781 2 m0 = pppoe_get_mbuf(len+PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; d967 1 a967 1 len = 2+2+2+2+sizeof(sc); /* service name, host unique */ d973 4 a976 3 len += 2+2+sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len+PPPOE_HEADERLEN); if (!m0) return ENOBUFS; d1021 2 a1022 1 if (!m0) return ENOBUFS; d1031 1 a1031 1 struct pppoe_softc *sc = (void*)sp; d1040 1 a1040 1 struct pppoe_softc *sc = (void*)sp; d1055 1 a1055 1 struct pppoe_softc *sc = (void*)ifp; @ 1.24 log @Fix copyright notice. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.23 2002/03/04 15:15:05 martin Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.23 2002/03/04 15:15:05 martin Exp $"); d142 1 a142 1 void pppoe_softintr_handler(void*); d145 1 a145 1 extern int sppp_ioctl(struct ifnet *ifp, unsigned long cmd, void *data); d149 2 a150 2 static void pppoe_disc_input(struct mbuf *m); static void pppoe_dispatch_disc_pkt(u_int8_t *p, size_t size, struct ifnet *rcvif, struct ether_header *eh); d155 7 a161 7 static int pppoe_connect(struct pppoe_softc *sc); static int pppoe_disconnect(struct pppoe_softc *sc); static void pppoe_abort_connect(struct pppoe_softc *sc); static int pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data); static void pppoe_tls(struct sppp *sp); static void pppoe_tlf(struct sppp *sp); static void pppoe_start(struct ifnet *ifp); d167 3 a169 3 static int pppoe_send_padi(struct pppoe_softc *sc); static int pppoe_send_padr(struct pppoe_softc *sc); static int pppoe_send_padt(struct pppoe_softc *sc); d175 2 a176 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif); d180 2 a181 2 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); d494 22 a515 22 /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_MBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", code, session); break; } d521 2 a522 2 u_int8_t *p; struct ether_header *eh; d524 7 a530 7 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); d532 1 a532 1 m_free(m); d538 3 a540 28 u_int8_t *p, vertype; u_int16_t session, plen, code; struct pppoe_softc *sc; KASSERT(m->m_flags & M_PKTHDR); m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %ld bytes\n", (long)m->m_pkthdr.len); goto drop; } p = mtod(m, u_int8_t*); vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", vertype); goto drop; } code = *p++; if (code != 0) goto drop; PPPOE_READ_16(p, session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) goto drop; d542 26 a567 1 PPPOE_READ_16(p, plen); d570 2 a571 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d574 1 a574 1 m_adj(m, PPPOE_HEADERLEN); d577 2 a578 2 { struct mbuf *p; d580 10 a589 10 printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } d591 11 a601 11 if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; sppp_input(&sc->sc_sppp.pp_if, m); return; d604 1 a604 1 m_free(m); d610 13 a622 13 struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); d625 3 a627 3 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, @ 1.24.4.1 log @Pull up revision 1.25 (requested by martin in ticket #1152): tabify. minor KNF @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d142 1 a142 1 void pppoe_softintr_handler(void *); d145 1 a145 1 extern int sppp_ioctl(struct ifnet *, unsigned long, void *); d149 2 a150 2 static void pppoe_disc_input(struct mbuf *); static void pppoe_dispatch_disc_pkt(u_int8_t *, size_t, struct ifnet *, struct ether_header *); d155 7 a161 7 static int pppoe_connect(struct pppoe_softc *); static int pppoe_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t); static void pppoe_tls(struct sppp *); static void pppoe_tlf(struct sppp *); static void pppoe_start(struct ifnet *); d167 3 a169 3 static int pppoe_send_padi(struct pppoe_softc *); static int pppoe_send_padr(struct pppoe_softc *); static int pppoe_send_padt(struct pppoe_softc *); d175 2 a176 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *); d180 2 a181 2 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); d494 22 a515 22 /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_MBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", code, session); break; } d521 2 a522 2 u_int8_t *p; struct ether_header *eh; d524 7 a530 7 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); d532 1 a532 1 m_free(m); d538 28 a565 3 u_int8_t *p, vertype; u_int16_t session, plen, code; struct pppoe_softc *sc; d567 1 a567 26 KASSERT(m->m_flags & M_PKTHDR); m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %ld bytes\n", (long)m->m_pkthdr.len); goto drop; } p = mtod(m, u_int8_t*); vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", vertype); goto drop; } code = *p++; if (code != 0) goto drop; PPPOE_READ_16(p, session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) goto drop; PPPOE_READ_16(p, plen); d570 2 a571 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d574 1 a574 1 m_adj(m, PPPOE_HEADERLEN); d577 2 a578 2 { struct mbuf *p; d580 10 a589 10 printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } d591 11 a601 11 if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; sppp_input(&sc->sc_sppp.pp_if, m); return; d604 1 a604 1 m_free(m); d610 13 a622 13 struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); d625 3 a627 3 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, @ 1.24.4.2 log @Pull up revision 1.26 (requested by martin in ticket #1152): more KNF. warn about mbuf misuse (passing pointer outside of mbuf is dangerous) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.1 2003/02/07 18:44:32 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.1 2003/02/07 18:44:32 tron Exp $"); d119 1 a119 1 d154 1 a154 1 void pppoeattach(int); d164 1 a164 1 static void pppoe_timeout(void *); d172 1 a172 1 static int pppoe_output(struct pppoe_softc *, struct mbuf *); d234 1 a234 1 d271 1 a271 2 if (session == 0) return NULL; d292 1 a292 2 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d294 1 a294 2 if (len != sizeof sc) return NULL; d398 1 a398 1 return; d526 1 a526 2 /* XXX it is not valid to pass pointer outside of mbuf */ eh = mtod(m, struct ether_header *); d591 1 a591 1 d737 1 a737 1 if (len + sizeof(struct ether_header) > MHLEN) { d764 1 a764 1 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ d771 1 a771 1 len += 2 + 2 + l2; d775 2 a776 3 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; d962 1 a962 1 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ d968 3 a970 4 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return ENOBUFS; d1015 1 a1015 2 if (!m0) return ENOBUFS; d1024 1 a1024 1 struct pppoe_softc *sc = (void *)sp; d1033 1 a1033 1 struct pppoe_softc *sc = (void *)sp; d1048 1 a1048 1 struct pppoe_softc *sc = (void *)ifp; @ 1.24.4.3 log @Pull up revision 1.27 (requested by martin in ticket #1152): style @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.2 2003/02/07 19:20:56 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.2 2003/02/07 19:20:56 tron Exp $"); d532 1 a532 1 p = mtod(m, u_int8_t *); d554 1 a554 1 p = mtod(m, u_int8_t *); d784 1 a784 1 p = mtod(m0, u_int8_t *); d806 1 a806 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d808 1 a808 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d977 1 a977 1 p = mtod(m0, u_int8_t *); d999 1 a999 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d1001 1 a1001 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1023 1 a1023 1 p = mtod(m0, u_int8_t *); d1076 1 a1076 1 p = mtod(m, u_int8_t *); @ 1.24.4.4 log @Pull up revision 1.28 (requested by martin in ticket #1152): more style @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.3 2003/02/07 19:56:56 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.3 2003/02/07 19:56:56 tron Exp $"); d217 1 a217 1 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; d219 1 a219 1 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ d411 1 a411 2 printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); d442 2 a443 3 printf("%s: %s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); d465 1 a465 2 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); d490 1 a490 2 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d500 1 a500 2 printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); d624 1 a624 1 etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; d710 1 a710 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d845 2 a846 2 /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; d848 3 a850 3 pppoe_abort_connect(sc); splx(x); return; d854 1 a854 2 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d864 1 a864 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d868 1 a868 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d875 1 a875 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d902 1 a902 2 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d921 1 a921 2 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); @ 1.24.4.5 log @Pull up revision 1.29 (requested by martin in ticket #1152): do not require PPPoE control packet to be put into a single mbuf. reviewed/tested by ymmt @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.4 2003/02/07 19:58:08 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.4 2003/02/07 19:58:08 tron Exp $"); d70 1 a70 13 struct pppoehdr { u_int8_t vertype; u_int8_t code; u_int16_t session; u_int16_t plen; } __attribute__((__packed__)); struct pppoetag { u_int16_t tag; u_int16_t len; } __attribute__((__packed__)); #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d93 5 d150 2 a151 2 static void pppoe_dispatch_disc_pkt(struct mbuf *, int); static void pppoe_data_input(struct mbuf *); d371 1 a371 1 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) d374 1 d378 1 a378 1 u_int8_t *ac_cookie; a379 13 struct pppoehdr *ph; struct pppoetag *pt; struct mbuf *n; int noff; struct ether_header *eh; if (m->m_len < sizeof(*eh)) { m = m_pullup(m, sizeof(*eh)); if (!m) goto done; } eh = mtod(m, struct ether_header *); off += sizeof(*eh); d384 3 a386 25 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); goto done; } n = m_pulldown(m, off, sizeof(*ph), &noff); if (!n) { printf("pppoe: could not get PPPoE header\n"); m = NULL; goto done; } ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); goto done; } session = ntohs(ph->session); plen = ntohs(ph->plen); off += sizeof(*ph); if (plen + off > m->m_pkthdr.len) { printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", m->m_pkthdr.len - off, plen); goto done; d388 16 a403 1 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ d407 4 a410 12 while (off + sizeof(*pt) < m->m_pkthdr.len) { n = m_pulldown(m, off, sizeof(*pt), &noff); if (!n) { printf("%s: parse error\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); m = NULL; goto done; } pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); tag = ntohs(pt->tag); len = ntohs(pt->len); if (off + len > m->m_pkthdr.len) { d413 1 a413 1 goto done; d417 1 a417 1 goto breakbreak; d423 2 a424 10 if (sc != NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG HUNIQUE ERROR"; m = NULL; goto done; } sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, len, m->m_pkthdr.rcvif); d428 1 a428 8 n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG ACCOOKIE ERROR"; m = NULL; break; } ac_cookie = mtod(n, caddr_t) + noff; d446 6 a451 1 goto done; a452 1 off += sizeof(*pt) + len; d454 1 a454 2 breakbreak:; switch (ph->code) { d458 1 a458 1 goto done; d464 1 a464 1 goto done; d469 1 a469 1 goto done; d472 1 a472 2 sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); d474 1 a474 1 goto done; d483 1 a483 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), pppoe_timeout, sc); d489 1 a489 1 goto done; d500 1 a500 1 goto done; d521 1 a521 1 ph->code, session); a523 4 done: m_freem(m); return; d529 2 d534 4 d539 3 a541 3 pppoe_dispatch_disc_pkt(m, 0); } else m_freem(m); d547 2 a548 1 u_int16_t session, plen; a549 1 struct pppoehdr *ph; d555 1 a555 2 printf("pppoe (data): dropping too short packet: %d bytes\n", m->m_pkthdr.len); d559 1 a559 6 m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; } ph = mtod(m, struct pppoehdr *); d561 3 a563 3 if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); d566 3 a568 1 if (ph->code != 0) d571 1 a571 1 session = ntohs(ph->session); d576 1 a576 1 plen = ntohs(ph->plen); d613 1 a613 1 m_freem(m); d849 2 a850 2 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { @ 1.24.4.6 log @Pull up revision 1.30 (requested by martin in ticket #1152): avoid unneeded call to m_pullup @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.5 2003/02/07 19:59:19 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.5 2003/02/07 19:59:19 tron Exp $"); d531 1 a531 1 PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), d607 4 a610 6 if (m->m_len < sizeof(*ph)) { m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; } d895 1 a895 1 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); @ 1.24.4.7 log @Pull up revision 1.31 (requested by martin in ticket #1152): fix loop condition. (don't skip last tag) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.6 2003/02/07 20:04:22 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.6 2003/02/07 20:04:22 tron Exp $"); d433 1 a433 1 while (off + sizeof(*pt) <= m->m_pkthdr.len) { @ 1.24.4.8 log @Pull up revision 1.32 (requested by martin in ticket #1152): - free buf when unneeded. - pass a consistent type to free(9). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.7 2003/02/07 20:06:26 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.7 2003/02/07 20:06:26 tron Exp $"); a263 6 if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); a517 2 if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); d559 1 a559 1 free(sc->sc_ac_cookie, M_DEVBUF); d996 1 a996 1 free(sc->sc_ac_cookie, M_DEVBUF); @ 1.24.4.9 log @Pull up revision 1.33 (requested by martin in ticket #1152): Fix typo in a comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.8 2003/02/07 20:07:20 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.8 2003/02/07 20:07:20 tron Exp $"); d513 1 a513 1 /* be quiet if there is not a single pppoe instance */ @ 1.24.4.10 log @Pull up revision 1.34 (requested by martin in ticket #1152): Add an option PPPOE_TERM_UNKNOWN_SESSIONS to forcefully disconnect sessions we don't know anything about with a PADT packet. Use with care, this is pretty dangerous and will kill all userland PPPoE implementations. Therefore it is not enabled by default nor added as a commented out option to GENERIC kernels. But it is highly usefull if you have a fixed IP, an ISP that does not use LCP echo requests for link monitoring and you want to recover quickly after a crash or otherwise ungracefull disconnect. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.9 2003/02/07 20:08:45 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.9 2003/02/07 20:08:45 tron Exp $"); a183 1 static struct mbuf *pppoe_get_mbuf(size_t len); a604 3 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS u_int8_t shost[ETHER_ADDR_LEN]; #endif a607 3 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); #endif d634 1 a634 25 if (sc == NULL) { #ifdef PPPOE_TERM_UNKNOWN_SESSIONS struct mbuf *m0; struct sockaddr dst; struct ether_header *eh; u_int8_t *p; printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) goto drop; p = mtod(m0, u_int8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOE); memcpy(&eh->ether_dhost, shost, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); m->m_pkthdr.rcvif->if_output(m->m_pkthdr.rcvif, m0, &dst, NULL); #endif a635 1 } @ 1.24.4.11 log @Pull up revision 1.35 (requested by martin in ticket #1152): Apply patch from Todd Vierling in PR kern/17665: remove a test that has been obsoleted by the authentication failure counter - enter slow retry mode always, not only if we already transfered data successfully (the test was designed to disable retries when the initial authentication setting was not correct, the auth failure counter does this job better). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.10 2003/02/07 20:10:28 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.10 2003/02/07 20:10:28 tron Exp $"); d933 1 a933 1 * is not set. d942 2 a943 1 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { @ 1.24.4.12 log @Pull up revision 1.36 (requested by martin in ticket #1152): In do not call pppoe_abort_connect if we fail to send the initial PADI packet - there is nothing to abort. In pppoe_abort_connect rearange state handling slightly to avoid calls to the PPP LCP state machine get into an infinite recursion. This should fix the symptoms of PR kern/19500, but does not touch the real cause for the lossage described there. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.11 2003/02/07 20:13:08 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.11 2003/02/07 20:13:08 tron Exp $"); d996 1 a996 1 int x, err, retry; a1001 2 /* save state, in case we fail to send PADI */ retry = sc->sc_padr_retried; d1005 1 a1005 11 if (err != 0) { /* * We failed to send a single PADI packet. * This is unfortunate, because we have no good way to recover * from here. */ /* recover state and return the error */ sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padr_retried = retry; } else { d1008 2 a1009 1 } d1055 2 a1056 1 sc->sc_state = PPPOE_STATE_CLOSING; a1059 4 /* clear connection state */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_INITIAL; @ 1.24.4.13 log @Pull up revision 1.37 (requested by martin in ticket #1152): Fix broken error handling in case M_PREPEND fails. Noticed by Matthias Scheeler. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.12 2003/02/07 20:15:02 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.12 2003/02/07 20:15:02 tron Exp $"); d1193 2 a1194 2 ifp->if_oerrors++; continue; @ 1.24.4.14 log @Pull up revision 1.39 (requested by martin in ticket #1152): PADT is always send with ethertype PPPOE_DISCOVERY, no matter if we have reached session state or not. Fixes PR kern/20203 by Shoichi Miyake. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.24.4.13 2003/02/07 20:16:37 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.24.4.13 2003/02/07 20:16:37 tron Exp $"); d176 1 a176 1 static int pppoe_send_padt(struct ifnet *, u_int, const u_int8_t *); d643 5 d650 15 a664 1 pppoe_send_padt(m->m_pkthdr.rcvif, session, shost); d1039 1 a1039 1 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const u_int8_t *)&sc->sc_dest); d1129 1 a1129 1 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const u_int8_t *dest) a1130 2 struct ether_header *eh; struct sockaddr dst; d1134 6 d1142 1 a1142 1 return EIO; d1144 2 a1145 10 PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOEDISC); memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); return outgoing_if->if_output(outgoing_if, m0, &dst, NULL); @ 1.24.4.15 log @Pullup rev 1.40 (requested by aymeric in ticket #1187) When looking up a Host-Uniq tag, do not consider NULL as a valid (struct pppoe_softc *). Although we do not generate such tags, other hosts could and some actually do. @ text @d1 1 a1 1 /* $NetBSD$ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD$"); d317 1 a317 1 if (sc == NULL) { @ 1.24.4.16 log @Pull up revision 1.45 (requested by martin in ticket #1438): When trying to (re-)establish a session cope with intermediate output failures of the underlying ethernet interface - just keep trying. @ text @d396 1 a396 1 int noff, err; d538 6 a543 9 if ((err = pppoe_send_padr(sc)) != 0) { if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d898 1 a898 1 int x, retry_wait, err; d932 5 a936 9 if ((err = pppoe_send_padi(sc)) != 0) { sc->sc_padi_retried--; if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to transmit PADI, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d948 6 a953 10 if ((err = pppoe_send_padi(sc)) != 0) { if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI" ", error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d957 6 a962 10 if ((err = pppoe_send_padr(sc)) != 0) { sc->sc_padr_retried--; if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADR, " "error=%d\n", sc->sc_sppp.pp_if.if_xname, err); } callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d988 14 a1001 4 if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: failed to send PADI, error=%d\n", sc->sc_sppp.pp_if.if_xname, err); callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); @ 1.24.2.1 log @catch up with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.32 2002/06/22 17:41:23 yamt Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.32 2002/06/22 17:41:23 yamt Exp $"); d70 1 a70 13 struct pppoehdr { u_int8_t vertype; u_int8_t code; u_int16_t session; u_int16_t plen; } __attribute__((__packed__)); struct pppoetag { u_int16_t tag; u_int16_t len; } __attribute__((__packed__)); #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d93 5 d119 1 a119 1 d142 1 a142 1 void pppoe_softintr_handler(void *); d145 1 a145 1 extern int sppp_ioctl(struct ifnet *, unsigned long, void *); d149 3 a151 3 static void pppoe_disc_input(struct mbuf *); static void pppoe_dispatch_disc_pkt(struct mbuf *, int); static void pppoe_data_input(struct mbuf *); d154 8 a161 8 void pppoeattach(int); static int pppoe_connect(struct pppoe_softc *); static int pppoe_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t); static void pppoe_tls(struct sppp *); static void pppoe_tlf(struct sppp *); static void pppoe_start(struct ifnet *); d164 1 a164 1 static void pppoe_timeout(void *); d167 3 a169 3 static int pppoe_send_padi(struct pppoe_softc *); static int pppoe_send_padr(struct pppoe_softc *); static int pppoe_send_padt(struct pppoe_softc *); d172 1 a172 1 static int pppoe_output(struct pppoe_softc *, struct mbuf *); d175 2 a176 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *); d180 2 a181 2 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); d217 1 a217 1 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; d219 1 a219 1 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ d234 1 a234 1 a256 6 if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); d271 1 a271 2 if (session == 0) return NULL; d292 1 a292 2 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d294 1 a294 2 if (len != sizeof sc) return NULL; d368 1 a368 1 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) d371 1 d375 1 a375 1 u_int8_t *ac_cookie; a376 13 struct pppoehdr *ph; struct pppoetag *pt; struct mbuf *n; int noff; struct ether_header *eh; if (m->m_len < sizeof(*eh)) { m = m_pullup(m, sizeof(*eh)); if (!m) goto done; } eh = mtod(m, struct ether_header *); off += sizeof(*eh); d381 8 a388 25 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); goto done; } n = m_pulldown(m, off, sizeof(*ph), &noff); if (!n) { printf("pppoe: could not get PPPoE header\n"); m = NULL; goto done; } ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); goto done; } session = ntohs(ph->session); plen = ntohs(ph->plen); off += sizeof(*ph); if (plen + off > m->m_pkthdr.len) { printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", m->m_pkthdr.len - off, plen); goto done; d390 11 a400 1 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ d404 6 a409 15 while (off + sizeof(*pt) <= m->m_pkthdr.len) { n = m_pulldown(m, off, sizeof(*pt), &noff); if (!n) { printf("%s: parse error\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); m = NULL; goto done; } pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); tag = ntohs(pt->tag); len = ntohs(pt->len); if (off + len > m->m_pkthdr.len) { printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); goto done; d413 1 a413 1 goto breakbreak; d419 2 a420 10 if (sc != NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG HUNIQUE ERROR"; m = NULL; goto done; } sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, len, m->m_pkthdr.rcvif); d424 1 a424 8 n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG ACCOOKIE ERROR"; m = NULL; break; } ac_cookie = mtod(n, caddr_t) + noff; d439 8 a446 4 printf("%s: %s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); goto done; a447 1 off += sizeof(*pt) + len; d449 1 a449 2 breakbreak:; switch (ph->code) { d453 1 a453 1 goto done; d459 1 a459 1 goto done; d462 2 a463 3 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); goto done; d466 1 a466 4 if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); d468 1 a468 1 goto done; d477 1 a477 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d483 1 a483 1 goto done; d487 1 a487 2 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d493 23 a515 28 goto done; /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", ph->code, session); break; } done: m_freem(m); return; d521 2 d524 9 a532 6 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(m, 0); } else m_freem(m); d538 28 a565 34 u_int16_t session, plen; struct pppoe_softc *sc; struct pppoehdr *ph; KASSERT(m->m_flags & M_PKTHDR); m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %d bytes\n", m->m_pkthdr.len); goto drop; } if (m->m_len < sizeof(*ph)) { m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; } } ph = mtod(m, struct pppoehdr *); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); goto drop; } if (ph->code != 0) goto drop; session = ntohs(ph->session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) goto drop; d567 1 a567 1 plen = ntohs(ph->plen); d570 2 a571 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d574 1 a574 1 m_adj(m, PPPOE_HEADERLEN); d577 2 a578 2 { struct mbuf *p; d580 10 a589 10 printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } d591 11 a601 11 if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; sppp_input(&sc->sc_sppp.pp_if, m); return; d604 1 a604 1 m_freem(m); d610 13 a622 13 struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); d625 3 a627 3 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, d706 1 a706 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d737 1 a737 1 if (len + sizeof(struct ether_header) > MHLEN) { d764 1 a764 1 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ d771 1 a771 1 len += 2 + 2 + l2; d775 2 a776 3 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; d779 1 a779 1 p = mtod(m0, u_int8_t *); d801 1 a801 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d803 1 a803 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d833 1 a833 1 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); d838 4 a841 4 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; d843 3 a845 3 pppoe_abort_connect(sc); splx(x); return; d849 1 a849 2 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d859 1 a859 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d863 1 a863 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d870 1 a870 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d897 1 a897 2 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d916 1 a916 2 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); d924 1 a924 1 free(sc->sc_ac_cookie, M_DEVBUF); d962 1 a962 1 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ d968 4 a971 5 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d993 1 a993 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d995 1 a995 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1015 2 a1016 3 if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d1024 1 a1024 1 struct pppoe_softc *sc = (void *)sp; d1033 1 a1033 1 struct pppoe_softc *sc = (void *)sp; d1048 1 a1048 1 struct pppoe_softc *sc = (void *)ifp; d1069 1 a1069 1 p = mtod(m, u_int8_t *); @ 1.24.2.2 log @catch up with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.33 2002/08/25 19:21:47 tron Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.33 2002/08/25 19:21:47 tron Exp $"); d513 1 a513 1 /* be quiet if there is not a single pppoe instance */ @ 1.23 log @Avoid noise from the kernel if we have pseudo-device pppoe configured but not used and a userland PPPoE pkg sends/receives PPPoE packets. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.22 2002/02/24 17:11:53 martin Exp $ */ d3 6 a8 2 /* * Copyright (c) 2001 Martin Husemann. All rights reserved. d18 7 d26 11 a36 12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.22 2002/02/24 17:11:53 martin Exp $"); @ 1.22 log @Clear M_BCAST and M_MCAST flags on mbufs before passing them down to the ethernet driver - just in case it would look at them and do the wrong thing. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.21 2002/02/10 15:13:43 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.21 2002/02/10 15:13:43 martin Exp $"); d446 3 a448 1 printf("pppoe: received PADO but could not find request for it\n"); d514 8 a521 5 eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); @ 1.21 log @Fix typo in comment. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.20 2002/02/01 13:50:00 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.20 2002/02/01 13:50:00 martin Exp $"); d616 1 @ 1.20 log @Avoid any non-error output for normal operations, only print those messages if the interface is set to debug. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.19 2002/02/01 13:40:16 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.19 2002/02/01 13:40:16 martin Exp $"); d1040 1 a1040 1 /* are we read to proccess data yet? */ @ 1.19 log @Tweak the slow-but-persistent connection reestablishment timeout, retrying is not realy expensive - do it once every minute. Prevent the MTU from being set bigger than what we can handle. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.18 2002/01/14 16:10:33 kleink Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.18 2002/01/14 16:10:33 kleink Exp $"); d474 2 a475 1 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d484 2 a485 2 /* signal upper layer */ printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); d495 1 d899 2 a900 1 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); @ 1.18 log @As discussed with Aymeric, is always required, so don't make its inclusion conditional. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.17 2002/01/14 16:04:44 aymeric Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.17 2002/01/14 16:04:44 aymeric Exp $"); d80 3 d101 1 a101 1 #define PPPOE_SLOW_RETRY (hz*240) /* persistent retry interval */ d204 1 a204 1 sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN - 2; /* two byte PPP protocol discriminator, then IP data */ d690 9 a699 1 /* FALLTHROUGH */ @ 1.17 log @Don't include machine/types.h (my fault in previous commit) Reported by Klaus Klein. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.16 2002/01/13 10:57:57 aymeric Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.16 2002/01/13 10:57:57 aymeric Exp $"); a54 1 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS a55 1 #endif @ 1.16 log @include machine/types.h include machine/intr.h if defined(__HAVE_GENERIC_SOFT_INTERRUPTS) It makes this file compile for the amiga. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.15 2002/01/04 12:21:25 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.15 2002/01/04 12:21:25 martin Exp $"); a54 1 #include @ 1.15 log @Move net/if_sppp.h to net/if_spppvar.h, create a new net/if_sppp.h containing the userland visible thinks (i.e. ioctl definitions). Remove all (both) old ioctls, as they had a brain dead API and made keeping binary compatibility more or less impossible. Replace by several new ioctls. While there, remove any arbitrary limits (resulting from the old, broken ioctls) and allow any length of names and passwords. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.14 2001/12/16 23:53:31 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.14 2001/12/16 23:53:31 martin Exp $"); d53 5 @ 1.14 log @Cleanup softc more completely on "ifconfig down", but only if we are currently in a connection reestablishement state. The previouse (incomplete/unconditional) cleanup confused the state machine. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.13 2001/12/16 11:40:52 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.13 2001/12/16 11:40:52 martin Exp $"); d48 1 a104 5 #define PPPOE_STATE_INITIAL 0 #define PPPOE_STATE_PADI_SENT 1 #define PPPOE_STATE_PADR_SENT 2 #define PPPOE_STATE_SESSION 3 #define PPPOE_STATE_CLOSING 4 d656 10 @ 1.13 log @Fix packet accounting (now netstat -i and netstat -ib show reasonable values). Implement a secondary connection-reestablishement mode, which is only entered after (1) we have successfully transfered payload data over this connection and (2) if initial retries did not reestablish a session. In this mode we retry (infrequently) forever, until adminstrator stops us (by "ifconfig ppppoe0 down"). XXX - need to display this mode in pppoectl. It is now possible to pull the DSL modems plug for say 15 minutes, plug it back in again and just wait. The connection will be reestablished within three minutes. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.12 2001/12/15 20:43:31 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.12 2001/12/15 20:43:31 martin Exp $"); d670 3 a672 1 if ((ifr->ifr_flags & IFF_UP) == 0) { d674 1 d677 1 @ 1.12 log @Enable additional error messages for the discovery phase, clarify some others. Change one timeout slightly - we need to make all others user settable. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.11 2001/12/10 23:23:24 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.11 2001/12/10 23:23:24 martin Exp $"); d94 3 a96 2 #define PPPOE_DISC_TIMEOUT hz/5 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times */ d580 2 a581 1 /* pass packet up */ d613 1 d663 14 d772 1 a772 1 int x; d781 13 d797 9 a805 3 pppoe_abort_connect(sc); splx(x); return; d808 1 a808 1 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried), pppoe_timeout, sc); @ 1.11 log @Enable active LCP keepalive handling in the PPP layer, the PPPoE layer itself has no means to detect broken connections. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.10 2001/12/10 00:24:12 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.10 2001/12/10 00:24:12 martin Exp $"); d94 4 a101 4 #define PPPOE_DISC_TIMEOUT hz/5 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times */ #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ d290 1 a290 1 printf("pppoe: invalid host unique value\n"); d297 1 a297 2 #ifdef PPPOE_DEBUG printf("%s: state=%d, not accepting host unique\n", a298 1 #endif a301 1 #ifdef PPPOE_DEBUG a303 1 #endif d964 1 a964 1 callout_reset(&sc->sc_timeout, hz/100, pppoe_timeout, sc); @ 1.10 log @Now that everything works without LINK1 set, do not set it by default. While here, remove an unnecessary splnet()/splx() pair. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.9 2001/12/01 18:25:23 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.9 2001/12/01 18:25:23 martin Exp $"); d207 2 a208 1 sc->sc_sppp.pp_flags |= PP_NOFRAMING; /* no serial encapsulation */ @ 1.9 log @Fail early when trying to identify a pppoe interface softc (from a HOST UNIQUE token) and our list of interfaces is empty. Without this test an unitinalized pointer may be dereferenced. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.8 2001/11/13 00:49:35 lukem Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.8 2001/11/13 00:49:35 lukem Exp $"); d203 1 a203 2 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST | IFF_LINK1; /* auto "dial" */ a801 1 x = splnet(); a802 1 splx(x); @ 1.8 log @remove unnecessary #if NFOO > 0 .... #endif wrappers @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.7 2001/11/12 23:49:42 lukem Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.7 2001/11/12 23:49:42 lukem Exp $"); d279 3 @ 1.7 log @add RCSIDs @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.6 2001/10/28 09:48:20 martin Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD$"); a53 2 #if NPPPOE > 0 a1004 2 #endif /* NPPPOE > 0 */ @ 1.6 log @Don't call if_alloc_sadl when creating the pppoe interface, it's called from sppp_attach. When destroying the interface, call sppp_detach for proper cleanup. This avoids a crash from the slow timeout handler for no longer existing interfaces (spotted by Rémi Zara). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.5 2001/09/04 20:41:32 martin Exp $ */ d28 3 @ 1.5 log @Make this interface cloning. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4 2001/06/24 20:35:50 martin Exp $ */ a224 1 if_alloc_sadl(&sc->sc_sppp.pp_if); d242 1 @ 1.5.4.1 log @Sync the thorpej-mips-cache branch with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.6 2001/10/28 09:48:20 martin Exp $ */ d225 1 a242 1 sppp_detach(&sc->sc_sppp.pp_if); @ 1.4 log @Take into account the two byte PPP protocol discrimator following the PPPoE header when calculating the MTU. Ooops... Thanks to Mario Kemper for noting this. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3 2001/06/18 12:32:47 martin Exp $ */ d95 1 d141 1 a141 1 void pppoeattach(void); d165 1 a165 2 /* XXX - turn into SLIST and implement "ifconfig create" */ struct pppoe_softc pppoe_softc[NPPPOE]; d167 7 a173 3 /* * Initialize device data structures */ d175 18 a192 1 pppoeattach() a194 1 int i = 0; d196 25 a220 24 memset(pppoe_softc, 0, sizeof pppoe_softc); for (sc = pppoe_softc; i < NPPPOE; sc++) { sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", i++); sc->sc_sppp.pp_if.if_softc = sc; sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN - 2; /* two byte PPP protocol discriminator, then IP data */ sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST | IFF_LINK1; /* auto "dial" */ sc->sc_sppp.pp_if.if_type = IFT_PPP; sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header)+PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; sc->sc_sppp.pp_flags |= PP_NOFRAMING; /* no serial encapsulation */ sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); callout_init(&sc->sc_timeout); sc->sc_sppp.pp_if.if_start = pppoe_start; sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ d222 2 a223 2 if_attach(&sc->sc_sppp.pp_if); sppp_attach(&sc->sc_sppp.pp_if); d225 1 a225 1 if_alloc_sadl(&sc->sc_sppp.pp_if); d227 1 a227 1 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d229 3 a231 1 } d233 5 a237 2 ppoediscinq.ifq_maxlen = IFQ_MAXLEN; ppoeinq.ifq_maxlen = IFQ_MAXLEN; d239 3 a241 2 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); d243 2 d256 1 a256 1 int i; d260 5 a264 5 for (i = 0; i < NPPPOE; i++) { if (pppoe_softc[i].sc_state == PPPOE_STATE_SESSION && pppoe_softc[i].sc_session == session) { if (pppoe_softc[i].sc_eth_if == rcvif) return &pppoe_softc[i]; d277 1 a277 1 struct pppoe_softc *sc = NULL; d279 6 a284 3 memcpy(&sc, token, len); /* XXX - change when turning softc array into an SLIST */ if (sc < &pppoe_softc[0] && sc > &pppoe_softc[NPPPOE-1]) { d290 1 @ 1.4.2.1 log @Update the kqueue branch to HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.5 2001/09/04 20:41:32 martin Exp $ */ a94 1 LIST_ENTRY(pppoe_softc) sc_list; d140 1 a140 1 void pppoeattach(int count); d164 2 a165 1 LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; d167 3 a169 7 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); struct if_clone pppoe_cloner = IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy); /* ARGSUSED */ d171 1 a171 18 pppoeattach(count) int count; { LIST_INIT(&pppoe_softc_list); if_clone_attach(&pppoe_cloner); ppoediscinq.ifq_maxlen = IFQ_MAXLEN; ppoeinq.ifq_maxlen = IFQ_MAXLEN; #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); #endif } int pppoe_clone_create(ifc, unit) struct if_clone *ifc; int unit; d174 1 d176 24 a199 25 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK); memset(sc, 0, sizeof(struct pppoe_softc)); sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", unit); sc->sc_sppp.pp_if.if_softc = sc; sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN - 2; /* two byte PPP protocol discriminator, then IP data */ sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST | IFF_LINK1; /* auto "dial" */ sc->sc_sppp.pp_if.if_type = IFT_PPP; sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header)+PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; sc->sc_sppp.pp_flags |= PP_NOFRAMING; /* no serial encapsulation */ sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); callout_init(&sc->sc_timeout); sc->sc_sppp.pp_if.if_start = pppoe_start; sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ d201 2 a202 2 if_attach(&sc->sc_sppp.pp_if); sppp_attach(&sc->sc_sppp.pp_if); d204 1 a204 1 if_alloc_sadl(&sc->sc_sppp.pp_if); d206 1 a206 1 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d208 1 a208 3 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); return 0; } d210 2 a211 5 void pppoe_clone_destroy(ifp) struct ifnet *ifp; { struct pppoe_softc * sc = ifp->if_softc; d213 2 a214 3 LIST_REMOVE(sc, sc_list); #if NBPFILTER > 0 bpfdetach(ifp); a215 2 if_detach(ifp); free(sc, M_DEVBUF); d227 1 a227 1 struct pppoe_softc *sc; d231 5 a235 5 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_state == PPPOE_STATE_SESSION && sc->sc_session == session) { if (sc->sc_eth_if == rcvif) return sc; d248 1 a248 1 struct pppoe_softc *sc, *t; d250 3 a252 6 memcpy(&t, token, len); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) if (sc == t) break; if (sc != t) { a257 1 @ 1.4.2.2 log @Sync kqueue branch with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4.2.1 2001/09/13 01:16:21 thorpej Exp $ */ a28 3 #include __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.15 2002/01/04 12:21:25 martin Exp $"); a44 1 #include d51 2 a92 5 #define PPPOE_DISC_TIMEOUT (hz*5) /* base for quick timeout calculation */ #define PPPOE_SLOW_RETRY (hz*240) /* persistent retry interval */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ d97 4 d102 5 d202 2 a203 1 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; d207 1 a207 2 sc->sc_sppp.pp_flags |= PP_KEEPALIVE| /* use LCP keepalive */ PP_NOFRAMING; /* no serial encapsulation */ d225 1 a242 1 sppp_detach(&sc->sc_sppp.pp_if); a277 3 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d286 1 a286 1 printf("pppoe: alien host unique tag, no session found\n"); d293 2 a294 1 printf("%s: host unique tag found, but it belongs to a connection in state %d\n", d296 1 d300 1 d303 1 d579 1 a579 2 /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; a610 1 sc->sc_sppp.pp_if.if_opackets++; a659 28 case PPPOEGETSESSION: { struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data; state->state = sc->sc_state; state->session_id = sc->sc_session; state->padi_retry_no = sc->sc_padi_retried; state->padr_retry_no = sc->sc_padr_retried; return 0; } break; case SIOCSIFFLAGS: { struct ifreq *ifr = (struct ifreq*) data; /* * Prevent running re-establishment timers overriding * administrators choice. */ if ((ifr->ifr_flags & IFF_UP) == 0 && sc->sc_state >= PPPOE_STATE_PADI_SENT && sc->sc_state < PPPOE_STATE_SESSION) { callout_stop(&sc->sc_timeout); sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); } } /* FALLTHROUGH */ d755 1 a755 1 int x, retry_wait; a763 13 /* * We have two basic ways of retrying: * - Quick retry mode: try a few times in short sequence * - Slow retry mode: we already had a connection successfully * established and will try infinitely (without user * intervention) * We only enter slow retry mode if IFF_LINK1 (aka autodial) * is not set and we already had a successfull connection. */ /* initialize for quick retry mode */ retry_wait = PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried); d767 3 a769 9 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; } else { pppoe_abort_connect(sc); splx(x); return; } d772 1 a772 1 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d799 1 d801 1 d966 1 a966 1 callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc); d1004 2 @ 1.4.2.3 log @Sync w/ -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4.2.2 2002/01/10 20:02:09 thorpej Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.4.2.2 2002/01/10 20:02:09 thorpej Exp $"); a54 2 #include a77 3 /* two byte PPP protocol discriminator, then IP data */ #define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) d96 1 a96 1 #define PPPOE_SLOW_RETRY (hz*60) /* persistent retry interval */ d199 1 a199 1 sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU; d469 1 a469 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d478 2 a479 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); a488 1 /* signal upper layer */ a684 9 return sppp_ioctl(ifp, cmd, data); } case SIOCSIFMTU: { struct ifreq *ifr = (struct ifreq*) data; if (ifr->ifr_mtu > PPPOE_MAXMTU) return EINVAL; return sppp_ioctl(ifp, cmd, data); d686 1 d884 1 a884 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); @ 1.4.2.4 log @Catch up with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4.2.3 2002/02/11 20:10:29 jdolecek Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.4.2.3 2002/02/11 20:10:29 jdolecek Exp $"); d446 1 a446 3 /* be quiete if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) printf("pppoe: received PADO but could not find request for it\n"); d512 5 a516 8 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); } a615 1 m->m_flags &= ~(M_BCAST|M_MCAST); d1040 1 a1040 1 /* are we ready to proccess data yet? */ @ 1.4.2.5 log @catch up with -current on kqueue branch @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4.2.4 2002/03/16 16:02:06 jdolecek Exp $ */ d3 2 a4 6 /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Martin Husemann . a13 7 * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. d15 12 a26 11 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.4.2.4 2002/03/16 16:02:06 jdolecek Exp $"); @ 1.4.2.6 log @sync kqueue branch with HEAD @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.4.2.5 2002/06/23 17:50:26 jdolecek Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.4.2.5 2002/06/23 17:50:26 jdolecek Exp $"); d70 1 a70 13 struct pppoehdr { u_int8_t vertype; u_int8_t code; u_int16_t session; u_int16_t plen; } __attribute__((__packed__)); struct pppoetag { u_int16_t tag; u_int16_t len; } __attribute__((__packed__)); #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d93 5 d119 1 a119 1 d142 1 a142 1 void pppoe_softintr_handler(void *); d145 1 a145 1 extern int sppp_ioctl(struct ifnet *, unsigned long, void *); d149 3 a151 3 static void pppoe_disc_input(struct mbuf *); static void pppoe_dispatch_disc_pkt(struct mbuf *, int); static void pppoe_data_input(struct mbuf *); d154 8 a161 8 void pppoeattach(int); static int pppoe_connect(struct pppoe_softc *); static int pppoe_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t); static void pppoe_tls(struct sppp *); static void pppoe_tlf(struct sppp *); static void pppoe_start(struct ifnet *); d164 1 a164 1 static void pppoe_timeout(void *); d167 3 a169 3 static int pppoe_send_padi(struct pppoe_softc *); static int pppoe_send_padr(struct pppoe_softc *); static int pppoe_send_padt(struct pppoe_softc *); d172 1 a172 1 static int pppoe_output(struct pppoe_softc *, struct mbuf *); d175 2 a176 3 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *); static struct mbuf *pppoe_get_mbuf(size_t len); d180 2 a181 2 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); d217 1 a217 1 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; d219 1 a219 1 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ d234 1 a234 1 a256 6 if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); d271 1 a271 2 if (session == 0) return NULL; d292 1 a292 2 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d294 1 a294 2 if (len != sizeof sc) return NULL; d368 1 a368 1 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) d371 1 d375 1 a375 1 u_int8_t *ac_cookie; a376 13 struct pppoehdr *ph; struct pppoetag *pt; struct mbuf *n; int noff; struct ether_header *eh; if (m->m_len < sizeof(*eh)) { m = m_pullup(m, sizeof(*eh)); if (!m) goto done; } eh = mtod(m, struct ether_header *); off += sizeof(*eh); d381 18 a398 25 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); goto done; } n = m_pulldown(m, off, sizeof(*ph), &noff); if (!n) { printf("pppoe: could not get PPPoE header\n"); m = NULL; goto done; } ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); goto done; } session = ntohs(ph->session); plen = ntohs(ph->plen); off += sizeof(*ph); if (plen + off > m->m_pkthdr.len) { printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", m->m_pkthdr.len - off, plen); goto done; d400 1 a400 1 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ d404 6 a409 15 while (off + sizeof(*pt) <= m->m_pkthdr.len) { n = m_pulldown(m, off, sizeof(*pt), &noff); if (!n) { printf("%s: parse error\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); m = NULL; goto done; } pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); tag = ntohs(pt->tag); len = ntohs(pt->len); if (off + len > m->m_pkthdr.len) { printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); goto done; d413 1 a413 1 goto breakbreak; d419 2 a420 10 if (sc != NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG HUNIQUE ERROR"; m = NULL; goto done; } sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, len, m->m_pkthdr.rcvif); d424 1 a424 8 n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG ACCOOKIE ERROR"; m = NULL; break; } ac_cookie = mtod(n, caddr_t) + noff; d439 8 a446 4 printf("%s: %s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); goto done; a447 1 off += sizeof(*pt) + len; d449 1 a449 2 breakbreak:; switch (ph->code) { d453 1 a453 1 goto done; d456 1 a456 1 /* be quiet if there is not a single pppoe instance */ d459 1 a459 1 goto done; d462 2 a463 3 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); goto done; d466 1 a466 4 if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); d468 1 a468 1 goto done; d477 1 a477 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d483 1 a483 1 goto done; d487 1 a487 2 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d493 23 a515 28 goto done; /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", ph->code, session); break; } done: m_freem(m); return; d521 2 d524 9 a532 6 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(m, 0); } else m_freem(m); d538 28 a565 6 u_int16_t session, plen; struct pppoe_softc *sc; struct pppoehdr *ph; #ifdef PPPOE_TERM_UNKNOWN_SESSIONS u_int8_t shost[ETHER_ADDR_LEN]; #endif d567 1 a567 60 KASSERT(m->m_flags & M_PKTHDR); #ifdef PPPOE_TERM_UNKNOWN_SESSIONS memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); #endif m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %d bytes\n", m->m_pkthdr.len); goto drop; } if (m->m_len < sizeof(*ph)) { m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; } } ph = mtod(m, struct pppoehdr *); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); goto drop; } if (ph->code != 0) goto drop; session = ntohs(ph->session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) { #ifdef PPPOE_TERM_UNKNOWN_SESSIONS struct mbuf *m0; struct sockaddr dst; struct ether_header *eh; u_int8_t *p; printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) goto drop; p = mtod(m0, u_int8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOE); memcpy(&eh->ether_dhost, shost, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); m->m_pkthdr.rcvif->if_output(m->m_pkthdr.rcvif, m0, &dst, NULL); #endif goto drop; } plen = ntohs(ph->plen); d570 2 a571 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d574 1 a574 1 m_adj(m, PPPOE_HEADERLEN); d577 2 a578 2 { struct mbuf *p; d580 10 a589 10 printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } d591 11 a601 11 if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; sppp_input(&sc->sc_sppp.pp_if, m); return; d604 1 a604 1 m_freem(m); d610 13 a622 13 struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); d625 3 a627 3 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, d706 1 a706 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d737 1 a737 1 if (len + sizeof(struct ether_header) > MHLEN) { d764 1 a764 1 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ d771 1 a771 1 len += 2 + 2 + l2; d775 2 a776 3 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; d779 1 a779 1 p = mtod(m0, u_int8_t *); d801 1 a801 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d803 1 a803 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d829 1 a829 1 * is not set. d833 1 a833 1 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); d838 4 a841 3 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; d843 3 a845 3 pppoe_abort_connect(sc); splx(x); return; d849 1 a849 2 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d859 1 a859 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d863 1 a863 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d870 1 a870 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d897 1 a897 2 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d916 1 a916 2 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); d924 1 a924 1 free(sc->sc_ac_cookie, M_DEVBUF); d962 1 a962 1 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ d968 4 a971 5 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d993 1 a993 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d995 1 a995 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1015 2 a1016 3 if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d1024 1 a1024 1 struct pppoe_softc *sc = (void *)sp; d1033 1 a1033 1 struct pppoe_softc *sc = (void *)sp; d1048 1 a1048 1 struct pppoe_softc *sc = (void *)ifp; d1069 1 a1069 1 p = mtod(m, u_int8_t *); @ 1.3 log @Protect interface queue manipulations by splnet(). Splsoftnet() is not enough. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.2 2001/06/14 05:44:24 itojun Exp $ */ d180 1 a180 1 sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN; @ 1.3.2.1 log @file if_pppoe.c was added on branch nathanw_sa on 2001-06-21 20:08:10 +0000 @ text @d1 972 @ 1.3.2.2 log @Catch up to -current. @ text @a0 972 /* $NetBSD: if_pppoe.c,v 1.3.2.1 2001/06/21 20:08:10 nathanw Exp $ */ /* * Copyright (c) 2001 Martin Husemann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "pppoe.h" #include "bpfilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if NBPFILTER > 0 #include #endif #if NPPPOE > 0 #undef PPPOE_DEBUG /* XXX - remove this or make it an option */ /* #define PPPOE_DEBUG 1 */ #define PPPOE_HEADERLEN 6 #define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ #define PPPOE_TAG_EOL 0x0000 /* end of list */ #define PPPOE_TAG_SNAME 0x0101 /* service name */ #define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ #define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ #define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ #define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ #define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ #define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ #define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ #define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ #define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ /* Read a 16 bit unsigned value from a buffer */ #define PPPOE_READ_16(PTR, VAL) \ (VAL) = ((PTR)[0] << 8) | (PTR)[1]; \ (PTR)+=2 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ #define PPPOE_ADD_16(PTR, VAL) \ *(PTR)++ = (VAL) / 256; \ *(PTR)++ = (VAL) % 256 /* Add a complete PPPoE header to the buffer pointed to by PTR */ #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ *(PTR)++ = PPPOE_VERTYPE; \ *(PTR)++ = (CODE); \ PPPOE_ADD_16(PTR, SESS); \ PPPOE_ADD_16(PTR, LEN) struct pppoe_softc { struct sppp sc_sppp; /* contains a struct ifnet as first element */ struct ifnet *sc_eth_if; /* ethernet interface we are using */ #define PPPOE_DISC_TIMEOUT hz/5 #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times */ #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ #define PPPOE_STATE_INITIAL 0 #define PPPOE_STATE_PADI_SENT 1 #define PPPOE_STATE_PADR_SENT 2 #define PPPOE_STATE_SESSION 3 #define PPPOE_STATE_CLOSING 4 int sc_state; /* discovery phase or session connected */ struct ether_addr sc_dest; /* hardware address of concentrator */ u_int16_t sc_session; /* PPPoE session id */ char *sc_service_name; /* if != NULL: requested name of service */ char *sc_concentrator_name; /* if != NULL: requested concentrator id */ u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ size_t sc_ac_cookie_len; /* length of cookie data */ struct callout sc_timeout; /* timeout while not in session state */ int sc_padi_retried; /* number of PADI retries already done */ int sc_padr_retried; /* number of PADR retries already done */ }; /* incoming traffic will be queued here */ struct ifqueue ppoediscinq = { NULL }; struct ifqueue ppoeinq = { NULL }; #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS void * pppoe_softintr = NULL; static void pppoe_softintr_handler(void *); #else struct callout pppoe_softintr = CALLOUT_INITIALIZER; void pppoe_softintr_handler(void*); #endif extern int sppp_ioctl(struct ifnet *ifp, unsigned long cmd, void *data); /* input routines */ static void pppoe_input(void); static void pppoe_disc_input(struct mbuf *m); static void pppoe_dispatch_disc_pkt(u_int8_t *p, size_t size, struct ifnet *rcvif, struct ether_header *eh); static void pppoe_data_input(struct mbuf *m); /* management routines */ void pppoeattach(void); static int pppoe_connect(struct pppoe_softc *sc); static int pppoe_disconnect(struct pppoe_softc *sc); static void pppoe_abort_connect(struct pppoe_softc *sc); static int pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data); static void pppoe_tls(struct sppp *sp); static void pppoe_tlf(struct sppp *sp); static void pppoe_start(struct ifnet *ifp); /* internal timeout handling */ static void pppoe_timeout(void*); /* sending actual protocol controll packets */ static int pppoe_send_padi(struct pppoe_softc *sc); static int pppoe_send_padr(struct pppoe_softc *sc); static int pppoe_send_padt(struct pppoe_softc *sc); /* raw output */ static int pppoe_output(struct pppoe_softc *sc, struct mbuf *m); /* internal helper functions */ static struct pppoe_softc * pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif); /* XXX - turn into SLIST and implement "ifconfig create" */ struct pppoe_softc pppoe_softc[NPPPOE]; /* * Initialize device data structures */ void pppoeattach() { struct pppoe_softc *sc; int i = 0; memset(pppoe_softc, 0, sizeof pppoe_softc); for (sc = pppoe_softc; i < NPPPOE; sc++) { sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", i++); sc->sc_sppp.pp_if.if_softc = sc; sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST | IFF_LINK1; /* auto "dial" */ sc->sc_sppp.pp_if.if_type = IFT_PPP; sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header)+PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; sc->sc_sppp.pp_flags |= PP_NOFRAMING; /* no serial encapsulation */ sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); callout_init(&sc->sc_timeout); sc->sc_sppp.pp_if.if_start = pppoe_start; sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ if_attach(&sc->sc_sppp.pp_if); sppp_attach(&sc->sc_sppp.pp_if); if_alloc_sadl(&sc->sc_sppp.pp_if); #if NBPFILTER > 0 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); #endif } ppoediscinq.ifq_maxlen = IFQ_MAXLEN; ppoeinq.ifq_maxlen = IFQ_MAXLEN; #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); #endif } /* * Find the interface handling the specified session. * Note: O(number of sessions open), this is a client-side only, mean * and lean implementation, so number of open sessions typically should * be 1. */ static struct pppoe_softc * pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif) { int i; if (session == 0) return NULL; for (i = 0; i < NPPPOE; i++) { if (pppoe_softc[i].sc_state == PPPOE_STATE_SESSION && pppoe_softc[i].sc_session == session) { if (pppoe_softc[i].sc_eth_if == rcvif) return &pppoe_softc[i]; else return NULL; } } return NULL; } /* Check host unique token passed and return appropriate softc pointer, * or NULL if token is bogus. */ static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif) { struct pppoe_softc *sc = NULL; if (len != sizeof sc) return NULL; memcpy(&sc, token, len); /* XXX - change when turning softc array into an SLIST */ if (sc < &pppoe_softc[0] && sc > &pppoe_softc[NPPPOE-1]) { #ifdef PPPOE_DEBUG printf("pppoe: invalid host unique value\n"); #endif return NULL; } /* should be safe to access *sc now */ if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { #ifdef PPPOE_DEBUG printf("%s: state=%d, not accepting host unique\n", sc->sc_sppp.pp_if.if_xname, sc->sc_state); #endif return NULL; } if (sc->sc_eth_if != rcvif) { #ifdef PPPOE_DEBUG printf("%s: wrong interface, not accepting host unique\n", sc->sc_sppp.pp_if.if_xname); #endif return NULL; } return sc; } #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS static void pppoe_softintr_handler(void *dummy) { /* called at splsoftnet() */ pppoe_input(); } #else void pppoe_softintr_handler(void *dummy) { int s = splnet(); pppoe_input(); callout_deactivate(&pppoe_softintr); splx(s); } #endif /* called at appropriate protection level */ static void pppoe_input() { struct mbuf *m; int s, disc_done, data_done; do { disc_done = 0; data_done = 0; for (;;) { s = splnet(); IF_DEQUEUE(&ppoediscinq, m); splx(s); if (m == NULL) break; disc_done = 1; pppoe_disc_input(m); } for (;;) { s = splnet(); IF_DEQUEUE(&ppoeinq, m); splx(s); if (m == NULL) break; data_done = 1; pppoe_data_input(m); } } while (disc_done || data_done); } /* analyze and handle a single received packet while not in session state */ static void pppoe_dispatch_disc_pkt(u_int8_t *p, size_t size, struct ifnet *rcvif, struct ether_header *eh) { u_int16_t tag, len; u_int8_t vertype, code; u_int16_t session, plen; struct pppoe_softc *sc; const char *err_msg = NULL; u_int8_t * ac_cookie; size_t ac_cookie_len; ac_cookie = NULL; ac_cookie_len = 0; session = 0; if (size <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %ld\n", (long)size); return; } vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", vertype); return; } code = *p++; PPPOE_READ_16(p, session); PPPOE_READ_16(p, plen); size -= PPPOE_HEADERLEN; if (plen > size) { printf("pppoe: packet content does not fit: data available = %ld, packet size = %ld\n", (long)size, (long)plen); return; } size = plen; /* ignore trailing garbage */ tag = 0; len = 0; sc = NULL; while (size > 4) { PPPOE_READ_16(p, tag); PPPOE_READ_16(p, len); if (len > size) { printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); return; } switch (tag) { case PPPOE_TAG_EOL: size = 0; break; case PPPOE_TAG_SNAME: break; /* ignored */ case PPPOE_TAG_ACNAME: break; /* ignored */ case PPPOE_TAG_HUNIQUE: if (sc == NULL) sc = pppoe_find_softc_by_hunique(p, len, rcvif); break; case PPPOE_TAG_ACCOOKIE: if (ac_cookie == NULL) { ac_cookie = p; ac_cookie_len = len; } break; case PPPOE_TAG_SNAME_ERR: err_msg = "SERVICE NAME ERROR"; break; case PPPOE_TAG_ACSYS_ERR: err_msg = "AC SYSTEM ERROR"; break; case PPPOE_TAG_GENERIC_ERR: err_msg = "GENERIC ERROR"; break; } if (err_msg) { printf("%s: %s\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); return; } if (size >= 0) { size -= 4 + len; if (len > 0) p += len; } } switch (code) { case PPPOE_CODE_PADI: case PPPOE_CODE_PADR: /* ignore, we are no access concentrator */ return; case PPPOE_CODE_PADO: if (sc == NULL) { printf("pppoe: received PADO but could not find request for it\n"); return; } if (sc->sc_state != PPPOE_STATE_PADI_SENT) { printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); return; } if (ac_cookie) { sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); if (sc->sc_ac_cookie == NULL) return; sc->sc_ac_cookie_len = ac_cookie_len; memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); } memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); callout_stop(&sc->sc_timeout); sc->sc_padr_retried = 0; sc->sc_state = PPPOE_STATE_PADR_SENT; if (pppoe_send_padr(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); break; case PPPOE_CODE_PADS: if (sc == NULL) return; sc->sc_session = session; callout_stop(&sc->sc_timeout); printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); sc->sc_state = PPPOE_STATE_SESSION; sc->sc_sppp.pp_up(&sc->sc_sppp); /* notify upper layers */ break; case PPPOE_CODE_PADT: if (sc == NULL) return; /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); /* signal upper layer */ printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_MBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", code, session); break; } } static void pppoe_disc_input(struct mbuf *m) { u_int8_t *p; struct ether_header *eh; eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); m_free(m); } static void pppoe_data_input(struct mbuf *m) { u_int8_t *p, vertype; u_int16_t session, plen, code; struct pppoe_softc *sc; KASSERT(m->m_flags & M_PKTHDR); m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %ld bytes\n", (long)m->m_pkthdr.len); goto drop; } p = mtod(m, u_int8_t*); vertype = *p++; if (vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", vertype); goto drop; } code = *p++; if (code != 0) goto drop; PPPOE_READ_16(p, session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) goto drop; PPPOE_READ_16(p, plen); #if NBPFILTER > 0 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); #endif m_adj(m, PPPOE_HEADERLEN); #ifdef PPPOE_DEBUG { struct mbuf *p; printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } #endif if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up */ sppp_input(&sc->sc_sppp.pp_if, m); return; drop: m_free(m); } static int pppoe_output(struct pppoe_softc *sc, struct mbuf *m) { struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); #ifdef PPPOE_DEBUG printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len); #endif return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL); } static int pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) { struct proc *p = curproc; /* XXX */ struct pppoe_softc *sc = (struct pppoe_softc*)ifp; int error = 0; switch (cmd) { case PPPOESETPARMS: { struct pppoediscparms *parms = (struct pppoediscparms*)data; if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) return error; if (parms->eth_ifname[0] != 0) { sc->sc_eth_if = ifunit(parms->eth_ifname); if (sc->sc_eth_if == NULL) return ENXIO; } if (parms->ac_name) { size_t s; char * p = malloc(parms->ac_name_len + 1, M_DEVBUF, M_WAITOK); copyinstr(parms->ac_name, p, parms->ac_name_len, &s); if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); sc->sc_concentrator_name = p; } if (parms->service_name) { size_t s; char * p = malloc(parms->service_name_len + 1, M_DEVBUF, M_WAITOK); copyinstr(parms->service_name, p, parms->service_name_len, &s); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); sc->sc_service_name = p; } return 0; } break; case PPPOEGETPARMS: { struct pppoediscparms *parms = (struct pppoediscparms*)data; memset(parms, 0, sizeof *parms); if (sc->sc_eth_if) strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ); return 0; } break; default: return sppp_ioctl(ifp, cmd, data); } return 0; } /* * Allocate a mbuf/cluster with space to store the given data length * of payload, leaving space for prepending an ethernet header * in front. */ static struct mbuf * pppoe_get_mbuf(size_t len) { struct mbuf *m; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) return NULL; if (len+sizeof(struct ether_header) > MHLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { struct mbuf *n; MFREE(m, n); return 0; } } m->m_data += sizeof(struct ether_header); m->m_len = len; m->m_pkthdr.len = len; m->m_pkthdr.rcvif = NULL; return m; } static int pppoe_send_padi(struct pppoe_softc *sc) { struct mbuf *m0; int len, l1, l2; u_int8_t *p; if (sc->sc_state >PPPOE_STATE_PADI_SENT) panic("pppoe_send_padi in state %d", sc->sc_state); /* calculate length of frame (excluding ethernet header + pppoe header) */ len = 2+2+2+2+sizeof sc; /* service name tag is required, host unique is send too */ if (sc->sc_service_name != NULL) { l1 = strlen(sc->sc_service_name); len += l1; } if (sc->sc_concentrator_name != NULL) { l2 = strlen(sc->sc_concentrator_name); len += 2+2+l2; } /* allocate a buffer */ m0 = pppoe_get_mbuf(len+PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; /* fill in pkt */ p = mtod(m0, u_int8_t*); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); memcpy(p, sc->sc_service_name, l1); p += l1; } else { PPPOE_ADD_16(p, 0); } if (sc->sc_concentrator_name != NULL) { PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); PPPOE_ADD_16(p, l2); memcpy(p, sc->sc_concentrator_name, l2); p += l2; } PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sizeof(sc)); memcpy(p, &sc, sizeof sc); #ifdef PPPOE_DEBUG p += sizeof sc; if (p - mtod(m0, u_int8_t*) != len + PPPOE_HEADERLEN) panic("pppoe_send_padi: garbled output len, should be %ld, is %ld", (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t*))); #endif /* send pkt */ return pppoe_output(sc, m0); } static void pppoe_timeout(void *arg) { int x; struct pppoe_softc *sc = (struct pppoe_softc*)arg; #ifdef PPPOE_DEBUG printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname); #endif switch (sc->sc_state) { case PPPOE_STATE_PADI_SENT: x = splnet(); sc->sc_padi_retried++; if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { pppoe_abort_connect(sc); splx(x); return; } if (pppoe_send_padi(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); splx(x); break; case PPPOE_STATE_PADR_SENT: x = splnet(); sc->sc_padr_retried++; if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_PADI_SENT; sc->sc_padr_retried = 0; if (pppoe_send_padi(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); splx(x); return; } if (pppoe_send_padr(sc) == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT*(1+sc->sc_padr_retried), pppoe_timeout, sc); else pppoe_abort_connect(sc); splx(x); break; case PPPOE_STATE_CLOSING: x = splnet(); pppoe_disconnect(sc); splx(x); break; default: return; /* all done, work in peace */ } } /* Start a connection (i.e. initiate discovery phase) */ static int pppoe_connect(struct pppoe_softc *sc) { int x, err; if (sc->sc_state != PPPOE_STATE_INITIAL) return EBUSY; x = splnet(); sc->sc_state = PPPOE_STATE_PADI_SENT; sc->sc_padr_retried = 0; err = pppoe_send_padi(sc); if (err == 0) callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); else pppoe_abort_connect(sc); splx(x); return err; } /* disconnect */ static int pppoe_disconnect(struct pppoe_softc *sc) { int err, x; x = splnet(); if (sc->sc_state < PPPOE_STATE_SESSION) err = EBUSY; else { printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); err = pppoe_send_padt(sc); } /* cleanup softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_MBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* notify upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); splx(x); return err; } /* Connection attempt aborted */ static void pppoe_abort_connect(struct pppoe_softc *sc) { printf("%s: could not establish connection\n", sc->sc_sppp.pp_if.if_xname); sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); /* notify upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); } /* Send a PADR packet */ static int pppoe_send_padr(struct pppoe_softc *sc) { struct mbuf *m0; u_int8_t *p; size_t len, l1; if (sc->sc_state != PPPOE_STATE_PADR_SENT) return EIO; len = 2+2+2+2+sizeof(sc); /* service name, host unique */ if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ l1 = strlen(sc->sc_service_name); len += l1; } if (sc->sc_ac_cookie_len > 0) len += 2+2+sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len+PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t*); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); memcpy(p, sc->sc_service_name, l1); p += l1; } else { PPPOE_ADD_16(p, 0); } if (sc->sc_ac_cookie_len > 0) { PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); PPPOE_ADD_16(p, sc->sc_ac_cookie_len); memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); p += sc->sc_ac_cookie_len; } PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sizeof(sc)); memcpy(p, &sc, sizeof sc); #ifdef PPPOE_DEBUG p += sizeof sc; if (p - mtod(m0, u_int8_t*) != len + PPPOE_HEADERLEN) panic("pppoe_send_padr: garbled output len, should be %ld, is %ld", (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t*))); #endif return pppoe_output(sc, m0); } /* send a PADT packet */ static int pppoe_send_padt(struct pppoe_softc *sc) { struct mbuf *m0; u_int8_t *p; if (sc->sc_state < PPPOE_STATE_SESSION) return EIO; #ifdef PPPOE_DEBUG printf("%s: sending PADT\n", sc->sc_sppp.pp_if.if_xname); #endif m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t*); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, sc->sc_session, 0); return pppoe_output(sc, m0); } static void pppoe_tls(struct sppp *sp) { struct pppoe_softc *sc = (void*)sp; if (sc->sc_state != PPPOE_STATE_INITIAL) return; pppoe_connect(sc); } static void pppoe_tlf(struct sppp *sp) { struct pppoe_softc *sc = (void*)sp; if (sc->sc_state < PPPOE_STATE_SESSION) return; /* * Do not call pppoe_disconnect here, the upper layer state * machine gets confused by this. We must return from this * function and defer disconnecting to the timeout handler. */ sc->sc_state = PPPOE_STATE_CLOSING; callout_reset(&sc->sc_timeout, hz/100, pppoe_timeout, sc); } static void pppoe_start(struct ifnet *ifp) { struct pppoe_softc *sc = (void*)ifp; struct mbuf *m; u_int8_t *p; size_t len; if (sppp_isempty(ifp)) return; /* are we read to proccess data yet? */ if (sc->sc_state < PPPOE_STATE_SESSION) { sppp_flush(&sc->sc_sppp.pp_if); return; } while ((m = sppp_dequeue(ifp)) != NULL) { len = m->m_pkthdr.len; M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT); if (m == NULL) { m_free(m); break; } p = mtod(m, u_int8_t*); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); #if NBPFILTER > 0 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); #endif pppoe_output(sc, m); } } #endif /* NPPPOE > 0 */ @ 1.3.2.3 log @Catch up with -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.2 2001/08/24 00:12:13 nathanw Exp $ */ d180 1 a180 1 sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN - 2; /* two byte PPP protocol discriminator, then IP data */ @ 1.3.2.4 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.3 2001/09/21 22:36:45 nathanw Exp $ */ a94 1 LIST_ENTRY(pppoe_softc) sc_list; d140 1 a140 1 void pppoeattach(int count); d164 2 a165 1 LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; d167 3 a169 7 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); struct if_clone pppoe_cloner = IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy); /* ARGSUSED */ d171 1 a171 18 pppoeattach(count) int count; { LIST_INIT(&pppoe_softc_list); if_clone_attach(&pppoe_cloner); ppoediscinq.ifq_maxlen = IFQ_MAXLEN; ppoeinq.ifq_maxlen = IFQ_MAXLEN; #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS pppoe_softintr = softintr_establish(IPL_SOFTNET, pppoe_softintr_handler, NULL); #endif } int pppoe_clone_create(ifc, unit) struct if_clone *ifc; int unit; d174 1 d176 24 a199 25 sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK); memset(sc, 0, sizeof(struct pppoe_softc)); sprintf(sc->sc_sppp.pp_if.if_xname, "pppoe%d", unit); sc->sc_sppp.pp_if.if_softc = sc; sc->sc_sppp.pp_if.if_mtu = ETHERMTU - PPPOE_HEADERLEN - 2; /* two byte PPP protocol discriminator, then IP data */ sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST | IFF_LINK1; /* auto "dial" */ sc->sc_sppp.pp_if.if_type = IFT_PPP; sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header)+PPPOE_HEADERLEN; sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER; sc->sc_sppp.pp_flags |= PP_NOFRAMING; /* no serial encapsulation */ sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl; IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd); /* changed to real address later */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); callout_init(&sc->sc_timeout); sc->sc_sppp.pp_if.if_start = pppoe_start; sc->sc_sppp.pp_tls = pppoe_tls; sc->sc_sppp.pp_tlf = pppoe_tlf; sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */ d201 2 a202 2 if_attach(&sc->sc_sppp.pp_if); sppp_attach(&sc->sc_sppp.pp_if); d204 1 a204 1 if_alloc_sadl(&sc->sc_sppp.pp_if); d206 1 a206 1 bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0); d208 1 a208 3 LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); return 0; } d210 2 a211 5 void pppoe_clone_destroy(ifp) struct ifnet *ifp; { struct pppoe_softc * sc = ifp->if_softc; d213 2 a214 3 LIST_REMOVE(sc, sc_list); #if NBPFILTER > 0 bpfdetach(ifp); a215 2 if_detach(ifp); free(sc, M_DEVBUF); d227 1 a227 1 struct pppoe_softc *sc; d231 5 a235 5 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { if (sc->sc_state == PPPOE_STATE_SESSION && sc->sc_session == session) { if (sc->sc_eth_if == rcvif) return sc; d248 1 a248 1 struct pppoe_softc *sc, *t; d250 3 a252 6 memcpy(&t, token, len); LIST_FOREACH(sc, &pppoe_softc_list, sc_list) if (sc == t) break; if (sc != t) { a257 1 @ 1.3.2.5 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.4 2001/11/14 19:17:24 nathanw Exp $ */ a28 3 #include __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.4 2001/11/14 19:17:24 nathanw Exp $"); d51 2 d225 1 a242 1 sppp_detach(&sc->sc_sppp.pp_if); d1004 2 @ 1.3.2.6 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.5 2002/01/08 00:33:52 nathanw Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.5 2002/01/08 00:33:52 nathanw Exp $"); a93 5 #define PPPOE_DISC_TIMEOUT (hz*5) /* base for quick timeout calculation */ #define PPPOE_SLOW_RETRY (hz*240) /* persistent retry interval */ #define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ #define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ d98 4 d203 2 a204 1 sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST; d208 1 a208 2 sc->sc_sppp.pp_flags |= PP_KEEPALIVE| /* use LCP keepalive */ PP_NOFRAMING; /* no serial encapsulation */ a278 3 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d287 1 a287 1 printf("pppoe: alien host unique tag, no session found\n"); d294 2 a295 1 printf("%s: host unique tag found, but it belongs to a connection in state %d\n", d297 1 d301 1 d304 1 d580 1 a580 2 /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; a611 1 sc->sc_sppp.pp_if.if_opackets++; a660 18 case SIOCSIFFLAGS: { struct ifreq *ifr = (struct ifreq*) data; /* * Prevent running re-establishment timers overriding * administrators choice. */ if ((ifr->ifr_flags & IFF_UP) == 0 && sc->sc_state >= PPPOE_STATE_PADI_SENT && sc->sc_state < PPPOE_STATE_SESSION) { callout_stop(&sc->sc_timeout); sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); } } /* FALLTHROUGH */ d756 1 a756 1 int x, retry_wait; a764 13 /* * We have two basic ways of retrying: * - Quick retry mode: try a few times in short sequence * - Slow retry mode: we already had a connection successfully * established and will try infinitely (without user * intervention) * We only enter slow retry mode if IFF_LINK1 (aka autodial) * is not set and we already had a successfull connection. */ /* initialize for quick retry mode */ retry_wait = PPPOE_DISC_TIMEOUT*(1+sc->sc_padi_retried); d768 3 a770 9 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; } else { pppoe_abort_connect(sc); splx(x); return; } d773 1 a773 1 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d800 1 d802 1 d967 1 a967 1 callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc); @ 1.3.2.7 log @curproc ==> curproc->l_proc @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.6 2002/01/09 02:54:45 nathanw Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.6 2002/01/09 02:54:45 nathanw Exp $"); a41 1 #include d620 1 a620 1 struct proc *p = curproc->l_proc; /* XXX */ @ 1.3.2.8 log @More catchup. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.7 2002/01/11 23:39:44 nathanw Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.7 2002/01/11 23:39:44 nathanw Exp $"); a48 1 #include d105 5 a663 10 case PPPOEGETSESSION: { struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data; state->state = sc->sc_state; state->session_id = sc->sc_session; state->padi_retry_no = sc->sc_padi_retried; state->padr_retry_no = sc->sc_padr_retried; return 0; } break; @ 1.3.2.9 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.8 2002/02/28 04:15:01 nathanw Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.8 2002/02/28 04:15:01 nathanw Exp $"); a55 2 #include a78 3 /* two byte PPP protocol discriminator, then IP data */ #define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) d97 1 a97 1 #define PPPOE_SLOW_RETRY (hz*60) /* persistent retry interval */ d200 1 a200 1 sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU; d470 1 a470 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d479 2 a480 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); a489 1 /* signal upper layer */ a609 1 m->m_flags &= ~(M_BCAST|M_MCAST); a685 9 return sppp_ioctl(ifp, cmd, data); } case SIOCSIFMTU: { struct ifreq *ifr = (struct ifreq*) data; if (ifr->ifr_mtu > PPPOE_MAXMTU) return EINVAL; return sppp_ioctl(ifp, cmd, data); d687 1 d885 1 a885 2 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); d1025 1 a1025 1 /* are we ready to proccess data yet? */ @ 1.3.2.10 log @Catch up to -current. (CVS: It's not just a program. It's an adventure!) @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.9 2002/04/01 07:48:22 nathanw Exp $ */ d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.9 2002/04/01 07:48:22 nathanw Exp $"); d447 1 a447 3 /* be quiete if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) printf("pppoe: received PADO but could not find request for it\n"); d513 5 a517 8 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { eh = mtod(m, struct ether_header*); m_adj(m, sizeof(struct ether_header)); p = mtod(m, u_int8_t*); KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh); } @ 1.3.2.11 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.10 2002/04/17 00:06:24 nathanw Exp $ */ d3 2 a4 6 /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Martin Husemann . a13 7 * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. d15 12 a26 11 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. d30 1 a30 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.10 2002/04/17 00:06:24 nathanw Exp $"); @ 1.3.2.12 log @Curproc->curlwp renaming. Change uses of "curproc->l_proc" back to "curproc", which is more like the original use. Bare uses of "curproc" are now "curlwp". "curproc" is now #defined in proc.h as ((curlwp) ? (curlwp)->l_proc) : NULL) so that it is always safe to reference curproc (*de*referencing curproc is another story, but that's always been true). @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.11 2002/06/24 22:11:34 nathanw Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.11 2002/06/24 22:11:34 nathanw Exp $"); d640 1 a640 1 struct proc *p = curproc; /* XXX */ @ 1.3.2.13 log @No longer need to pull in lwp.h; proc.h pulls it in for us. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.12 2002/07/12 01:40:29 nathanw Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.12 2002/07/12 01:40:29 nathanw Exp $"); d52 1 @ 1.3.2.14 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.13 2002/08/01 02:46:39 nathanw Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.13 2002/08/01 02:46:39 nathanw Exp $"); d70 1 a70 13 struct pppoehdr { u_int8_t vertype; u_int8_t code; u_int16_t session; u_int16_t plen; } __attribute__((__packed__)); struct pppoetag { u_int16_t tag; u_int16_t len; } __attribute__((__packed__)); #define PPPOE_HEADERLEN sizeof(struct pppoehdr) d93 5 d119 1 a119 1 d142 1 a142 1 void pppoe_softintr_handler(void *); d145 1 a145 1 extern int sppp_ioctl(struct ifnet *, unsigned long, void *); d149 3 a151 3 static void pppoe_disc_input(struct mbuf *); static void pppoe_dispatch_disc_pkt(struct mbuf *, int); static void pppoe_data_input(struct mbuf *); d154 8 a161 8 void pppoeattach(int); static int pppoe_connect(struct pppoe_softc *); static int pppoe_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t); static void pppoe_tls(struct sppp *); static void pppoe_tlf(struct sppp *); static void pppoe_start(struct ifnet *); d164 1 a164 1 static void pppoe_timeout(void *); d167 3 a169 3 static int pppoe_send_padi(struct pppoe_softc *); static int pppoe_send_padr(struct pppoe_softc *); static int pppoe_send_padt(struct pppoe_softc *); d172 1 a172 1 static int pppoe_output(struct pppoe_softc *, struct mbuf *); d175 2 a176 2 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *); static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *, size_t, struct ifnet *); d180 2 a181 2 int pppoe_clone_create __P((struct if_clone *, int)); void pppoe_clone_destroy __P((struct ifnet *)); d217 1 a217 1 sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN; d219 1 a219 1 sc->sc_sppp.pp_flags |= PP_KEEPALIVE | /* use LCP keepalive */ d234 1 a234 1 a256 6 if (sc->sc_concentrator_name) free(sc->sc_concentrator_name, M_DEVBUF); if (sc->sc_service_name) free(sc->sc_service_name, M_DEVBUF); if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); d271 1 a271 2 if (session == 0) return NULL; d292 1 a292 2 if (LIST_EMPTY(&pppoe_softc_list)) return NULL; d294 1 a294 2 if (len != sizeof sc) return NULL; d368 1 a368 1 static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off) d371 1 d375 1 a375 1 u_int8_t *ac_cookie; a376 13 struct pppoehdr *ph; struct pppoetag *pt; struct mbuf *n; int noff; struct ether_header *eh; if (m->m_len < sizeof(*eh)) { m = m_pullup(m, sizeof(*eh)); if (!m) goto done; } eh = mtod(m, struct ether_header *); off += sizeof(*eh); d381 8 a388 25 if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) { printf("pppoe: packet too short: %d\n", m->m_pkthdr.len); goto done; } n = m_pulldown(m, off, sizeof(*ph), &noff); if (!n) { printf("pppoe: could not get PPPoE header\n"); m = NULL; goto done; } ph = (struct pppoehdr *)(mtod(n, caddr_t) + noff); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); goto done; } session = ntohs(ph->session); plen = ntohs(ph->plen); off += sizeof(*ph); if (plen + off > m->m_pkthdr.len) { printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", m->m_pkthdr.len - off, plen); goto done; d390 11 a400 1 m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */ d404 6 a409 15 while (off + sizeof(*pt) <= m->m_pkthdr.len) { n = m_pulldown(m, off, sizeof(*pt), &noff); if (!n) { printf("%s: parse error\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe"); m = NULL; goto done; } pt = (struct pppoetag *)(mtod(n, caddr_t) + noff); tag = ntohs(pt->tag); len = ntohs(pt->len); if (off + len > m->m_pkthdr.len) { printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); goto done; d413 1 a413 1 goto breakbreak; d419 2 a420 10 if (sc != NULL) break; n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG HUNIQUE ERROR"; m = NULL; goto done; } sc = pppoe_find_softc_by_hunique(mtod(n, caddr_t) + noff, len, m->m_pkthdr.rcvif); d424 1 a424 8 n = m_pulldown(m, off + sizeof(*pt), len, &noff); if (!n) { err_msg = "TAG ACCOOKIE ERROR"; m = NULL; break; } ac_cookie = mtod(n, caddr_t) + noff; d439 8 a446 4 printf("%s: %s\n", sc ? sc->sc_sppp.pp_if.if_xname : "pppoe", err_msg); goto done; a447 1 off += sizeof(*pt) + len; d449 1 a449 2 breakbreak:; switch (ph->code) { d453 1 a453 1 goto done; d459 1 a459 1 goto done; d462 2 a463 3 printf("%s: received unexpected PADO\n", sc->sc_sppp.pp_if.if_xname); goto done; d466 1 a466 4 if (sc->sc_ac_cookie) free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF, M_DONTWAIT); d468 1 a468 1 goto done; d477 1 a477 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d483 1 a483 1 goto done; d487 1 a487 2 printf("%s: session 0x%x connected\n", sc->sc_sppp.pp_if.if_xname, session); d493 23 a515 28 goto done; /* stop timer (we might be about to transmit a PADT ourself) */ callout_stop(&sc->sc_timeout); if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG) printf("%s: session 0x%x terminated, received PADT\n", sc->sc_sppp.pp_if.if_xname, session); /* clean up softc */ sc->sc_state = PPPOE_STATE_INITIAL; memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); if (sc->sc_ac_cookie) { free(sc->sc_ac_cookie, M_DEVBUF); sc->sc_ac_cookie = NULL; } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; /* signal upper layer */ sc->sc_sppp.pp_down(&sc->sc_sppp); break; default: printf("%s: unknown code (0x%04x) session = 0x%04x\n", sc? sc->sc_sppp.pp_if.if_xname : "pppoe", ph->code, session); break; } done: m_freem(m); return; d521 2 d524 9 a532 6 /* avoid error messages if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { KASSERT(m->m_flags & M_PKTHDR); pppoe_dispatch_disc_pkt(m, 0); } else m_freem(m); d538 28 a565 34 u_int16_t session, plen; struct pppoe_softc *sc; struct pppoehdr *ph; KASSERT(m->m_flags & M_PKTHDR); m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %d bytes\n", m->m_pkthdr.len); goto drop; } if (m->m_len < sizeof(*ph)) { m = m_pullup(m, sizeof(*ph)); if (!m) { printf("pppoe: could not get PPPoE header\n"); return; } } ph = mtod(m, struct pppoehdr *); if (ph->vertype != PPPOE_VERTYPE) { printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); goto drop; } if (ph->code != 0) goto drop; session = ntohs(ph->session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif); if (sc == NULL) goto drop; d567 1 a567 1 plen = ntohs(ph->plen); d570 2 a571 2 if(sc->sc_sppp.pp_if.if_bpf) bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m); d574 1 a574 1 m_adj(m, PPPOE_HEADERLEN); d577 2 a578 2 { struct mbuf *p; d580 10 a589 10 printf("%s: pkthdr.len=%d, pppoe.len=%d", sc->sc_sppp.pp_if.if_xname, m->m_pkthdr.len, plen); p = m; while (p) { printf(" l=%d", p->m_len); p = p->m_next; } printf("\n"); } d591 11 a601 11 if (m->m_pkthdr.len < plen) goto drop; /* fix incoming interface pointer (not the raw ethernet interface anymore) */ m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if; /* pass packet up and account for it */ sc->sc_sppp.pp_if.if_ipackets++; sppp_input(&sc->sc_sppp.pp_if, m); return; d604 1 a604 1 m_freem(m); d610 13 a622 13 struct sockaddr dst; struct ether_header *eh; u_int16_t etype; if (sc->sc_eth_if == NULL) return EIO; memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC; eh->ether_type = htons(etype); memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest); d625 3 a627 3 printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n", sc->sc_sppp.pp_if.if_xname, etype, sc->sc_state, sc->sc_session, d706 1 a706 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d737 1 a737 1 if (len + sizeof(struct ether_header) > MHLEN) { d764 1 a764 1 len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ d771 1 a771 1 len += 2 + 2 + l2; d775 2 a776 3 m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); /* header len + payload len */ if (!m0) return ENOBUFS; d779 1 a779 1 p = mtod(m0, u_int8_t *); d801 1 a801 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d803 1 a803 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d833 1 a833 1 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); d838 4 a841 4 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0 && sc->sc_sppp.pp_if.if_ibytes) { /* slow retry mode */ retry_wait = PPPOE_SLOW_RETRY; d843 3 a845 3 pppoe_abort_connect(sc); splx(x); return; d849 1 a849 2 callout_reset(&sc->sc_timeout, retry_wait, pppoe_timeout, sc); d859 1 a859 2 memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); d863 1 a863 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); d870 1 a870 3 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); d897 1 a897 2 callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); d916 1 a916 2 printf("%s: disconnecting\n", sc->sc_sppp.pp_if.if_xname); d924 1 a924 1 free(sc->sc_ac_cookie, M_DEVBUF); d962 1 a962 1 len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ d968 4 a971 5 len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN); if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d993 1 a993 1 if (p - mtod(m0, u_int8_t *) != len + PPPOE_HEADERLEN) d995 1 a995 1 (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, u_int8_t *))); d1015 2 a1016 3 if (!m0) return ENOBUFS; p = mtod(m0, u_int8_t *); d1024 1 a1024 1 struct pppoe_softc *sc = (void *)sp; d1033 1 a1033 1 struct pppoe_softc *sc = (void *)sp; d1048 1 a1048 1 struct pppoe_softc *sc = (void *)ifp; d1069 1 a1069 1 p = mtod(m, u_int8_t *); @ 1.3.2.15 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.14 2002/08/27 23:47:54 nathanw Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.14 2002/08/27 23:47:54 nathanw Exp $"); d513 1 a513 1 /* be quiet if there is not a single pppoe instance */ @ 1.3.2.16 log @Catch up to -current. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.15 2002/09/17 21:22:50 nathanw Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.15 2002/09/17 21:22:50 nathanw Exp $"); a183 1 static struct mbuf *pppoe_get_mbuf(size_t len); a604 3 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS u_int8_t shost[ETHER_ADDR_LEN]; #endif a607 3 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); #endif d634 1 a634 25 if (sc == NULL) { #ifdef PPPOE_TERM_UNKNOWN_SESSIONS struct mbuf *m0; struct sockaddr dst; struct ether_header *eh; u_int8_t *p; printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); m0 = pppoe_get_mbuf(PPPOE_HEADERLEN); if (!m0) goto drop; p = mtod(m0, u_int8_t *); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); memset(&dst, 0, sizeof dst); dst.sa_family = AF_UNSPEC; eh = (struct ether_header*)&dst.sa_data; eh->ether_type = htons(ETHERTYPE_PPPOE); memcpy(&eh->ether_dhost, shost, ETHER_ADDR_LEN); m0->m_flags &= ~(M_BCAST|M_MCAST); m->m_pkthdr.rcvif->if_output(m->m_pkthdr.rcvif, m0, &dst, NULL); #endif a635 1 } d901 1 a901 1 * is not set. d910 2 a911 1 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { @ 1.3.2.17 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.16 2002/12/29 20:55:43 thorpej Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.16 2002/12/29 20:55:43 thorpej Exp $"); d996 1 a996 1 int x, err, retry; a1001 2 /* save state, in case we fail to send PADI */ retry = sc->sc_padr_retried; d1005 1 a1005 11 if (err != 0) { /* * We failed to send a single PADI packet. * This is unfortunate, because we have no good way to recover * from here. */ /* recover state and return the error */ sc->sc_state = PPPOE_STATE_INITIAL; sc->sc_padr_retried = retry; } else { d1008 2 a1009 1 } d1055 2 a1056 1 sc->sc_state = PPPOE_STATE_CLOSING; a1059 4 /* clear connection state */ memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_INITIAL; @ 1.3.2.18 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.3.2.17 2003/01/15 18:59:04 thorpej Exp $ */ d40 1 a40 1 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.3.2.17 2003/01/15 18:59:04 thorpej Exp $"); d1193 2 a1194 2 ifp->if_oerrors++; continue; @ 1.2 log @change the meaning of ifnet.if_lastchange to meet RFC1573 ifLastChange. follows BSD/OS practice and ucd-snmp code (FreeBSD does it for specific interfaces only). was: if_lastchange get updated on every packet transmission/receipt. now: if_lastchange get updated when IFF_UP is changed. @ text @d1 1 a1 1 /* $NetBSD: if_pppoe.c,v 1.1 2001/04/29 09:50:37 martin Exp $ */ d297 1 a297 1 int idle = 0; d299 5 a303 3 while (!idle) { idle = 1; if (!IF_IS_EMPTY(&ppoediscinq)) { d305 3 a307 1 idle = 0; d310 3 a312 1 if (!IF_IS_EMPTY(&ppoeinq)) { d314 3 a316 1 idle = 0; d319 1 a319 1 } @ 1.1 log @Add an in-kernel PPPoE (ppp over ethernet, RFC 2516) implementation, based on the existing net/if_spppsubr.c stuff. While there are completely userland (bpf based) implementations available, those have a vastly larger per packet overhead thus causing major CPU overhead and higher latency. On an i386 base router, running a 486DX at 50MHz my line (768kBit/s downstream) was limited to something (varying) between 10 and 20 kByte/s effective download rate. With this implementation I get full bandwidth (~85kByte/s). This is client side only. Arguably the right way to add full PPPoE support (including server side) would be a variation of the ppp line discipline and appropriate modifications to pppd. I promise every help I can give to anyone doing that - but I needed this realy fast. Besids, on low memory NAT boxes with typically a single PPPoE connection, this implementation is more lightweight than a pppd based one, which nicely fits my needs. @ text @d1 1 a1 1 /* $NetBSD$ */ a945 1 microtime(&ifp->if_lastchange); @