1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
7 #include "alloc-util.h"
10 #include "logs-show.h"
11 #include "main-func.h"
12 #include "networkctl.h"
13 #include "networkctl-address-label.h"
14 #include "networkctl-config-file.h"
15 #include "networkctl-list.h"
16 #include "networkctl-lldp.h"
17 #include "networkctl-misc.h"
18 #include "networkctl-status-link.h"
19 #include "parse-argument.h"
20 #include "parse-util.h"
21 #include "path-util.h"
22 #include "pretty-print.h"
23 #include "string-util.h"
26 PagerFlags arg_pager_flags
= 0;
27 bool arg_legend
= true;
28 bool arg_no_reload
= false;
30 bool arg_stats
= false;
31 bool arg_full
= false;
32 bool arg_runtime
= false;
33 bool arg_stdin
= false;
34 unsigned arg_lines
= 10;
35 char *arg_drop_in
= NULL
;
36 sd_json_format_flags_t arg_json_format_flags
= SD_JSON_FORMAT_OFF
;
37 bool arg_ask_password
= true;
39 STATIC_DESTRUCTOR_REGISTER(arg_drop_in
, freep
);
41 static int help(void) {
42 _cleanup_free_
char *link
= NULL
;
45 r
= terminal_urlify_man("networkctl", "1", &link
);
49 printf("%s [OPTIONS...] COMMAND\n\n"
50 "%sQuery and control the networking subsystem.%s\n"
52 " list [PATTERN...] List links\n"
53 " status [PATTERN...] Show link status\n"
54 " lldp [PATTERN...] Show LLDP neighbors\n"
55 " label Show current address label entries in the kernel\n"
56 " delete DEVICES... Delete virtual netdevs\n"
57 " up DEVICES... Bring devices up\n"
58 " down DEVICES... Bring devices down\n"
59 " renew DEVICES... Renew dynamic configurations\n"
60 " forcerenew DEVICES... Trigger DHCP reconfiguration of all connected clients\n"
61 " reconfigure DEVICES... Reconfigure interfaces\n"
62 " reload Reload .network and .netdev files\n"
63 " edit FILES|DEVICES... Edit network configuration files\n"
64 " cat [FILES|DEVICES...] Show network configuration files\n"
65 " mask FILES... Mask network configuration files\n"
66 " unmask FILES... Unmask network configuration files\n"
67 " persistent-storage BOOL\n"
68 " Notify systemd-networkd if persistent storage is ready\n"
70 " -h --help Show this help\n"
71 " --version Show package version\n"
72 " --no-pager Do not pipe output into a pager\n"
73 " --no-legend Do not show the headers and footers\n"
74 " --no-ask-password Do not prompt for password\n"
75 " -a --all Show status for all links\n"
76 " -s --stats Show detailed link statistics\n"
77 " -l --full Do not ellipsize output\n"
78 " -n --lines=INTEGER Number of journal entries to show\n"
79 " --json=pretty|short|off\n"
80 " Generate JSON output\n"
81 " --no-reload Do not reload systemd-networkd or systemd-udevd\n"
82 " after editing network config\n"
83 " --drop-in=NAME Edit specified drop-in instead of main config file\n"
84 " --runtime Edit runtime config files\n"
85 " --stdin Read new contents of edited file from stdin\n"
86 "\nSee the %s for details.\n",
87 program_invocation_short_name
,
95 static int parse_argv(int argc
, char *argv
[]) {
108 static const struct option options
[] = {
109 { "help", no_argument
, NULL
, 'h' },
110 { "version", no_argument
, NULL
, ARG_VERSION
},
111 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
112 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
113 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
114 { "all", no_argument
, NULL
, 'a' },
115 { "stats", no_argument
, NULL
, 's' },
116 { "full", no_argument
, NULL
, 'l' },
117 { "lines", required_argument
, NULL
, 'n' },
118 { "json", required_argument
, NULL
, ARG_JSON
},
119 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
120 { "drop-in", required_argument
, NULL
, ARG_DROP_IN
},
121 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
122 { "stdin", no_argument
, NULL
, ARG_STDIN
},
131 while ((c
= getopt_long(argc
, argv
, "hasln:", options
, NULL
)) >= 0) {
142 arg_pager_flags
|= PAGER_DISABLE
;
150 arg_no_reload
= true;
153 case ARG_NO_ASK_PASSWORD
:
154 arg_ask_password
= false;
167 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Empty drop-in file name.");
169 if (!endswith(optarg
, ".conf")) {
172 conf
= strjoin(optarg
, ".conf");
176 free_and_replace(arg_drop_in
, conf
);
178 r
= free_and_strdup(&arg_drop_in
, optarg
);
183 if (!filename_is_valid(arg_drop_in
))
184 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
185 "Invalid drop-in file name '%s'.", arg_drop_in
);
202 if (safe_atou(optarg
, &arg_lines
) < 0)
203 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
204 "Failed to parse lines '%s'", optarg
);
208 r
= parse_json_argument(optarg
, &arg_json_format_flags
);
217 assert_not_reached();
224 static int networkctl_main(int argc
, char *argv
[]) {
225 static const Verb verbs
[] = {
226 { "list", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_ONLINE_ONLY
, list_links
},
227 { "status", VERB_ANY
, VERB_ANY
, VERB_ONLINE_ONLY
, link_status
},
228 { "lldp", VERB_ANY
, VERB_ANY
, 0, link_lldp_status
},
229 { "label", 1, 1, 0, list_address_labels
},
230 { "delete", 2, VERB_ANY
, 0, link_delete
},
231 { "up", 2, VERB_ANY
, 0, link_up_down
},
232 { "down", 2, VERB_ANY
, 0, link_up_down
},
233 { "renew", 2, VERB_ANY
, VERB_ONLINE_ONLY
, link_renew
},
234 { "forcerenew", 2, VERB_ANY
, VERB_ONLINE_ONLY
, link_force_renew
},
235 { "reconfigure", 2, VERB_ANY
, VERB_ONLINE_ONLY
, verb_reconfigure
},
236 { "reload", 1, 1, VERB_ONLINE_ONLY
, verb_reload
},
237 { "edit", 2, VERB_ANY
, 0, verb_edit
},
238 { "cat", 1, VERB_ANY
, 0, verb_cat
},
239 { "mask", 2, VERB_ANY
, 0, verb_mask
},
240 { "unmask", 2, VERB_ANY
, 0, verb_unmask
},
241 { "persistent-storage", 2, 2, 0, verb_persistent_storage
},
245 return dispatch_verb(argc
, argv
, verbs
, NULL
);
248 static int run(int argc
, char* argv
[]) {
253 r
= parse_argv(argc
, argv
);
257 journal_browse_prepare();
259 return networkctl_main(argc
, argv
);
262 DEFINE_MAIN_FUNCTION(run
);