2 * bearer.c TIPC bearer functionality.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Richard Alpe <richard.alpe@ericsson.com>
17 #include <arpa/inet.h>
19 #include <linux/tipc_netlink.h>
20 #include <linux/tipc.h>
21 #include <linux/genetlink.h>
23 #include <libmnl/libmnl.h>
24 #include <sys/socket.h>
31 #define UDP_PROP_PORT 2
39 static void _print_bearer_opts(void)
43 " priority - Bearer link priority\n"
44 " tolerance - Bearer link tolerance\n"
45 " window - Bearer link window\n"
46 " mtu - Bearer link mtu\n");
49 void print_bearer_media(void)
53 " udp - User Datagram Protocol\n"
58 static void cmd_bearer_enable_l2_help(struct cmdl
*cmdl
, char *media
)
61 "Usage: %s bearer enable media %s device DEVICE [OPTIONS]\n"
63 " domain DOMAIN - Discovery domain\n"
64 " priority PRIORITY - Bearer priority\n",
65 cmdl
->argv
[0], media
);
68 static void cmd_bearer_enable_udp_help(struct cmdl
*cmdl
, char *media
)
71 "Usage: %s bearer enable [OPTIONS] media %s name NAME localip IP [UDP OPTIONS]\n\n"
73 " domain DOMAIN - Discovery domain\n"
74 " priority PRIORITY - Bearer priority\n\n"
76 " localport PORT - Local UDP port (default 6118)\n"
77 " remoteip IP - Remote IP address\n"
78 " remoteport PORT - Remote UDP port (default 6118)\n",
79 cmdl
->argv
[0], media
);
82 static int get_netid_cb(const struct nlmsghdr
*nlh
, void *data
)
84 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
85 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
86 struct nlattr
*attrs
[TIPC_NLA_NET_MAX
+ 1] = {};
87 int *netid
= (int*)data
;
89 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
90 if (!info
[TIPC_NLA_NET
])
92 mnl_attr_parse_nested(info
[TIPC_NLA_NET
], parse_attrs
, attrs
);
93 if (!attrs
[TIPC_NLA_NET_ID
])
95 *netid
= mnl_attr_get_u32(attrs
[TIPC_NLA_NET_ID
]);
100 static int generate_multicast(short af
, char *buf
, int bufsize
)
103 char mnl_msg
[MNL_SOCKET_BUFFER_SIZE
];
104 struct nlmsghdr
*nlh
;
106 if (!(nlh
= msg_init(mnl_msg
, TIPC_NL_NET_GET
))) {
107 fprintf(stderr
, "error, message initialization failed\n");
110 if (msg_dumpit(nlh
, get_netid_cb
, &netid
)) {
111 fprintf(stderr
, "error, failed to fetch TIPC network id from kernel\n");
115 snprintf(buf
, bufsize
, "228.0.%u.%u", (netid
>>8) & 0xFF, netid
& 0xFF);
117 snprintf(buf
, bufsize
, "ff02::%u", netid
);
122 static int nl_add_udp_enable_opts(struct nlmsghdr
*nlh
, struct opt
*opts
,
128 char buf
[INET6_ADDRSTRLEN
];
129 char *locport
= "6118";
130 char *remport
= "6118";
133 struct addrinfo
*loc
= NULL
;
134 struct addrinfo
*rem
= NULL
;
135 struct addrinfo hints
= {
136 .ai_family
= AF_UNSPEC
,
137 .ai_socktype
= SOCK_DGRAM
140 if (!(opt
= get_opt(opts
, "localip"))) {
141 fprintf(stderr
, "error, udp bearer localip missing\n");
142 cmd_bearer_enable_udp_help(cmdl
, "udp");
147 if ((opt
= get_opt(opts
, "remoteip")))
150 if ((opt
= get_opt(opts
, "localport")))
153 if ((opt
= get_opt(opts
, "remoteport")))
156 if ((err
= getaddrinfo(locip
, locport
, &hints
, &loc
))) {
157 fprintf(stderr
, "UDP local address error: %s\n",
163 if (generate_multicast(loc
->ai_family
, buf
, sizeof(buf
))) {
164 fprintf(stderr
, "Failed to generate multicast address\n");
171 if ((err
= getaddrinfo(remip
, remport
, &hints
, &rem
))) {
172 fprintf(stderr
, "UDP remote address error: %s\n",
178 if (rem
->ai_family
!= loc
->ai_family
) {
179 fprintf(stderr
, "UDP local and remote AF mismatch\n");
185 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_UDP_OPTS
);
186 mnl_attr_put(nlh
, TIPC_NLA_UDP_LOCAL
, loc
->ai_addrlen
, loc
->ai_addr
);
187 mnl_attr_put(nlh
, TIPC_NLA_UDP_REMOTE
, rem
->ai_addrlen
, rem
->ai_addr
);
188 mnl_attr_nest_end(nlh
, nest
);
196 static char *cmd_get_media_type(const struct cmd
*cmd
, struct cmdl
*cmdl
,
199 struct opt
*opt
= get_opt(opts
, "media");
205 fprintf(stderr
, "error, missing bearer media\n");
211 static int nl_add_bearer_name(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
212 struct cmdl
*cmdl
, struct opt
*opts
,
213 const struct tipc_sup_media
*sup_media
)
215 char bname
[TIPC_MAX_BEARER_NAME
];
218 if ((err
= cmd_get_unique_bearer_name(cmd
, cmdl
, opts
, bname
, sup_media
)))
221 mnl_attr_put_strz(nlh
, TIPC_NLA_BEARER_NAME
, bname
);
225 int cmd_get_unique_bearer_name(const struct cmd
*cmd
, struct cmdl
*cmdl
,
226 struct opt
*opts
, char *bname
,
227 const struct tipc_sup_media
*sup_media
)
232 const struct tipc_sup_media
*entry
;
234 if (!(media
= cmd_get_media_type(cmd
, cmdl
, opts
)))
237 for (entry
= sup_media
; entry
->media
; entry
++) {
238 if (strcmp(entry
->media
, media
))
241 if (!(opt
= get_opt(opts
, entry
->identifier
))) {
243 (entry
->help
)(cmdl
, media
);
245 fprintf(stderr
, "error, missing bearer %s\n",
250 identifier
= opt
->val
;
251 snprintf(bname
, TIPC_MAX_BEARER_NAME
, "%s:%s", media
, identifier
);
256 fprintf(stderr
, "error, invalid media type %s\n", media
);
261 static void cmd_bearer_add_udp_help(struct cmdl
*cmdl
, char *media
)
263 fprintf(stderr
, "Usage: %s bearer add media %s name NAME remoteip REMOTEIP\n\n",
264 cmdl
->argv
[0], media
);
267 static void cmd_bearer_add_help(struct cmdl
*cmdl
)
269 fprintf(stderr
, "Usage: %s bearer add media udp name NAME remoteip REMOTEIP\n",
273 static int udp_bearer_add(struct nlmsghdr
*nlh
, struct opt
*opts
,
278 struct nlattr
*opts_nest
;
279 char *remport
= "6118";
281 opts_nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_UDP_OPTS
);
283 if ((opt
= get_opt(opts
, "remoteport")))
286 if ((opt
= get_opt(opts
, "remoteip"))) {
288 struct addrinfo
*addr
= NULL
;
289 struct addrinfo hints
= {
290 .ai_family
= AF_UNSPEC
,
291 .ai_socktype
= SOCK_DGRAM
294 if ((err
= getaddrinfo(ip
, remport
, &hints
, &addr
))) {
295 fprintf(stderr
, "UDP address error: %s\n",
301 mnl_attr_put(nlh
, TIPC_NLA_UDP_REMOTE
, addr
->ai_addrlen
,
305 fprintf(stderr
, "error, missing remoteip\n");
308 mnl_attr_nest_end(nlh
, opts_nest
);
313 static int cmd_bearer_add_media(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
314 struct cmdl
*cmdl
, void *data
)
318 char buf
[MNL_SOCKET_BUFFER_SIZE
];
320 struct nlattr
*attrs
;
321 struct opt opts
[] = {
322 { "remoteip", OPT_KEYVAL
, NULL
},
323 { "remoteport", OPT_KEYVAL
, NULL
},
324 { "name", OPT_KEYVAL
, NULL
},
325 { "media", OPT_KEYVAL
, NULL
},
328 const struct tipc_sup_media sup_media
[] = {
329 { "udp", "name", cmd_bearer_add_udp_help
},
333 /* Rewind optind to include media in the option list */
335 if (parse_opts(opts
, cmdl
) < 0)
338 if (!(opt
= get_opt(opts
, "media"))) {
339 fprintf(stderr
, "error, missing media value\n");
344 if (strcmp(media
, "udp") != 0) {
345 fprintf(stderr
, "error, no \"%s\" media specific options available\n",
349 if (!(opt
= get_opt(opts
, "name"))) {
350 fprintf(stderr
, "error, missing media name\n");
354 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_ADD
))) {
355 fprintf(stderr
, "error, message initialisation failed\n");
359 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
360 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
364 err
= udp_bearer_add(nlh
, opts
, cmdl
);
368 mnl_attr_nest_end(nlh
, attrs
);
370 return msg_doit(nlh
, NULL
, NULL
);
373 static int cmd_bearer_add(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
374 struct cmdl
*cmdl
, void *data
)
376 const struct cmd cmds
[] = {
377 { "media", cmd_bearer_add_media
, cmd_bearer_add_help
},
381 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
384 static void cmd_bearer_enable_help(struct cmdl
*cmdl
)
387 "Usage: %s bearer enable [OPTIONS] media MEDIA ARGS...\n\n"
389 " domain DOMAIN - Discovery domain\n"
390 " priority PRIORITY - Bearer priority\n",
392 print_bearer_media();
395 static int cmd_bearer_enable(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
396 struct cmdl
*cmdl
, void *data
)
401 char buf
[MNL_SOCKET_BUFFER_SIZE
];
402 struct opt opts
[] = {
403 { "device", OPT_KEYVAL
, NULL
},
404 { "domain", OPT_KEYVAL
, NULL
},
405 { "localip", OPT_KEYVAL
, NULL
},
406 { "localport", OPT_KEYVAL
, NULL
},
407 { "media", OPT_KEYVAL
, NULL
},
408 { "name", OPT_KEYVAL
, NULL
},
409 { "priority", OPT_KEYVAL
, NULL
},
410 { "remoteip", OPT_KEYVAL
, NULL
},
411 { "remoteport", OPT_KEYVAL
, NULL
},
414 struct tipc_sup_media sup_media
[] = {
415 { "udp", "name", cmd_bearer_enable_udp_help
},
416 { "eth", "device", cmd_bearer_enable_l2_help
},
417 { "ib", "device", cmd_bearer_enable_l2_help
},
421 if (parse_opts(opts
, cmdl
) < 0) {
427 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_ENABLE
))) {
428 fprintf(stderr
, "error: message initialisation failed\n");
431 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
433 if ((opt
= get_opt(opts
, "domain")))
434 mnl_attr_put_u32(nlh
, TIPC_NLA_BEARER_DOMAIN
, atoi(opt
->val
));
436 if ((opt
= get_opt(opts
, "priority"))) {
437 struct nlattr
*props
;
439 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_PROP
);
440 mnl_attr_put_u32(nlh
, TIPC_NLA_PROP_PRIO
, atoi(opt
->val
));
441 mnl_attr_nest_end(nlh
, props
);
444 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
448 opt
= get_opt(opts
, "media");
449 if (opt
&& strcmp(opt
->val
, "udp") == 0) {
450 err
= nl_add_udp_enable_opts(nlh
, opts
, cmdl
);
454 mnl_attr_nest_end(nlh
, nest
);
456 return msg_doit(nlh
, NULL
, NULL
);
459 static void cmd_bearer_disable_l2_help(struct cmdl
*cmdl
, char *media
)
461 fprintf(stderr
, "Usage: %s bearer disable media %s device DEVICE\n",
462 cmdl
->argv
[0], media
);
465 static void cmd_bearer_disable_udp_help(struct cmdl
*cmdl
, char *media
)
467 fprintf(stderr
, "Usage: %s bearer disable media %s name NAME\n",
468 cmdl
->argv
[0], media
);
471 static void cmd_bearer_disable_help(struct cmdl
*cmdl
)
473 fprintf(stderr
, "Usage: %s bearer disable media MEDIA ARGS...\n",
475 print_bearer_media();
478 static int cmd_bearer_disable(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
479 struct cmdl
*cmdl
, void *data
)
482 char buf
[MNL_SOCKET_BUFFER_SIZE
];
484 struct opt opts
[] = {
485 { "device", OPT_KEYVAL
, NULL
},
486 { "name", OPT_KEYVAL
, NULL
},
487 { "media", OPT_KEYVAL
, NULL
},
490 struct tipc_sup_media sup_media
[] = {
491 { "udp", "name", cmd_bearer_disable_udp_help
},
492 { "eth", "device", cmd_bearer_disable_l2_help
},
493 { "ib", "device", cmd_bearer_disable_l2_help
},
497 if (parse_opts(opts
, cmdl
) < 0) {
503 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_DISABLE
))) {
504 fprintf(stderr
, "error, message initialisation failed\n");
508 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
509 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
512 mnl_attr_nest_end(nlh
, nest
);
514 return msg_doit(nlh
, NULL
, NULL
);
518 static void cmd_bearer_set_help(struct cmdl
*cmdl
)
520 fprintf(stderr
, "Usage: %s bearer set OPTION media MEDIA ARGS...\n",
522 _print_bearer_opts();
523 print_bearer_media();
526 static void cmd_bearer_set_udp_help(struct cmdl
*cmdl
, char *media
)
528 fprintf(stderr
, "Usage: %s bearer set OPTION media %s name NAME\n\n",
529 cmdl
->argv
[0], media
);
530 _print_bearer_opts();
533 static void cmd_bearer_set_l2_help(struct cmdl
*cmdl
, char *media
)
536 "Usage: %s bearer set [OPTION]... media %s device DEVICE\n",
537 cmdl
->argv
[0], media
);
538 _print_bearer_opts();
541 static int cmd_bearer_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
542 struct cmdl
*cmdl
, void *data
)
547 char buf
[MNL_SOCKET_BUFFER_SIZE
];
548 struct nlattr
*props
;
549 struct nlattr
*attrs
;
550 struct opt opts
[] = {
551 { "device", OPT_KEYVAL
, NULL
},
552 { "media", OPT_KEYVAL
, NULL
},
553 { "name", OPT_KEYVAL
, NULL
},
556 struct tipc_sup_media sup_media
[] = {
557 { "udp", "name", cmd_bearer_set_udp_help
},
558 { "eth", "device", cmd_bearer_set_l2_help
},
559 { "ib", "device", cmd_bearer_set_l2_help
},
563 if (strcmp(cmd
->cmd
, "priority") == 0)
564 prop
= TIPC_NLA_PROP_PRIO
;
565 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
566 prop
= TIPC_NLA_PROP_TOL
;
567 else if ((strcmp(cmd
->cmd
, "window") == 0))
568 prop
= TIPC_NLA_PROP_WIN
;
569 else if ((strcmp(cmd
->cmd
, "mtu") == 0))
570 prop
= TIPC_NLA_PROP_MTU
;
574 if (cmdl
->optind
>= cmdl
->argc
) {
575 fprintf(stderr
, "error, missing value\n");
578 val
= atoi(shift_cmdl(cmdl
));
580 if (parse_opts(opts
, cmdl
) < 0)
583 if (prop
== TIPC_NLA_PROP_MTU
) {
584 char *media
= cmd_get_media_type(cmd
, cmdl
, opts
);
588 else if (strcmp(media
, "udp")) {
589 fprintf(stderr
, "error, not supported for media\n");
594 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_SET
))) {
595 fprintf(stderr
, "error, message initialisation failed\n");
598 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
600 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_PROP
);
601 mnl_attr_put_u32(nlh
, prop
, val
);
602 mnl_attr_nest_end(nlh
, props
);
604 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
608 mnl_attr_nest_end(nlh
, attrs
);
610 return msg_doit(nlh
, NULL
, NULL
);
613 static int cmd_bearer_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
614 struct cmdl
*cmdl
, void *data
)
616 const struct cmd cmds
[] = {
617 { "priority", cmd_bearer_set_prop
, cmd_bearer_set_help
},
618 { "tolerance", cmd_bearer_set_prop
, cmd_bearer_set_help
},
619 { "window", cmd_bearer_set_prop
, cmd_bearer_set_help
},
620 { "mtu", cmd_bearer_set_prop
, cmd_bearer_set_help
},
624 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
627 static void cmd_bearer_get_help(struct cmdl
*cmdl
)
629 fprintf(stderr
, "Usage: %s bearer get [OPTION] media MEDIA ARGS...\n",
631 _print_bearer_opts();
632 print_bearer_media();
635 static void cmd_bearer_get_udp_help(struct cmdl
*cmdl
, char *media
)
637 fprintf(stderr
, "Usage: %s bearer get [OPTION] media %s name NAME [UDP OPTIONS]\n\n",
638 cmdl
->argv
[0], media
);
641 " remoteip - Remote ip address\n"
642 " remoteport - Remote port\n"
643 " localip - Local ip address\n"
644 " localport - Local port\n\n");
645 _print_bearer_opts();
648 static void cmd_bearer_get_l2_help(struct cmdl
*cmdl
, char *media
)
651 "Usage: %s bearer get OPTION media %s device DEVICE\n",
652 cmdl
->argv
[0], media
);
653 _print_bearer_opts();
657 static int bearer_dump_udp_cb(const struct nlmsghdr
*nlh
, void *data
)
659 struct sockaddr_storage
*addr
;
660 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
661 struct nlattr
*info
[TIPC_NLA_UDP_MAX
+ 1] = {};
663 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
665 if (!info
[TIPC_NLA_UDP_REMOTE
])
668 addr
= mnl_attr_get_payload(info
[TIPC_NLA_UDP_REMOTE
]);
670 if (addr
->ss_family
== AF_INET
) {
671 struct sockaddr_in
*ipv4
= (struct sockaddr_in
*) addr
;
673 printf("%s\n", inet_ntoa(ipv4
->sin_addr
));
674 } else if (addr
->ss_family
== AF_INET6
) {
675 char straddr
[INET6_ADDRSTRLEN
];
676 struct sockaddr_in6
*ipv6
= (struct sockaddr_in6
*) addr
;
678 if (!inet_ntop(AF_INET6
, &ipv6
->sin6_addr
, straddr
,
680 fprintf(stderr
, "error, parsing IPv6 addr\n");
683 printf("%s\n", straddr
);
692 static int bearer_get_udp_cb(const struct nlmsghdr
*nlh
, void *data
)
694 struct cb_data
*cb_data
= (struct cb_data
*) data
;
695 struct sockaddr_storage
*addr
;
696 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
697 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
698 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
699 struct nlattr
*opts
[TIPC_NLA_UDP_MAX
+ 1] = {};
701 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
702 if (!info
[TIPC_NLA_BEARER
])
705 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
706 if (!attrs
[TIPC_NLA_BEARER_UDP_OPTS
])
709 mnl_attr_parse_nested(attrs
[TIPC_NLA_BEARER_UDP_OPTS
], parse_attrs
, opts
);
710 if (!opts
[TIPC_NLA_UDP_LOCAL
])
713 if ((cb_data
->attr
== TIPC_NLA_UDP_REMOTE
) &&
714 (cb_data
->prop
== UDP_PROP_IP
) &&
715 opts
[TIPC_NLA_UDP_MULTI_REMOTEIP
]) {
716 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(cb_data
->nlh
);
718 genl
->cmd
= TIPC_NL_UDP_GET_REMOTEIP
;
719 return msg_dumpit(cb_data
->nlh
, bearer_dump_udp_cb
, NULL
);
722 addr
= mnl_attr_get_payload(opts
[cb_data
->attr
]);
724 if (addr
->ss_family
== AF_INET
) {
725 struct sockaddr_in
*ipv4
= (struct sockaddr_in
*) addr
;
727 switch (cb_data
->prop
) {
729 printf("%s\n", inet_ntoa(ipv4
->sin_addr
));
732 printf("%u\n", ntohs(ipv4
->sin_port
));
738 } else if (addr
->ss_family
== AF_INET6
) {
739 char straddr
[INET6_ADDRSTRLEN
];
740 struct sockaddr_in6
*ipv6
= (struct sockaddr_in6
*) addr
;
742 switch (cb_data
->prop
) {
744 if (!inet_ntop(AF_INET6
, &ipv6
->sin6_addr
, straddr
,
746 fprintf(stderr
, "error, parsing IPv6 addr\n");
749 printf("%s\n", straddr
);
752 printf("%u\n", ntohs(ipv6
->sin6_port
));
765 static int bearer_get_cb(const struct nlmsghdr
*nlh
, void *data
)
768 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
769 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
770 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
771 struct nlattr
*props
[TIPC_NLA_PROP_MAX
+ 1] = {};
773 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
774 if (!info
[TIPC_NLA_BEARER
])
777 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
778 if (!attrs
[TIPC_NLA_BEARER_PROP
])
781 mnl_attr_parse_nested(attrs
[TIPC_NLA_BEARER_PROP
], parse_attrs
, props
);
785 printf("%u\n", mnl_attr_get_u32(props
[*prop
]));
790 static int cmd_bearer_get_media(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
791 struct cmdl
*cmdl
, void *data
)
795 char buf
[MNL_SOCKET_BUFFER_SIZE
];
797 struct cb_data cb_data
= {0};
798 struct nlattr
*attrs
;
799 struct opt opts
[] = {
800 { "localip", OPT_KEY
, NULL
},
801 { "localport", OPT_KEY
, NULL
},
802 { "remoteip", OPT_KEY
, NULL
},
803 { "remoteport", OPT_KEY
, NULL
},
804 { "name", OPT_KEYVAL
, NULL
},
805 { "media", OPT_KEYVAL
, NULL
},
808 struct tipc_sup_media sup_media
[] = {
809 { "udp", "name", cmd_bearer_get_udp_help
},
813 /* Rewind optind to include media in the option list */
815 if (parse_opts(opts
, cmdl
) < 0)
818 if (!(opt
= get_opt(opts
, "media"))) {
819 fprintf(stderr
, "error, missing media value\n");
825 cmd_bearer_get_udp_help(cmdl
, media
);
828 if (strcmp(media
, "udp") != 0) {
829 fprintf(stderr
, "error, no \"%s\" media specific options\n", media
);
832 if (!(opt
= get_opt(opts
, "name"))) {
833 fprintf(stderr
, "error, missing media name\n");
837 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
838 fprintf(stderr
, "error, message initialisation failed\n");
842 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
843 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
846 mnl_attr_nest_end(nlh
, attrs
);
849 if (has_opt(opts
, "localip")) {
850 cb_data
.attr
= TIPC_NLA_UDP_LOCAL
;
851 cb_data
.prop
= UDP_PROP_IP
;
852 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
853 } else if (has_opt(opts
, "localport")) {
854 cb_data
.attr
= TIPC_NLA_UDP_LOCAL
;
855 cb_data
.prop
= UDP_PROP_PORT
;
856 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
857 } else if (has_opt(opts
, "remoteip")) {
858 cb_data
.attr
= TIPC_NLA_UDP_REMOTE
;
859 cb_data
.prop
= UDP_PROP_IP
;
860 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
861 } else if (has_opt(opts
, "remoteport")) {
862 cb_data
.attr
= TIPC_NLA_UDP_REMOTE
;
863 cb_data
.prop
= UDP_PROP_PORT
;
864 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
866 fprintf(stderr
, "error, missing UDP option\n");
870 static int cmd_bearer_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
871 struct cmdl
*cmdl
, void *data
)
875 char buf
[MNL_SOCKET_BUFFER_SIZE
];
876 struct nlattr
*attrs
;
877 struct opt opts
[] = {
878 { "device", OPT_KEYVAL
, NULL
},
879 { "media", OPT_KEYVAL
, NULL
},
880 { "name", OPT_KEYVAL
, NULL
},
883 struct tipc_sup_media sup_media
[] = {
884 { "udp", "name", cmd_bearer_get_udp_help
},
885 { "eth", "device", cmd_bearer_get_l2_help
},
886 { "ib", "device", cmd_bearer_get_l2_help
},
895 if (strcmp(cmd
->cmd
, "priority") == 0)
896 prop
= TIPC_NLA_PROP_PRIO
;
897 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
898 prop
= TIPC_NLA_PROP_TOL
;
899 else if ((strcmp(cmd
->cmd
, "window") == 0))
900 prop
= TIPC_NLA_PROP_WIN
;
901 else if ((strcmp(cmd
->cmd
, "mtu") == 0))
902 prop
= TIPC_NLA_PROP_MTU
;
906 if (parse_opts(opts
, cmdl
) < 0)
909 if (prop
== TIPC_NLA_PROP_MTU
) {
910 char *media
= cmd_get_media_type(cmd
, cmdl
, opts
);
914 else if (strcmp(media
, "udp")) {
915 fprintf(stderr
, "error, not supported for media\n");
920 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
921 fprintf(stderr
, "error, message initialisation failed\n");
925 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
926 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
929 mnl_attr_nest_end(nlh
, attrs
);
931 return msg_doit(nlh
, bearer_get_cb
, &prop
);
934 static int cmd_bearer_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
935 struct cmdl
*cmdl
, void *data
)
937 const struct cmd cmds
[] = {
938 { "priority", cmd_bearer_get_prop
, cmd_bearer_get_help
},
939 { "tolerance", cmd_bearer_get_prop
, cmd_bearer_get_help
},
940 { "window", cmd_bearer_get_prop
, cmd_bearer_get_help
},
941 { "mtu", cmd_bearer_get_prop
, cmd_bearer_get_help
},
942 { "media", cmd_bearer_get_media
, cmd_bearer_get_help
},
946 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
949 static int bearer_list_cb(const struct nlmsghdr
*nlh
, void *data
)
951 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
952 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
953 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
955 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
956 if (!info
[TIPC_NLA_BEARER
]) {
957 fprintf(stderr
, "No bearer in netlink response\n");
961 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
962 if (!attrs
[TIPC_NLA_BEARER_NAME
]) {
963 fprintf(stderr
, "Bearer name missing in netlink response\n");
967 printf("%s\n", mnl_attr_get_str(attrs
[TIPC_NLA_BEARER_NAME
]));
972 static int cmd_bearer_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
973 struct cmdl
*cmdl
, void *data
)
975 char buf
[MNL_SOCKET_BUFFER_SIZE
];
978 fprintf(stderr
, "Usage: %s bearer list\n", cmdl
->argv
[0]);
982 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
983 fprintf(stderr
, "error, message initialisation failed\n");
987 return msg_dumpit(nlh
, bearer_list_cb
, NULL
);
990 void cmd_bearer_help(struct cmdl
*cmdl
)
993 "Usage: %s bearer COMMAND [ARGS] ...\n"
996 " add - Add data to existing bearer\n"
997 " enable - Enable a bearer\n"
998 " disable - Disable a bearer\n"
999 " set - Set various bearer properties\n"
1000 " get - Get various bearer properties\n"
1001 " list - List bearers\n", cmdl
->argv
[0]);
1004 int cmd_bearer(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
1007 const struct cmd cmds
[] = {
1008 { "add", cmd_bearer_add
, cmd_bearer_add_help
},
1009 { "disable", cmd_bearer_disable
, cmd_bearer_disable_help
},
1010 { "enable", cmd_bearer_enable
, cmd_bearer_enable_help
},
1011 { "get", cmd_bearer_get
, cmd_bearer_get_help
},
1012 { "list", cmd_bearer_list
, NULL
},
1013 { "set", cmd_bearer_set
, cmd_bearer_set_help
},
1017 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);