├── .gitattributes ├── .github └── workflows │ └── slim_armor.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── build.sh ├── devtools ├── Dockerfile └── README.md ├── global.sh ├── img ├── openwrt.drawio.png └── slimbuild.drawio.png ├── patches-modules ├── 0000-common-configs │ ├── custom.sh │ └── openwrt │ │ └── 0002-default-password.patch ├── 0001-fullcone-nat │ ├── custom.sh │ ├── feeds │ │ └── luci │ │ │ └── 0001-add-fullcone-option.patch │ ├── misc │ │ └── 952-net-conntrack-events-support-multiple-registrant.patch │ ├── openwrt-fullconenat │ │ ├── Makefile │ │ └── files │ │ │ └── Makefile │ └── openwrt │ │ ├── 0001-fullcone_option.patch │ │ └── 0002-fullcone_firewall.patch ├── 0002-upnp │ └── custom.sh ├── 0003-nf-conntrack-max │ └── openwrt │ │ └── 202-enlarge-nf-conntrack.patch ├── 0004-workaround-for-realtime-connection-status-crash │ ├── README.md │ └── feeds │ │ └── luci │ │ └── 0001-remove-connectionns-menu.patch ├── 0005-slim-localization-configuration │ ├── custom.sh │ └── slim-localization │ │ ├── Makefile │ │ └── files │ │ └── root │ │ └── etc │ │ └── uci-defaults │ │ └── slim-localization └── 0006-fake-vermagic │ └── custom.sh ├── profiles ├── official │ ├── config │ └── profile.sh ├── r1cl │ ├── appendconfig │ ├── config │ └── profile.sh └── slim │ ├── appendconfig │ ├── config │ └── profile.sh └── slimapps └── application ├── luci-app-boostupnp ├── Makefile ├── luasrc │ ├── controller │ │ └── boostupnp.lua │ └── model │ │ └── cbi │ │ └── upnp │ │ └── boostupnp.lua └── root │ ├── etc │ └── uci-defaults │ │ └── 40_luci-boostupnp │ └── usr │ └── sbin │ └── boostupnp.sh ├── luci-app-filetransfer ├── Makefile ├── etc │ └── uci-defaults │ │ └── luci-filetransfer ├── luasrc │ ├── controller │ │ └── filetransfer.lua │ ├── model │ │ └── cbi │ │ │ └── updownload.lua │ └── view │ │ └── cbi │ │ ├── other_button.htm │ │ ├── other_download.htm │ │ ├── other_dvalue.htm │ │ └── other_upload.htm └── po │ └── zh-cn │ └── filetransfer.po ├── luci-app-taghost ├── Makefile └── luasrc │ ├── controller │ └── taghost.lua │ └── model │ └── cbi │ └── taghost.lua └── luci-lib-fs ├── Makefile └── files └── fs.lua /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /.github/workflows/slim_armor.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow that is manually triggered 2 | 3 | name: Build with default profile - "slim" 4 | 5 | 6 | on: 7 | release: 8 | types: created 9 | push: 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | build_armor: 14 | runs-on: ubuntu-20.04 15 | strategy: 16 | matrix: 17 | slim_profile: ['slim', 'r1cl', 'official'] 18 | 19 | steps: 20 | - name: Start job for profiles 21 | run: echo "Profile ${{ matrix.slim_profile }}" 22 | 23 | - uses: actions/checkout@v2 24 | with: 25 | repository: 'ryohuang/slim-wrt' 26 | path: 'slim-wrt' 27 | 28 | - name: Install build tools 29 | env: 30 | DEBIAN_FRONTEND: noninteractive 31 | DEBCONF_NONINTERACTIVE_SEEN: true 32 | run: | 33 | sudo apt-get update &&\ 34 | sudo apt-get install -qqy --no-install-recommends build-essential asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch unzip zlib1g-dev lib32gcc1 libc6-dev-i386 subversion flex uglifyjs git-core gcc-multilib p7zip p7zip-full msmtp libssl-dev texinfo npm python-is-python3 ssh-client wget curl file screen && \ 35 | sudo apt-get clean && \ 36 | sudo rm -rf /var/lib/apt/lists/* 37 | 38 | - name: Showtime 39 | run: | 40 | cd $GITHUB_WORKSPACE/slim-wrt 41 | echo "build with profile ${{ matrix.slim_profile }}" 42 | make SLIM_CFG_PROFILE=${{ matrix.slim_profile }} showtime 43 | 44 | - name: Show vermagic and kernel config 45 | run: | 46 | set -x 47 | cd $GITHUB_WORKSPACE/slim-wrt 48 | find ./ -name .vermagic -exec cat {} \; 49 | find ./ -name .config.set -exec cat {} \; 50 | 51 | 52 | - name: Show outputs and zip ipks 53 | run: | 54 | df -h 55 | echo "SHOW IMAGES" 56 | ls $GITHUB_WORKSPACE/slim-wrt/images/${{ matrix.slim_profile }} 57 | echo "SHOW PACKAGES" 58 | ls $GITHUB_WORKSPACE/slim-wrt/ipks/${{ matrix.slim_profile }} 59 | cd $GITHUB_WORKSPACE/slim-wrt/ipks 60 | zip -r ${{ matrix.slim_profile }}.zip ./${{ matrix.slim_profile }} 61 | 62 | - name: Rename build info files 63 | run: | 64 | set -x 65 | profile=${{ matrix.slim_profile }} 66 | cd $GITHUB_WORKSPACE/slim-wrt/images/$profile 67 | for filename in ./**; do 68 | name=${filename##*/} 69 | if echo "$name" | grep -qE "buildinfo|sha256sums"; then 70 | mv $name $profile-$name 71 | fi 72 | done 73 | 74 | - name: Show outputs after rename 75 | run: | 76 | df -h 77 | echo "SHOW IMAGES" 78 | ls $GITHUB_WORKSPACE/slim-wrt/images/${{ matrix.slim_profile }} 79 | echo "SHOW PACKAGES" 80 | ls $GITHUB_WORKSPACE/slim-wrt/ipks 81 | 82 | - uses: actions/upload-artifact@v2 83 | with: 84 | name: ${{ matrix.slim_profile }}-images 85 | path: ${{ github.workspace }}/slim-wrt/images/${{ matrix.slim_profile }}/* 86 | 87 | - uses: xresloader/upload-to-github-release@v1 88 | env: 89 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 90 | with: 91 | file: "./slim-wrt/images/${{ matrix.slim_profile }}/**;./slim-wrt/ipks/${{ matrix.slim_profile }}.zip" 92 | tags: true 93 | draft: true 94 | overwrite: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /downloaded 2 | /*-src 3 | /built 4 | /images 5 | /ipks -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "slimapps/application/luci-theme-argon"] 2 | path = slimapps/application/luci-theme-argon 3 | url = https://github.com/jerrykuku/luci-theme-argon.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ALL: 2 | bash build.sh help_msg 3 | 4 | showtime: clone encore 5 | 6 | clone: 7 | bash build.sh clone_openwrt submodules 8 | 9 | cleandist: 10 | bash build.sh clear_dist 11 | 12 | clean: 13 | bash build.sh clear_stage clear_patches 14 | 15 | play: 16 | bash build.sh create_workspace patch_openwrt patch_feeds do_custom_script prepare_stage make_it move_built 17 | 18 | encore: clean play 19 | 20 | 21 | %: 22 | echo $1 23 | bash build.sh $@ 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slim-Openwrt 2 | 3 | > 给小小的Openwrt穿上盔甲 4 | 5 | ## 特点 6 | 7 | * 完全开源 8 | * 基于Openwrt最新稳定版并随之同步更新 9 | * 优化Upnp 10 | * Fullcone NAT (基于[LEAN](!https://github.com/coolsnowwolf/lede)) 11 | * 为特别设备设置特别的网关和DNS 12 | 13 | ## 动机 14 | 15 | 整个开源社区已经充满了各种各样的Openwrt修改版本,论坛上还有各个玩家自行编译的版本,但是我还是想自己做一个。 16 | 17 | 国内最流行的Openwrt修改版本应该就是Lean的那一版。Lean的版本确实很符合国情也好用。同时我也发现了一些问题。Lean的分支感觉离官方版本很远了,内核版本已经是5.x,但是软件源版本是18.x,导致很多时候装ipk会报依赖错误。 Lean的版本很多默认配置直接内置在了内部的makefile中,比如一个迅雷加速的东西也会被作为最小安装包被各个版本内置--可能很多人根本用不上吧? 但是,Lean的固件依然是现在国内最好用的开源Openwrt固件。Lean的改动像是改造出了一个金刚狼——让Openwrt强大好用了好几倍,但是对Openwrt的改动伤筋动骨。 18 | 19 | 我想实现的是一套盔甲,让Openwrt穿上后可以成为钢铁侠。而且目标是19.07能穿,21.02也能穿,之后22,23也能穿。所有就有了这个项目。 20 | 21 | ## 实现方法 22 | 23 | 下图是简单的Openwrt编译过程。 24 | 25 | 26 | ![Openwrt编译](./img/openwrt.drawio.png) 27 | 28 | 我们努力的方向有两个: 29 | 30 | 1. 改进默认配置的产生方法。make menuconfig很好用,但是配置不易传播和重复执行,对CI也不友好。 31 | 2. 在`make`之前是我们穿戴`盔甲`的时机。 32 | 33 | 34 | 于是我们有了这样的编译流程: 35 | 36 | ![Slim-wrt编译](./img/slimbuild.drawio.png) 37 | 38 | 1. 加入自定义的feed,指向本项目的slimapps目录。具体每个app做什么会在其目录下另写文档,在此不再赘述。 39 | 2. 对openwrt应用补丁。例如`patches-modules/0001-fullcone-nat/openwrt` 40 | 3. 对`luci`进行补丁。 41 | 4. 配置每个项目的profile,拷贝到openwrt根目录下之后执行defconfig就会生成相应配置。 42 | 5. 配置生成后再额外补充一些内容到.config文件。 43 | 6. make,等待之后固件就生出来了。 44 | 45 | ## 编译方法 46 | 47 | ```shell 48 | # 如果是编译x86/kvm使用的版本 49 | make SLIM_CFG_PROFILE=slim showtime 50 | # 或者忽略SLIM_CFG_PROFILE,因为默认就是slim这个配置 51 | make showtime 52 | # 如果编译Miwifi版本 53 | make SLIM_CFG_PROFILE=r1cl showtime 54 | 55 | # 修改之后重新编译,注意profile参数和之前一致 56 | make SLIM_CFG_PROFILE=slim encore 57 | ``` -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./global.sh 4 | 5 | echo "Start the build script" 6 | 7 | echo $SLIM_PROFILE 8 | 9 | load_profile() { 10 | echo $SLIM_CFG_PROFILE_DIR/profile.sh 11 | if [ -f $SLIM_CFG_PROFILE_DIR/profile.sh ] 12 | then 13 | echo Exist profile. Override some configs now. 14 | source $SLIM_CFG_PROFILE_DIR/profile.sh 15 | else 16 | echo No profile. Override some configs with default values now. 17 | fi 18 | 19 | SLIM_CFG_WORK_PATH="$SLIM_CFG_TOP_DIR/$SLIM_CFG_PROFILE-src" 20 | SLIM_CFG_BIN_IMG_DIR="$SLIM_CFG_WORK_PATH/bin/targets/$SLIM_CFG_TARGET/$SLIM_CFG_ARCH" 21 | SLIM_CFG_PATCHES_MODULES="$SLIM_CFG_TOP_DIR/patches-modules" 22 | SLIM_CFG_PROFILE_DIR="$SLIM_CFG_TOP_DIR/profiles/$SLIM_CFG_PROFILE" 23 | cd $SLIM_CFG_TOP_DIR 24 | } 25 | 26 | 27 | 28 | clone_openwrt() { 29 | # delete download dir for a fresh code base 30 | if [ -d $SLIM_CFG_DOWNLOAD_PATH/$SLIM_CFG_CLONE_PATH ] 31 | then 32 | rm -rf $SLIM_CFG_DOWNLOAD_PATH/$SLIM_CFG_CLONE_PATH 33 | fi 34 | 35 | if [ ! -d $SLIM_CFG_DOWNLOAD_PATH ] 36 | then 37 | mkdir $SLIM_CFG_DOWNLOAD_PATH 38 | fi 39 | 40 | cd $SLIM_CFG_DOWNLOAD_PATH 41 | if [ ! -d $SLIM_CFG_CLONE_PATH ] 42 | then 43 | git clone https://github.com/openwrt/openwrt.git $SLIM_CFG_CLONE_PATH 44 | fi 45 | cd $SLIM_CFG_CLONE_PATH 46 | git checkout $SLIM_CFG_OPENWRT_COMMIT 47 | ./scripts/feeds update -a 48 | ./scripts/feeds install -a 49 | cd $SLIM_CFG_TOP_DIR 50 | } 51 | 52 | submodules() { 53 | cd $SLIM_CFG_TOP_DIR 54 | git submodule 55 | git submodule init 56 | git submodule update 57 | cd $SLIM_CFG_TOP_DIR 58 | } 59 | 60 | create_workspace() { 61 | if [ ! -d $SLIM_CFG_WORK_PATH ] 62 | then 63 | cp -rf $SLIM_CFG_CLONE_PATH $SLIM_CFG_WORK_PATH 64 | fi 65 | cd $SLIM_CFG_TOP_DIR 66 | } 67 | 68 | list_dirs(){ 69 | echo $1 70 | cd $1 71 | j=0 72 | for i in `ls -d */` 73 | do 74 | rp=`realpath $i` 75 | patch_folder_list[j]=$rp 76 | j=`expr $j + 1` 77 | done 78 | echo ${patch_folder_list[@]} 79 | } 80 | 81 | # test it with : bash build.sh clear_patches patch_openwrt 82 | # arg1: The patch's full path. 83 | # Echo true, if found in exclude list 84 | # 85 | is_excluded_patch() { 86 | rtn="false" 87 | if [ -z "$SLIM_CFG_EXCLUDE_PATCH" ]; then 88 | rtn="false" 89 | else 90 | for patch_name in ${SLIM_CFG_EXCLUDE_PATCH[@]} 91 | do 92 | full_patch_name=$SLIM_CFG_PATCHES_MODULES/$patch_name 93 | if [ "$full_patch_name" == "$1" ] 94 | then 95 | rtn="true" 96 | break 97 | fi 98 | done 99 | fi 100 | echo $rtn 101 | } 102 | 103 | patch_openwrt() { 104 | patch_folder_list=`list_dirs "$SLIM_CFG_PATCHES_MODULES"` 105 | echo Patches list : ${patch_folder_list[@]} 106 | echo Process the patches. 107 | 108 | for i in ${patch_folder_list[@]} 109 | do 110 | echo Patch at $i 111 | retval=`is_excluded_patch "$i"` 112 | if [ "$retval" == "true" ] 113 | then 114 | echo "Exclude patch $i" 115 | continue 116 | fi 117 | if [ -d $i/openwrt ] 118 | then 119 | echo Apply patches in $i/openwrt 120 | cd $SLIM_CFG_WORK_PATH 121 | git apply $i/openwrt/*.patch 122 | fi 123 | done 124 | cd $SLIM_CFG_TOP_DIR 125 | } 126 | 127 | patch_feeds() { 128 | patch_folder_list=`list_dirs "$SLIM_CFG_PATCHES_MODULES"` 129 | for i in ${patch_folder_list[@]} 130 | do 131 | echo ------ Find feed patch in $i ------ 132 | retval=`is_excluded_patch "$i"` 133 | if [ "$retval" == "true" ] 134 | then 135 | echo "Exclude patch $i" 136 | continue 137 | fi 138 | if [ -d $i/feeds ] 139 | then 140 | echo ------ Found feed patch in $i/feeds ------ 141 | feed_folder_list=`list_dirs "$i/feeds"` 142 | for j in ${feed_folder_list[@]} 143 | do 144 | echo ----- feeds patch at $j ------ 145 | if [ "$j" == "$i/feeds" ] 146 | then 147 | echo ------ skip dir . ------- 148 | else 149 | echo ------ apply feed patch in $j ------ 150 | feed_name=${j##*/} 151 | feed_in_workspace=$SLIM_CFG_WORK_PATH/feeds/$feed_name 152 | cd $feed_in_workspace && git apply $j/*.patch 153 | fi 154 | done 155 | fi 156 | done 157 | cd $SLIM_CFG_TOP_DIR 158 | } 159 | 160 | do_custom_script() { 161 | patch_folder_list=`list_dirs "$SLIM_CFG_PATCHES_MODULES"` 162 | 163 | for i in ${patch_folder_list[@]} 164 | do 165 | retval=`is_excluded_patch "$i"` 166 | if [ "$retval" == "true" ] 167 | then 168 | echo "Exclude patch $i" 169 | continue 170 | fi 171 | if [ -f $i/custom.sh ] 172 | then 173 | cd $i 174 | source custom.sh 175 | cd $SLIM_CFG_TOP_DIR 176 | fi 177 | done 178 | cd $SLIM_CFG_TOP_DIR 179 | } 180 | 181 | clear_patches() { 182 | # clear patches in openwrt 183 | cd $SLIM_CFG_WORK_PATH && git reset --hard ; git clean -df 184 | # clear patches in feeds 185 | feeds_folder_list=`list_dirs "$SLIM_CFG_WORK_PATH/feeds/"` 186 | for i in ${feeds_folder_list[@]} 187 | do 188 | if [[ "$i" =~ ".tmp" ]];then 189 | real_feed_dir=${i%.tmp} 190 | # do the real job. 191 | cd $real_feed_dir && git reset --hard ; git clean -df 192 | fi 193 | done 194 | cd $SLIM_CFG_TOP_DIR 195 | } 196 | 197 | # do the stuff before showtime 198 | prepare_stage() { 199 | if [ -f $SLIM_CFG_PROFILE_DIR/config ] 200 | then 201 | cp -fr $SLIM_CFG_PROFILE_DIR/config $SLIM_CFG_WORK_PATH/.config 202 | fi 203 | cd $SLIM_CFG_WORK_PATH 204 | rm -f build.log 205 | make defconfig | tee -a build.log 206 | make download | tee -a build.log 207 | if [ -f $SLIM_CFG_PROFILE_DIR/appendconfig ] 208 | then 209 | cat $SLIM_CFG_PROFILE_DIR/appendconfig >> $SLIM_CFG_WORK_PATH/.config 210 | fi 211 | # Replace ##SLIMVERSIONTAG with current tag or git hash 212 | # A gittag should be v19.07.7-21030301 213 | # v: means version 214 | # 19.07.7: means openwrt branch 215 | # 210303: means 2021-03-03 (year-mon-day) 216 | # 01: means release number 217 | sample="v19.07.7-21030301" 218 | gittag=$( git describe --tags ) 219 | githash=$( git rev-parse HEAD | cut -b 1-7 ) 220 | if [ ${#sample} == ${#gittag} ] 221 | then 222 | sed -i "s/##SLIMVERSIONTAG/$gittag/g" $SLIM_CFG_WORK_PATH/.config 223 | else 224 | sed -i "s/##SLIMVERSIONTAG/$githash/g" $SLIM_CFG_WORK_PATH/.config 225 | fi 226 | cd $SLIM_CFG_TOP_DIR 227 | } 228 | 229 | 230 | make_it() { 231 | cd $SLIM_CFG_WORK_PATH 232 | make -j$(($(nproc)+2)) V=s | tee -a build.log 233 | cd $SLIM_CFG_TOP_DIR 234 | } 235 | 236 | get_pkg_arch_from_config() 237 | { 238 | config_file_path="$1" 239 | cat $config_file_path | grep "^CONFIG_TARGET_ARCH_PACKAGES" | sed 's/^.*="\(.*\)"/\1/g' 240 | } 241 | 242 | move_built() { 243 | # move images and related files (version, buildinfo , etc) 244 | img_dst="$SLIM_CFG_TOP_DIR/images/$SLIM_CFG_PROFILE" 245 | if [ -d $img_dst ] 246 | then 247 | echo "Clean old images" 248 | rm -rf $img_dst 249 | fi 250 | mkdir -p $img_dst 251 | # list built files 252 | cd $SLIM_CFG_WORK_PATH/bin/targets/$SLIM_CFG_TARGET/$SLIM_CFG_ARCH 253 | for i in `ls` 254 | do 255 | if [ -f "$i" ] 256 | then 257 | cp $i $img_dst 258 | fi 259 | done 260 | # move ipks 261 | ipk_dst="$SLIM_CFG_TOP_DIR/ipks/$SLIM_CFG_PROFILE" 262 | if [ -d $ipk_dst ] 263 | then 264 | echo "Clean old images" 265 | rm -rf $ipk_dst 266 | fi 267 | mkdir -p $ipk_dst 268 | target_arch_packages=$(get_pkg_arch_from_config "$SLIM_CFG_WORK_PATH/.config") 269 | # x86.slim-src\bin\packages\x86_64\ 270 | cd $SLIM_CFG_WORK_PATH/bin/packages/${target_arch_packages} 271 | for i in `find . -maxdepth 3 -name "*.ipk"` 272 | do 273 | cp -rf $i $ipk_dst 274 | done 275 | cd $SLIM_CFG_WORK_PATH/bin/targets/$SLIM_CFG_TARGET/$SLIM_CFG_ARCH 276 | for i in `find . -maxdepth 3 -name "*.ipk"` 277 | do 278 | cp -rf $i $ipk_dst 279 | done 280 | cd $SLIM_CFG_TOP_DIR 281 | } 282 | 283 | clear_stage() { 284 | # remove /ipks and /images 285 | rm -rf $SLIM_CFG_TOP_DIR/ipks 286 | rm -rf $SLIM_CFG_TOP_DIR/images 287 | cd $SLIM_CFG_TOP_DIR 288 | } 289 | 290 | clear_dist() { 291 | clear_stage 292 | rm -rf $SLIM_CFG_TOP_DIR/downloaded 293 | rm -rf $SLIM_CFG_TOP_DIR/*-src 294 | } 295 | 296 | help_msg() { 297 | cat << EOF 298 | usage: bash build.sh [actions] 299 | 300 | actions: 301 | load_profile: Load profiles. Profiles should defined in /profiles dir. 302 | clone_openwrt: Clone a fresh openwrt codebase. Codebase controlled by SLIM_CFG_OPENWRT_BRANCH and SLIM_CFG_OPENWRT_COMMIT. 303 | EOF 304 | } 305 | 306 | # load_profile 307 | # clone_openwrt 308 | # submodules 309 | # create_workspace 310 | # patch_openwrt 311 | # patch_feeds 312 | # do_custom_script 313 | # prepare_stage 314 | # make_it 315 | # move_built 316 | # clear_patches 317 | 318 | load_profile # always load profiles 319 | 320 | for i in "$@"; do 321 | echo $i 322 | case $i in 323 | "clear_stage") 324 | clear_stage 325 | ;; 326 | "clone_openwrt") 327 | clone_openwrt 328 | ;; 329 | "submodules") 330 | submodules 331 | ;; 332 | "create_workspace") 333 | create_workspace 334 | ;; 335 | "patch_openwrt") 336 | patch_openwrt 337 | ;; 338 | "patch_feeds") 339 | patch_feeds 340 | ;; 341 | "do_custom_script") 342 | do_custom_script 343 | ;; 344 | "make_it") 345 | make_it 346 | ;; 347 | "move_built") 348 | move_built 349 | ;; 350 | "clear_patches") 351 | clear_patches 352 | ;; 353 | "prepare_stage") 354 | prepare_stage 355 | ;; 356 | "clear_dist") 357 | clear_dist 358 | ;; 359 | "help_msg") 360 | help_msg 361 | ;; 362 | *) 363 | echo "Unknow command $i" 364 | help_msg 365 | exit 1 366 | esac 367 | done -------------------------------------------------------------------------------- /devtools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG USER=user 4 | ARG UID=1000 5 | ARG GID=1000 6 | # default password for user 7 | ARG PW=docker 8 | # only on local machine 9 | RUN sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list 10 | 11 | RUN export DEBIAN_FRONTEND=noninteractive; \ 12 | export DEBCONF_NONINTERACTIVE_SEEN=true; \ 13 | echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ 14 | echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ 15 | apt-get update &&\ 16 | apt-get install -qqy --no-install-recommends libpkgconf-dev libpkgconf3 rsync build-essential asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch unzip zlib1g-dev lib32gcc1 libc6-dev-i386 subversion flex uglifyjs git-core gcc-multilib p7zip p7zip-full msmtp libssl-dev texinfo npm python-is-python3 ssh-client wget curl file screen && \ 17 | apt-get clean && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | RUN useradd -m ${USER} --uid=${UID} && echo "${USER}:${PW}" | \ 21 | chpasswd 22 | 23 | USER ${UID}:${GID} 24 | WORKDIR /home/${USER} 25 | 26 | # set dummy git config 27 | RUN git config --global user.name "user" && git config --global user.email "user@example.com" -------------------------------------------------------------------------------- /devtools/README.md: -------------------------------------------------------------------------------- 1 | # Build tools 2 | 3 | ## Build with docker 4 | 5 | ```shell 6 | # build the image 7 | cd devtools 8 | docker build --build-arg UID=$(id -u) \ 9 | --build-arg GID=$(id -g) \ 10 | -t slim_builder . 11 | cd /path/of/source/code 12 | docker run -v $(pwd):/home/user slim_builder /bin/bash -c "id && ls -l /home/user && make encore" 13 | ``` -------------------------------------------------------------------------------- /global.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | scriptpath="$(readlink -f "$0")" 6 | SLIM_CFG_TOP_DIR="${scriptpath%/${0##*/}}" 7 | SLIM_CFG_OPENWRT_BRANCH="openwrt-19.07" 8 | SLIM_CFG_OPENWRT_COMMIT="d5ae5658730a82312a20e68220f92f611b11d094" 9 | SLIM_CFG_OPENWRT_ABBREV_COMMIT=$( echo "$SLIM_CFG_OPENWRT_COMMIT" | cut -b 1-7 ) 10 | SLIM_CFG_OPENWRT_VERSION="19.07" 11 | SLIM_CFG_TARGET="x86" 12 | SLIM_CFG_ARCH="64" 13 | 14 | SLIM_CFG_DOWNLOAD_PATH="$SLIM_CFG_TOP_DIR/downloaded" 15 | SLIM_CFG_CLONE_PATH="$SLIM_CFG_TOP_DIR/downloaded/$SLIM_CFG_OPENWRT_BRANCH-$SLIM_CFG_OPENWRT_ABBREV_COMMIT" 16 | 17 | if [ -z $SLIM_CFG_PROFILE ] 18 | then 19 | SLIM_CFG_PROFILE="slim" 20 | fi 21 | 22 | echo Work with profile : $SLIM_CFG_PROFILE 23 | SLIM_CFG_PROFILE_DIR="$SLIM_CFG_TOP_DIR/profiles/$SLIM_CFG_PROFILE" 24 | 25 | 26 | # should override by profile 27 | SLIM_CFG_WORK_PATH="" 28 | SLIM_CFG_BIN_IMG_DIR="" 29 | SLIM_CFG_PATCHES_MODULES="" 30 | -------------------------------------------------------------------------------- /img/openwrt.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryohuang/slim-wrt/01a0efa23f608fb1ff2269d907fc3fd98f7f2840/img/openwrt.drawio.png -------------------------------------------------------------------------------- /img/slimbuild.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryohuang/slim-wrt/01a0efa23f608fb1ff2269d907fc3fd98f7f2840/img/slimbuild.drawio.png -------------------------------------------------------------------------------- /patches-modules/0000-common-configs/custom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # append slimapps 4 | if grep -q "slim" $SLIM_CFG_WORK_PATH/feeds.conf.default 5 | then 6 | echo "Already exit slimapps" 7 | else 8 | cat <> $SLIM_CFG_WORK_PATH/feeds.conf.default 9 | 10 | src-cpy slim ../slimapps 11 | src-git diskman https://github.com/lisaac/luci-app-diskman.git^975859fb7030ded885287c312a8127333f656930 12 | 13 | EOT 14 | fi 15 | 16 | # all the custom scripts will run in their own path. 17 | cd $SLIM_CFG_WORK_PATH 18 | ./scripts/feeds update slim 19 | ./scripts/feeds install -a -p slim 20 | # diskman depends on parted 21 | mkdir -p package/parted && wget https://raw.githubusercontent.com/lisaac/luci-app-diskman/master/Parted.Makefile -O package/parted/Makefile 22 | ./scripts/feeds update diskman 23 | ./scripts/feeds install -a -p diskman 24 | cd $SLIM_CFG_TOP_DIR -------------------------------------------------------------------------------- /patches-modules/0000-common-configs/openwrt/0002-default-password.patch: -------------------------------------------------------------------------------- 1 | diff --git a/package/base-files/files/etc/shadow b/package/base-files/files/etc/shadow 2 | index 4b4154f21f..e71733be22 100644 3 | --- a/package/base-files/files/etc/shadow 4 | +++ b/package/base-files/files/etc/shadow 5 | @@ -1,4 +1,4 @@ 6 | -root::0:0:99999:7::: 7 | +root:$1$BHFAI6e7$H180r06ukZ8FMIt/j2J8t.:18668:0:99999:7::: 8 | daemon:*:0:0:99999:7::: 9 | ftp:*:0:0:99999:7::: 10 | network:*:0:0:99999:7::: 11 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/custom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # all the custom scripts will run in their own path. 4 | echo "Script executed from: ${PWD}" 5 | 6 | # copy fullcone package 7 | cp -rf ${PWD}/openwrt-fullconenat $SLIM_CFG_WORK_PATH/package 8 | 9 | # copy kernle patch for fullcone 10 | cp -rf ${PWD}/misc/952-net-conntrack-events-support-multiple-registrant.patch $SLIM_CFG_WORK_PATH/target/linux/generic/hack-4.14/952-net-conntrack-events-support-multiple-registrant.patch 11 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/feeds/luci/0001-add-fullcone-option.patch: -------------------------------------------------------------------------------- 1 | diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js 2 | index b2f9b81..3d05156 100644 3 | --- a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js 4 | +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js 5 | @@ -57,6 +57,8 @@ return view.extend({ 6 | 7 | o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets')); 8 | 9 | + o = s.option(form.Flag, 'fullcone', _('Enable fullcone NAT')); 10 | + 11 | var p = [ 12 | s.option(form.ListValue, 'input', _('Input')), 13 | s.option(form.ListValue, 'output', _('Output')), 14 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/misc/952-net-conntrack-events-support-multiple-registrant.patch: -------------------------------------------------------------------------------- 1 | diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h 2 | index 12d967b..c2b98b6 100644 3 | --- a/include/net/netfilter/nf_conntrack_ecache.h 4 | +++ b/include/net/netfilter/nf_conntrack_ecache.h 5 | @@ -71,6 +71,10 @@ struct nf_ct_event { 6 | int report; 7 | }; 8 | 9 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 10 | +extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb); 11 | +extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb); 12 | +#else 13 | struct nf_ct_event_notifier { 14 | int (*fcn)(unsigned int events, struct nf_ct_event *item); 15 | }; 16 | @@ -79,7 +83,7 @@ int nf_conntrack_register_notifier(struc 17 | struct nf_ct_event_notifier *nb); 18 | void nf_conntrack_unregister_notifier(struct net *net, 19 | struct nf_ct_event_notifier *nb); 20 | - 21 | +#endif 22 | void nf_ct_deliver_cached_events(struct nf_conn *ct); 23 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, 24 | u32 portid, int report); 25 | @@ -87,12 +91,15 @@ int nf_conntrack_eventmask_report(unsign 26 | static inline void 27 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) 28 | { 29 | - struct net *net = nf_ct_net(ct); 30 | struct nf_conntrack_ecache *e; 31 | +#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 32 | + struct net *net = nf_ct_net(ct); 33 | 34 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 35 | return; 36 | 37 | +#endif 38 | + 39 | e = nf_ct_ecache_find(ct); 40 | if (e == NULL) 41 | return; 42 | @@ -104,10 +111,12 @@ static inline int 43 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, 44 | u32 portid, int report) 45 | { 46 | +#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 47 | const struct net *net = nf_ct_net(ct); 48 | 49 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 50 | return 0; 51 | +#endif 52 | 53 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); 54 | } 55 | @@ -115,11 +124,14 @@ nf_conntrack_event_report(enum ip_conntr 56 | static inline int 57 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) 58 | { 59 | +#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 60 | const struct net *net = nf_ct_net(ct); 61 | 62 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 63 | return 0; 64 | 65 | +#endif 66 | + 67 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); 68 | } 69 | 70 | diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h 71 | index e469e85..1d31db8 100644 72 | --- a/include/net/netns/conntrack.h 73 | +++ b/include/net/netns/conntrack.h 74 | @@ -114,7 +114,11 @@ struct netns_ct { 75 | 76 | struct ct_pcpu __percpu *pcpu_lists; 77 | struct ip_conntrack_stat __percpu *stat; 78 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 79 | + struct atomic_notifier_head nf_conntrack_chain; 80 | +#else 81 | struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; 82 | +#endif 83 | struct nf_exp_event_notifier __rcu *nf_expect_event_cb; 84 | struct nf_ip_net nf_ct_proto; 85 | #if defined(CONFIG_NF_CONNTRACK_LABELS) 86 | diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig 87 | index 63073be..08d7aab 100644 88 | --- a/net/netfilter/Kconfig 89 | +++ b/net/netfilter/Kconfig 90 | @@ -118,6 +118,14 @@ config NF_CONNTRACK_EVENTS 91 | 92 | If unsure, say `N'. 93 | 94 | +config NF_CONNTRACK_CHAIN_EVENTS 95 | + bool "Register multiple callbacks to ct events" 96 | + depends on NF_CONNTRACK_EVENTS 97 | + help 98 | + Support multiple registrations. 99 | + 100 | + If unsure, say `N'. 101 | + 102 | config NF_CONNTRACK_TIMEOUT 103 | bool 'Connection tracking timeout' 104 | depends on NETFILTER_ADVANCED 105 | diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c 106 | index 6bd1508..9b81c7c 100644 107 | --- a/net/netfilter/nf_conntrack_core.c 108 | +++ b/net/netfilter/nf_conntrack_core.c 109 | @@ -2167,6 +2167,10 @@ int nf_conntrack_init_net(struct net *ne 110 | ret = nf_conntrack_proto_pernet_init(net); 111 | if (ret < 0) 112 | goto err_proto; 113 | + 114 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 115 | + ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain); 116 | +#endif 117 | return 0; 118 | 119 | err_proto: 120 | diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c 121 | index da9df2d..e0e2a8f 100644 122 | --- a/net/netfilter/nf_conntrack_ecache.c 123 | +++ b/net/netfilter/nf_conntrack_ecache.c 124 | @@ -18,6 +18,9 @@ 125 | #include 126 | #include 127 | #include 128 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 129 | +#include 130 | +#endif 131 | #include 132 | #include 133 | #include 134 | @@ -117,6 +120,38 @@ static void ecache_work(struct work_stru 135 | schedule_delayed_work(&ctnet->ecache_dwork, delay); 136 | } 137 | 138 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 139 | +int 140 | +nf_conntrack_eventmask_report(unsigned int eventmask, 141 | + struct nf_conn *ct, 142 | + u32 portid, 143 | + int report) 144 | +{ 145 | + struct nf_conntrack_ecache *e; 146 | + struct net *net = nf_ct_net(ct); 147 | + 148 | + e = nf_ct_ecache_find(ct); 149 | + if (e == NULL) 150 | + return 0; 151 | + 152 | + if (nf_ct_is_confirmed(ct)) { 153 | + struct nf_ct_event item = { 154 | + .ct = ct, 155 | + .portid = e->portid ? e->portid : portid, 156 | + .report = report 157 | + }; 158 | + /* This is a resent of a destroy event? If so, skip missed */ 159 | + unsigned long missed = e->portid ? 0 : e->missed; 160 | + 161 | + if (!((eventmask | missed) & e->ctmask)) 162 | + return 0; 163 | + 164 | + atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item); 165 | + } 166 | + 167 | + return 0; 168 | +} 169 | +#else 170 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, 171 | u32 portid, int report) 172 | { 173 | @@ -171,10 +206,52 @@ out_unlock: 174 | rcu_read_unlock(); 175 | return ret; 176 | } 177 | +#endif 178 | EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report); 179 | 180 | /* deliver cached events and clear cache entry - must be called with locally 181 | * disabled softirqs */ 182 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 183 | +void nf_ct_deliver_cached_events(struct nf_conn *ct) 184 | +{ 185 | + unsigned long events, missed; 186 | + struct nf_conntrack_ecache *e; 187 | + struct nf_ct_event item; 188 | + struct net *net = nf_ct_net(ct); 189 | + 190 | + e = nf_ct_ecache_find(ct); 191 | + if (e == NULL) 192 | + return; 193 | + 194 | + events = xchg(&e->cache, 0); 195 | + 196 | + if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events) 197 | + return; 198 | + 199 | + /* We make a copy of the missed event cache without taking 200 | + * the lock, thus we may send missed events twice. However, 201 | + * this does not harm and it happens very rarely. */ 202 | + missed = e->missed; 203 | + 204 | + if (!((events | missed) & e->ctmask)) 205 | + return; 206 | + 207 | + item.ct = ct; 208 | + item.portid = 0; 209 | + item.report = 0; 210 | + 211 | + atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, 212 | + events | missed, 213 | + &item); 214 | + 215 | + if (likely(!missed)) 216 | + return; 217 | + 218 | + spin_lock_bh(&ct->lock); 219 | + e->missed &= ~missed; 220 | + spin_unlock_bh(&ct->lock); 221 | +} 222 | +#else 223 | void nf_ct_deliver_cached_events(struct nf_conn *ct) 224 | { 225 | struct net *net = nf_ct_net(ct); 226 | @@ -225,6 +302,7 @@ void nf_ct_deliver_cached_events(struct 227 | out_unlock: 228 | rcu_read_unlock(); 229 | } 230 | +#endif 231 | EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); 232 | 233 | void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, 234 | @@ -257,6 +335,12 @@ out_unlock: 235 | rcu_read_unlock(); 236 | } 237 | 238 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 239 | +int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb) 240 | +{ 241 | + return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); 242 | +} 243 | +#else 244 | int nf_conntrack_register_notifier(struct net *net, 245 | struct nf_ct_event_notifier *new) 246 | { 247 | @@ -277,8 +361,15 @@ out_unlock: 248 | mutex_unlock(&nf_ct_ecache_mutex); 249 | return ret; 250 | } 251 | +#endif 252 | EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); 253 | 254 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 255 | +int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb) 256 | +{ 257 | + return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); 258 | +} 259 | +#else 260 | void nf_conntrack_unregister_notifier(struct net *net, 261 | struct nf_ct_event_notifier *new) 262 | { 263 | @@ -292,6 +383,7 @@ void nf_conntrack_unregister_notifier(st 264 | mutex_unlock(&nf_ct_ecache_mutex); 265 | /* synchronize_rcu() is called from ctnetlink_exit. */ 266 | } 267 | +#endif 268 | EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); 269 | 270 | int nf_ct_expect_register_notifier(struct net *net, 271 | diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c 272 | index 04111c1..8c741f7 100644 273 | --- a/net/netfilter/nf_conntrack_netlink.c 274 | +++ b/net/netfilter/nf_conntrack_netlink.c 275 | @@ -28,6 +28,11 @@ 276 | #include 277 | #include 278 | #include 279 | + 280 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 281 | +#include 282 | +#endif 283 | + 284 | #include 285 | 286 | #include 287 | @@ -618,14 +623,22 @@ static size_t ctnetlink_nlmsg_size(const 288 | ; 289 | } 290 | 291 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 292 | +static int ctnetlink_conntrack_event(struct notifier_block *this, 293 | + unsigned long events, void *ptr) 294 | +#else 295 | static int 296 | ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) 297 | +#endif 298 | { 299 | const struct nf_conntrack_zone *zone; 300 | struct net *net; 301 | struct nlmsghdr *nlh; 302 | struct nfgenmsg *nfmsg; 303 | struct nlattr *nest_parms; 304 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 305 | + struct nf_ct_event *item = (struct nf_ct_event *)ptr; 306 | +#endif 307 | struct nf_conn *ct = item->ct; 308 | struct sk_buff *skb; 309 | unsigned int type; 310 | @@ -3290,9 +3303,15 @@ static int ctnetlink_stat_exp_cpu(struct 311 | } 312 | 313 | #ifdef CONFIG_NF_CONNTRACK_EVENTS 314 | +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS 315 | +static struct notifier_block ctnl_notifier = { 316 | + .notifier_call = ctnetlink_conntrack_event, 317 | +}; 318 | +#else 319 | static struct nf_ct_event_notifier ctnl_notifier = { 320 | .fcn = ctnetlink_conntrack_event, 321 | }; 322 | +#endif 323 | 324 | static struct nf_exp_event_notifier ctnl_notifier_exp = { 325 | .fcn = ctnetlink_expect_event, 326 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/openwrt-fullconenat/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Chion Tang 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | include $(INCLUDE_DIR)/kernel.mk 10 | 11 | PKG_NAME:=fullconenat 12 | PKG_RELEASE:=3 13 | 14 | PKG_SOURCE_DATE:=2019-10-21 15 | PKG_SOURCE_PROTO:=git 16 | PKG_SOURCE_URL:=https://github.com/Chion82/netfilter-full-cone-nat.git 17 | PKG_SOURCE_VERSION:=0cf3b48fd7d2fa81d0297d1fff12bbd0580fc435 18 | 19 | PKG_LICENSE:=GPL-2.0 20 | PKG_LICENSE_FILES:=LICENSE 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | 24 | define Package/iptables-mod-fullconenat 25 | SUBMENU:=Firewall 26 | SECTION:=net 27 | CATEGORY:=Network 28 | TITLE:=FULLCONENAT iptables extension 29 | DEPENDS:=+iptables +kmod-ipt-fullconenat 30 | MAINTAINER:=Chion Tang 31 | endef 32 | 33 | define Package/iptables-mod-fullconenat/install 34 | $(INSTALL_DIR) $(1)/usr/lib/iptables 35 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/libipt_FULLCONENAT.so $(1)/usr/lib/iptables 36 | endef 37 | 38 | define KernelPackage/ipt-fullconenat 39 | SUBMENU:=Netfilter Extensions 40 | TITLE:=FULLCONENAT netfilter module 41 | DEPENDS:=+kmod-nf-ipt +kmod-nf-nat 42 | MAINTAINER:=Chion Tang 43 | KCONFIG:=CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y 44 | FILES:=$(PKG_BUILD_DIR)/xt_FULLCONENAT.ko 45 | endef 46 | 47 | include $(INCLUDE_DIR)/kernel-defaults.mk 48 | 49 | define Build/Prepare 50 | $(call Build/Prepare/Default) 51 | $(CP) ./files/Makefile $(PKG_BUILD_DIR)/ 52 | endef 53 | 54 | define Build/Compile 55 | +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ 56 | CROSS_COMPILE="$(TARGET_CROSS)" \ 57 | ARCH="$(LINUX_KARCH)" \ 58 | M="$(PKG_BUILD_DIR)" \ 59 | EXTRA_CFLAGS="$(BUILDFLAGS)" \ 60 | modules 61 | $(call Build/Compile/Default) 62 | endef 63 | 64 | $(eval $(call BuildPackage,iptables-mod-fullconenat)) 65 | $(eval $(call KernelPackage,ipt-fullconenat)) 66 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/openwrt-fullconenat/files/Makefile: -------------------------------------------------------------------------------- 1 | libipt_FULLCONENAT.so: libipt_FULLCONENAT.o 2 | $(CC) -shared -lxtables -o $@ $^; 3 | libipt_FULLCONENAT.o: libipt_FULLCONENAT.c 4 | $(CC) ${CFLAGS} -fPIC -D_INIT=$*_init -c -o $@ $<; 5 | 6 | obj-m += xt_FULLCONENAT.o 7 | 8 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/openwrt/0001-fullcone_option.patch: -------------------------------------------------------------------------------- 1 | --- a/package/network/config/firewall/Makefile 2 | +++ b/package/network/config/firewall/Makefile 3 | @@ -28,7 +28,7 @@ define Package/firewall 4 | SECTION:=net 5 | CATEGORY:=Base system 6 | TITLE:=OpenWrt C Firewall 7 | - DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat 8 | + DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat +iptables-mod-fullconenat 9 | endef 10 | 11 | define Package/firewall/description 12 | --- a/package/network/config/firewall/files/firewall.config 13 | +++ b/package/network/config/firewall/files/firewall.config 14 | @@ -3,6 +3,7 @@ config defaults 15 | option input ACCEPT 16 | option output ACCEPT 17 | option forward REJECT 18 | + option fullcone 1 19 | # Uncomment this line to disable ipv6 rules 20 | # option disable_ipv6 1 21 | 22 | -------------------------------------------------------------------------------- /patches-modules/0001-fullcone-nat/openwrt/0002-fullcone_firewall.patch: -------------------------------------------------------------------------------- 1 | --- /dev/null 2 | +++ b/package/network/config/firewall/patches/200-fullconenat.patch 3 | @@ -0,0 +1,63 @@ 4 | +index 85a3750..9fac9b1 100644 5 | +--- a/defaults.c 6 | ++++ b/defaults.c 7 | +@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts[] = { 8 | + FW3_OPT("synflood_protect", bool, defaults, syn_flood), 9 | + FW3_OPT("synflood_rate", limit, defaults, syn_flood_rate), 10 | + FW3_OPT("synflood_burst", int, defaults, syn_flood_rate.burst), 11 | +- 12 | ++ 13 | ++ FW3_OPT("fullcone", bool, defaults, fullcone), 14 | ++ 15 | + FW3_OPT("tcp_syncookies", bool, defaults, tcp_syncookies), 16 | + FW3_OPT("tcp_ecn", int, defaults, tcp_ecn), 17 | + FW3_OPT("tcp_window_scaling", bool, defaults, tcp_window_scaling), 18 | +diff --git a/options.h b/options.h 19 | +index 6edd174..c02eb97 100644 20 | +--- a/options.h 21 | ++++ b/options.h 22 | +@@ -267,6 +267,7 @@ struct fw3_defaults 23 | + bool drop_invalid; 24 | + 25 | + bool syn_flood; 26 | ++ bool fullcone; 27 | + struct fw3_limit syn_flood_rate; 28 | + 29 | + bool tcp_syncookies; 30 | +diff --git a/zones.c b/zones.c 31 | +index 2aa7473..57eead0 100644 32 | +--- a/zones.c 33 | ++++ b/zones.c 34 | +@@ -627,6 +627,7 @@ print_zone_rule(struct fw3_ipt_handle *h 35 | + struct fw3_address *msrc; 36 | + struct fw3_address *mdest; 37 | + struct fw3_ipt_rule *r; 38 | ++ struct fw3_defaults *defs = &state->defaults; 39 | + 40 | + if (!fw3_is_family(zone, handle->family)) 41 | + return; 42 | +@@ -712,8 +713,22 @@ print_zone_rule(struct fw3_ipt_handle *h 43 | + { 44 | + r = fw3_ipt_rule_new(handle); 45 | + fw3_ipt_rule_src_dest(r, msrc, mdest); 46 | +- fw3_ipt_rule_target(r, "MASQUERADE"); 47 | +- fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); 48 | ++ /*FIXME: Workaround for FULLCONE-NAT*/ 49 | ++ if(defs->fullcone) 50 | ++ { 51 | ++ warn("%s will enable FULLCONE-NAT", zone->name); 52 | ++ fw3_ipt_rule_target(r, "FULLCONENAT"); 53 | ++ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); 54 | ++ r = fw3_ipt_rule_new(handle); 55 | ++ fw3_ipt_rule_src_dest(r, msrc, mdest); 56 | ++ fw3_ipt_rule_target(r, "FULLCONENAT"); 57 | ++ fw3_ipt_rule_append(r, "zone_%s_prerouting", zone->name); 58 | ++ } 59 | ++ else 60 | ++ { 61 | ++ fw3_ipt_rule_target(r, "MASQUERADE"); 62 | ++ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); 63 | ++ } 64 | + } 65 | + } 66 | + } 67 | -------------------------------------------------------------------------------- /patches-modules/0002-upnp/custom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # all the custom scripts will run in their own path. 4 | echo "Script executed from: ${PWD}" 5 | 6 | echo "Dummy file." -------------------------------------------------------------------------------- /patches-modules/0003-nf-conntrack-max/openwrt/202-enlarge-nf-conntrack.patch: -------------------------------------------------------------------------------- 1 | --- a/package/kernel/linux/files/sysctl-nf-conntrack.conf 2 | +++ b/package/kernel/linux/files/sysctl-nf-conntrack.conf 3 | @@ -3,7 +3,7 @@ 4 | 5 | net.netfilter.nf_conntrack_acct=1 6 | net.netfilter.nf_conntrack_checksum=0 7 | -net.netfilter.nf_conntrack_max=16384 8 | +net.netfilter.nf_conntrack_max=65535 9 | net.netfilter.nf_conntrack_tcp_timeout_established=7440 10 | net.netfilter.nf_conntrack_udp_timeout=60 11 | net.netfilter.nf_conntrack_udp_timeout_stream=180 12 | 13 | -------------------------------------------------------------------------------- /patches-modules/0004-workaround-for-realtime-connection-status-crash/README.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | This is a known issue: https://github.com/openwrt/luci/issues/4816 4 | This patch hides the menu entry as a workaround. -------------------------------------------------------------------------------- /patches-modules/0004-workaround-for-realtime-connection-status-crash/feeds/luci/0001-remove-connectionns-menu.patch: -------------------------------------------------------------------------------- 1 | --- a/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json 2 | +++ b/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json 3 | @@ -90,14 +90,5 @@ 4 | "depends": { 5 | "uci": { "wireless": { "@wifi-device": true } } 6 | } 7 | - }, 8 | - 9 | - "admin/status/realtime/connections": { 10 | - "title": "Connections", 11 | - "order": 4, 12 | - "action": { 13 | - "type": "view", 14 | - "path": "status/connections" 15 | - } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /patches-modules/0005-slim-localization-configuration/custom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # all the custom scripts will run in their own path. 4 | echo "Script executed from: ${PWD}" 5 | 6 | # copy fullcone package 7 | cp -rf ${PWD}/slim-localization $SLIM_CFG_WORK_PATH/package 8 | -------------------------------------------------------------------------------- /patches-modules/0005-slim-localization-configuration/slim-localization/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021 OpenWrt-dist 3 | # 4 | # This is free software, licensed under the GNU General Public License v3. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=slim-localization 11 | PKG_VERSION:=1.0 12 | PKG_RELEASE:=1 13 | 14 | PKG_LICENSE:=GPLv3 15 | PKG_LICENSE_FILES:=LICENSE 16 | PKG_MAINTAINER:=ryohuang 17 | 18 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) 19 | 20 | include $(INCLUDE_DIR)/package.mk 21 | 22 | define Package/slim-localization 23 | SECTION:=luci 24 | CATEGORY:=Slim 25 | TITLE:=Slim localization configuration 26 | PKGARCH:=all 27 | DEPENDS:=+luci \ 28 | +luci-i18n-base-zh-cn \ 29 | +luci-i18n-firewall-zh-cn \ 30 | +luci-i18n-upnp-zh-cn \ 31 | +luci-i18n-ttyd-zh-cn 32 | endef 33 | 34 | define Package/slim-localization/description 35 | slim localization configuration 36 | endef 37 | 38 | define Build/Prepare 39 | endef 40 | 41 | define Build/Configure 42 | endef 43 | 44 | define Build/Compile 45 | endef 46 | 47 | define Package/slim-localization/postinst 48 | endef 49 | 50 | define Package/slim-localization/install 51 | $(INSTALL_DIR) $(1)/etc/uci-defaults 52 | $(INSTALL_BIN) ./files/root/etc/uci-defaults/slim-localization $(1)/etc/uci-defaults/slim-localization 53 | endef 54 | 55 | 56 | $(eval $(call BuildPackage,slim-localization)) 57 | -------------------------------------------------------------------------------- /patches-modules/0005-slim-localization-configuration/slim-localization/files/root/etc/uci-defaults/slim-localization: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | uci batch <<-EOF 3 | set system.@system[0].zonename=Asia/Shanghai 4 | set system.@system[0].timezone=CST-8 5 | commit system 6 | set luci.main.lang=zh_cn 7 | commit luci 8 | EOF 9 | exit 0 -------------------------------------------------------------------------------- /patches-modules/0006-fake-vermagic/custom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # all the custom scripts will run in their own path. 4 | echo "Script executed from: ${PWD}" 5 | 6 | if [[ ! -z $SLIM_FAKE_VERMAGIC ]] 7 | then 8 | echo "Caution! We will set a fake vermagic now!" 9 | OLD='grep.*mkhash md5.*vermagic' 10 | NEW="echo $SLIM_FAKE_VERMAGIC > \$(LINUX_DIR)/.vermagic" 11 | sed -i 's@'"$OLD"'@'"$NEW"'@' $SLIM_CFG_WORK_PATH/include/kernel-defaults.mk 12 | fi -------------------------------------------------------------------------------- /profiles/official/config: -------------------------------------------------------------------------------- 1 | CONFIG_TARGET_x86=y 2 | CONFIG_TARGET_x86_64=y 3 | CONFIG_TARGET_x86_64_Generic=y 4 | CONFIG_ALL_KMODS=y 5 | CONFIG_ALL_NONSHARED=y 6 | CONFIG_DEVEL=y 7 | CONFIG_AUTOREMOVE=y 8 | CONFIG_BUILDBOT=y 9 | CONFIG_IB=y 10 | CONFIG_IMAGEOPT=y 11 | CONFIG_JSON_OVERVIEW_IMAGE_INFO=y 12 | CONFIG_KERNEL_BUILD_DOMAIN="buildhost" 13 | CONFIG_KERNEL_BUILD_USER="builder" 14 | # CONFIG_KERNEL_KALLSYMS is not set 15 | CONFIG_PACKAGE_cgi-io=y 16 | CONFIG_PACKAGE_libiwinfo=y 17 | CONFIG_PACKAGE_libiwinfo-lua=y 18 | CONFIG_PACKAGE_liblua=y 19 | CONFIG_PACKAGE_liblucihttp=y 20 | CONFIG_PACKAGE_liblucihttp-lua=y 21 | CONFIG_PACKAGE_libubus-lua=y 22 | CONFIG_PACKAGE_lua=y 23 | CONFIG_PACKAGE_luci=y 24 | CONFIG_PACKAGE_luci-app-firewall=y 25 | CONFIG_PACKAGE_luci-app-opkg=y 26 | CONFIG_PACKAGE_luci-base=y 27 | CONFIG_PACKAGE_luci-lib-ip=y 28 | CONFIG_PACKAGE_luci-lib-jsonc=y 29 | CONFIG_PACKAGE_luci-lib-nixio=y 30 | CONFIG_PACKAGE_luci-mod-admin-full=y 31 | CONFIG_PACKAGE_luci-mod-network=y 32 | CONFIG_PACKAGE_luci-mod-status=y 33 | CONFIG_PACKAGE_luci-mod-system=y 34 | CONFIG_PACKAGE_luci-proto-ipv6=y 35 | CONFIG_PACKAGE_luci-proto-ppp=y 36 | CONFIG_PACKAGE_luci-theme-bootstrap=y 37 | CONFIG_PACKAGE_rpcd=y 38 | CONFIG_PACKAGE_rpcd-mod-file=y 39 | CONFIG_PACKAGE_rpcd-mod-iwinfo=y 40 | CONFIG_PACKAGE_rpcd-mod-luci=y 41 | CONFIG_PACKAGE_rpcd-mod-rrdns=y 42 | CONFIG_PACKAGE_uhttpd=y 43 | CONFIG_SDK=y 44 | CONFIG_VERSIONOPT=y 45 | CONFIG_VERSION_BUG_URL="" 46 | CONFIG_VERSION_CODE="" 47 | CONFIG_VERSION_DIST="OpenWrt" 48 | CONFIG_VERSION_FILENAMES=y 49 | CONFIG_VERSION_HOME_URL="" 50 | CONFIG_VERSION_HWREV="" 51 | CONFIG_VERSION_MANUFACTURER="" 52 | CONFIG_VERSION_MANUFACTURER_URL="" 53 | CONFIG_VERSION_NUMBER="" 54 | CONFIG_VERSION_PRODUCT="" 55 | CONFIG_VERSION_REPO="http://downloads.openwrt.org/releases/19.07.7" 56 | CONFIG_VERSION_SUPPORT_URL="" 57 | # CONFIG_COLLECT_KERNEL_DEBUG is not set 58 | -------------------------------------------------------------------------------- /profiles/official/profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SLIM_CFG_TARGET="x86" 4 | SLIM_CFG_ARCH="64" 5 | 6 | SLIM_CFG_EXCLUDE_PATCH=(\ 7 | 0000-common-configs \ 8 | 0002-upnp \ 9 | 0003-nf-conntrack-max \ 10 | 0004-workaround-for-realtime-connection-status-crash \ 11 | 0005-slim-localization-configuration \ 12 | 0006-fake-vermagic \ 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /profiles/r1cl/appendconfig: -------------------------------------------------------------------------------- 1 | 2 | CONFIG_VERSIONOPT=y 3 | CONFIG_VERSION_DIST="Slim-OpenWrt" 4 | CONFIG_VERSION_NUMBER="19.07.7" 5 | CONFIG_VERSION_CODE="Mark I ##SLIMVERSIONTAG" 6 | CONFIG_VERSION_REPO="http://downloads.openwrt.org/releases/19.07.7" 7 | CONFIG_VERSION_HOME_URL="" 8 | CONFIG_VERSION_MANUFACTURER="" 9 | CONFIG_VERSION_MANUFACTURER_URL="" 10 | CONFIG_VERSION_BUG_URL="" 11 | CONFIG_VERSION_SUPPORT_URL="" 12 | CONFIG_VERSION_PRODUCT="" 13 | CONFIG_VERSION_HWREV="" 14 | CONFIG_VERSION_FILENAMES=y 15 | CONFIG_VERSION_CODE_FILENAMES=y 16 | -------------------------------------------------------------------------------- /profiles/r1cl/config: -------------------------------------------------------------------------------- 1 | CONFIG_TARGET_ramips=y 2 | CONFIG_TARGET_ramips_mt76x8=y 3 | CONFIG_TARGET_ramips_mt76x8_DEVICE_miwifi-nano=y 4 | 5 | CONFIG_PACKAGE_luci=y 6 | CONFIG_PACKAGE_luci-i18n-base-zh-cn=y 7 | CONFIG_PACKAGE_luci-app-taghost=y 8 | CONFIG_PACKAGE_luci-app-upnp=y 9 | CONFIG_PACKAGE_luci-app-boostupnp=y 10 | CONFIG_PACKAGE_luci-app-sqm=y 11 | CONFIG_PACKAGE_luci-app-ttyd=y 12 | CONFIG_PACKAGE_luci-theme-argon=y 13 | CONFIG_PACKAGE_luci-app-filetransfer=y 14 | 15 | CONFIG_FEED_slim=m 16 | CONFIG_FEED_diskman=m 17 | -------------------------------------------------------------------------------- /profiles/r1cl/profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SLIM_CFG_TARGET="ramips" 4 | SLIM_CFG_ARCH="mt76x8" 5 | 6 | SLIM_CFG_EXCLUDE_PATCH=(\ 7 | 0002-upnp \ 8 | 0001-fullcone-nat \ 9 | ) 10 | 11 | echo ${SLIM_CFG_EXCLUDE_PATCH[*]} 12 | 13 | # You can add more exclude patches as following lines. 14 | # SLIM_CFG_EXCLUDE_PATCH=(\ 15 | # 0002-upnp \ 16 | # 0003-nf-conntrack-max \ 17 | # ) -------------------------------------------------------------------------------- /profiles/slim/appendconfig: -------------------------------------------------------------------------------- 1 | 2 | CONFIG_VERSIONOPT=y 3 | CONFIG_VERSION_DIST="Slim-OpenWrt" 4 | CONFIG_VERSION_NUMBER="19.07.7" 5 | CONFIG_VERSION_CODE="Mark I ##SLIMVERSIONTAG" 6 | CONFIG_VERSION_REPO="http://mirror.sjtu.edu.cn/openwrt/releases/19.07.7" 7 | CONFIG_VERSION_HOME_URL="" 8 | CONFIG_VERSION_MANUFACTURER="" 9 | CONFIG_VERSION_MANUFACTURER_URL="" 10 | CONFIG_VERSION_BUG_URL="" 11 | CONFIG_VERSION_SUPPORT_URL="" 12 | CONFIG_VERSION_PRODUCT="" 13 | CONFIG_VERSION_HWREV="" 14 | CONFIG_VERSION_FILENAMES=y 15 | CONFIG_VERSION_CODE_FILENAMES=y 16 | -------------------------------------------------------------------------------- /profiles/slim/config: -------------------------------------------------------------------------------- 1 | CONFIG_TARGET_x86=y 2 | CONFIG_TARGET_x86_64=y 3 | CONFIG_TARGET_x86_64_Generic=y 4 | 5 | CONFIG_PACKAGE_luci=y 6 | CONFIG_PACKAGE_luci-app-taghost=y 7 | CONFIG_PACKAGE_luci-app-upnp=y 8 | CONFIG_PACKAGE_luci-app-boostupnp=y 9 | CONFIG_PACKAGE_luci-app-sqm=y 10 | CONFIG_PACKAGE_luci-app-ttyd=y 11 | CONFIG_PACKAGE_luci-theme-argon=y 12 | CONFIG_PACKAGE_luci-app-filetransfer=y 13 | 14 | CONFIG_FEED_slim=m 15 | CONFIG_FEED_diskman=m 16 | 17 | CONFIG_PACKAGE_slim-localization=y 18 | CONFIG_PACKAGE_luci-app-diskman=y -------------------------------------------------------------------------------- /profiles/slim/profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SLIM_CFG_TARGET="x86" 4 | SLIM_CFG_ARCH="64" 5 | 6 | SLIM_CFG_EXCLUDE_PATCH=(\ 7 | 0002-upnp \ 8 | ) 9 | 10 | echo ${SLIM_CFG_EXCLUDE_PATCH[*]} 11 | 12 | # You can add more exclude patches as following lines. 13 | # SLIM_CFG_EXCLUDE_PATCH=(\ 14 | # 0002-upnp \ 15 | # 0003-nf-conntrack-max \ 16 | # ) 17 | 18 | SLIM_FAKE_VERMAGIC="68143adfcb7fc62a239c4be112fe40de" 19 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-boostupnp/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | PKG_NAME:=luci-app-boostupnp 10 | 11 | LUCI_TITLE:=luci-app-boostupnp 12 | LUCI_DEPENDS:=+miniupnpd +curl 13 | LUCI_PKGARCH:=all 14 | PKG_VERSION:=1.0 15 | PKG_RELEASE:=6 16 | 17 | include $(TOPDIR)/feeds/luci/luci.mk 18 | 19 | # call BuildPackage - OpenWrt buildroot signature 20 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-boostupnp/luasrc/controller/boostupnp.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2008 Steven Barth 2 | -- Copyright 2008 Jo-Philipp Wich 3 | -- Licensed to the public under the Apache License 2.0. 4 | 5 | module("luci.controller.boostupnp", package.seeall) 6 | 7 | function index() 8 | if not nixio.fs.access("/etc/config/upnpd") then 9 | return 10 | end 11 | 12 | local page 13 | 14 | page = entry({"admin", "services", "boostupnp"}, cbi("upnp/boostupnp"), _("BoostUPnP")) 15 | page.dependent = true 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-boostupnp/luasrc/model/cbi/upnp/boostupnp.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2008 Steven Barth 2 | -- Copyright 2008-2011 Jo-Philipp Wich 3 | -- Licensed to the public under the Apache License 2.0. 4 | 5 | m = Map("upnpd", luci.util.pcdata(translate("Universal Plug & Play")), 6 | translate("UPnP allows clients in the local network to automatically configure the router.")) 7 | 8 | 9 | s = m:section(NamedSection, "config", "upnpd", translate("MiniUPnP extra settings")) 10 | s.addremove = false 11 | s:tab("general", translate("Settings for router behined DMZ")) 12 | 13 | 14 | s:taboption("general", Value, "external_iface", translate("External Network Interface"), 15 | translate("usually is wan")).rmempty = true 16 | 17 | s:taboption("general", Value, "internal_iface", translate("Internal Network Interface"), 18 | translate("usually is lan")).rmempty = true 19 | 20 | return m 21 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-boostupnp/root/etc/uci-defaults/40_luci-boostupnp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | logger boostupnp "uci-default" 4 | 5 | test -f /etc/crontabs/root || touch /etc/crontabs/root 6 | grep -q "boostupnp.sh" /etc/crontabs/root || echo "*/5 * * * * /usr/sbin/boostupnp.sh" >> /etc/crontabs/root 7 | /etc/init.d/cron restart 8 | 9 | rm -f /tmp/luci-indexcache 10 | exit 0 11 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-boostupnp/root/usr/sbin/boostupnp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | upnplog(){ 5 | echo "$1" 6 | logger boostupnp "$1" 7 | } 8 | 9 | # get public ip address 10 | ip=$(curl -s https://api.ipify.org) 11 | upnplog "My public IP address is: $ip" 12 | 13 | # check public ip 14 | if [ -z "$ip" ];then 15 | upnplog "No validate public IP, exit !" 16 | exit 17 | fi 18 | 19 | 20 | if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then 21 | upnplog "Validate public IP" 22 | else 23 | upnplog "Wrong IP address" 24 | exit 25 | fi 26 | 27 | # get upnp configed external ip 28 | upnp_ext_ip=$(uci get upnpd.config.external_ip) 29 | upnplog "My upnp external IP address is: $upnp_ext_ip" 30 | 31 | 32 | if [ "$ip" = "$upnp_ext_ip" ];then 33 | upnplog "Upnp external IP up to date. Exit." 34 | exit 35 | fi 36 | 37 | # ok, set new external ip to upnp 38 | uci set upnpd.config.external_ip=$ip 39 | uci commit upnpd 40 | 41 | # restart upnpd 42 | /etc/init.d/miniupnpd restart & 43 | 44 | upnplog "Configed new external for upnp: $ip" 45 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | LUCI_TITLE:=LuCI page for IPK upload 10 | LUCI_DEPENDS:=+luci-lib-fs 11 | PKG_VERSION:=1 12 | PKG_RELEASE:=2 13 | 14 | include $(TOPDIR)/feeds/luci/luci.mk 15 | 16 | # call BuildPackage - OpenWrt buildroot signature 17 | 18 | 19 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/etc/uci-defaults/luci-filetransfer: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua 4 | 5 | rm -f /tmp/luci-indexcache 6 | exit 0 7 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/controller/filetransfer.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | luci-app-filetransfer 3 | Description: File upload / download 4 | Author: yuleniwo xzm2@qq.com QQ:529698939 5 | Modify: ayongwifi@126.com www.openwrtdl.com 6 | ]]-- 7 | 8 | module("luci.controller.filetransfer", package.seeall) 9 | 10 | function index() 11 | entry({"admin", "system", "filetransfer"}, form("updownload"), _("FileTransfer"),89) 12 | end 13 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/model/cbi/updownload.lua: -------------------------------------------------------------------------------- 1 | local fs = require "luci.fs" 2 | local http = luci.http 3 | 4 | ful = SimpleForm("upload", translate("Upload"), nil) 5 | ful.reset = false 6 | ful.submit = false 7 | 8 | sul = ful:section(SimpleSection, "", translate("Upload file to '/tmp/upload/'")) 9 | fu = sul:option(FileUpload, "") 10 | fu.template = "cbi/other_upload" 11 | um = sul:option(DummyValue, "", nil) 12 | um.template = "cbi/other_dvalue" 13 | 14 | fdl = SimpleForm("download", translate("Download"), nil) 15 | fdl.reset = false 16 | fdl.submit = false 17 | sdl = fdl:section(SimpleSection, "", translate("Download file")) 18 | fd = sdl:option(FileUpload, "") 19 | fd.template = "cbi/other_download" 20 | dm = sdl:option(DummyValue, "", nil) 21 | dm.template = "cbi/other_dvalue" 22 | 23 | function Download() 24 | local sPath, sFile, fd, block 25 | sPath = http.formvalue("dlfile") 26 | sFile = nixio.fs.basename(sPath) 27 | if luci.fs.isdirectory(sPath) then 28 | fd = io.popen('tar -C "%s" -cz .' % {sPath}, "r") 29 | sFile = sFile .. ".tar.gz" 30 | else 31 | fd = nixio.open(sPath, "r") 32 | end 33 | if not fd then 34 | dm.value = translate("Couldn't open file: ") .. sPath 35 | return 36 | end 37 | dm.value = nil 38 | http.header('Content-Disposition', 'attachment; filename="%s"' % {sFile}) 39 | http.prepare_content("application/octet-stream") 40 | while true do 41 | block = fd:read(nixio.const.buffersize) 42 | if (not block) or (#block ==0) then 43 | break 44 | else 45 | http.write(block) 46 | end 47 | end 48 | fd:close() 49 | http.close() 50 | end 51 | 52 | local dir, fd 53 | dir = "/tmp/upload/" 54 | nixio.fs.mkdir(dir) 55 | http.setfilehandler( 56 | function(meta, chunk, eof) 57 | if not fd then 58 | if not meta then return end 59 | 60 | if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end 61 | 62 | if not fd then 63 | um.value = translate("Create upload file error.") 64 | return 65 | end 66 | end 67 | if chunk and fd then 68 | fd:write(chunk) 69 | end 70 | if eof and fd then 71 | fd:close() 72 | fd = nil 73 | um.value = translate("File saved to") .. ' "/tmp/upload/' .. meta.file .. '"' 74 | end 75 | end 76 | ) 77 | 78 | if luci.http.formvalue("upload") then 79 | 80 | 81 | local f = luci.http.formvalue("ulfile") 82 | if #f <= 0 then 83 | um.value = translate("No specify upload file.") 84 | end 85 | elseif luci.http.formvalue("download") then 86 | Download() 87 | end 88 | 89 | local function getSizeStr(size) 90 | local i = 0 91 | local byteUnits = {' kB', ' MB', ' GB', ' TB'} 92 | repeat 93 | size = size / 1024 94 | i = i + 1 95 | until(size <= 1024) 96 | return string.format("%.1f", size) .. byteUnits[i] 97 | end 98 | 99 | local inits, attr = {} 100 | for i, f in ipairs(fs.glob("/tmp/upload/*")) do 101 | attr = fs.stat(f) 102 | if attr then 103 | inits[i] = {} 104 | inits[i].name = fs.basename(f) 105 | inits[i].mtime = os.date("%Y-%m-%d %H:%M:%S", attr.mtime) 106 | inits[i].modestr = attr.modestr 107 | inits[i].size = getSizeStr(attr.size) 108 | inits[i].remove = 0 109 | inits[i].install = false 110 | end 111 | end 112 | 113 | form = SimpleForm("filelist", translate("Upload file list"), nil) 114 | form.reset = false 115 | form.submit = false 116 | 117 | tb = form:section(Table, inits) 118 | nm = tb:option(DummyValue, "name", translate("File name")) 119 | mt = tb:option(DummyValue, "mtime", translate("Modify time")) 120 | ms = tb:option(DummyValue, "modestr", translate("Attributes")) 121 | sz = tb:option(DummyValue, "size", translate("Size")) 122 | btnrm = tb:option(Button, "remove", translate("Remove")) 123 | btnrm.render = function(self, section, scope) 124 | self.inputstyle = "remove" 125 | Button.render(self, section, scope) 126 | end 127 | 128 | btnrm.write = function(self, section) 129 | local v = luci.fs.unlink("/tmp/upload/" .. luci.fs.basename(inits[section].name)) 130 | if v then table.remove(inits, section) end 131 | return v 132 | end 133 | 134 | function IsIpkFile(name) 135 | name = name or "" 136 | local ext = string.lower(string.sub(name, -4, -1)) 137 | return ext == ".ipk" 138 | end 139 | 140 | btnis = tb:option(Button, "install", translate("Install")) 141 | btnis.template = "cbi/other_button" 142 | btnis.render = function(self, section, scope) 143 | if not inits[section] then return false end 144 | if IsIpkFile(inits[section].name) then 145 | scope.display = "" 146 | else 147 | scope.display = "none" 148 | end 149 | self.inputstyle = "apply" 150 | Button.render(self, section, scope) 151 | end 152 | 153 | btnis.write = function(self, section) 154 | local r = luci.sys.exec(string.format('opkg --force-depends install "/tmp/upload/%s"', inits[section].name)) 155 | form.description = string.format('%s', r) 156 | end 157 | 158 | return ful, fdl, form 159 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/view/cbi/other_button.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | <% if self:cfgvalue(section) ~= false then %> 3 | " style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> 4 | <% else %> 5 | - 6 | <% end %> 7 | <%+cbi/valuefooter%> 8 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/view/cbi/other_download.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | 3 | 4 | 5 | <%+cbi/valuefooter%> 6 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | 3 | <% 4 | local val = self:cfgvalue(section) or self.default or "" 5 | write(pcdata(val)) 6 | %> 7 | 8 | <%+cbi/valuefooter%> 9 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | 3 | 4 | 5 | <%+cbi/valuefooter%> 6 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-filetransfer/po/zh-cn/filetransfer.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Project-Id-Version: \n" 5 | "POT-Creation-Date: \n" 6 | "PO-Revision-Date: \n" 7 | "Last-Translator: dingpengyu \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "Language: zh_CN\n" 12 | "X-Generator: Poedit 2.3.1\n" 13 | 14 | msgid "Choose local file:" 15 | msgstr "选择本地文件:" 16 | 17 | msgid "Couldn't open file:" 18 | msgstr "无法打开文件:" 19 | 20 | msgid "Create upload file error." 21 | msgstr "创建上传文件失败。" 22 | 23 | msgid "Download" 24 | msgstr "下载" 25 | 26 | msgid "Download file" 27 | msgstr "下载文件" 28 | 29 | msgid "File name" 30 | msgstr "文件名" 31 | 32 | msgid "File saved to" 33 | msgstr "文件保存到" 34 | 35 | msgid "FileTransfer" 36 | msgstr "文件传输" 37 | 38 | msgid "Install" 39 | msgstr "安装" 40 | 41 | msgid "Attributes" 42 | msgstr "属性" 43 | 44 | msgid "Modify time" 45 | msgstr "修改时间" 46 | 47 | msgid "No specify upload file." 48 | msgstr "未指定上传文件。" 49 | 50 | msgid "Path on Route:" 51 | msgstr "路由根目录:" 52 | 53 | msgid "Remove" 54 | msgstr "移除" 55 | 56 | msgid "Size" 57 | msgstr "大小" 58 | 59 | msgid "Upload" 60 | msgstr "上传" 61 | 62 | msgid "Upload file list" 63 | msgstr "上传文件列表" 64 | 65 | msgid "Upload file to '/tmp/upload/'" 66 | msgstr "将文件上传到'/tmp/upload/'" 67 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-taghost/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2016 Openwrt.org 2 | # 3 | # This is free software, licensed under the Apache License, Version 2.0 . 4 | # 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | LUCI_TITLE:=luci-app-taghost 9 | LUCI_PKGARCH:=all 10 | PKG_VERSION:=1.0 11 | PKG_RELEASE:=1 12 | 13 | include $(TOPDIR)/feeds/luci/luci.mk 14 | 15 | # call BuildPackage - OpenWrt buildroot signature 16 | 17 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-taghost/luasrc/controller/taghost.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 给设备加tag以指定不同网关 3 | ]]-- 4 | 5 | module("luci.controller.taghost", package.seeall) 6 | 7 | function index() 8 | if not nixio.fs.access("/etc/config/dhcp") then 9 | return 10 | end 11 | entry({"admin", "network", "taghost"}, cbi("taghost"), _("TAG HOST"), 45).dependent = true 12 | end 13 | -------------------------------------------------------------------------------- /slimapps/application/luci-app-taghost/luasrc/model/cbi/taghost.lua: -------------------------------------------------------------------------------- 1 | local sys = require "luci.sys" 2 | local ifaces = sys.net:devices() 3 | local log = luci.util.perror 4 | local uci = require("luci.model.uci").cursor() 5 | 6 | 7 | m = Map("dhcp", translate("Tag your device"), 8 | translatef("Tag a device and set another gateway for it.")) 9 | 10 | 11 | 12 | -- device list 13 | devices = m:section(TypedSection, "host", translate("Bind to tag")) 14 | devices.template = "cbi/tblsection" 15 | devices.anonymous = true 16 | devices.addremove = true 17 | 18 | a = devices:option(Value, "name", translate("Device Name")) 19 | a.datatype = "string" 20 | a.optional = false 21 | 22 | a = devices:option(Value, "mac", translate("MAC Address")) 23 | a.datatype = "macaddr" 24 | a.optional = false 25 | luci.ip.neighbors({family = 4}, function(neighbor) 26 | if neighbor.reachable then 27 | a:value(neighbor.mac, "%s (%s)" %{neighbor.mac, neighbor.dest:string()}) 28 | end 29 | end) 30 | 31 | a = devices:option(Value, "tag", translate("Device Tag")) 32 | a.datatype = "string" 33 | a.optional = false 34 | 35 | uci:foreach("dhcp","tag", 36 | function(i) 37 | -- log(i['.name']) 38 | a:value(i['.name']) 39 | end) 40 | 41 | -- dhcp section 42 | t = m:section(TypedSection, "tag", translate("DHCP tags")) 43 | t.addremove = true 44 | t.anonymous = false 45 | 46 | a = t:option(DynamicList, "dhcp_option", translate("dhcp_option"),translate("3 means gateway and 6 means dns") ) 47 | a.optional = false 48 | a.datatype = "string" 49 | 50 | return m 51 | 52 | -------------------------------------------------------------------------------- /slimapps/application/luci-lib-fs/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2009 OpenWrt.org 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=luci-lib-fs 11 | PKG_VERSION:=1.0 12 | PKG_RELEASE:=1 13 | 14 | PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 15 | PKG_INSTALL:=1 16 | 17 | include $(INCLUDE_DIR)/package.mk 18 | 19 | define Package/luci-lib-fs 20 | SUBMENU:=Lua 21 | SECTION:=lang 22 | CATEGORY:=Languages 23 | TITLE:=luci-lib-fs 24 | PKGARCH:=all 25 | URL:=https://github.com/lbthomsen/openwrt-luci 26 | DEPENDS:=+luci +luci-lib-nixio 27 | endef 28 | 29 | define Package/luci-lib-fs/description 30 | luci-lib-fs 31 | endef 32 | 33 | define Build/Configure 34 | endef 35 | 36 | define Build/Compile 37 | endef 38 | 39 | define Build/Install 40 | endef 41 | 42 | 43 | define Package/luci-lib-fs/install 44 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci 45 | $(CP) ./files/*.lua $(1)/usr/lib/lua/luci 46 | 47 | endef 48 | 49 | $(eval $(call BuildPackage,luci-lib-fs)) 50 | -------------------------------------------------------------------------------- /slimapps/application/luci-lib-fs/files/fs.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | LuCI - Filesystem tools 3 | 4 | Description: 5 | A module offering often needed filesystem manipulation functions 6 | 7 | FileId: 8 | $Id$ 9 | 10 | License: 11 | Copyright 2008 Steven Barth 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | 25 | ]]-- 26 | 27 | local io = require "io" 28 | local os = require "os" 29 | local ltn12 = require "luci.ltn12" 30 | local fs = require "nixio.fs" 31 | local nutil = require "nixio.util" 32 | 33 | local type = type 34 | 35 | --- LuCI filesystem library. 36 | module "luci.fs" 37 | 38 | --- Test for file access permission on given path. 39 | -- @class function 40 | -- @name access 41 | -- @param str String value containing the path 42 | -- @return Number containing the return code, 0 on sucess or nil on error 43 | -- @return String containing the error description (if any) 44 | -- @return Number containing the os specific errno (if any) 45 | access = fs.access 46 | 47 | --- Evaluate given shell glob pattern and return a table containing all matching 48 | -- file and directory entries. 49 | -- @class function 50 | -- @name glob 51 | -- @param filename String containing the path of the file to read 52 | -- @return Table containing file and directory entries or nil if no matches 53 | -- @return String containing the error description (if no matches) 54 | -- @return Number containing the os specific errno (if no matches) 55 | function glob(...) 56 | local iter, code, msg = fs.glob(...) 57 | if iter then 58 | return nutil.consume(iter) 59 | else 60 | return nil, code, msg 61 | end 62 | end 63 | 64 | --- Checks wheather the given path exists and points to a regular file. 65 | -- @param filename String containing the path of the file to test 66 | -- @return Boolean indicating wheather given path points to regular file 67 | function isfile(filename) 68 | return fs.stat(filename, "type") == "reg" 69 | end 70 | 71 | --- Checks wheather the given path exists and points to a directory. 72 | -- @param dirname String containing the path of the directory to test 73 | -- @return Boolean indicating wheather given path points to directory 74 | function isdirectory(dirname) 75 | return fs.stat(dirname, "type") == "dir" 76 | end 77 | 78 | --- Read the whole content of the given file into memory. 79 | -- @param filename String containing the path of the file to read 80 | -- @return String containing the file contents or nil on error 81 | -- @return String containing the error message on error 82 | readfile = fs.readfile 83 | 84 | --- Write the contents of given string to given file. 85 | -- @param filename String containing the path of the file to read 86 | -- @param data String containing the data to write 87 | -- @return Boolean containing true on success or nil on error 88 | -- @return String containing the error message on error 89 | writefile = fs.writefile 90 | 91 | --- Copies a file. 92 | -- @param source Source file 93 | -- @param dest Destination 94 | -- @return Boolean containing true on success or nil on error 95 | copy = fs.datacopy 96 | 97 | --- Renames a file. 98 | -- @param source Source file 99 | -- @param dest Destination 100 | -- @return Boolean containing true on success or nil on error 101 | rename = fs.move 102 | 103 | --- Get the last modification time of given file path in Unix epoch format. 104 | -- @param path String containing the path of the file or directory to read 105 | -- @return Number containing the epoch time or nil on error 106 | -- @return String containing the error description (if any) 107 | -- @return Number containing the os specific errno (if any) 108 | function mtime(path) 109 | return fs.stat(path, "mtime") 110 | end 111 | 112 | --- Set the last modification time of given file path in Unix epoch format. 113 | -- @param path String containing the path of the file or directory to read 114 | -- @param mtime Last modification timestamp 115 | -- @param atime Last accessed timestamp 116 | -- @return 0 in case of success nil on error 117 | -- @return String containing the error description (if any) 118 | -- @return Number containing the os specific errno (if any) 119 | function utime(path, mtime, atime) 120 | return fs.utimes(path, atime, mtime) 121 | end 122 | 123 | --- Return the last element - usually the filename - from the given path with 124 | -- the directory component stripped. 125 | -- @class function 126 | -- @name basename 127 | -- @param path String containing the path to strip 128 | -- @return String containing the base name of given path 129 | -- @see dirname 130 | basename = fs.basename 131 | 132 | --- Return the directory component of the given path with the last element 133 | -- stripped of. 134 | -- @class function 135 | -- @name dirname 136 | -- @param path String containing the path to strip 137 | -- @return String containing the directory component of given path 138 | -- @see basename 139 | dirname = fs.dirname 140 | 141 | --- Return a table containing all entries of the specified directory. 142 | -- @class function 143 | -- @name dir 144 | -- @param path String containing the path of the directory to scan 145 | -- @return Table containing file and directory entries or nil on error 146 | -- @return String containing the error description on error 147 | -- @return Number containing the os specific errno on error 148 | function dir(...) 149 | local iter, code, msg = fs.dir(...) 150 | if iter then 151 | local t = nutil.consume(iter) 152 | t[#t+1] = "." 153 | t[#t+1] = ".." 154 | return t 155 | else 156 | return nil, code, msg 157 | end 158 | end 159 | 160 | --- Create a new directory, recursively on demand. 161 | -- @param path String with the name or path of the directory to create 162 | -- @param recursive Create multiple directory levels (optional, default is true) 163 | -- @return Number with the return code, 0 on sucess or nil on error 164 | -- @return String containing the error description on error 165 | -- @return Number containing the os specific errno on error 166 | function mkdir(path, recursive) 167 | return recursive and fs.mkdirr(path) or fs.mkdir(path) 168 | end 169 | 170 | --- Remove the given empty directory. 171 | -- @class function 172 | -- @name rmdir 173 | -- @param path String containing the path of the directory to remove 174 | -- @return Number with the return code, 0 on sucess or nil on error 175 | -- @return String containing the error description on error 176 | -- @return Number containing the os specific errno on error 177 | rmdir = fs.rmdir 178 | 179 | local stat_tr = { 180 | reg = "regular", 181 | dir = "directory", 182 | lnk = "link", 183 | chr = "character device", 184 | blk = "block device", 185 | fifo = "fifo", 186 | sock = "socket" 187 | } 188 | --- Get information about given file or directory. 189 | -- @class function 190 | -- @name stat 191 | -- @param path String containing the path of the directory to query 192 | -- @return Table containing file or directory properties or nil on error 193 | -- @return String containing the error description on error 194 | -- @return Number containing the os specific errno on error 195 | function stat(path, key) 196 | local data, code, msg = fs.stat(path) 197 | if data then 198 | data.mode = data.modestr 199 | data.type = stat_tr[data.type] or "?" 200 | end 201 | return key and data and data[key] or data, code, msg 202 | end 203 | 204 | --- Set permissions on given file or directory. 205 | -- @class function 206 | -- @name chmod 207 | -- @param path String containing the path of the directory 208 | -- @param perm String containing the permissions to set ([ugoa][+-][rwx]) 209 | -- @return Number with the return code, 0 on sucess or nil on error 210 | -- @return String containing the error description on error 211 | -- @return Number containing the os specific errno on error 212 | chmod = fs.chmod 213 | 214 | --- Create a hard- or symlink from given file (or directory) to specified target 215 | -- file (or directory) path. 216 | -- @class function 217 | -- @name link 218 | -- @param path1 String containing the source path to link 219 | -- @param path2 String containing the destination path for the link 220 | -- @param symlink Boolean indicating wheather to create a symlink (optional) 221 | -- @return Number with the return code, 0 on sucess or nil on error 222 | -- @return String containing the error description on error 223 | -- @return Number containing the os specific errno on error 224 | function link(src, dest, sym) 225 | return sym and fs.symlink(src, dest) or fs.link(src, dest) 226 | end 227 | 228 | --- Remove the given file. 229 | -- @class function 230 | -- @name unlink 231 | -- @param path String containing the path of the file to remove 232 | -- @return Number with the return code, 0 on sucess or nil on error 233 | -- @return String containing the error description on error 234 | -- @return Number containing the os specific errno on error 235 | unlink = fs.unlink 236 | 237 | --- Retrieve target of given symlink. 238 | -- @class function 239 | -- @name readlink 240 | -- @param path String containing the path of the symlink to read 241 | -- @return String containing the link target or nil on error 242 | -- @return String containing the error description on error 243 | -- @return Number containing the os specific errno on error 244 | readlink = fs.readlink 245 | --------------------------------------------------------------------------------