Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

OpenBSD 3.3

  • Loading branch information...
commit 02dfb0ac27b6e99b6f08b86e3572128a74848b86 1 parent 2ef2904
itojun authored
Showing with 20,182 additions and 4,862 deletions.
  1. +3 −3 openbsd/sys/Makefile
  2. +29 −43 openbsd/sys/adosfs/adlookup.c
  3. +200 −0 openbsd/sys/altq/altq.h
  4. +582 −0 openbsd/sys/altq/altq_cbq.c
  5. +129 −0 openbsd/sys/altq/altq_cbq.h
  6. +1,171 −0 openbsd/sys/altq/altq_cdnr.c
  7. +302 −0 openbsd/sys/altq/altq_cdnr.h
  8. +207 −0 openbsd/sys/altq/altq_classq.h
  9. +1,687 −0 openbsd/sys/altq/altq_hfsc.c
  10. +252 −0 openbsd/sys/altq/altq_hfsc.h
  11. +580 −0 openbsd/sys/altq/altq_priq.c
  12. +102 −0 openbsd/sys/altq/altq_priq.h
  13. +636 −0 openbsd/sys/altq/altq_red.c
  14. +124 −0 openbsd/sys/altq/altq_red.h
  15. +438 −0 openbsd/sys/altq/altq_rio.c
  16. +128 −0 openbsd/sys/altq/altq_rio.h
  17. +1,779 −0 openbsd/sys/altq/altq_rmclass.c
  18. +267 −0 openbsd/sys/altq/altq_rmclass.h
  19. +113 −0 openbsd/sys/altq/altq_rmclass_debug.h
  20. +872 −0 openbsd/sys/altq/altq_subr.c
  21. +136 −0 openbsd/sys/altq/altq_var.h
  22. +176 −0 openbsd/sys/altq/if_altq.h
  23. +2 −4 openbsd/sys/arch/alpha/alpha/conf.c
  24. +1 −1  openbsd/sys/arch/alpha/alpha/cpu.c
  25. +1 −52 openbsd/sys/arch/alpha/alpha/db_interface.c
  26. +2 −2 openbsd/sys/arch/alpha/alpha/dec_1000a.c
  27. +2 −2 openbsd/sys/arch/alpha/alpha/disksubr.c
  28. +1 −314 openbsd/sys/arch/alpha/alpha/locore.s
  29. +8 −30 openbsd/sys/arch/alpha/alpha/machdep.c
  30. +2 −2 openbsd/sys/arch/alpha/alpha/pmap.c
  31. +1 −19 openbsd/sys/arch/alpha/alpha/trap.c
  32. +5 −2 openbsd/sys/arch/alpha/conf/GENERIC
  33. +2 −6 openbsd/sys/arch/alpha/conf/Makefile.alpha
  34. +1 −1  openbsd/sys/arch/alpha/dev/bus_dma.c
  35. +14 −14 openbsd/sys/arch/alpha/include/alpha_cpu.h
  36. +1 −3 openbsd/sys/arch/alpha/include/db_machdep.h
  37. +8 −8 openbsd/sys/arch/alpha/include/intrcnt.h
  38. +6 −1 openbsd/sys/arch/alpha/include/pcb.h
  39. +8 −1 openbsd/sys/arch/alpha/include/stdarg.h
  40. +1 −2  openbsd/sys/arch/alpha/include/sysarch.h
  41. +1 −0  openbsd/sys/arch/alpha/isa/isapnp_machdep.c
  42. +1 −0  openbsd/sys/arch/alpha/isa/isapnp_machdep.h
  43. +2 −2 openbsd/sys/arch/alpha/pci/pci_eb64plus_intr.s
  44. +2 −1  openbsd/sys/arch/alpha/stand/Makefile.inc
  45. +2 −2 openbsd/sys/arch/alpha/tc/scc.c
  46. +3 −7 openbsd/sys/arch/hp300/conf/Makefile.hp300
  47. +1 −3 openbsd/sys/arch/hp300/conf/files.hp300
  48. +6 −7 openbsd/sys/arch/hp300/dev/ac.c
  49. +2 −2 openbsd/sys/arch/hp300/dev/diodevs
  50. +3 −3 openbsd/sys/arch/hp300/dev/diodevs.h
  51. +2 −2 openbsd/sys/arch/hp300/dev/diodevs_data.h
  52. +3 −4 openbsd/sys/arch/hp300/dev/grf.c
  53. +3 −3 openbsd/sys/arch/hp300/dev/grf_rb.c
  54. +2 −2 openbsd/sys/arch/hp300/dev/grf_tc.c
  55. +25 −25 openbsd/sys/arch/hp300/dev/hd.c
  56. +4 −4 openbsd/sys/arch/hp300/dev/hdvar.h
  57. +4 −4 openbsd/sys/arch/hp300/dev/hil.c
  58. +1 −4 openbsd/sys/arch/hp300/dev/scsi.c
  59. +24 −39 openbsd/sys/arch/hp300/dev/sd.c
  60. +4 −4 openbsd/sys/arch/hp300/dev/sdvar.h
  61. +6 −15 openbsd/sys/arch/hp300/dev/st.c
  62. +2 −2 openbsd/sys/arch/hp300/hp300/clock.c
  63. +3 −3 openbsd/sys/arch/hp300/hp300/clockreg.h
  64. +1 −4 openbsd/sys/arch/hp300/hp300/conf.c
  65. +3 −7 openbsd/sys/arch/hp300/hp300/hpux_machdep.c
  66. +6 −35 openbsd/sys/arch/hp300/hp300/machdep.c
  67. +2 −2 openbsd/sys/arch/hp300/hp300/pmap_bootstrap.c
  68. +59 −32 openbsd/sys/arch/hp300/hp300/trap.c
  69. +2 −2 openbsd/sys/arch/hp300/include/cpu.h
  70. +2 −2 openbsd/sys/arch/hp300/include/hp300spu.h
  71. +20 −26 openbsd/sys/arch/hp300/include/intr.h
  72. +6 −1 openbsd/sys/arch/hp300/include/pcb.h
  73. +2 −97 openbsd/sys/arch/hp300/include/vmparam.h
  74. +3 −1 openbsd/sys/arch/hp300/stand/Makefile.inc
  75. +0 −3  openbsd/sys/arch/hppa/compile/.cvsignore
  76. +126 −13 openbsd/sys/arch/hppa/conf/GENERIC
  77. +3 −6 openbsd/sys/arch/hppa/conf/Makefile.hppa
  78. +136 −11 openbsd/sys/arch/hppa/conf/RAMDISK
  79. +46 −15 openbsd/sys/arch/hppa/conf/files.hppa
  80. +37 −10 openbsd/sys/arch/hppa/conf/ld.script
  81. +12 −55 openbsd/sys/arch/hppa/dev/asp.c
  82. +2 −41 openbsd/sys/arch/hppa/dev/clock.c
  83. +9 −2 openbsd/sys/arch/hppa/dev/cpu.c
  84. +40 −12 openbsd/sys/arch/hppa/dev/cpudevs
  85. +23 −3 openbsd/sys/arch/hppa/dev/cpudevs.h
  86. +25 −5 openbsd/sys/arch/hppa/dev/cpudevs_data.h
  87. +49 −70 openbsd/sys/arch/hppa/dev/lasi.c
  88. +9 −8 openbsd/sys/arch/hppa/dev/mem.c
  89. +83 −0 openbsd/sys/arch/hppa/dev/phantomas.c
  90. +10 −0 openbsd/sys/arch/hppa/gsc/Makefile
  91. +2 −2 openbsd/sys/arch/hppa/gsc/com_gsc.c
  92. +3 −3 openbsd/sys/arch/hppa/gsc/fdc_gsc.c
  93. +17 −77 openbsd/sys/arch/hppa/gsc/gscbus.c
  94. +6 −8 openbsd/sys/arch/hppa/gsc/gscbusvar.h
  95. +1,072 −0 openbsd/sys/arch/hppa/gsc/gsckbc.c
  96. +64 −0 openbsd/sys/arch/hppa/gsc/gsckbcreg.h
  97. +607 −0 openbsd/sys/arch/hppa/gsc/gsckbd.c
  98. +849 −0 openbsd/sys/arch/hppa/gsc/gsckbdmap.c
  99. +29 −0 openbsd/sys/arch/hppa/gsc/gsckbdmap.h
  100. +29 −0 openbsd/sys/arch/hppa/gsc/gsckbdvar.h
  101. +1,260 −0 openbsd/sys/arch/hppa/gsc/harmony.c
  102. +157 −0 openbsd/sys/arch/hppa/gsc/harmonyreg.h
  103. +117 −0 openbsd/sys/arch/hppa/gsc/harmonyvar.h
  104. +88 −0 openbsd/sys/arch/hppa/gsc/hil_gsc.c
  105. +32 −32 openbsd/sys/arch/hppa/gsc/if_ie_gsc.c
  106. +4 −4 openbsd/sys/arch/hppa/gsc/lpt_gsc.c
  107. +219 −0 openbsd/sys/arch/hppa/gsc/makemap.awk
  108. +200 −0 openbsd/sys/arch/hppa/gsc/osiop_gsc.c
  109. +392 −81 openbsd/sys/arch/hppa/hppa/autoconf.c
  110. +8 −5 openbsd/sys/arch/hppa/hppa/conf.c
  111. +27 −10 openbsd/sys/arch/hppa/hppa/db_interface.c
  112. +18 −6 openbsd/sys/arch/hppa/hppa/disksubr.c
  113. +60 −62 openbsd/sys/arch/hppa/hppa/fpemu.S
  114. +3 −3 openbsd/sys/arch/hppa/hppa/in_cksum.c
  115. +174 −74 openbsd/sys/arch/hppa/hppa/intr.c
  116. +436 −274 openbsd/sys/arch/hppa/hppa/locore.S
  117. +103 −84 openbsd/sys/arch/hppa/hppa/machdep.c
  118. +25 −21 openbsd/sys/arch/hppa/hppa/mainbus.c
  119. +216 −299 openbsd/sys/arch/hppa/hppa/pmap.c
  120. +88 −84 openbsd/sys/arch/hppa/hppa/process_machdep.c
  121. +35 −1 openbsd/sys/arch/hppa/hppa/sys_machdep.c
  122. +141 −135 openbsd/sys/arch/hppa/hppa/trap.c
  123. +39 −35 openbsd/sys/arch/hppa/hppa/vm_machdep.c
  124. +18 −57 openbsd/sys/arch/hppa/hppa/wscons_machdep.c
  125. +7 −6 openbsd/sys/arch/hppa/include/autoconf.h
  126. +16 −3 openbsd/sys/arch/hppa/include/cpu.h
  127. +3 −3 openbsd/sys/arch/hppa/include/db_machdep.h
  128. +3 −3 openbsd/sys/arch/hppa/include/disklabel.h
  129. +75 −0 openbsd/sys/arch/hppa/include/eisa_machdep.h
  130. +1 −5 openbsd/sys/arch/hppa/include/exec.h
  131. +6 −2 openbsd/sys/arch/hppa/include/float.h
  132. +57 −0 openbsd/sys/arch/hppa/include/hil_machdep.h
  133. +129 −87 openbsd/sys/arch/hppa/include/intr.h
  134. +2 −6 openbsd/sys/arch/hppa/include/iomod.h
  135. +63 −0 openbsd/sys/arch/hppa/include/isa_machdep.h
  136. +82 −0 openbsd/sys/arch/hppa/include/loadfile_machdep.h
  137. +2 −1  openbsd/sys/arch/hppa/include/pcb.h
  138. +23 −4 openbsd/sys/arch/hppa/include/pdc.h
  139. +6 −16 openbsd/sys/arch/hppa/include/pmap.h
  140. +3 −7 openbsd/sys/arch/hppa/include/profile.h
  141. +47 −47 openbsd/sys/arch/hppa/include/psl.h
  142. +8 −1 openbsd/sys/arch/hppa/include/stdarg.h
  143. +2 −2 openbsd/sys/arch/hppa/include/trap.h
  144. +3 −1 openbsd/sys/arch/hppa/include/types.h
  145. +14 −5 openbsd/sys/arch/hppa/include/vmparam.h
  146. +2 −2 openbsd/sys/arch/hppa/spmath/dfadd.c
  147. +2 −2 openbsd/sys/arch/hppa/spmath/dfsub.c
  148. +3 −1 openbsd/sys/arch/hppa/spmath/divu.S
  149. +3 −1 openbsd/sys/arch/hppa/spmath/impys.S
  150. +3 −1 openbsd/sys/arch/hppa/spmath/impyu.S
  151. +2 −2 openbsd/sys/arch/hppa/spmath/sfadd.c
  152. +2 −2 openbsd/sys/arch/hppa/spmath/sfsub.c
  153. +2 −1  openbsd/sys/arch/hppa/stand/Makefile.inc
  154. +12 −15 openbsd/sys/arch/hppa/stand/boot/Makefile
  155. +3 −3 openbsd/sys/arch/hppa/stand/boot/boot.8
  156. +4 −11 openbsd/sys/arch/hppa/stand/boot/conf.c
  157. +64 −0 openbsd/sys/arch/hppa/stand/boot/exec.c
  158. +4 −5 openbsd/sys/arch/hppa/stand/libsa/Makefile
  159. +48 −56 openbsd/sys/arch/hppa/stand/libsa/cmd_hppa.c
  160. +2 −2 openbsd/sys/arch/hppa/stand/libsa/dev_hppa.c
  161. +2 −1  openbsd/sys/arch/hppa/stand/libsa/dev_hppa.h
  162. +7 −6 openbsd/sys/arch/hppa/stand/libsa/dk.c
  163. +3 −2 openbsd/sys/arch/hppa/stand/libsa/machdep.c
  164. +69 −69 openbsd/sys/arch/hppa/stand/libsa/pdc.c
  165. +8 −4 openbsd/sys/arch/hppa/stand/mkboot/Makefile
  166. +61 −1 openbsd/sys/arch/hppa/stand/mkboot/mkboot.8
  167. +2 −2 openbsd/sys/arch/i386/conf/DISKLESS
  168. +26 −4 openbsd/sys/arch/i386/conf/GENERIC
  169. +3 −6 openbsd/sys/arch/i386/conf/Makefile.i386
  170. +4 −4 openbsd/sys/arch/i386/conf/RAMDISK
  171. +7 −7 openbsd/sys/arch/i386/conf/RAMDISKB
  172. +12 −2 openbsd/sys/arch/i386/conf/files.i386
  173. +11 −6 openbsd/sys/arch/i386/i386/apm.c
  174. +19 −1 openbsd/sys/arch/i386/i386/autoconf.c
  175. +2 −12 openbsd/sys/arch/i386/i386/conf.c
  176. +2 −2 openbsd/sys/arch/i386/i386/db_disasm.c
  177. +9 −15 openbsd/sys/arch/i386/i386/db_memrw.c
  178. +2 −2 openbsd/sys/arch/i386/i386/db_trace.c
  179. +6 −8 openbsd/sys/arch/i386/i386/freebsd_machdep.c
  180. +73 −32 openbsd/sys/arch/i386/i386/i686_mem.c
  181. +6 −2 openbsd/sys/arch/i386/i386/linux_machdep.c
  182. +15 −226 openbsd/sys/arch/i386/i386/locore.s
  183. +141 −50 openbsd/sys/arch/i386/i386/machdep.c
  184. +59 −46 openbsd/sys/arch/i386/i386/math_emulate.c
  185. +8 −13 openbsd/sys/arch/i386/i386/mem.c
  186. +3 −3 openbsd/sys/arch/i386/i386/pmap.c
  187. +12 −19 openbsd/sys/arch/i386/i386/trap.c
  188. +3 −3 openbsd/sys/arch/i386/i386/vm86.c
  189. +12 −17 openbsd/sys/arch/i386/i386/vm_machdep.c
  190. +2 −2 openbsd/sys/arch/i386/include/bus.h
  191. +2 −4 openbsd/sys/arch/i386/include/cpu.h
  192. +2 −1  openbsd/sys/arch/i386/include/disklabel.h
  193. +3 −3 openbsd/sys/arch/i386/include/intr.h
  194. +1 −5 openbsd/sys/arch/i386/include/pmap.h
  195. +3 −1 openbsd/sys/arch/i386/include/specialreg.h
  196. +8 −1 openbsd/sys/arch/i386/include/stdarg.h
  197. +1 −5 openbsd/sys/arch/i386/include/types.h
  198. +6 −6 openbsd/sys/arch/i386/include/vmparam.h
  199. +7 −6 openbsd/sys/arch/i386/isa/isa_machdep.c
  200. +2 −2 openbsd/sys/arch/i386/isa/isa_machdep.h
  201. +3 −2 openbsd/sys/arch/i386/pci/agp_machdep.c
  202. +246 −0 openbsd/sys/arch/i386/pci/elan520.c
  203. +147 −0 openbsd/sys/arch/i386/pci/elan520reg.h
  204. +6 −1 openbsd/sys/arch/i386/pci/pchb.c
  205. +2 −1  openbsd/sys/arch/i386/stand/Makefile.inc
  206. +5 −5 openbsd/sys/arch/i386/stand/biosboot/biosboot.8
  207. +4 −4 openbsd/sys/arch/i386/stand/boot/boot.8
  208. +3 −3 openbsd/sys/arch/i386/stand/installboot/installboot.8
  209. +2 −2 openbsd/sys/arch/i386/stand/libsa/bioscons.c
  210. +2 −2 openbsd/sys/arch/m68k/060sp/fpsp.s
  211. +23 −25 openbsd/sys/arch/m68k/fpe/fpu_calcea.c
  212. +7 −9 openbsd/sys/arch/m68k/fpe/fpu_emulate.c
  213. +21 −1 openbsd/sys/arch/m68k/include/asm.h
  214. +1 −5 openbsd/sys/arch/m68k/include/cpu.h
  215. +2 −18 openbsd/sys/arch/m68k/include/pmap_motorola.h
  216. +34 −3 openbsd/sys/arch/m68k/include/psl.h
  217. +8 −1 openbsd/sys/arch/m68k/include/stdarg.h
  218. +178 −0 openbsd/sys/arch/m68k/include/vmparam.h
  219. +2 −141 openbsd/sys/arch/m68k/m68k/copy.s
  220. +21 −1 openbsd/sys/arch/m68k/m68k/m68k_machdep.c
  221. +6 −6 openbsd/sys/arch/m68k/m68k/mappedcopy.c
  222. +119 −225 openbsd/sys/arch/m68k/m68k/pmap_motorola.c
  223. +5 −5 openbsd/sys/arch/m68k/m68k/regdump.c
  224. +8 −12 openbsd/sys/arch/m68k/m68k/sig_machdep.c
  225. +3 −7 openbsd/sys/arch/mac68k/conf/Makefile.mac68k
  226. +2 −4 openbsd/sys/arch/mac68k/dev/adb_direct.c
  227. +2 −2 openbsd/sys/arch/mac68k/dev/esp.c
  228. +3 −4 openbsd/sys/arch/mac68k/dev/grf.c
  229. +1 −1  openbsd/sys/arch/mac68k/dev/if_ae.c
  230. +1 −4 openbsd/sys/arch/mac68k/dev/if_sn.c
  231. +3 −2 openbsd/sys/arch/mac68k/dev/mac68k5380.c
  232. +5 −5 openbsd/sys/arch/mac68k/dev/ncr5380.c
  233. +3 −1 openbsd/sys/arch/mac68k/dev/pm_direct.c
  234. +19 −4 openbsd/sys/arch/mac68k/include/intr.h
  235. +1 −2  openbsd/sys/arch/mac68k/include/pcb.h
  236. +3 −2 openbsd/sys/arch/mac68k/include/pmap.h
  237. +2 −2 openbsd/sys/arch/mac68k/include/proc.h
  238. +3 −95 openbsd/sys/arch/mac68k/include/vmparam.h
  239. +34 −23 openbsd/sys/arch/mac68k/mac68k/autoconf.c
  240. +1 −4 openbsd/sys/arch/mac68k/mac68k/conf.c
  241. +75 −193 openbsd/sys/arch/mac68k/mac68k/disksubr.c
  242. +17 −39 openbsd/sys/arch/mac68k/mac68k/machdep.c
  243. +2 −2 openbsd/sys/arch/mac68k/mac68k/pmap_bootstrap.c
  244. +59 −32 openbsd/sys/arch/mac68k/mac68k/trap.c
  245. +30 −11 openbsd/sys/arch/macppc/conf/GENERIC
  246. +3 −7 openbsd/sys/arch/macppc/conf/Makefile.macppc
  247. +7 −5 openbsd/sys/arch/macppc/conf/RAMDISK
  248. +2 −33 openbsd/sys/arch/macppc/dev/adb_direct.c
  249. +29 −1 openbsd/sys/arch/macppc/dev/akbdmap.h
  250. +4 −4 openbsd/sys/arch/macppc/dev/macintr.c
  251. +4 −4 openbsd/sys/arch/macppc/dev/openpic.c
  252. +1 −42 openbsd/sys/arch/macppc/dev/pm_direct.c
  253. +2 −1  openbsd/sys/arch/macppc/include/bus.h
  254. +4 −1 openbsd/sys/arch/macppc/include/rbus_machdep.h
  255. +7 −4 openbsd/sys/arch/macppc/macppc/conf.c
  256. +3 −3 openbsd/sys/arch/macppc/macppc/cpu.c
  257. +1 −2  openbsd/sys/arch/macppc/macppc/disksubr.c
  258. +9 −9 openbsd/sys/arch/macppc/macppc/dma.c
  259. +1 −38 openbsd/sys/arch/macppc/macppc/locore.S
  260. +3 −21 openbsd/sys/arch/macppc/macppc/machdep.c
  261. +2 −2 openbsd/sys/arch/macppc/macppc/ofw_machdep.c
  262. +10 −8 openbsd/sys/arch/macppc/pci/mpcpcibus.c
  263. +3 −10 openbsd/sys/arch/macppc/pci/pci_addr_fixup.c
  264. +10 −9 openbsd/sys/arch/macppc/pci/vgafb.c
  265. +2 −1  openbsd/sys/arch/macppc/stand/Makefile.inc
  266. +3 −3 openbsd/sys/arch/macppc/stand/ofwboot/Makefile
  267. +2 −2 openbsd/sys/arch/macppc/stand/tbxidata/bsd.tbxi
  268. +3 −7 openbsd/sys/arch/mvme68k/conf/Makefile.mvme68k
  269. +10 −4 openbsd/sys/arch/mvme68k/dev/if_ie.c
  270. +3 −3 openbsd/sys/arch/mvme68k/dev/if_le.c
  271. +2 −2 openbsd/sys/arch/mvme68k/dev/sbic.c
  272. +6 −6 openbsd/sys/arch/mvme68k/dev/sbicreg.h
  273. +2 −2 openbsd/sys/arch/mvme68k/dev/ssh.c
  274. +2 −2 openbsd/sys/arch/mvme68k/dev/sshdma.c
  275. +5 −5 openbsd/sys/arch/mvme68k/dev/sshreg.h
  276. +2 −2 openbsd/sys/arch/mvme68k/dev/vs.c
  277. +2 −14 openbsd/sys/arch/mvme68k/include/disklabel.h
  278. +19 −4 openbsd/sys/arch/mvme68k/include/intr.h
  279. +2 −96 openbsd/sys/arch/mvme68k/include/vmparam.h
  280. +19 −22 openbsd/sys/arch/mvme68k/mvme68k/autoconf.c
  281. +1 −4 openbsd/sys/arch/mvme68k/mvme68k/conf.c
  282. +3 −7 openbsd/sys/arch/mvme68k/mvme68k/hpux_machdep.c
  283. +52 −30 openbsd/sys/arch/mvme68k/mvme68k/locore.s
  284. +2 −85 openbsd/sys/arch/mvme68k/mvme68k/machdep.c
  285. +2 −2 openbsd/sys/arch/mvme68k/mvme68k/pmap_bootstrap.c
  286. +59 −32 openbsd/sys/arch/mvme68k/mvme68k/trap.c
  287. +2 −1  openbsd/sys/arch/mvme68k/stand/Makefile.inc
  288. +32 −4 openbsd/sys/arch/mvme68k/stand/installboot/installboot.8
  289. +7 −2 openbsd/sys/arch/mvme68k/stand/netboot/if_ie.c
  290. +2 −2 openbsd/sys/arch/mvme88k/conf/GENERIC
  291. +4 −4 openbsd/sys/arch/mvme88k/conf/M187
  292. +4 −4 openbsd/sys/arch/mvme88k/conf/M197
  293. +2 −6 openbsd/sys/arch/mvme88k/conf/Makefile.mvme88k
  294. +3 −1 openbsd/sys/arch/mvme88k/conf/files.mvme88k
  295. +2 −2 openbsd/sys/arch/mvme88k/ddb/db_trace.c
  296. +3 −2 openbsd/sys/arch/mvme88k/dev/cl.c
  297. +8 −2 openbsd/sys/arch/mvme88k/dev/if_ie.c
  298. +3 −3 openbsd/sys/arch/mvme88k/dev/ssh.c
  299. +5 −5 openbsd/sys/arch/mvme88k/dev/sshreg.h
  300. +2 −2 openbsd/sys/arch/mvme88k/dev/vs.c
Sorry, we could not display the entire diff because too many files (1,294) changed.
View
6 openbsd/sys/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.14 2001/09/07 15:36:53 jason Exp $
+# $OpenBSD: Makefile,v 1.16 2002/12/31 16:22:26 miod Exp $
# $NetBSD: Makefile,v 1.5 1995/09/15 21:05:21 pk Exp $
-SUBDIR= arch/alpha arch/amiga arch/hp300 arch/i386 arch/m68k \
+SUBDIR= arch/alpha arch/hp300 arch/hppa arch/i386 arch/m68k \
arch/mac68k arch/macppc arch/mvme68k arch/mvme88k \
- arch/mvmeppc arch/sparc arch/sparc64 arch/sun3 arch/vax
+ arch/mvmeppc arch/sparc arch/sparc64 arch/vax
.include <bsd.subdir.mk>
View
72 openbsd/sys/adosfs/adlookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: adlookup.c,v 1.11 1997/12/18 00:59:01 gene Exp $ */
+/* $OpenBSD: adlookup.c,v 1.13 2003/03/16 00:30:38 margarida Exp $ */
/* $NetBSD: adlookup.c,v 1.17 1996/10/25 23:13:58 cgd Exp $ */
/*
@@ -90,6 +90,7 @@ adosfs_lookup(v)
*vpp = NULL;
ucp = cnp->cn_cred;
nameiop = cnp->cn_nameiop;
+ cnp->cn_flags &= ~PDIRUNLOCK;
flags = cnp->cn_flags;
last = flags & ISLASTCN;
lockp = flags & LOCKPARENT;
@@ -107,41 +108,17 @@ adosfs_lookup(v)
return (ENOTDIR);
if ((error = VOP_ACCESS(vdp, VEXEC, ucp, cnp->cn_proc)) != 0)
return (error);
+ if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ return (EROFS);
+
/*
- * cache lookup algorithm borrowed from ufs_lookup()
- * its not consistent with otherthings in this function..
+ * Before tediously performing a linear scan of the directory,
+ * check the name cache to see if the directory/name pair
+ * we are looking for is known already.
*/
- if ((error = cache_lookup(vdp, vpp, cnp)) != 0) {
- if (error == ENOENT)
- return (error);
-
- vpid = (*vpp)->v_id;
- if (vdp == *vpp) {
- VREF(vdp);
- error = 0;
- } else if (flags & ISDOTDOT) {
- VOP_UNLOCK(vdp, 0, p); /* race */
- error = vget(*vpp, LK_EXCLUSIVE, p);
- if (error == 0 && lockp && last)
- error =
- vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p);
- } else {
- error = vget(*vpp, LK_EXCLUSIVE, p);
- /* if (lockp == 0 || error || last) */
- if (lockp == 0 || error || last == 0)
- VOP_UNLOCK(vdp, 0, p);
- }
- if (error == 0) {
- if (vpid == vdp->v_id)
- return (0);
- vput(*vpp);
- if (lockp && vdp != *vpp && last)
- VOP_UNLOCK(vdp, 0, p);
- }
- *vpp = NULL;
- if ((error = vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p)) != 0)
- return (error);
- }
+ if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
+ return (error);
/*
* fake a '.'
@@ -161,7 +138,7 @@ adosfs_lookup(v)
* cannot get `..' while `vdp' is locked
* e.g. procA holds lock on `..' and waits for `vdp'
* we wait for `..' and hold lock on `vdp'. deadlock.
- * becuase `vdp' may have been acheived through symlink
+ * because `vdp' may have been achieved through symlink
* fancy detection code that decreases the race
* window size is not reasonably possible.
*
@@ -170,16 +147,21 @@ adosfs_lookup(v)
* fail. Otherwise we have the child (..) if this is the
* last and the caller requested LOCKPARENT, attempt to
* relock the parent. If that fails unlock the child (..)
- * and fail. Otherwise we have succeded.
+ * and fail. Otherwise we have succeeded.
*
*/
VOP_UNLOCK(vdp, 0, p); /* race */
+ cnp->cn_flags |= PDIRUNLOCK;
if ((error = VFS_VGET(vdp->v_mount, ABLKTOINO(adp->pblock),
- vpp)) != 0)
- vn_lock(vdp, LK_RETRY | LK_EXCLUSIVE, p);
- else if (last && lockp &&
- (error = vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p)))
- vput(*vpp);
+ vpp)) != 0) {
+ if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p) == 0)
+ cnp->cn_flags &= ~PDIRUNLOCK;
+ } else if (last && lockp) {
+ if ((error = vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p)))
+ vput(*vpp);
+ else
+ cnp->cn_flags &= ~PDIRUNLOCK;
+ }
if (error) {
*vpp = NULL;
return (error);
@@ -238,8 +220,10 @@ adosfs_lookup(v)
#endif
return (error);
}
- if (lockp == 0)
+ if (lockp == 0) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
cnp->cn_nameiop |= SAVENAME;
#ifdef ADOSFS_DIAGNOSTIC
printf("EJUSTRETURN)");
@@ -278,8 +262,10 @@ adosfs_lookup(v)
}
if (vdp == *vpp)
VREF(vdp);
- else if (lockp == 0 || last == 0)
+ else if (lockp == 0 || last == 0) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
found_lockdone:
if ((cnp->cn_flags & MAKEENTRY) && nocache == 0)
cache_enter(vdp, *vpp, cnp);
View
200 openbsd/sys/altq/altq.h
@@ -0,0 +1,200 @@
+/* $OpenBSD: altq.h,v 1.5 2003/01/30 09:55:42 henning Exp $ */
+/* $KAME: altq.h,v 1.6 2000/12/14 08:12:45 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1998-2000
+ * Sony Computer Science Laboratories Inc. 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 SONY CSL 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 SONY CSL 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.
+ */
+
+#ifndef _ALTQ_ALTQ_H_
+#define _ALTQ_ALTQ_H_
+
+#include <sys/param.h>
+#include <sys/ioccom.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+/* altq discipline type */
+#define ALTQT_NONE 0 /* reserved */
+#define ALTQT_CBQ 1 /* cbq */
+#define ALTQT_WFQ 2 /* wfq */
+#define ALTQT_AFMAP 3 /* afmap */
+#define ALTQT_FIFOQ 4 /* fifoq */
+#define ALTQT_RED 5 /* red */
+#define ALTQT_RIO 6 /* rio */
+#define ALTQT_LOCALQ 7 /* local use */
+#define ALTQT_HFSC 8 /* hfsc */
+#define ALTQT_CDNR 9 /* traffic conditioner */
+#define ALTQT_BLUE 10 /* blue */
+#define ALTQT_PRIQ 11 /* priority queue */
+#define ALTQT_MAX 12 /* should be max discipline type + 1 */
+
+struct altqreq {
+ char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
+ u_long arg; /* request-specific argument */
+};
+
+/* simple token backet meter profile */
+struct tb_profile {
+ u_int rate; /* rate in bit-per-sec */
+ u_int depth; /* depth in bytes */
+};
+
+struct tbrreq {
+ char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct tb_profile tb_prof; /* token bucket profile */
+};
+
+/*
+ * common network flow info structure
+ */
+struct flowinfo {
+ u_char fi_len; /* total length */
+ u_char fi_family; /* address family */
+ u_int8_t fi_data[46]; /* actually longer; address family
+ specific flow info. */
+};
+
+/*
+ * flow info structure for internet protocol family.
+ * (currently this is the only protocol family supported)
+ */
+struct flowinfo_in {
+ u_char fi_len; /* sizeof(struct flowinfo_in) */
+ u_char fi_family; /* AF_INET */
+ u_int8_t fi_proto; /* IPPROTO_XXX */
+ u_int8_t fi_tos; /* type-of-service */
+ struct in_addr fi_dst; /* dest address */
+ struct in_addr fi_src; /* src address */
+ u_int16_t fi_dport; /* dest port */
+ u_int16_t fi_sport; /* src port */
+ u_int32_t fi_gpi; /* generalized port id for ipsec */
+ u_int8_t _pad[28]; /* make the size equal to
+ flowinfo_in6 */
+};
+
+#ifdef SIN6_LEN
+struct flowinfo_in6 {
+ u_char fi6_len; /* sizeof(struct flowinfo_in6) */
+ u_char fi6_family; /* AF_INET6 */
+ u_int8_t fi6_proto; /* IPPROTO_XXX */
+ u_int8_t fi6_tclass; /* traffic class */
+ u_int32_t fi6_flowlabel; /* ipv6 flowlabel */
+ u_int16_t fi6_dport; /* dest port */
+ u_int16_t fi6_sport; /* src port */
+ u_int32_t fi6_gpi; /* generalized port id */
+ struct in6_addr fi6_dst; /* dest address */
+ struct in6_addr fi6_src; /* src address */
+};
+#endif /* INET6 */
+
+/*
+ * flow filters for AF_INET and AF_INET6
+ */
+struct flow_filter {
+ int ff_ruleno;
+ struct flowinfo_in ff_flow;
+ struct {
+ struct in_addr mask_dst;
+ struct in_addr mask_src;
+ u_int8_t mask_tos;
+ u_int8_t _pad[3];
+ } ff_mask;
+ u_int8_t _pad2[24]; /* make size equal to flow_filter6 */
+};
+
+#ifdef SIN6_LEN
+struct flow_filter6 {
+ int ff_ruleno;
+ struct flowinfo_in6 ff_flow6;
+ struct {
+ struct in6_addr mask6_dst;
+ struct in6_addr mask6_src;
+ u_int8_t mask6_tclass;
+ u_int8_t _pad[3];
+ } ff_mask6;
+};
+#endif /* INET6 */
+
+/*
+ * generic packet counter
+ */
+struct pktcntr {
+ u_int64_t packets;
+ u_int64_t bytes;
+};
+
+#define PKTCNTR_ADD(cntr, len) \
+ do { (cntr)->packets++; (cntr)->bytes += len; } while (0)
+
+/*
+ * altq related ioctls
+ */
+#define ALTQGTYPE _IOWR('q', 0, struct altqreq) /* get queue type */
+#if 0
+/*
+ * these ioctls are currently discipline-specific but could be shared
+ * in the future.
+ */
+#define ALTQATTACH _IOW('q', 1, struct altqreq) /* attach discipline */
+#define ALTQDETACH _IOW('q', 2, struct altqreq) /* detach discipline */
+#define ALTQENABLE _IOW('q', 3, struct altqreq) /* enable discipline */
+#define ALTQDISABLE _IOW('q', 4, struct altqreq) /* disable discipline*/
+#define ALTQCLEAR _IOW('q', 5, struct altqreq) /* (re)initialize */
+#define ALTQCONFIG _IOWR('q', 6, struct altqreq) /* set config params */
+#define ALTQADDCLASS _IOWR('q', 7, struct altqreq) /* add a class */
+#define ALTQMODCLASS _IOWR('q', 8, struct altqreq) /* modify a class */
+#define ALTQDELCLASS _IOWR('q', 9, struct altqreq) /* delete a class */
+#define ALTQADDFILTER _IOWR('q', 10, struct altqreq) /* add a filter */
+#define ALTQDELFILTER _IOWR('q', 11, struct altqreq) /* delete a filter */
+#define ALTQGETSTATS _IOWR('q', 12, struct altqreq) /* get statistics */
+#define ALTQGETCNTR _IOWR('q', 13, struct altqreq) /* get a pkt counter */
+#endif /* 0 */
+#define ALTQTBRSET _IOW('q', 14, struct tbrreq) /* set tb regulator */
+#define ALTQTBRGET _IOWR('q', 15, struct tbrreq) /* get tb regulator */
+
+/* queue macros only in FreeBSD */
+#ifndef LIST_EMPTY
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+#endif
+#ifndef LIST_FOREACH
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
+#endif
+
+#ifdef KERNEL
+#ifndef _KERNEL
+#define _KERNEL
+#endif
+#endif
+
+#ifdef _KERNEL
+#include <altq/altq_var.h>
+#endif
+
+#endif /* _ALTQ_ALTQ_H_ */
View
582 openbsd/sys/altq/altq_cbq.c
@@ -0,0 +1,582 @@
+/* $OpenBSD: altq_cbq.c,v 1.14 2003/03/11 02:25:59 kjc Exp $ */
+/* $KAME: altq_cbq.c,v 1.9 2000/12/14 08:12:45 thorpej Exp $ */
+
+/*
+ * Copyright (c) Sun Microsystems, Inc. 1993-1998 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the SMCC Technology
+ * Development Group at Sun Microsystems, Inc.
+ *
+ * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE
+ * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is
+ * provided "as is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this software.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <net/pfvar.h>
+#include <altq/altq.h>
+#include <altq/altq_cbq.h>
+
+/*
+ * Forward Declarations.
+ */
+static int cbq_class_destroy(cbq_state_t *, struct rm_class *);
+static struct rm_class *clh_to_clp(cbq_state_t *, u_int32_t);
+static int cbq_clear_interface(cbq_state_t *);
+static int cbq_request(struct ifaltq *, int, void *);
+static int cbq_enqueue(struct ifaltq *, struct mbuf *,
+ struct altq_pktattr *);
+static struct mbuf *cbq_dequeue(struct ifaltq *, int);
+static void cbqrestart(struct ifaltq *);
+static void get_class_stats(class_stats_t *, struct rm_class *);
+static void cbq_purge(cbq_state_t *);
+
+/*
+ * int
+ * cbq_class_destroy(cbq_mod_state_t *, struct rm_class *) - This
+ * function destroys a given traffic class. Before destroying
+ * the class, all traffic for that class is released.
+ */
+static int
+cbq_class_destroy(cbq_state_t *cbqp, struct rm_class *cl)
+{
+ u_int32_t chandle;
+
+ chandle = cl->stats_.handle;
+
+ /* delete the class */
+ rmc_delete_class(&cbqp->ifnp, cl);
+
+ /*
+ * free the class handle
+ */
+ switch (chandle) {
+ case ROOT_CLASS_HANDLE:
+ cbqp->ifnp.root_ = NULL;
+ break;
+ case DEFAULT_CLASS_HANDLE:
+ cbqp->ifnp.default_ = NULL;
+ break;
+ case CTL_CLASS_HANDLE:
+ cbqp->ifnp.ctl_ = NULL;
+ break;
+ case NULL_CLASS_HANDLE:
+ break;
+ default:
+ if (chandle >= CBQ_MAX_CLASSES)
+ break;
+ cbqp->cbq_class_tbl[chandle] = NULL;
+ }
+
+ return (0);
+}
+
+/* convert class handle to class pointer */
+static struct rm_class *
+clh_to_clp(cbq_state_t *cbqp, u_int32_t chandle)
+{
+ switch (chandle) {
+ case NULL_CLASS_HANDLE:
+ return (NULL);
+ case ROOT_CLASS_HANDLE:
+ return (cbqp->ifnp.root_);
+ case DEFAULT_CLASS_HANDLE:
+ return (cbqp->ifnp.default_);
+ case CTL_CLASS_HANDLE:
+ return (cbqp->ifnp.ctl_);
+ }
+
+ if (chandle >= CBQ_MAX_CLASSES)
+ return (NULL);
+
+ return (cbqp->cbq_class_tbl[chandle]);
+}
+
+static int
+cbq_clear_interface(cbq_state_t *cbqp)
+{
+ int again, i;
+ struct rm_class *cl;
+
+ /* clear out the classes now */
+ do {
+ again = 0;
+ for (i = 0; i < CBQ_MAX_CLASSES; i++) {
+ if ((cl = cbqp->cbq_class_tbl[i]) != NULL) {
+ if (is_a_parent_class(cl))
+ again++;
+ else {
+ cbq_class_destroy(cbqp, cl);
+ cbqp->cbq_class_tbl[i] = NULL;
+ }
+ }
+ }
+ if (cbqp->ifnp.ctl_ != NULL &&
+ !is_a_parent_class(cbqp->ifnp.ctl_)) {
+ cbq_class_destroy(cbqp, cbqp->ifnp.ctl_);
+ cbqp->ifnp.ctl_ = NULL;
+ }
+ if (cbqp->ifnp.default_ != NULL &&
+ !is_a_parent_class(cbqp->ifnp.default_)) {
+ cbq_class_destroy(cbqp, cbqp->ifnp.default_);
+ cbqp->ifnp.default_ = NULL;
+ }
+ if (cbqp->ifnp.root_ != NULL &&
+ !is_a_parent_class(cbqp->ifnp.root_)) {
+ cbq_class_destroy(cbqp, cbqp->ifnp.root_);
+ cbqp->ifnp.root_ = NULL;
+ }
+ } while (again);
+
+ return (0);
+}
+
+static int
+cbq_request(struct ifaltq *ifq, int req, void *arg)
+{
+ cbq_state_t *cbqp = (cbq_state_t *)ifq->altq_disc;
+
+ switch (req) {
+ case ALTRQ_PURGE:
+ cbq_purge(cbqp);
+ break;
+ }
+ return (0);
+}
+
+/* copy the stats info in rm_class to class_states_t */
+static void
+get_class_stats(class_stats_t *statsp, struct rm_class *cl)
+{
+ statsp->xmit_cnt = cl->stats_.xmit_cnt;
+ statsp->drop_cnt = cl->stats_.drop_cnt;
+ statsp->over = cl->stats_.over;
+ statsp->borrows = cl->stats_.borrows;
+ statsp->overactions = cl->stats_.overactions;
+ statsp->delays = cl->stats_.delays;
+
+ statsp->depth = cl->depth_;
+ statsp->priority = cl->pri_;
+ statsp->maxidle = cl->maxidle_;
+ statsp->minidle = cl->minidle_;
+ statsp->offtime = cl->offtime_;
+ statsp->qmax = qlimit(cl->q_);
+ statsp->ns_per_byte = cl->ns_per_byte_;
+ statsp->wrr_allot = cl->w_allotment_;
+ statsp->qcnt = qlen(cl->q_);
+ statsp->avgidle = cl->avgidle_;
+
+ statsp->qtype = qtype(cl->q_);
+#ifdef ALTQ_RED
+ if (q_is_red(cl->q_))
+ red_getstats(cl->red_, &statsp->red[0]);
+#endif
+#ifdef ALTQ_RIO
+ if (q_is_rio(cl->q_))
+ rio_getstats((rio_t *)cl->red_, &statsp->red[0]);
+#endif
+}
+
+int
+cbq_pfattach(struct pf_altq *a)
+{
+ struct ifnet *ifp;
+ int s, error;
+
+ if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL)
+ return (EINVAL);
+ s = splimp();
+ error = altq_attach(&ifp->if_snd, ALTQT_CBQ, a->altq_disc,
+ cbq_enqueue, cbq_dequeue, cbq_request, NULL, NULL);
+ splx(s);
+ return (error);
+}
+
+int
+cbq_add_altq(struct pf_altq *a)
+{
+ cbq_state_t *cbqp;
+ struct ifnet *ifp;
+
+ if ((ifp = ifunit(a->ifname)) == NULL)
+ return (EINVAL);
+ if (!ALTQ_IS_READY(&ifp->if_snd))
+ return (ENODEV);
+
+ /* allocate and initialize cbq_state_t */
+ MALLOC(cbqp, cbq_state_t *, sizeof(cbq_state_t), M_DEVBUF, M_WAITOK);
+ if (cbqp == NULL)
+ return (ENOMEM);
+ bzero(cbqp, sizeof(cbq_state_t));
+ CALLOUT_INIT(&cbqp->cbq_callout);
+ cbqp->cbq_qlen = 0;
+ cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */
+
+ /* keep the state in pf_altq */
+ a->altq_disc = cbqp;
+
+ return (0);
+}
+
+int
+cbq_remove_altq(struct pf_altq *a)
+{
+ cbq_state_t *cbqp;
+
+ if ((cbqp = a->altq_disc) == NULL)
+ return (EINVAL);
+ a->altq_disc = NULL;
+
+ cbq_clear_interface(cbqp);
+
+ if (cbqp->ifnp.ctl_)
+ cbq_class_destroy(cbqp, cbqp->ifnp.ctl_);
+ if (cbqp->ifnp.default_)
+ cbq_class_destroy(cbqp, cbqp->ifnp.default_);
+ if (cbqp->ifnp.root_)
+ cbq_class_destroy(cbqp, cbqp->ifnp.root_);
+
+ /* deallocate cbq_state_t */
+ FREE(cbqp, M_DEVBUF);
+
+ return (0);
+}
+
+int
+cbq_add_queue(struct pf_altq *a)
+{
+ struct rm_class *borrow, *parent;
+ cbq_state_t *cbqp;
+ struct rm_class *cl;
+ struct cbq_opts *opts;
+ u_int32_t chandle;
+ int i;
+
+ if ((cbqp = a->altq_disc) == NULL)
+ return (EINVAL);
+
+ opts = &a->pq_u.cbq_opts;
+ /* check parameters */
+ if (a->priority >= RM_MAXPRIO)
+ return (EINVAL);
+
+ /* Get pointers to parent and borrow classes. */
+ parent = clh_to_clp(cbqp, a->parent_qid);
+ if (opts->flags & CBQCLF_BORROW)
+ borrow = parent;
+ else
+ borrow = NULL;
+
+ /*
+ * A class must borrow from it's parent or it can not
+ * borrow at all. Hence, borrow can be null.
+ */
+ if (parent == NULL && (opts->flags & CBQCLF_ROOTCLASS) == 0) {
+ printf("cbq_add_queue: no parent class!\n");
+ return (EINVAL);
+ }
+
+ if ((borrow != parent) && (borrow != NULL)) {
+ printf("cbq_add_class: borrow class != parent\n");
+ return (EINVAL);
+ }
+
+ /*
+ * allocate class handle
+ */
+ switch (opts->flags & CBQCLF_CLASSMASK) {
+ case CBQCLF_ROOTCLASS:
+ if (parent != NULL)
+ return (EINVAL);
+ if (cbqp->ifnp.root_)
+ return (EINVAL);
+ chandle = ROOT_CLASS_HANDLE;
+ break;
+ case CBQCLF_DEFCLASS:
+ if (cbqp->ifnp.default_)
+ return (EINVAL);
+ chandle = DEFAULT_CLASS_HANDLE;
+ break;
+ case CBQCLF_CTLCLASS:
+ if (cbqp->ifnp.ctl_)
+ return (EINVAL);
+ chandle = CTL_CLASS_HANDLE;
+ break;
+ case 0:
+ if (a->qid) {
+ chandle = a->qid;
+ if (chandle >= CBQ_MAX_CLASSES &&
+ chandle != DEFAULT_CLASS_HANDLE &&
+ chandle != CTL_CLASS_HANDLE)
+ return (EINVAL);
+ if (cbqp->cbq_class_tbl[chandle] != NULL)
+ return (EBUSY);
+ } else {
+ /* find a free class slot. for now, reserve qid 0 */
+ for (i = 1; i < CBQ_MAX_CLASSES; i++)
+ if (cbqp->cbq_class_tbl[i] == NULL)
+ break;
+ if (i == CBQ_MAX_CLASSES)
+ return (ENOSPC);
+ chandle = (u_int32_t)i;
+ }
+ break;
+ default:
+ /* more than two flags bits set */
+ return (EINVAL);
+ }
+
+ /*
+ * create a class. if this is a root class, initialize the
+ * interface.
+ */
+ if (chandle == ROOT_CLASS_HANDLE) {
+ rmc_init(cbqp->ifnp.ifq_, &cbqp->ifnp, opts->ns_per_byte,
+ cbqrestart, a->qlimit, RM_MAXQUEUED,
+ opts->maxidle, opts->minidle, opts->offtime,
+ opts->flags);
+ cl = cbqp->ifnp.root_;
+ } else {
+ cl = rmc_newclass(a->priority,
+ &cbqp->ifnp, opts->ns_per_byte,
+ rmc_delay_action, a->qlimit, parent, borrow,
+ opts->maxidle, opts->minidle, opts->offtime,
+ opts->pktsize, opts->flags);
+ }
+ if (cl == NULL)
+ return (ENOMEM);
+
+ /* return handle to user space. */
+ a->qid = chandle;
+
+ cl->stats_.handle = chandle;
+ cl->stats_.depth = cl->depth_;
+
+ /* save the allocated class */
+ switch (chandle) {
+ case NULL_CLASS_HANDLE:
+ case ROOT_CLASS_HANDLE:
+ break;
+ case DEFAULT_CLASS_HANDLE:
+ cbqp->ifnp.default_ = cl;
+ break;
+ case CTL_CLASS_HANDLE:
+ cbqp->ifnp.ctl_ = cl;
+ break;
+ default:
+ cbqp->cbq_class_tbl[chandle] = cl;
+ break;
+ }
+ return (0);
+}
+
+int
+cbq_remove_queue(struct pf_altq *a)
+{
+ struct rm_class *cl;
+ cbq_state_t *cbqp;
+
+ if ((cbqp = a->altq_disc) == NULL)
+ return (EINVAL);
+
+ if ((cl = clh_to_clp(cbqp, a->qid)) == NULL)
+ return (EINVAL);
+
+ /* if we are a parent class, then return an error. */
+ if (is_a_parent_class(cl))
+ return (EINVAL);
+
+ /* delete the class */
+ rmc_delete_class(&cbqp->ifnp, cl);
+
+ /*
+ * free the class handle
+ */
+ switch (a->qid) {
+ case ROOT_CLASS_HANDLE:
+ cbqp->ifnp.root_ = NULL;
+ break;
+ case DEFAULT_CLASS_HANDLE:
+ cbqp->ifnp.default_ = NULL;
+ break;
+ case CTL_CLASS_HANDLE:
+ cbqp->ifnp.ctl_ = NULL;
+ break;
+ case NULL_CLASS_HANDLE:
+ break;
+ default:
+ if (a->qid >= CBQ_MAX_CLASSES)
+ break;
+ cbqp->cbq_class_tbl[a->qid] = NULL;
+ }
+
+ return (0);
+}
+
+int
+cbq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes)
+{
+ cbq_state_t *cbqp;
+ struct rm_class *cl;
+ class_stats_t stats;
+ int error = 0;
+
+ if ((cbqp = altq_lookup(a->ifname, ALTQT_CBQ)) == NULL)
+ return (EBADF);
+
+ if ((cl = clh_to_clp(cbqp, a->qid)) == NULL)
+ return (EINVAL);
+
+ if (*nbytes < sizeof(stats))
+ return (EINVAL);
+
+ get_class_stats(&stats, cl);
+ stats.handle = a->qid;
+
+ if ((error = copyout((caddr_t)&stats, ubuf, sizeof(stats))) != 0)
+ return (error);
+ *nbytes = sizeof(stats);
+ return (0);
+}
+
+/*
+ * int
+ * cbq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pattr)
+ * - Queue data packets.
+ *
+ * cbq_enqueue is set to ifp->if_altqenqueue and called by an upper
+ * layer (e.g. ether_output). cbq_enqueue queues the given packet
+ * to the cbq, then invokes the driver's start routine.
+ *
+ * Assumptions: called in splimp
+ * Returns: 0 if the queueing is successful.
+ * ENOBUFS if a packet dropping occurred as a result of
+ * the queueing.
+ */
+
+static int
+cbq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
+{
+ cbq_state_t *cbqp = (cbq_state_t *)ifq->altq_disc;
+ struct rm_class *cl;
+ struct m_tag *t;
+ int len;
+
+ /* grab class set by classifier */
+ if ((m->m_flags & M_PKTHDR) == 0) {
+ /* should not happen */
+ printf("altq: packet for %s does not have pkthdr\n",
+ ifq->altq_ifp->if_xname);
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ t = m_tag_find(m, PACKET_TAG_PF_QID, NULL);
+ if (t == NULL ||
+ (cl = clh_to_clp(cbqp, ((struct altq_tag *)(t+1))->qid)) == NULL) {
+ cl = cbqp->ifnp.default_;
+ if (cl == NULL) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ cl->pktattr_ = NULL;
+ }
+
+ len = m_pktlen(m);
+ if (rmc_queue_packet(cl, m) != 0) {
+ /* drop occurred. some mbuf was freed in rmc_queue_packet. */
+ PKTCNTR_ADD(&cl->stats_.drop_cnt, len);
+ return (ENOBUFS);
+ }
+
+ /* successfully queued. */
+ ++cbqp->cbq_qlen;
+ IFQ_INC_LEN(ifq);
+ return (0);
+}
+
+static struct mbuf *
+cbq_dequeue(struct ifaltq *ifq, int op)
+{
+ cbq_state_t *cbqp = (cbq_state_t *)ifq->altq_disc;
+ struct mbuf *m;
+
+ m = rmc_dequeue_next(&cbqp->ifnp, op);
+
+ if (m && op == ALTDQ_REMOVE) {
+ --cbqp->cbq_qlen; /* decrement # of packets in cbq */
+ IFQ_DEC_LEN(ifq);
+
+ /* Update the class. */
+ rmc_update_class_util(&cbqp->ifnp);
+ }
+ return (m);
+}
+
+/*
+ * void
+ * cbqrestart(queue_t *) - Restart sending of data.
+ * called from rmc_restart in splimp via timeout after waking up
+ * a suspended class.
+ * Returns: NONE
+ */
+
+static void
+cbqrestart(struct ifaltq *ifq)
+{
+ cbq_state_t *cbqp;
+ struct ifnet *ifp;
+
+ if (!ALTQ_IS_ENABLED(ifq))
+ /* cbq must have been detached */
+ return;
+
+ if ((cbqp = (cbq_state_t *)ifq->altq_disc) == NULL)
+ /* should not happen */
+ return;
+
+ ifp = ifq->altq_ifp;
+ if (ifp->if_start &&
+ cbqp->cbq_qlen > 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+}
+
+static void cbq_purge(cbq_state_t *cbqp)
+{
+ struct rm_class *cl;
+ int i;
+
+ for (i = 0; i < CBQ_MAX_CLASSES; i++)
+ if ((cl = cbqp->cbq_class_tbl[i]) != NULL)
+ rmc_dropall(cl);
+ if (ALTQ_IS_ENABLED(cbqp->ifnp.ifq_))
+ cbqp->ifnp.ifq_->ifq_len = 0;
+}
View
129 openbsd/sys/altq/altq_cbq.h
@@ -0,0 +1,129 @@
+/* $OpenBSD: altq_cbq.h,v 1.6 2002/12/16 17:27:19 henning Exp $ */
+/* $KAME: altq_cbq.h,v 1.5 2000/12/02 13:44:40 kjc Exp $ */
+
+/*
+ * Copyright (c) Sun Microsystems, Inc. 1993-1998 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the SMCC Technology
+ * Development Group at Sun Microsystems, Inc.
+ *
+ * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE
+ * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is
+ * provided "as is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this software.
+ */
+
+#ifndef _ALTQ_ALTQ_CBQ_H_
+#define _ALTQ_ALTQ_CBQ_H_
+
+#include <altq/altq.h>
+#include <altq/altq_rmclass.h>
+#include <altq/altq_red.h>
+#include <altq/altq_rio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Define a well known class handles
+ */
+#define NULL_CLASS_HANDLE 0xffffffff
+#define ROOT_CLASS_HANDLE 0xfffffffe
+#define DEFAULT_CLASS_HANDLE 0xfffffffd
+#define CTL_CLASS_HANDLE 0xfffffffc
+
+/* class flags shoud be same as class flags in rm_class.h */
+#define CBQCLF_RED 0x0001 /* use RED */
+#define CBQCLF_ECN 0x0002 /* use RED/ECN */
+#define CBQCLF_RIO 0x0004 /* use RIO */
+#define CBQCLF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */
+#define CBQCLF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
+#define CBQCLF_BORROW 0x0020 /* borrow from parent */
+
+/* class flags only for root class */
+#define CBQCLF_WRR 0x0100 /* weighted-round robin */
+#define CBQCLF_EFFICIENT 0x0200 /* work-conserving */
+
+/* class flags for special classes */
+#define CBQCLF_ROOTCLASS 0x1000 /* root class */
+#define CBQCLF_DEFCLASS 0x2000 /* default class */
+#define CBQCLF_CTLCLASS 0x4000 /* control class */
+#define CBQCLF_CLASSMASK 0xf000 /* class mask */
+
+#define CBQ_MAXQSIZE 200
+
+typedef struct _cbq_class_stats_ {
+ u_int32_t handle;
+ u_int depth;
+
+ struct pktcntr xmit_cnt; /* packets sent in this class */
+ struct pktcntr drop_cnt; /* dropped packets */
+ u_int over; /* # times went over limit */
+ u_int borrows; /* # times tried to borrow */
+ u_int overactions; /* # times invoked overlimit action */
+ u_int delays; /* # times invoked delay actions */
+
+ /* other static class parameters useful for debugging */
+ int priority;
+ int maxidle;
+ int minidle;
+ int offtime;
+ int qmax;
+ int ns_per_byte;
+ int wrr_allot;
+
+ int qcnt; /* # packets in queue */
+ int avgidle;
+
+ /* red and rio related info */
+ int qtype;
+ struct redstats red[3];
+} class_stats_t;
+
+#ifdef _KERNEL
+/*
+ * Define macros only good for kernel drivers and modules.
+ */
+#define CBQ_WATCHDOG (HZ / 20)
+#define CBQ_TIMEOUT 10
+#define CBQ_LS_TIMEOUT (20 * hz / 1000)
+
+#define CBQ_MAX_CLASSES 256
+
+/*
+ * Define State structures.
+ */
+typedef struct cbqstate {
+ int cbq_qlen; /* # of packets in cbq */
+ struct rm_class *cbq_class_tbl[CBQ_MAX_CLASSES];
+
+ struct rm_ifdat ifnp;
+ struct callout cbq_callout; /* for timeouts */
+} cbq_state_t;
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_ALTQ_ALTQ_CBQ_H_ */
View
1,171 openbsd/sys/altq/altq_cdnr.c
@@ -0,0 +1,1171 @@
+/* $OpenBSD: altq_cdnr.c,v 1.7 2002/12/16 17:27:20 henning Exp $ */
+/* $KAME: altq_cdnr.c,v 1.8 2000/12/14 08:12:45 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1999-2000
+ * Sony Computer Science Laboratories Inc. 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 SONY CSL 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 SONY CSL 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 <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif
+
+#include <altq/altq.h>
+#include <altq/altq_cdnr.h>
+
+/*
+ * diffserv traffic conditioning module
+ */
+
+int altq_cdnr_enabled = 0;
+
+/* cdnr_list keeps all cdnr's allocated. */
+static LIST_HEAD(, top_cdnr) tcb_list;
+
+static int altq_cdnr_input(struct mbuf *, int);
+static struct top_cdnr *tcb_lookup(char *ifname);
+static struct cdnr_block *cdnr_handle2cb(u_long);
+static u_long cdnr_cb2handle(struct cdnr_block *);
+static void *cdnr_cballoc(struct top_cdnr *, int,
+ struct tc_action *(*)(struct cdnr_block *, struct cdnr_pktinfo *));
+static void cdnr_cbdestroy(void *);
+static int tca_verify_action(struct tc_action *);
+static void tca_import_action(struct tc_action *, struct tc_action *);
+static void tca_invalidate_action(struct tc_action *);
+
+static int generic_element_destroy(struct cdnr_block *);
+static struct top_cdnr *top_create(struct ifaltq *);
+static int top_destroy(struct top_cdnr *);
+static struct cdnr_block *element_create(struct top_cdnr *,
+ struct tc_action *);
+static int element_destroy(struct cdnr_block *);
+static void tb_import_profile(struct tbe *, struct tb_profile *);
+static struct tbmeter *tbm_create(struct top_cdnr *, struct tb_profile *,
+ struct tc_action *, struct tc_action *);
+static int tbm_destroy(struct tbmeter *);
+static struct tc_action *tbm_input(struct cdnr_block *,
+ struct cdnr_pktinfo *);
+static struct trtcm *trtcm_create(struct top_cdnr *,
+ struct tb_profile *, struct tb_profile *,
+ struct tc_action *, struct tc_action *, struct tc_action *,
+ int);
+static int trtcm_destroy(struct trtcm *);
+static struct tc_action *trtcm_input(struct cdnr_block *,
+ struct cdnr_pktinfo *);
+static struct tswtcm *tswtcm_create(struct top_cdnr *,
+ u_int32_t, u_int32_t, u_int32_t,
+ struct tc_action *, struct tc_action *, struct tc_action *);
+static int tswtcm_destroy(struct tswtcm *);
+static struct tc_action *tswtcm_input(struct cdnr_block *,
+ struct cdnr_pktinfo *);
+
+static int cdnrcmd_if_attach(char *);
+static int cdnrcmd_if_detach(char *);
+static int cdnrcmd_add_element(struct cdnr_add_element *);
+static int cdnrcmd_delete_element(struct cdnr_delete_element *);
+static int cdnrcmd_add_tbm(struct cdnr_add_tbmeter *);
+static int cdnrcmd_modify_tbm(struct cdnr_modify_tbmeter *);
+static int cdnrcmd_tbm_stats(struct cdnr_tbmeter_stats *);
+static int cdnrcmd_add_trtcm(struct cdnr_add_trtcm *);
+static int cdnrcmd_modify_trtcm(struct cdnr_modify_trtcm *);
+static int cdnrcmd_tcm_stats(struct cdnr_tcm_stats *);
+static int cdnrcmd_add_tswtcm(struct cdnr_add_tswtcm *);
+static int cdnrcmd_modify_tswtcm(struct cdnr_modify_tswtcm *);
+static int cdnrcmd_get_stats(struct cdnr_get_stats *);
+
+#if 1
+/* dummy */
+int cdnr_dummy(void);
+
+int cdnr_dummy(void)
+{
+ altq_cdnr_input(NULL, 0);
+
+ cdnrcmd_if_attach(NULL);
+ cdnrcmd_if_detach(NULL);
+ cdnrcmd_add_element(NULL);
+ cdnrcmd_delete_element(NULL);
+ cdnrcmd_add_tbm(NULL);
+ cdnrcmd_modify_tbm(NULL);
+ cdnrcmd_tbm_stats(NULL);
+ cdnrcmd_add_trtcm(NULL);
+ cdnrcmd_modify_trtcm(NULL);
+ cdnrcmd_tcm_stats(NULL);
+ cdnrcmd_add_tswtcm(NULL);
+ cdnrcmd_modify_tswtcm(NULL);
+ cdnrcmd_get_stats(NULL);
+ return (0);
+}
+
+#endif
+
+/*
+ * top level input function called from ip_input.
+ * should be called before converting header fields to host-byte-order.
+ */
+int
+altq_cdnr_input(m, af)
+ struct mbuf *m;
+ int af; /* address family */
+{
+ struct ifnet *ifp;
+ struct ip *ip;
+ struct top_cdnr *top;
+ struct tc_action *tca;
+ struct cdnr_block *cb;
+ struct cdnr_pktinfo pktinfo;
+
+ ifp = m->m_pkthdr.rcvif;
+ if (!ALTQ_IS_CNDTNING(&ifp->if_snd))
+ /* traffic conditioner is not enabled on this interface */
+ return (1);
+
+ top = ifp->if_snd.altq_cdnr;
+
+ ip = mtod(m, struct ip *);
+#ifdef INET6
+ if (af == AF_INET6) {
+ u_int32_t flowlabel;
+
+ flowlabel = ((struct ip6_hdr *)ip)->ip6_flow;
+ pktinfo.pkt_dscp = (ntohl(flowlabel) >> 20) & DSCP_MASK;
+ } else
+#endif
+ pktinfo.pkt_dscp = ip->ip_tos & DSCP_MASK;
+ pktinfo.pkt_len = m_pktlen(m);
+
+ tca = NULL;
+
+#if 0
+ cb = acc_classify(&top->tc_classifier, m, af);
+#endif
+ if (cb != NULL)
+ tca = &cb->cb_action;
+
+ if (tca == NULL)
+ tca = &top->tc_block.cb_action;
+
+ while (1) {
+ PKTCNTR_ADD(&top->tc_cnts[tca->tca_code], pktinfo.pkt_len);
+
+ switch (tca->tca_code) {
+ case TCACODE_PASS:
+ return (1);
+ case TCACODE_DROP:
+ m_freem(m);
+ return (0);
+ case TCACODE_RETURN:
+ return (0);
+ case TCACODE_MARK:
+#ifdef INET6
+ if (af == AF_INET6) {
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
+ u_int32_t flowlabel;
+
+ flowlabel = ntohl(ip6->ip6_flow);
+ flowlabel = (tca->tca_dscp << 20) |
+ (flowlabel & ~(DSCP_MASK << 20));
+ ip6->ip6_flow = htonl(flowlabel);
+ } else
+#endif
+ ip->ip_tos = tca->tca_dscp |
+ (ip->ip_tos & DSCP_CUMASK);
+ return (1);
+ case TCACODE_NEXT:
+ cb = tca->tca_next;
+ tca = (*cb->cb_input)(cb, &pktinfo);
+ break;
+ case TCACODE_NONE:
+ default:
+ return (1);
+ }
+ }
+}
+
+static struct top_cdnr *
+tcb_lookup(ifname)
+ char *ifname;
+{
+ struct top_cdnr *top;
+ struct ifnet *ifp;
+
+ if ((ifp = ifunit(ifname)) != NULL)
+ LIST_FOREACH(top, &tcb_list, tc_next)
+ if (top->tc_ifq->altq_ifp == ifp)
+ return (top);
+ return (NULL);
+}
+
+static struct cdnr_block *
+cdnr_handle2cb(handle)
+ u_long handle;
+{
+ struct cdnr_block *cb;
+
+ cb = (struct cdnr_block *)handle;
+ if (handle != ALIGN(cb))
+ return (NULL);
+
+ if (cb == NULL || cb->cb_handle != handle)
+ return (NULL);
+ return (cb);
+}
+
+static u_long
+cdnr_cb2handle(cb)
+ struct cdnr_block *cb;
+{
+ return (cb->cb_handle);
+}
+
+static void *
+cdnr_cballoc(top, type, input_func)
+ struct top_cdnr *top;
+ int type;
+ struct tc_action *(*input_func)(struct cdnr_block *,
+ struct cdnr_pktinfo *);
+{
+ struct cdnr_block *cb;
+ int size;
+
+ switch (type) {
+ case TCETYPE_TOP:
+ size = sizeof(struct top_cdnr);
+ break;
+ case TCETYPE_ELEMENT:
+ size = sizeof(struct cdnr_block);
+ break;
+ case TCETYPE_TBMETER:
+ size = sizeof(struct tbmeter);
+ break;
+ case TCETYPE_TRTCM:
+ size = sizeof(struct trtcm);
+ break;
+ case TCETYPE_TSWTCM:
+ size = sizeof(struct tswtcm);
+ break;
+ default:
+ return (NULL);
+ }
+
+ MALLOC(cb, struct cdnr_block *, size, M_DEVBUF, M_WAITOK);
+ if (cb == NULL)
+ return (NULL);
+ bzero(cb, size);
+
+ cb->cb_len = size;
+ cb->cb_type = type;
+ cb->cb_ref = 0;
+ cb->cb_handle = (u_long)cb;
+ if (top == NULL)
+ cb->cb_top = (struct top_cdnr *)cb;
+ else
+ cb->cb_top = top;
+
+ if (input_func != NULL) {
+ /*
+ * if this cdnr has an action function,
+ * make tc_action to call itself.
+ */
+ cb->cb_action.tca_code = TCACODE_NEXT;
+ cb->cb_action.tca_next = cb;
+ cb->cb_input = input_func;
+ } else
+ cb->cb_action.tca_code = TCACODE_NONE;
+
+ /* if this isn't top, register the element to the top level cdnr */
+ if (top != NULL)
+ LIST_INSERT_HEAD(&top->tc_elements, cb, cb_next);
+
+ return ((void *)cb);
+}
+
+static void
+cdnr_cbdestroy(cblock)
+ void *cblock;
+{
+ struct cdnr_block *cb = cblock;
+
+ /* remove from the top level cdnr */
+ if (cb->cb_top != cblock)
+ LIST_REMOVE(cb, cb_next);
+
+ FREE(cb, M_DEVBUF);
+}
+
+/*
+ * conditioner common destroy routine
+ */
+static int
+generic_element_destroy(cb)
+ struct cdnr_block *cb;
+{
+ int error = 0;
+
+ switch (cb->cb_type) {
+ case TCETYPE_TOP:
+ error = top_destroy((struct top_cdnr *)cb);
+ break;
+ case TCETYPE_ELEMENT:
+ error = element_destroy(cb);
+ break;
+ case TCETYPE_TBMETER:
+ error = tbm_destroy((struct tbmeter *)cb);
+ break;
+ case TCETYPE_TRTCM:
+ error = trtcm_destroy((struct trtcm *)cb);
+ break;
+ case TCETYPE_TSWTCM:
+ error = tswtcm_destroy((struct tswtcm *)cb);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+static int
+tca_verify_action(utca)
+ struct tc_action *utca;
+{
+ switch (utca->tca_code) {
+ case TCACODE_PASS:
+ case TCACODE_DROP:
+ case TCACODE_MARK:
+ /* these are ok */
+ break;
+
+ case TCACODE_HANDLE:
+ /* verify handle value */
+ if (cdnr_handle2cb(utca->tca_handle) == NULL)
+ return (-1);
+ break;
+
+ case TCACODE_NONE:
+ case TCACODE_RETURN:
+ case TCACODE_NEXT:
+ default:
+ /* should not be passed from a user */
+ return (-1);
+ }
+ return (0);
+}
+
+static void
+tca_import_action(ktca, utca)
+ struct tc_action *ktca, *utca;
+{
+ struct cdnr_block *cb;
+
+ *ktca = *utca;
+ if (ktca->tca_code == TCACODE_HANDLE) {
+ cb = cdnr_handle2cb(ktca->tca_handle);
+ if (cb == NULL) {
+ ktca->tca_code = TCACODE_NONE;
+ return;
+ }
+ ktca->tca_code = TCACODE_NEXT;
+ ktca->tca_next = cb;
+ cb->cb_ref++;
+ } else if (ktca->tca_code == TCACODE_MARK) {
+ ktca->tca_dscp &= DSCP_MASK;
+ }
+ return;
+}
+
+static void
+tca_invalidate_action(tca)
+ struct tc_action *tca;
+{
+ struct cdnr_block *cb;
+
+ if (tca->tca_code == TCACODE_NEXT) {
+ cb = tca->tca_next;
+ if (cb == NULL)
+ return;
+ cb->cb_ref--;
+ }
+ tca->tca_code = TCACODE_NONE;
+}
+
+/*
+ * top level traffic conditioner
+ */
+static struct top_cdnr *
+top_create(ifq)
+ struct ifaltq *ifq;
+{
+ struct top_cdnr *top;
+
+ if ((top = cdnr_cballoc(NULL, TCETYPE_TOP, NULL)) == NULL)
+ return (NULL);
+
+ top->tc_ifq = ifq;
+ /* set default action for the top level conditioner */
+ top->tc_block.cb_action.tca_code = TCACODE_PASS;
+
+ LIST_INSERT_HEAD(&tcb_list, top, tc_next);
+
+ ifq->altq_cdnr = top;
+
+ return (top);
+}
+
+static int
+top_destroy(top)
+ struct top_cdnr *top;
+{
+ struct cdnr_block *cb;
+
+ if (ALTQ_IS_CNDTNING(top->tc_ifq))
+ ALTQ_CLEAR_CNDTNING(top->tc_ifq);
+ top->tc_ifq->altq_cdnr = NULL;
+
+ /*
+ * destroy all the conditioner elements belonging to this interface
+ */
+ while ((cb = LIST_FIRST(&top->tc_elements)) != NULL) {
+ while (cb != NULL && cb->cb_ref > 0)
+ cb = LIST_NEXT(cb, cb_next);
+ if (cb != NULL)
+ generic_element_destroy(cb);
+ }
+
+ LIST_REMOVE(top, tc_next);
+
+ cdnr_cbdestroy(top);
+
+ /* if there is no active conditioner, remove the input hook */
+ if (altq_input != NULL) {
+ LIST_FOREACH(top, &tcb_list, tc_next)
+ if (ALTQ_IS_CNDTNING(top->tc_ifq))
+ break;
+ if (top == NULL)
+ altq_input = NULL;
+ }
+
+ return (0);
+}
+
+/*
+ * simple tc elements without input function (e.g., dropper and makers).
+ */
+static struct cdnr_block *
+element_create(top, action)
+ struct top_cdnr *top;
+ struct tc_action *action;
+{
+ struct cdnr_block *cb;
+
+ if (tca_verify_action(action) < 0)
+ return (NULL);
+
+ if ((cb = cdnr_cballoc(top, TCETYPE_ELEMENT, NULL)) == NULL)
+ return (NULL);
+
+ tca_import_action(&cb->cb_action, action);
+
+ return (cb);
+}
+
+static int
+element_destroy(cb)
+ struct cdnr_block *cb;
+{
+ if (cb->cb_ref > 0)
+ return (EBUSY);
+
+ tca_invalidate_action(&cb->cb_action);
+
+ cdnr_cbdestroy(cb);
+ return (0);
+}
+
+/*
+ * internal representation of token bucket parameters
+ * rate: byte_per_unittime << 32
+ * (((bits_per_sec) / 8) << 32) / machclk_freq
+ * depth: byte << 32
+ *
+ */
+#define TB_SHIFT 32
+#define TB_SCALE(x) ((u_int64_t)(x) << TB_SHIFT)
+#define TB_UNSCALE(x) ((x) >> TB_SHIFT)
+
+static void
+tb_import_profile(tb, profile)
+ struct tbe *tb;
+ struct tb_profile *profile;
+{
+ tb->rate = TB_SCALE(profile->rate / 8) / machclk_freq;
+ tb->depth = TB_SCALE(profile->depth);
+ if (tb->rate > 0)
+ tb->filluptime = tb->depth / tb->rate;
+ else
+ tb->filluptime = 0xffffffffffffffffLL;
+ tb->token = tb->depth;
+ tb->last = read_machclk();
+}
+
+/*
+ * simple token bucket meter
+ */
+static struct tbmeter *
+tbm_create(top, profile, in_action, out_action)
+ struct top_cdnr *top;
+ struct tb_profile *profile;
+ struct tc_action *in_action, *out_action;
+{
+ struct tbmeter *tbm = NULL;
+
+ if (tca_verify_action(in_action) < 0
+ || tca_verify_action(out_action) < 0)
+ return (NULL);
+
+ if ((tbm = cdnr_cballoc(top, TCETYPE_TBMETER,
+ tbm_input)) == NULL)
+ return (NULL);
+
+ tb_import_profile(&tbm->tb, profile);
+
+ tca_import_action(&tbm->in_action, in_action);
+ tca_import_action(&tbm->out_action, out_action);
+
+ return (tbm);
+}
+
+static int
+tbm_destroy(tbm)
+ struct tbmeter *tbm;
+{
+ if (tbm->cdnrblk.cb_ref > 0)
+ return (EBUSY);
+
+ tca_invalidate_action(&tbm->in_action);
+ tca_invalidate_action(&tbm->out_action);
+
+ cdnr_cbdestroy(tbm);
+ return (0);
+}
+
+static struct tc_action *
+tbm_input(cb, pktinfo)
+ struct cdnr_block *cb;
+ struct cdnr_pktinfo *pktinfo;
+{
+ struct tbmeter *tbm = (struct tbmeter *)cb;
+ u_int64_t len;
+ u_int64_t interval, now;
+
+ len = TB_SCALE(pktinfo->pkt_len);
+
+ if (tbm->tb.token < len) {
+ now = read_machclk();
+ interval = now - tbm->tb.last;
+ if (interval >= tbm->tb.filluptime)
+ tbm->tb.token = tbm->tb.depth;
+ else {
+ tbm->tb.token += interval * tbm->tb.rate;
+ if (tbm->tb.token > tbm->tb.depth)
+ tbm->tb.token = tbm->tb.depth;
+ }
+ tbm->tb.last = now;
+ }
+
+ if (tbm->tb.token < len) {
+ PKTCNTR_ADD(&tbm->out_cnt, pktinfo->pkt_len);
+ return (&tbm->out_action);
+ }
+
+ tbm->tb.token -= len;
+ PKTCNTR_ADD(&tbm->in_cnt, pktinfo->pkt_len);
+ return (&tbm->in_action);
+}
+
+/*
+ * two rate three color marker
+ * as described in draft-heinanen-diffserv-trtcm-01.txt
+ */
+static struct trtcm *
+trtcm_create(top, cmtd_profile, peak_profile,
+ green_action, yellow_action, red_action, coloraware)
+ struct top_cdnr *top;
+ struct tb_profile *cmtd_profile, *peak_profile;
+ struct tc_action *green_action, *yellow_action, *red_action;
+ int coloraware;
+{
+ struct trtcm *tcm = NULL;
+
+ if (tca_verify_action(green_action) < 0
+ || tca_verify_action(yellow_action) < 0
+ || tca_verify_action(red_action) < 0)
+ return (NULL);
+
+ if ((tcm = cdnr_cballoc(top, TCETYPE_TRTCM,
+ trtcm_input)) == NULL)
+ return (NULL);
+
+ tb_import_profile(&tcm->cmtd_tb, cmtd_profile);
+ tb_import_profile(&tcm->peak_tb, peak_profile);
+
+ tca_import_action(&tcm->green_action, green_action);
+ tca_import_action(&tcm->yellow_action, yellow_action);
+ tca_import_action(&tcm->red_action, red_action);
+
+ /* set dscps to use */
+ if (tcm->green_action.tca_code == TCACODE_MARK)
+ tcm->green_dscp = tcm->green_action.tca_dscp & DSCP_MASK;
+ else
+ tcm->green_dscp = DSCP_AF11;
+ if (tcm->yellow_action.tca_code == TCACODE_MARK)
+ tcm->yellow_dscp = tcm->yellow_action.tca_dscp & DSCP_MASK;
+ else
+ tcm->yellow_dscp = DSCP_AF12;
+ if (tcm->red_action.tca_code == TCACODE_MARK)
+ tcm->red_dscp = tcm->red_action.tca_dscp & DSCP_MASK;
+ else
+ tcm->red_dscp = DSCP_AF13;
+
+ tcm->coloraware = coloraware;
+
+ return (tcm);
+}
+
+static int
+trtcm_destroy(tcm)
+ struct trtcm *tcm;
+{
+ if (tcm->cdnrblk.cb_ref > 0)
+ return (EBUSY);
+
+ tca_invalidate_action(&tcm->green_action);
+ tca_invalidate_action(&tcm->yellow_action);
+ tca_invalidate_action(&tcm->red_action);
+
+ cdnr_cbdestroy(tcm);
+ return (0);
+}
+
+static struct tc_action *
+trtcm_input(cb, pktinfo)
+ struct cdnr_block *cb;
+ struct cdnr_pktinfo *pktinfo;
+{
+ struct trtcm *tcm = (struct trtcm *)cb;
+ u_int64_t len;
+ u_int64_t interval, now;
+ u_int8_t color;
+
+ len = TB_SCALE(pktinfo->pkt_len);
+ if (tcm->coloraware) {
+ color = pktinfo->pkt_dscp;
+ if (color != tcm->yellow_dscp && color != tcm->red_dscp)
+ color = tcm->green_dscp;
+ } else {
+ /* if color-blind, precolor it as green */
+ color = tcm->green_dscp;
+ }
+
+ now = read_machclk();
+ if (tcm->cmtd_tb.token < len) {
+ interval = now - tcm->cmtd_tb.last;
+ if (interval >= tcm->cmtd_tb.filluptime)
+ tcm->cmtd_tb.token = tcm->cmtd_tb.depth;
+ else {
+ tcm->cmtd_tb.token += interval * tcm->cmtd_tb.rate;
+ if (tcm->cmtd_tb.token > tcm->cmtd_tb.depth)
+ tcm->cmtd_tb.token = tcm->cmtd_tb.depth;
+ }
+ tcm->cmtd_tb.last = now;
+ }
+ if (tcm->peak_tb.token < len) {
+ interval = now - tcm->peak_tb.last;
+ if (interval >= tcm->peak_tb.filluptime)
+ tcm->peak_tb.token = tcm->peak_tb.depth;
+ else {
+ tcm->peak_tb.token += interval * tcm->peak_tb.rate;
+ if (tcm->peak_tb.token > tcm->peak_tb.depth)
+ tcm->peak_tb.token = tcm->peak_tb.depth;
+ }
+ tcm->peak_tb.last = now;
+ }
+
+ if (color == tcm->red_dscp || tcm->peak_tb.token < len) {
+ pktinfo->pkt_dscp = tcm->red_dscp;
+ PKTCNTR_ADD(&tcm->red_cnt, pktinfo->pkt_len);
+ return (&tcm->red_action);
+ }
+
+ if (color == tcm->yellow_dscp || tcm->cmtd_tb.token < len) {
+ pktinfo->pkt_dscp = tcm->yellow_dscp;
+ tcm->peak_tb.token -= len;
+ PKTCNTR_ADD(&tcm->yellow_cnt, pktinfo->pkt_len);
+ return (&tcm->yellow_action);
+ }
+
+ pktinfo->pkt_dscp = tcm->green_dscp;
+ tcm->cmtd_tb.token -= len;
+ tcm->peak_tb.token -= len;
+ PKTCNTR_ADD(&tcm->green_cnt, pktinfo->pkt_len);
+ return (&tcm->green_action);
+}
+
+/*
+ * time sliding window three color marker
+ * as described in draft-fang-diffserv-tc-tswtcm-00.txt
+ */
+static struct tswtcm *
+tswtcm_create(top, cmtd_rate, peak_rate, avg_interval,
+ green_action, yellow_action, red_action)
+ struct top_cdnr *top;
+ u_int32_t cmtd_rate, peak_rate, avg_interval;
+ struct tc_action *green_action, *yellow_action, *red_action;
+{
+ struct tswtcm *tsw;
+
+ if (tca_verify_action(green_action) < 0
+ || tca_verify_action(yellow_action) < 0
+ || tca_verify_action(red_action) < 0)
+ return (NULL);
+
+ if ((tsw = cdnr_cballoc(top, TCETYPE_TSWTCM,
+ tswtcm_input)) == NULL)
+ return (NULL);
+
+ tca_import_action(&tsw->green_action, green_action);
+ tca_import_action(&tsw->yellow_action, yellow_action);
+ tca_import_action(&tsw->red_action, red_action);
+
+ /* set dscps to use */
+ if (tsw->green_action.tca_code == TCACODE_MARK)
+ tsw->green_dscp = tsw->green_action.tca_dscp & DSCP_MASK;
+ else
+ tsw->green_dscp = DSCP_AF11;
+ if (tsw->yellow_action.tca_code == TCACODE_MARK)
+ tsw->yellow_dscp = tsw->yellow_action.tca_dscp & DSCP_MASK;
+ else
+ tsw->yellow_dscp = DSCP_AF12;
+ if (tsw->red_action.tca_code == TCACODE_MARK)
+ tsw->red_dscp = tsw->red_action.tca_dscp & DSCP_MASK;
+ else
+ tsw->red_dscp = DSCP_AF13;
+
+ /* convert rates from bits/sec to bytes/sec */
+ tsw->cmtd_rate = cmtd_rate / 8;
+ tsw->peak_rate = peak_rate / 8;
+ tsw->avg_rate = 0;
+
+ /* timewin is converted from msec to machine clock unit */
+ tsw->timewin = (u_int64_t)machclk_freq * avg_interval / 1000;
+
+ return (tsw);
+}
+
+static int
+tswtcm_destroy(tsw)
+ struct tswtcm *tsw;
+{
+ if (tsw->cdnrblk.cb_ref > 0)
+ return (EBUSY);
+
+ tca_invalidate_action(&tsw->green_action);
+ tca_invalidate_action(&tsw->yellow_action);
+ tca_invalidate_action(&tsw->red_action);
+
+ cdnr_cbdestroy(tsw);
+ return (0);
+}
+
+static struct tc_action *
+tswtcm_input(cb, pktinfo)
+ struct cdnr_block *cb;
+ struct cdnr_pktinfo *pktinfo;
+{
+ struct tswtcm *tsw = (struct tswtcm *)cb;
+ int len;
+ u_int32_t avg_rate;
+ u_int64_t interval, now, tmp;
+
+ /*
+ * rate estimator
+ */
+ len = pktinfo->pkt_len;
+ now = read_machclk();
+
+ interval = now - tsw->t_front;
+ /*
+ * calculate average rate:
+ * avg = (avg * timewin + pkt_len)/(timewin + interval)
+ * pkt_len needs to be multiplied by machclk_freq in order to
+ * get (bytes/sec).
+ * note: when avg_rate (bytes/sec) and timewin (machclk unit) are
+ * less than 32 bits, the following 64-bit operation has enough
+ * precision.
+ */
+ tmp = ((u_int64_t)tsw->avg_rate * tsw->timewin
+ + (u_int64_t)len * machclk_freq) / (tsw->timewin + interval);
+ tsw->avg_rate = avg_rate = (u_int32_t)tmp;
+ tsw->t_front = now;
+
+ /*
+ * marker
+ */
+ if (avg_rate > tsw->cmtd_rate) {
+ u_int32_t randval = random() % avg_rate;
+
+ if (avg_rate > tsw->peak_rate) {
+ if (randval < avg_rate - tsw->peak_rate) {
+ /* mark red */
+ pktinfo->pkt_dscp = tsw->red_dscp;
+ PKTCNTR_ADD(&tsw->red_cnt, len);
+ return (&tsw->red_action);
+ } else if (randval < avg_rate - tsw->cmtd_rate)
+ goto mark_yellow;
+ } else {
+ /* peak_rate >= avg_rate > cmtd_rate */
+ if (randval < avg_rate - tsw->cmtd_rate) {
+ mark_yellow:
+ pktinfo->pkt_dscp = tsw->yellow_dscp;
+ PKTCNTR_ADD(&tsw->yellow_cnt, len);
+ return (&tsw->yellow_action);
+ }
+ }
+ }
+
+ /* mark green */
+ pktinfo->pkt_dscp = tsw->green_dscp;
+ PKTCNTR_ADD(&tsw->green_cnt, len);
+ return (&tsw->green_action);
+}
+
+/*
+ * ioctl requests
+ */
+static int
+cdnrcmd_if_attach(ifname)
+ char *ifname;
+{
+ struct ifnet *ifp;
+ struct top_cdnr *top;
+
+ if ((ifp = ifunit(ifname)) == NULL)
+ return (EBADF);
+
+ if (ifp->if_snd.altq_cdnr != NULL)
+ return (EBUSY);
+
+ if ((top = top_create(&ifp->if_snd)) == NULL)
+ return (ENOMEM);
+ return (0);
+}
+
+static int
+cdnrcmd_if_detach(ifname)
+ char *ifname;
+{
+ struct top_cdnr *top;
+
+ if ((top = tcb_lookup(ifname)) == NULL)
+ return (EBADF);
+
+ return top_destroy(top);
+}
+
+static int
+cdnrcmd_add_element(ap)
+ struct cdnr_add_element *ap;
+{
+ struct top_cdnr *top;
+ struct cdnr_block *cb;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ cb = element_create(top, &ap->action);
+ if (cb == NULL)
+ return (EINVAL);
+ /* return a class handle to the user */
+ ap->cdnr_handle = cdnr_cb2handle(cb);
+ return (0);
+}
+
+static int
+cdnrcmd_delete_element(ap)
+ struct cdnr_delete_element *ap;
+{
+ struct top_cdnr *top;
+ struct cdnr_block *cb;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ if (cb->cb_type != TCETYPE_ELEMENT)
+ return generic_element_destroy(cb);
+
+ return element_destroy(cb);
+}
+
+static int
+cdnrcmd_add_tbm(ap)
+ struct cdnr_add_tbmeter *ap;
+{
+ struct top_cdnr *top;
+ struct tbmeter *tbm;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ tbm = tbm_create(top, &ap->profile, &ap->in_action, &ap->out_action);
+ if (tbm == NULL)
+ return (EINVAL);
+ /* return a class handle to the user */
+ ap->cdnr_handle = cdnr_cb2handle(&tbm->cdnrblk);
+ return (0);
+}
+
+static int
+cdnrcmd_modify_tbm(ap)
+ struct cdnr_modify_tbmeter *ap;
+{
+ struct tbmeter *tbm;
+
+ if ((tbm = (struct tbmeter *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ tb_import_profile(&tbm->tb, &ap->profile);
+
+ return (0);
+}
+
+static int
+cdnrcmd_tbm_stats(ap)
+ struct cdnr_tbmeter_stats *ap;
+{
+ struct tbmeter *tbm;
+
+ if ((tbm = (struct tbmeter *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ ap->in_cnt = tbm->in_cnt;
+ ap->out_cnt = tbm->out_cnt;
+
+ return (0);
+}
+
+static int
+cdnrcmd_add_trtcm(ap)
+ struct cdnr_add_trtcm *ap;
+{
+ struct top_cdnr *top;
+ struct trtcm *tcm;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ tcm = trtcm_create(top, &ap->cmtd_profile, &ap->peak_profile,
+ &ap->green_action, &ap->yellow_action,
+ &ap->red_action, ap->coloraware);
+ if (tcm == NULL)
+ return (EINVAL);
+
+ /* return a class handle to the user */
+ ap->cdnr_handle = cdnr_cb2handle(&tcm->cdnrblk);
+ return (0);
+}
+
+static int
+cdnrcmd_modify_trtcm(ap)
+ struct cdnr_modify_trtcm *ap;
+{
+ struct trtcm *tcm;
+
+ if ((tcm = (struct trtcm *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ tb_import_profile(&tcm->cmtd_tb, &ap->cmtd_profile);
+ tb_import_profile(&tcm->peak_tb, &ap->peak_profile);
+
+ return (0);
+}
+
+static int
+cdnrcmd_tcm_stats(ap)
+ struct cdnr_tcm_stats *ap;
+{
+ struct cdnr_block *cb;
+
+ if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ if (cb->cb_type == TCETYPE_TRTCM) {
+ struct trtcm *tcm = (struct trtcm *)cb;
+
+ ap->green_cnt = tcm->green_cnt;
+ ap->yellow_cnt = tcm->yellow_cnt;
+ ap->red_cnt = tcm->red_cnt;
+ } else if (cb->cb_type == TCETYPE_TSWTCM) {
+ struct tswtcm *tsw = (struct tswtcm *)cb;
+
+ ap->green_cnt = tsw->green_cnt;
+ ap->yellow_cnt = tsw->yellow_cnt;
+ ap->red_cnt = tsw->red_cnt;
+ } else
+ return (EINVAL);
+
+ return (0);
+}
+
+static int
+cdnrcmd_add_tswtcm(ap)
+ struct cdnr_add_tswtcm *ap;
+{
+ struct top_cdnr *top;
+ struct tswtcm *tsw;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ if (ap->cmtd_rate > ap->peak_rate)
+ return (EINVAL);
+
+ tsw = tswtcm_create(top, ap->cmtd_rate, ap->peak_rate,
+ ap->avg_interval, &ap->green_action,
+ &ap->yellow_action, &ap->red_action);
+ if (tsw == NULL)
+ return (EINVAL);
+
+ /* return a class handle to the user */
+ ap->cdnr_handle = cdnr_cb2handle(&tsw->cdnrblk);
+ return (0);
+}
+
+static int
+cdnrcmd_modify_tswtcm(ap)
+ struct cdnr_modify_tswtcm *ap;
+{
+ struct tswtcm *tsw;
+
+ if ((tsw = (struct tswtcm *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
+ return (EINVAL);
+
+ if (ap->cmtd_rate > ap->peak_rate)
+ return (EINVAL);
+
+ /* convert rates from bits/sec to bytes/sec */
+ tsw->cmtd_rate = ap->cmtd_rate / 8;
+ tsw->peak_rate = ap->peak_rate / 8;
+ tsw->avg_rate = 0;
+
+ /* timewin is converted from msec to machine clock unit */
+ tsw->timewin = (u_int64_t)machclk_freq * ap->avg_interval / 1000;
+
+ return (0);
+}
+
+static int
+cdnrcmd_get_stats(ap)
+ struct cdnr_get_stats *ap;
+{
+ struct top_cdnr *top;
+ struct cdnr_block *cb;
+ struct tbmeter *tbm;
+ struct trtcm *tcm;
+ struct tswtcm *tsw;
+ struct tce_stats tce, *usp;
+ int error, n, nskip, nelements;
+
+ if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
+ return (EBADF);
+
+ /* copy action stats */
+ bcopy(top->tc_cnts, ap->cnts, sizeof(ap->cnts));
+
+ /* stats for each element */
+ nelements = ap->nelements;
+ usp = ap->tce_stats;
+ if (nelements <= 0 || usp == NULL)
+ return (0);
+
+ nskip = ap->nskip;