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",
72 cmdl
->argv
[0], media
);
75 " domain DOMAIN - Discovery domain\n"
76 " priority PRIORITY - Bearer priority\n\n");
79 " localport PORT - Local UDP port (default 6118)\n"
80 " remoteip IP - Remote IP address\n"
81 " remoteport PORT - Remote UDP port (default 6118)\n");
84 static int get_netid_cb(const struct nlmsghdr
*nlh
, void *data
)
86 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
87 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
88 struct nlattr
*attrs
[TIPC_NLA_NET_MAX
+ 1] = {};
89 int *netid
= (int*)data
;
91 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
92 if (!info
[TIPC_NLA_NET
])
94 mnl_attr_parse_nested(info
[TIPC_NLA_NET
], parse_attrs
, attrs
);
95 if (!attrs
[TIPC_NLA_NET_ID
])
97 *netid
= mnl_attr_get_u32(attrs
[TIPC_NLA_NET_ID
]);
102 static int generate_multicast(short af
, char *buf
, int bufsize
)
105 char mnl_msg
[MNL_SOCKET_BUFFER_SIZE
];
106 struct nlmsghdr
*nlh
;
108 if (!(nlh
= msg_init(mnl_msg
, TIPC_NL_NET_GET
))) {
109 fprintf(stderr
, "error, message initialization failed\n");
112 if (msg_dumpit(nlh
, get_netid_cb
, &netid
)) {
113 fprintf(stderr
, "error, failed to fetch TIPC network id from kernel\n");
117 snprintf(buf
, bufsize
, "228.0.%u.%u", (netid
>>8) & 0xFF, netid
& 0xFF);
119 snprintf(buf
, bufsize
, "ff02::%u", netid
);
124 static int nl_add_udp_enable_opts(struct nlmsghdr
*nlh
, struct opt
*opts
,
130 char buf
[INET6_ADDRSTRLEN
];
131 char *locport
= "6118";
132 char *remport
= "6118";
135 struct addrinfo
*loc
= NULL
;
136 struct addrinfo
*rem
= NULL
;
137 struct addrinfo hints
= {
138 .ai_family
= AF_UNSPEC
,
139 .ai_socktype
= SOCK_DGRAM
142 if (!(opt
= get_opt(opts
, "localip"))) {
143 fprintf(stderr
, "error, udp bearer localip missing\n");
144 cmd_bearer_enable_udp_help(cmdl
, "udp");
149 if ((opt
= get_opt(opts
, "remoteip")))
152 if ((opt
= get_opt(opts
, "localport")))
155 if ((opt
= get_opt(opts
, "remoteport")))
158 if ((err
= getaddrinfo(locip
, locport
, &hints
, &loc
))) {
159 fprintf(stderr
, "UDP local address error: %s\n",
165 if (generate_multicast(loc
->ai_family
, buf
, sizeof(buf
))) {
166 fprintf(stderr
, "Failed to generate multicast address\n");
173 if ((err
= getaddrinfo(remip
, remport
, &hints
, &rem
))) {
174 fprintf(stderr
, "UDP remote address error: %s\n",
180 if (rem
->ai_family
!= loc
->ai_family
) {
181 fprintf(stderr
, "UDP local and remote AF mismatch\n");
187 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_UDP_OPTS
);
188 mnl_attr_put(nlh
, TIPC_NLA_UDP_LOCAL
, loc
->ai_addrlen
, loc
->ai_addr
);
189 mnl_attr_put(nlh
, TIPC_NLA_UDP_REMOTE
, rem
->ai_addrlen
, rem
->ai_addr
);
190 mnl_attr_nest_end(nlh
, nest
);
198 static char *cmd_get_media_type(const struct cmd
*cmd
, struct cmdl
*cmdl
,
201 struct opt
*opt
= get_opt(opts
, "media");
207 fprintf(stderr
, "error, missing bearer media\n");
213 static int nl_add_bearer_name(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
214 struct cmdl
*cmdl
, struct opt
*opts
,
215 const struct tipc_sup_media
*sup_media
)
217 char bname
[TIPC_MAX_BEARER_NAME
];
220 if ((err
= cmd_get_unique_bearer_name(cmd
, cmdl
, opts
, bname
, sup_media
)))
223 mnl_attr_put_strz(nlh
, TIPC_NLA_BEARER_NAME
, bname
);
227 int cmd_get_unique_bearer_name(const struct cmd
*cmd
, struct cmdl
*cmdl
,
228 struct opt
*opts
, char *bname
,
229 const struct tipc_sup_media
*sup_media
)
234 const struct tipc_sup_media
*entry
;
236 if (!(media
= cmd_get_media_type(cmd
, cmdl
, opts
)))
239 for (entry
= sup_media
; entry
->media
; entry
++) {
240 if (strcmp(entry
->media
, media
))
243 if (!(opt
= get_opt(opts
, entry
->identifier
))) {
245 (entry
->help
)(cmdl
, media
);
247 fprintf(stderr
, "error, missing bearer %s\n",
252 identifier
= opt
->val
;
253 snprintf(bname
, TIPC_MAX_BEARER_NAME
, "%s:%s", media
, identifier
);
258 fprintf(stderr
, "error, invalid media type %s\n", media
);
263 static void cmd_bearer_add_udp_help(struct cmdl
*cmdl
, char *media
)
265 fprintf(stderr
, "Usage: %s bearer add media %s name NAME remoteip REMOTEIP\n\n",
266 cmdl
->argv
[0], media
);
269 static void cmd_bearer_add_help(struct cmdl
*cmdl
)
271 fprintf(stderr
, "Usage: %s bearer add media udp name NAME remoteip REMOTEIP\n",
275 static int udp_bearer_add(struct nlmsghdr
*nlh
, struct opt
*opts
,
280 struct nlattr
*opts_nest
;
281 char *remport
= "6118";
283 opts_nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_UDP_OPTS
);
285 if ((opt
= get_opt(opts
, "remoteport")))
288 if ((opt
= get_opt(opts
, "remoteip"))) {
290 struct addrinfo
*addr
= NULL
;
291 struct addrinfo hints
= {
292 .ai_family
= AF_UNSPEC
,
293 .ai_socktype
= SOCK_DGRAM
296 if ((err
= getaddrinfo(ip
, remport
, &hints
, &addr
))) {
297 fprintf(stderr
, "UDP address error: %s\n",
303 mnl_attr_put(nlh
, TIPC_NLA_UDP_REMOTE
, addr
->ai_addrlen
,
307 fprintf(stderr
, "error, missing remoteip\n");
310 mnl_attr_nest_end(nlh
, opts_nest
);
315 static int cmd_bearer_add_media(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
316 struct cmdl
*cmdl
, void *data
)
320 char buf
[MNL_SOCKET_BUFFER_SIZE
];
322 struct nlattr
*attrs
;
323 struct opt opts
[] = {
324 { "remoteip", OPT_KEYVAL
, NULL
},
325 { "remoteport", OPT_KEYVAL
, NULL
},
326 { "name", OPT_KEYVAL
, NULL
},
327 { "media", OPT_KEYVAL
, NULL
},
330 const struct tipc_sup_media sup_media
[] = {
331 { "udp", "name", cmd_bearer_add_udp_help
},
335 /* Rewind optind to include media in the option list */
337 if (parse_opts(opts
, cmdl
) < 0)
340 if (!(opt
= get_opt(opts
, "media"))) {
341 fprintf(stderr
, "error, missing media value\n");
346 if (strcmp(media
, "udp") != 0) {
347 fprintf(stderr
, "error, no \"%s\" media specific options available\n",
351 if (!(opt
= get_opt(opts
, "name"))) {
352 fprintf(stderr
, "error, missing media name\n");
356 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_ADD
))) {
357 fprintf(stderr
, "error, message initialisation failed\n");
361 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
362 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
366 err
= udp_bearer_add(nlh
, opts
, cmdl
);
370 mnl_attr_nest_end(nlh
, attrs
);
372 return msg_doit(nlh
, NULL
, NULL
);
375 static int cmd_bearer_add(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
376 struct cmdl
*cmdl
, void *data
)
378 const struct cmd cmds
[] = {
379 { "media", cmd_bearer_add_media
, cmd_bearer_add_help
},
383 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
386 static void cmd_bearer_enable_help(struct cmdl
*cmdl
)
389 "Usage: %s bearer enable [OPTIONS] media MEDIA ARGS...\n\n"
391 " domain DOMAIN - Discovery domain\n"
392 " priority PRIORITY - Bearer priority\n",
394 print_bearer_media();
397 static int cmd_bearer_enable(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
398 struct cmdl
*cmdl
, void *data
)
403 char buf
[MNL_SOCKET_BUFFER_SIZE
];
404 struct opt opts
[] = {
405 { "device", OPT_KEYVAL
, NULL
},
406 { "domain", OPT_KEYVAL
, NULL
},
407 { "localip", OPT_KEYVAL
, NULL
},
408 { "localport", OPT_KEYVAL
, NULL
},
409 { "media", OPT_KEYVAL
, NULL
},
410 { "name", OPT_KEYVAL
, NULL
},
411 { "priority", OPT_KEYVAL
, NULL
},
412 { "remoteip", OPT_KEYVAL
, NULL
},
413 { "remoteport", OPT_KEYVAL
, NULL
},
416 struct tipc_sup_media sup_media
[] = {
417 { "udp", "name", cmd_bearer_enable_udp_help
},
418 { "eth", "device", cmd_bearer_enable_l2_help
},
419 { "ib", "device", cmd_bearer_enable_l2_help
},
423 if (parse_opts(opts
, cmdl
) < 0) {
429 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_ENABLE
))) {
430 fprintf(stderr
, "error: message initialisation failed\n");
433 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
435 if ((opt
= get_opt(opts
, "domain")))
436 mnl_attr_put_u32(nlh
, TIPC_NLA_BEARER_DOMAIN
, atoi(opt
->val
));
438 if ((opt
= get_opt(opts
, "priority"))) {
439 struct nlattr
*props
;
441 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_PROP
);
442 mnl_attr_put_u32(nlh
, TIPC_NLA_PROP_PRIO
, atoi(opt
->val
));
443 mnl_attr_nest_end(nlh
, props
);
446 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
450 opt
= get_opt(opts
, "media");
451 if (opt
&& strcmp(opt
->val
, "udp") == 0) {
452 err
= nl_add_udp_enable_opts(nlh
, opts
, cmdl
);
456 mnl_attr_nest_end(nlh
, nest
);
458 return msg_doit(nlh
, NULL
, NULL
);
461 static void cmd_bearer_disable_l2_help(struct cmdl
*cmdl
, char *media
)
463 fprintf(stderr
, "Usage: %s bearer disable media %s device DEVICE\n",
464 cmdl
->argv
[0], media
);
467 static void cmd_bearer_disable_udp_help(struct cmdl
*cmdl
, char *media
)
469 fprintf(stderr
, "Usage: %s bearer disable media %s name NAME\n",
470 cmdl
->argv
[0], media
);
473 static void cmd_bearer_disable_help(struct cmdl
*cmdl
)
475 fprintf(stderr
, "Usage: %s bearer disable media MEDIA ARGS...\n",
477 print_bearer_media();
480 static int cmd_bearer_disable(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
481 struct cmdl
*cmdl
, void *data
)
484 char buf
[MNL_SOCKET_BUFFER_SIZE
];
486 struct opt opts
[] = {
487 { "device", OPT_KEYVAL
, NULL
},
488 { "name", OPT_KEYVAL
, NULL
},
489 { "media", OPT_KEYVAL
, NULL
},
492 struct tipc_sup_media sup_media
[] = {
493 { "udp", "name", cmd_bearer_disable_udp_help
},
494 { "eth", "device", cmd_bearer_disable_l2_help
},
495 { "ib", "device", cmd_bearer_disable_l2_help
},
499 if (parse_opts(opts
, cmdl
) < 0) {
505 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_DISABLE
))) {
506 fprintf(stderr
, "error, message initialisation failed\n");
510 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
511 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
514 mnl_attr_nest_end(nlh
, nest
);
516 return msg_doit(nlh
, NULL
, NULL
);
520 static void cmd_bearer_set_help(struct cmdl
*cmdl
)
522 fprintf(stderr
, "Usage: %s bearer set OPTION media MEDIA ARGS...\n",
524 _print_bearer_opts();
525 print_bearer_media();
528 static void cmd_bearer_set_udp_help(struct cmdl
*cmdl
, char *media
)
530 fprintf(stderr
, "Usage: %s bearer set OPTION media %s name NAME\n\n",
531 cmdl
->argv
[0], media
);
532 _print_bearer_opts();
535 static void cmd_bearer_set_l2_help(struct cmdl
*cmdl
, char *media
)
538 "Usage: %s bearer set [OPTION]... media %s device DEVICE\n",
539 cmdl
->argv
[0], media
);
540 _print_bearer_opts();
543 static int cmd_bearer_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
544 struct cmdl
*cmdl
, void *data
)
549 char buf
[MNL_SOCKET_BUFFER_SIZE
];
550 struct nlattr
*props
;
551 struct nlattr
*attrs
;
552 struct opt opts
[] = {
553 { "device", OPT_KEYVAL
, NULL
},
554 { "media", OPT_KEYVAL
, NULL
},
555 { "name", OPT_KEYVAL
, NULL
},
558 struct tipc_sup_media sup_media
[] = {
559 { "udp", "name", cmd_bearer_set_udp_help
},
560 { "eth", "device", cmd_bearer_set_l2_help
},
561 { "ib", "device", cmd_bearer_set_l2_help
},
565 if (strcmp(cmd
->cmd
, "priority") == 0)
566 prop
= TIPC_NLA_PROP_PRIO
;
567 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
568 prop
= TIPC_NLA_PROP_TOL
;
569 else if ((strcmp(cmd
->cmd
, "window") == 0))
570 prop
= TIPC_NLA_PROP_WIN
;
571 else if ((strcmp(cmd
->cmd
, "mtu") == 0))
572 prop
= TIPC_NLA_PROP_MTU
;
576 if (cmdl
->optind
>= cmdl
->argc
) {
577 fprintf(stderr
, "error, missing value\n");
580 val
= atoi(shift_cmdl(cmdl
));
582 if (parse_opts(opts
, cmdl
) < 0)
585 if (prop
== TIPC_NLA_PROP_MTU
) {
586 char *media
= cmd_get_media_type(cmd
, cmdl
, opts
);
590 else if (strcmp(media
, "udp")) {
591 fprintf(stderr
, "error, not supported for media\n");
596 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_SET
))) {
597 fprintf(stderr
, "error, message initialisation failed\n");
600 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
602 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER_PROP
);
603 mnl_attr_put_u32(nlh
, prop
, val
);
604 mnl_attr_nest_end(nlh
, props
);
606 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
610 mnl_attr_nest_end(nlh
, attrs
);
612 return msg_doit(nlh
, NULL
, NULL
);
615 static int cmd_bearer_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
616 struct cmdl
*cmdl
, void *data
)
618 const struct cmd cmds
[] = {
619 { "priority", cmd_bearer_set_prop
, cmd_bearer_set_help
},
620 { "tolerance", cmd_bearer_set_prop
, cmd_bearer_set_help
},
621 { "window", cmd_bearer_set_prop
, cmd_bearer_set_help
},
622 { "mtu", cmd_bearer_set_prop
, cmd_bearer_set_help
},
626 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
629 static void cmd_bearer_get_help(struct cmdl
*cmdl
)
631 fprintf(stderr
, "Usage: %s bearer get [OPTION] media MEDIA ARGS...\n",
633 _print_bearer_opts();
634 print_bearer_media();
637 static void cmd_bearer_get_udp_help(struct cmdl
*cmdl
, char *media
)
639 fprintf(stderr
, "Usage: %s bearer get [OPTION] media %s name NAME [UDP OPTIONS]\n\n",
640 cmdl
->argv
[0], media
);
643 " remoteip - Remote ip address\n"
644 " remoteport - Remote port\n"
645 " localip - Local ip address\n"
646 " localport - Local port\n\n");
647 _print_bearer_opts();
650 static void cmd_bearer_get_l2_help(struct cmdl
*cmdl
, char *media
)
653 "Usage: %s bearer get OPTION media %s device DEVICE\n",
654 cmdl
->argv
[0], media
);
655 _print_bearer_opts();
659 static int bearer_dump_udp_cb(const struct nlmsghdr
*nlh
, void *data
)
661 struct sockaddr_storage
*addr
;
662 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
663 struct nlattr
*info
[TIPC_NLA_UDP_MAX
+ 1] = {};
665 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
667 if (!info
[TIPC_NLA_UDP_REMOTE
])
670 addr
= mnl_attr_get_payload(info
[TIPC_NLA_UDP_REMOTE
]);
672 if (addr
->ss_family
== AF_INET
) {
673 struct sockaddr_in
*ipv4
= (struct sockaddr_in
*) addr
;
675 printf("%s\n", inet_ntoa(ipv4
->sin_addr
));
676 } else if (addr
->ss_family
== AF_INET6
) {
677 char straddr
[INET6_ADDRSTRLEN
];
678 struct sockaddr_in6
*ipv6
= (struct sockaddr_in6
*) addr
;
680 if (!inet_ntop(AF_INET6
, &ipv6
->sin6_addr
, straddr
,
682 fprintf(stderr
, "error, parsing IPv6 addr\n");
685 printf("%s\n", straddr
);
694 static int bearer_get_udp_cb(const struct nlmsghdr
*nlh
, void *data
)
696 struct cb_data
*cb_data
= (struct cb_data
*) data
;
697 struct sockaddr_storage
*addr
;
698 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
699 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
700 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
701 struct nlattr
*opts
[TIPC_NLA_UDP_MAX
+ 1] = {};
703 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
704 if (!info
[TIPC_NLA_BEARER
])
707 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
708 if (!attrs
[TIPC_NLA_BEARER_UDP_OPTS
])
711 mnl_attr_parse_nested(attrs
[TIPC_NLA_BEARER_UDP_OPTS
], parse_attrs
, opts
);
712 if (!opts
[TIPC_NLA_UDP_LOCAL
])
715 if ((cb_data
->attr
== TIPC_NLA_UDP_REMOTE
) &&
716 (cb_data
->prop
== UDP_PROP_IP
) &&
717 opts
[TIPC_NLA_UDP_MULTI_REMOTEIP
]) {
718 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(cb_data
->nlh
);
720 genl
->cmd
= TIPC_NL_UDP_GET_REMOTEIP
;
721 return msg_dumpit(cb_data
->nlh
, bearer_dump_udp_cb
, NULL
);
724 addr
= mnl_attr_get_payload(opts
[cb_data
->attr
]);
726 if (addr
->ss_family
== AF_INET
) {
727 struct sockaddr_in
*ipv4
= (struct sockaddr_in
*) addr
;
729 switch (cb_data
->prop
) {
731 printf("%s\n", inet_ntoa(ipv4
->sin_addr
));
734 printf("%u\n", ntohs(ipv4
->sin_port
));
740 } else if (addr
->ss_family
== AF_INET6
) {
741 char straddr
[INET6_ADDRSTRLEN
];
742 struct sockaddr_in6
*ipv6
= (struct sockaddr_in6
*) addr
;
744 switch (cb_data
->prop
) {
746 if (!inet_ntop(AF_INET6
, &ipv6
->sin6_addr
, straddr
,
748 fprintf(stderr
, "error, parsing IPv6 addr\n");
751 printf("%s\n", straddr
);
754 printf("%u\n", ntohs(ipv6
->sin6_port
));
767 static int bearer_get_cb(const struct nlmsghdr
*nlh
, void *data
)
770 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
771 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
772 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
773 struct nlattr
*props
[TIPC_NLA_PROP_MAX
+ 1] = {};
775 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
776 if (!info
[TIPC_NLA_BEARER
])
779 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
780 if (!attrs
[TIPC_NLA_BEARER_PROP
])
783 mnl_attr_parse_nested(attrs
[TIPC_NLA_BEARER_PROP
], parse_attrs
, props
);
787 printf("%u\n", mnl_attr_get_u32(props
[*prop
]));
792 static int cmd_bearer_get_media(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
793 struct cmdl
*cmdl
, void *data
)
797 char buf
[MNL_SOCKET_BUFFER_SIZE
];
799 struct cb_data cb_data
= {0};
800 struct nlattr
*attrs
;
801 struct opt opts
[] = {
802 { "localip", OPT_KEY
, NULL
},
803 { "localport", OPT_KEY
, NULL
},
804 { "remoteip", OPT_KEY
, NULL
},
805 { "remoteport", OPT_KEY
, NULL
},
806 { "name", OPT_KEYVAL
, NULL
},
807 { "media", OPT_KEYVAL
, NULL
},
810 struct tipc_sup_media sup_media
[] = {
811 { "udp", "name", cmd_bearer_get_udp_help
},
815 /* Rewind optind to include media in the option list */
817 if (parse_opts(opts
, cmdl
) < 0)
820 if (!(opt
= get_opt(opts
, "media"))) {
821 fprintf(stderr
, "error, missing media value\n");
827 cmd_bearer_get_udp_help(cmdl
, media
);
830 if (strcmp(media
, "udp") != 0) {
831 fprintf(stderr
, "error, no \"%s\" media specific options\n", media
);
834 if (!(opt
= get_opt(opts
, "name"))) {
835 fprintf(stderr
, "error, missing media name\n");
839 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
840 fprintf(stderr
, "error, message initialisation failed\n");
844 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
845 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
848 mnl_attr_nest_end(nlh
, attrs
);
851 if (has_opt(opts
, "localip")) {
852 cb_data
.attr
= TIPC_NLA_UDP_LOCAL
;
853 cb_data
.prop
= UDP_PROP_IP
;
854 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
855 } else if (has_opt(opts
, "localport")) {
856 cb_data
.attr
= TIPC_NLA_UDP_LOCAL
;
857 cb_data
.prop
= UDP_PROP_PORT
;
858 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
859 } else if (has_opt(opts
, "remoteip")) {
860 cb_data
.attr
= TIPC_NLA_UDP_REMOTE
;
861 cb_data
.prop
= UDP_PROP_IP
;
862 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
863 } else if (has_opt(opts
, "remoteport")) {
864 cb_data
.attr
= TIPC_NLA_UDP_REMOTE
;
865 cb_data
.prop
= UDP_PROP_PORT
;
866 return msg_doit(nlh
, bearer_get_udp_cb
, &cb_data
);
868 fprintf(stderr
, "error, missing UDP option\n");
872 static int cmd_bearer_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
873 struct cmdl
*cmdl
, void *data
)
877 char buf
[MNL_SOCKET_BUFFER_SIZE
];
878 struct nlattr
*attrs
;
879 struct opt opts
[] = {
880 { "device", OPT_KEYVAL
, NULL
},
881 { "media", OPT_KEYVAL
, NULL
},
882 { "name", OPT_KEYVAL
, NULL
},
885 struct tipc_sup_media sup_media
[] = {
886 { "udp", "name", cmd_bearer_get_udp_help
},
887 { "eth", "device", cmd_bearer_get_l2_help
},
888 { "ib", "device", cmd_bearer_get_l2_help
},
897 if (strcmp(cmd
->cmd
, "priority") == 0)
898 prop
= TIPC_NLA_PROP_PRIO
;
899 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
900 prop
= TIPC_NLA_PROP_TOL
;
901 else if ((strcmp(cmd
->cmd
, "window") == 0))
902 prop
= TIPC_NLA_PROP_WIN
;
903 else if ((strcmp(cmd
->cmd
, "mtu") == 0))
904 prop
= TIPC_NLA_PROP_MTU
;
908 if (parse_opts(opts
, cmdl
) < 0)
911 if (prop
== TIPC_NLA_PROP_MTU
) {
912 char *media
= cmd_get_media_type(cmd
, cmdl
, opts
);
916 else if (strcmp(media
, "udp")) {
917 fprintf(stderr
, "error, not supported for media\n");
922 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
923 fprintf(stderr
, "error, message initialisation failed\n");
927 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_BEARER
);
928 err
= nl_add_bearer_name(nlh
, cmd
, cmdl
, opts
, sup_media
);
931 mnl_attr_nest_end(nlh
, attrs
);
933 return msg_doit(nlh
, bearer_get_cb
, &prop
);
936 static int cmd_bearer_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
937 struct cmdl
*cmdl
, void *data
)
939 const struct cmd cmds
[] = {
940 { "priority", cmd_bearer_get_prop
, cmd_bearer_get_help
},
941 { "tolerance", cmd_bearer_get_prop
, cmd_bearer_get_help
},
942 { "window", cmd_bearer_get_prop
, cmd_bearer_get_help
},
943 { "mtu", cmd_bearer_get_prop
, cmd_bearer_get_help
},
944 { "media", cmd_bearer_get_media
, cmd_bearer_get_help
},
948 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
951 static int bearer_list_cb(const struct nlmsghdr
*nlh
, void *data
)
953 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
954 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
955 struct nlattr
*attrs
[TIPC_NLA_BEARER_MAX
+ 1] = {};
957 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
958 if (!info
[TIPC_NLA_BEARER
]) {
959 fprintf(stderr
, "No bearer in netlink response\n");
963 mnl_attr_parse_nested(info
[TIPC_NLA_BEARER
], parse_attrs
, attrs
);
964 if (!attrs
[TIPC_NLA_BEARER_NAME
]) {
965 fprintf(stderr
, "Bearer name missing in netlink response\n");
969 printf("%s\n", mnl_attr_get_str(attrs
[TIPC_NLA_BEARER_NAME
]));
974 static int cmd_bearer_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
975 struct cmdl
*cmdl
, void *data
)
977 char buf
[MNL_SOCKET_BUFFER_SIZE
];
980 fprintf(stderr
, "Usage: %s bearer list\n", cmdl
->argv
[0]);
984 if (!(nlh
= msg_init(buf
, TIPC_NL_BEARER_GET
))) {
985 fprintf(stderr
, "error, message initialisation failed\n");
989 return msg_dumpit(nlh
, bearer_list_cb
, NULL
);
992 void cmd_bearer_help(struct cmdl
*cmdl
)
995 "Usage: %s bearer COMMAND [ARGS] ...\n"
998 " add - Add data to existing bearer\n"
999 " enable - Enable a bearer\n"
1000 " disable - Disable a bearer\n"
1001 " set - Set various bearer properties\n"
1002 " get - Get various bearer properties\n"
1003 " list - List bearers\n", cmdl
->argv
[0]);
1006 int cmd_bearer(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
1009 const struct cmd cmds
[] = {
1010 { "add", cmd_bearer_add
, cmd_bearer_add_help
},
1011 { "disable", cmd_bearer_disable
, cmd_bearer_disable_help
},
1012 { "enable", cmd_bearer_enable
, cmd_bearer_enable_help
},
1013 { "get", cmd_bearer_get
, cmd_bearer_get_help
},
1014 { "list", cmd_bearer_list
, NULL
},
1015 { "set", cmd_bearer_set
, cmd_bearer_set_help
},
1019 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);