Merge pull request #1026 from danrl/mwan
[project/luci.git] / applications / luci-app-openvpn / luasrc / model / cbi / openvpn-advanced.lua
1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Licensed to the public under the Apache License 2.0.
3
4 require("luci.ip")
5 require("luci.model.uci")
6
7
8 local knownParams = {
9         --
10         --Widget
11         --      Name
12         --      Default(s)
13         --      Description
14         --      Option(s)
15
16         { "Service", {
17         -- initialisation and daemon options
18                 { ListValue,
19                         "verb",
20                         { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
21                         translate("Set output verbosity") },
22                 { Flag,
23                         "mlock",
24                         0,
25                         translate("Disable Paging") },
26                 { Flag,
27                         "disable_occ",
28                         0,
29                         translate("Disable options consistency check") },
30         --      { Value,
31         --              "user",
32         --              "root",
33         --              translate("Set UID to user") },
34         --      { Value,
35         --              "group",
36         --              "root",
37         --              translate("Set GID to group") },
38                 { Value,
39                         "cd",
40                         "/etc/openvpn",
41                         translate("Change to directory before initialization") },
42                 { Value,
43                         "chroot",
44                         "/var/run",
45                         translate("Chroot to directory after initialization") },
46         --      { Value,
47         --              "daemon",
48         --              "Instance-Name",
49         --              translate("Daemonize after initialization") },
50         --      { Value,
51         --              "syslog",
52         --              "Instance-Name",
53         --              translate("Output to syslog and do not daemonize") },
54                 { Flag,
55                         "passtos",
56                         0,
57                         translate("TOS passthrough (applies to IPv4 only)") },
58         --      { Value,
59         --              "inetd",
60         --              "nowait Instance-Name",
61         --              translate("Run as an inetd or xinetd server") },
62                 { Value,
63                         "log",
64                         "/var/log/openvpn.log",
65                         translate("Write log to file") },
66                 { Value,
67                         "log_append",
68                         "/var/log/openvpn.log",
69                         translate("Append log to file") },
70                 { Flag,
71                         "suppress_timestamps",
72                         0,
73                         translate("Don't log timestamps") },
74         --      { Value,
75         --              "writepid",
76         --              "/var/run/openvpn.pid",
77         --              translate("Write process ID to file") },
78                 { Value,
79                         "nice",
80                         0,
81                         translate("Change process priority") },
82                 { Flag,
83                         "fast_io",
84                         0,
85                         translate("Optimize TUN/TAP/UDP writes") },
86                 { Value,
87                         "echo",
88                         "some params echoed to log",
89                         translate("Echo parameters to log") },
90                 { ListValue,
91                         "remap_usr1",
92                         { "SIGHUP", "SIGTERM" },
93                         translate("Remap SIGUSR1 signals") },
94                 { Value,
95                         "status",
96                         "/var/run/openvpn.status 5",
97                         translate("Write status to file every n seconds") },
98                 { Value,
99                         "status_version",
100                         { 1, 2 },
101                         translate("Status file format version") },      -- status
102                 { Value,
103                         "mute",
104                         5,
105                         translate("Limit repeated log messages") },
106                 { Value,
107                         "up",
108                         "/usr/bin/ovpn-up",
109                         translate("Shell cmd to execute after tun device open") },
110                 { Value,
111                         "up_delay",
112                         5,
113                         translate("Delay tun/tap open and up script execution") },
114                 { Value,
115                         "down",
116                         "/usr/bin/ovpn-down",
117                         translate("Shell cmd to run after tun device close") },
118                 { Flag,
119                         "down_pre",
120                         0,
121                         translate("Call down cmd/script before TUN/TAP close") },
122                 { Flag,
123                         "up_restart",
124                         0,
125                         translate("Run up/down scripts for all restarts") },
126                 { Value,
127                         "route_up",
128                         "/usr/bin/ovpn-routeup",
129                         translate("Execute shell cmd after routes are added") },
130                 { Value,
131                         "ipchange",
132                         "/usr/bin/ovpn-ipchange",
133                         translate("Execute shell command on remote ip change"),
134                         { mode="p2p" } },
135                 { DynamicList,
136                         "setenv",
137                         { "VAR1 value1", "VAR2 value2" },
138                         translate("Pass environment variables to script") },
139                 { Value,
140                         "tls_verify",
141                         "/usr/bin/ovpn-tlsverify",
142                         translate("Shell command to verify X509 name") },
143                 { Value,
144                         "client_connect",
145                         "/usr/bin/ovpn-clientconnect",
146                         translate("Run script cmd on client connection") },
147                 { Flag,
148                         "client_disconnect",
149                         0,
150                         translate("Run script cmd on client disconnection") },
151                 { Value,
152                         "learn_address",
153                         "/usr/bin/ovpn-learnaddress",
154                         translate("Executed in server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table") },
155                 { Value,
156                         "auth_user_pass_verify",
157                         "/usr/bin/ovpn-userpass via-env",
158                         translate("Executed in server mode on new client connections, when the client is still untrusted") },
159                 { ListValue,
160                         "script_security",
161                         { 0, 1, 2, 3 },
162                         translate("Policy level over usage of external programs and scripts") },
163         } },
164
165         { "Networking", {
166         -- socket config
167                 { ListValue,
168                         "mode",
169                         { "p2p", "server" },
170                         translate("Major mode") },
171                 { Value,
172                         "local",
173                         "0.0.0.0",
174                         translate("Local host name or ip address") },
175                 { Value,
176                         "port",
177                         1194,
178                         translate("TCP/UDP port # for both local and remote") },
179                 { Value,
180                         "lport",
181                         1194,
182                         translate("TCP/UDP port # for local (default=1194)") },
183                 { Value,
184                         "rport",
185                         1194,
186                         translate("TCP/UDP port # for remote (default=1194)") },
187                 { Flag,
188                         "float",
189                         0,
190                         translate("Allow remote to change its IP or port") },
191                 { Flag,
192                         "nobind",
193                         0,
194                         translate("Do not bind to local address and port") },
195                 { Value,
196                         "dev",
197                         "tun0",
198                         translate("tun/tap device") },
199                 { ListValue,
200                         "dev_type",
201                         { "tun", "tap" },
202                         translate("Type of used device") },
203                 { Value,
204                         "dev_node",
205                         "/dev/net/tun",
206                         translate("Use tun/tap device node") },
207                 { Flag,
208                         "tun_ipv6",
209                         0,
210                         translate("Make tun device IPv6 capable") },
211                 { Value,
212                         "ifconfig",
213                         "10.200.200.3 10.200.200.1",
214                         translate("Set tun/tap adapter parameters") },
215                 { Flag,
216                         "ifconfig_noexec",
217                         0,
218                         translate("Don't actually execute ifconfig") },
219                 { Flag,
220                         "ifconfig_nowarn",
221                         0,
222                         translate("Don't warn on ifconfig inconsistencies") },
223                 { DynamicList,
224                         "route",
225                         "10.123.0.0 255.255.0.0",
226                         translate("Add route after establishing connection") },
227                 { Value,
228                         "route_gateway",
229                         "10.234.1.1",
230                         translate("Specify a default gateway for routes") },
231                 { Value,
232                         "route_delay",
233                         0,
234                         translate("Delay n seconds after connection") },
235                 { Flag,
236                         "route_noexec",
237                         0,
238                         translate("Don't add routes automatically") },
239                 { Flag,
240                         "route_nopull",
241                         0,
242                         translate("Don't pull routes automatically") },
243                 { ListValue,
244                         "mtu_disc",
245                         { "yes", "maybe", "no" },
246                         translate("Enable Path MTU discovery") },
247                 { Flag,
248                         "mtu_test",
249                         0,
250                         translate("Empirically measure MTU") },
251                 { ListValue,
252                         "comp_lzo",
253                         { "yes", "no", "adaptive" },
254                         translate("Use fast LZO compression") },
255                 { Flag,
256                         "comp_noadapt",
257                         0,
258                         translate("Don't use adaptive lzo compression"),
259                         { comp_lzo=1 } },
260                 { Value,
261                         "link_mtu",
262                         1500,
263                         translate("Set TCP/UDP MTU") },
264                 { Value,
265                         "tun_mtu",
266                         1500,
267                         translate("Set tun/tap device MTU") },
268                 { Value,
269                         "tun_mtu_extra",
270                         1500,
271                         translate("Set tun/tap device overhead") },
272                 { Value,
273                         "fragment",
274                         1500,
275                         translate("Enable internal datagram fragmentation"),
276                         { proto="udp" } },
277                 { Value,
278                         "mssfix",
279                         1500,
280                         translate("Set upper bound on TCP MSS"),
281                         { proto="udp" } },
282                 { Value,
283                         "sndbuf",
284                         65536,
285                         translate("Set the TCP/UDP send buffer size") },
286                 { Value,
287                         "rcvbuf",
288                         65536,
289                         translate("Set the TCP/UDP receive buffer size") },
290                 { Value,
291                         "txqueuelen",
292                         100,
293                         translate("Set tun/tap TX queue length") },
294                 { Value,
295                         "shaper",
296                         10240,
297                         translate("Shaping for peer bandwidth") },
298                 { Value,
299                         "inactive",
300                         240,
301                         translate("tun/tap inactivity timeout") },
302                 { Value,
303                         "keepalive",
304                         "10 60",
305                         translate("Helper directive to simplify the expression of --ping and --ping-restart in server mode configurations") },
306                 { Value,
307                         "ping",
308                         30,
309                         translate("Ping remote every n seconds over TCP/UDP port") },
310                 { Value,
311                         "ping_exit",
312                         120,
313                         translate("Remote ping timeout") },
314                 { Value,
315                         "ping_restart",
316                         60,
317                         translate("Restart after remote ping timeout") },
318                 { Flag,
319                         "ping_timer_rem",
320                         0,
321                         translate("Only process ping timeouts if routes exist") },
322                 { Flag,
323                         "persist_tun",
324                         0,
325                         translate("Keep tun/tap device open on restart") },
326                 { Flag,
327                         "persist_key",
328                         0,
329                         translate("Don't re-read key on restart") },
330                 { Flag,
331                         "persist_local_ip",
332                         0,
333                         translate("Keep local IP address on restart") },
334                 { Flag,
335                         "persist_remote_ip",
336                         0,
337                         translate("Keep remote IP address on restart") },
338         -- management channel
339                 { Value,
340                         "management",
341                         "127.0.0.1 31194 /etc/openvpn/mngmt-pwds",
342                         translate("Enable management interface on <em>IP</em> <em>port</em>") },
343         -- management
344                 { Flag,
345                         "management_query_passwords",
346                         0,
347                         translate("Query management channel for private key") },
348         -- management
349                 { Flag,
350                         "management_hold",
351                         0,
352                         translate("Start OpenVPN in a hibernating state") },
353         -- management
354                 { Value,
355                         "management_log_cache",
356                         100,
357                         translate("Number of lines for log file history") },
358                 { ListValue,
359                         "topology",
360                         { "net30", "p2p", "subnet" },
361                         translate("'net30', 'p2p', or 'subnet'"),
362                         {dev_type="tun" } },
363         } },
364
365         { "VPN", {
366                 { Value,
367                         "server",
368                         "10.200.200.0 255.255.255.0",
369                         translate("Configure server mode"),
370                         { server_mode="1" } },
371                 { Value,
372                         "server_bridge",
373                         "10.200.200.1 255.255.255.0 10.200.200.200 10.200.200.250",
374                         translate("Configure server bridge"),
375                         { server_mode="1" } },
376                 { DynamicList,
377                         "push",
378                         { "redirect-gateway", "comp-lzo" },
379                         translate("Push options to peer"),
380                         { server_mode="1" } },
381                 { Flag,
382                         "push_reset",
383                         0,
384                         translate("Don't inherit global push options"),
385                         { server_mode="1" } },
386                 { Flag,
387                         "disable",
388                         0,
389                         translate("Client is disabled"),
390                         { server_mode="1" } },
391                 { Value,
392                         "ifconfig_pool",
393                         "10.200.200.100 10.200.200.150 255.255.255.0",
394                         translate("Set aside a pool of subnets"),
395                         { server_mode="1" } },
396                 { Value,
397                         "ifconfig_pool_persist",
398                         "/etc/openvpn/ipp.txt 600",
399                         translate("Persist/unpersist ifconfig-pool"),
400                         { server_mode="1" } },
401         -- deprecated and replaced by --topology p2p
402         --      { Flag,
403         --              "ifconfig_pool_linear",
404         --              0,
405         --              translate("Use individual addresses rather than /30 subnets"),
406         --              { server_mode="1" } },
407                 { Value,
408                         "ifconfig_push",
409                         "10.200.200.1 255.255.255.255",
410                         translate("Push an ifconfig option to remote"),
411                         { server_mode="1" } },
412                 { Value,
413                         "iroute",
414                         "10.200.200.0 255.255.255.0",
415                         translate("Route subnet to client"),
416                         { server_mode="1" } },
417                 { Flag,
418                         "client_to_client",
419                         0,
420                         translate("Allow client-to-client traffic"),
421                         { server_mode="1" } },
422                 { Flag,
423                         "duplicate_cn",
424                         0,
425                         translate("Allow multiple clients with same certificate"),
426                         { server_mode="1" } },
427                 { Value,
428                         "client_config_dir",
429                         "/etc/openvpn/ccd",
430                         translate("Directory for custom client config files"),
431                         { server_mode="1" } },
432                 { Flag,
433                         "ccd_exclusive",
434                         0,
435                         translate("Refuse connection if no custom client config"),
436                         { server_mode="1" } },
437                 { Value,
438                         "tmp_dir",
439                         "/var/run/openvpn",
440                         translate("Temporary directory for client-connect return file"),
441                         { server_mode="1" } },
442                 { Value,
443                         "hash_size",
444                         "256 256",
445                         translate("Set size of real and virtual address hash tables"),
446                         { server_mode="1" } },
447                 { Value,
448                         "bcast_buffers",
449                         256,
450                         translate("Number of allocated broadcast buffers"),
451                         { server_mode="1" } },
452                 { Value,
453                         "tcp_queue_limit",
454                         64,
455                         translate("Maximum number of queued TCP output packets"),
456                         { server_mode="1" } },
457                 { Value,
458                         "max_clients",
459                         10,
460                         translate("Allowed maximum of connected clients"),
461                         { server_mode="1" } },
462                 { Value,
463                         "max_routes_per_client",
464                         256,
465                         translate("Allowed maximum of internal"),
466                         { server_mode="1" } },
467                 { Value,
468                         "connect_freq",
469                         "3 10",
470                         translate("Allowed maximum of new connections"),
471                         { server_mode="1" } },
472                 { Flag,
473                         "client_cert_not_required",
474                         0,
475                         translate("Don't require client certificate"),
476                         { server_mode="1" } },
477                 { Flag,
478                         "username_as_common_name",
479                         0,
480                         translate("Use username as common name"),
481                         { server_mode="1" } },
482                 { Flag,
483                         "client",
484                         0,
485                         translate("Configure client mode"),
486                         { server_mode="0" }, { server_mode="" } },
487                 { Flag,
488                         "pull",
489                         0,
490                         translate("Accept options pushed from server"),
491                         { client="1" } },
492                 { Value,
493                         "auth_user_pass",
494                         "/etc/openvpn/userpass.txt",
495                         translate("Authenticate using username/password"),
496                         { client="1" } },
497                 { ListValue,
498                         "auth_retry",
499                         { "none", "nointeract", "interact" },
500                         translate("Handling of authentication failures"),
501                         { client="1" } },
502                 { Value,
503                         "explicit_exit_notify",
504                         1,
505                         translate("Send notification to peer on disconnect"),
506                         { client="1" } },
507                 { DynamicList,
508                         "remote",
509                         "1.2.3.4",
510                         translate("Remote host name or ip address"),
511                         { client="1" } },
512                 { Flag,
513                         "remote_random",
514                         1,
515                         translate("Randomly choose remote server"),
516                         { client="1" } },
517                 { ListValue,
518                         "proto",
519                         { "udp", "tcp-client", "tcp-server" },
520                         translate("Use protocol"),
521                         { client="1" } },
522                 { Value,
523                         "connect_retry",
524                         5,
525                         translate("Connection retry interval"),
526                         { proto="tcp-client" }, { client="1" } },
527                 { Value,
528                         "http_proxy",
529                         "192.168.1.100 8080",
530                         translate("Connect to remote host through an HTTP proxy"),
531                         { client="1" } },
532                 { Flag,
533                         "http_proxy_retry",
534                         0,
535                         translate("Retry indefinitely on HTTP proxy errors"),
536                         { client="1" } },
537                 { Value,
538                         "http_proxy_timeout",
539                         5,
540                         translate("Proxy timeout in seconds"),
541                         { client="1" } },
542                 { DynamicList,
543                         "http_proxy_option",
544                         { "VERSION 1.0", "AGENT OpenVPN/2.0.9" },
545                         translate("Set extended HTTP proxy options"),
546                         { client="1" } },
547                 { Value,
548                         "socks_proxy",
549                         "192.168.1.200 1080",
550                         translate("Connect through Socks5 proxy"),
551                         { client="1" } },
552         -- client && socks_proxy
553                 { Value,
554                         "socks_proxy_retry",
555                         5,
556                         translate("Retry indefinitely on Socks proxy errors"),
557                         { client="1" } },
558                 { Value,
559                         "resolv_retry",
560                         "infinite",
561                         translate("If hostname resolve fails, retry"),
562                         { client="1" } },
563                 { ListValue,
564                         "redirect_gateway",
565                         { "", "local", "def1", "local def1" },
566                         translate("Automatically redirect default route"),
567                         { client="1" } },
568         } },
569
570         { "Cryptography", {
571                 { FileUpload,
572                         "secret",
573                         "/etc/openvpn/secret.key",
574                         translate("Enable Static Key encryption mode (non-TLS)") },
575         -- parse
576                 { Value,
577                         "auth",
578                         "SHA1",
579                         translate("HMAC authentication for packets") },
580         -- parse
581                 { Value,
582                         "cipher",
583                         "BF-CBC",
584                         translate("Encryption cipher for packets") },
585         -- parse
586                 { Value,
587                         "keysize",
588                         1024,
589                         translate("Size of cipher key") },
590         -- parse
591                 { Value,
592                         "engine",
593                         "dynamic",
594                         translate("Enable OpenSSL hardware crypto engines") },
595                 { Flag,
596                         "no_replay",
597                         0,
598                         translate("Disable replay protection") },
599                 { Value,
600                         "replay_window",
601                         "64 15",
602                         translate("Replay protection sliding window size") },
603                 { Flag,
604                         "mute_replay_warnings",
605                         0,
606                         translate("Silence the output of replay warnings") },
607                 { Value,
608                         "replay_persist",
609                         "/var/run/openvpn-replay-state",
610                         translate("Persist replay-protection state") },
611                 { Flag,
612                         "no_iv",
613                         0,
614                         translate("Disable cipher initialisation vector") },
615                 { Flag,
616                         "tls_server",
617                         0,
618                         translate("Enable TLS and assume server role"),
619                         { tls_client="" }, { tls_client="0" } },
620                 { Flag,
621                         "tls_client",
622                         0,
623                         translate("Enable TLS and assume client role"),
624                         { tls_server="" }, { tls_server="0" } },
625                 { FileUpload,
626                         "ca",
627                         "/etc/easy-rsa/keys/ca.crt",
628                         translate("Certificate authority") },
629                 { FileUpload,
630                         "dh",
631                         "/etc/easy-rsa/keys/dh1024.pem",
632                         translate("Diffie Hellman parameters") },
633                 { FileUpload,
634                         "cert",
635                         "/etc/easy-rsa/keys/some-client.crt",
636                         translate("Local certificate") },
637                 { FileUpload,
638                         "key",
639                         "/etc/easy-rsa/keys/some-client.key",
640                         translate("Local private key") },
641                 { FileUpload,
642                         "pkcs12",
643                         "/etc/easy-rsa/keys/some-client.pk12",
644                         translate("PKCS#12 file containing keys") },
645                 { ListValue,
646                         "key_method",
647                         { 1, 2 },
648                         translate("Enable TLS and assume client role") },
649                 { Value,
650                         "tls_cipher",
651                         "DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5",
652                         translate("TLS cipher") },
653                 { Value,
654                         "tls_timeout",
655                         2,
656                         translate("Retransmit timeout on TLS control channel") },
657                 { Value,
658                         "reneg_bytes",
659                         1024,
660                         translate("Renegotiate data chan. key after bytes") },
661                 { Value,
662                         "reneg_pkts",
663                         100,
664                         translate("Renegotiate data chan. key after packets") },
665                 { Value,
666                         "reneg_sec",
667                         3600,
668                         translate("Renegotiate data chan. key after seconds") },
669                 { Value,
670                         "hand_window",
671                         60,
672                         translate("Timeframe for key exchange") },
673                 { Value,
674                         "tran_window",
675                         3600,
676                         translate("Key transition window") },
677                 { Flag,
678                         "single_session",
679                         0,
680                         translate("Allow only one session") },
681                 { Flag,
682                         "tls_exit",
683                         0,
684                         translate("Exit on TLS negotiation failure") },
685                 { Value,
686                         "tls_auth",
687                         "/etc/openvpn/tlsauth.key",
688                         translate("Additional authentication over TLS") },
689         --      { Value,
690         --              "askpass",
691         --              "[file]",
692         --              translate("Get PEM password from controlling tty before we daemonize") },
693                 { Flag,
694                         "auth_nocache",
695                         0,
696                         translate("Don't cache --askpass or --auth-user-pass passwords") },
697                 { Value,
698                         "tls_remote",
699                         "remote_x509_name",
700                         translate("Only accept connections from given X509 name") },
701                 { ListValue,
702                         "ns_cert_type",
703                         { "client", "server" },
704                         translate("Require explicit designation on certificate") },
705                 { ListValue,
706                         "remote_cert_tls",
707                         { "client", "server" },
708                         translate("Require explicit key usage on certificate") },
709                 { Value,
710                         "crl_verify",
711                         "/etc/easy-rsa/keys/crl.pem",
712                         translate("Check peer certificate against a CRL") },
713                 { Value,
714                         "tls_version_min",
715                         "1.0",
716                         translate("The lowest supported TLS version") },
717                 { Value,
718                         "tls_version_max",
719                         "1.2",
720                         translate("The highest supported TLS version") },
721                 { Value,
722                         "key_direction",
723                         "1",
724                         translate("The key direction for 'tls-auth' and 'secret' options") },
725         } }
726 }
727
728
729 local cts = { }
730 local params = { }
731
732 local m = Map("openvpn")
733 local p = m:section( SimpleSection )
734
735 p.template = "openvpn/pageswitch"
736 p.mode     = "advanced"
737 p.instance = arg[1]
738 p.category = arg[2] or "Service"
739
740 for _, c in ipairs(knownParams) do
741         cts[#cts+1] = c[1]
742         if c[1] == p.category then params = c[2] end
743 end
744
745 p.categories = cts
746
747
748 local s = m:section(
749         NamedSection, arg[1], "openvpn",
750         translate("%s" % arg[2])
751 )
752
753 s.title     = translate("%s" % arg[2])
754 s.addremove = false
755 s.anonymous = true
756
757
758 for _, option in ipairs(params) do
759         local o = s:option(
760                 option[1], option[2],
761                 option[2], option[4]
762         )
763
764         if option[1] == DummyValue then
765                 o.value = option[3]
766         else
767                 if option[1] == DynamicList then
768                         function o.cfgvalue(...)
769                                 local val = AbstractValue.cfgvalue(...)
770                                 return ( val and type(val) ~= "table" ) and { val } or val
771                         end
772                 end
773
774                 o.optional = true
775
776                 if type(option[3]) == "table" then
777                         if o.optional then o:value("", "-- remove --") end
778                         for _, v in ipairs(option[3]) do
779                                 v = tostring(v)
780                                 o:value(v)
781                         end
782                         o.default = tostring(option[3][1])
783                 else
784                         o.default = tostring(option[3])
785                 end
786         end
787
788         for i=5,#option do
789                 if type(option[i]) == "table" then
790                         o:depends(option[i])
791                 end
792         end
793 end
794
795 return m