| /* |
| * team_monitor.c - Network team device dummy event monitor |
| * Copyright (C) 2011-2015 Jiri Pirko <jiri@resnulli.us> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include <stdio.h> |
| #include <signal.h> |
| #include <errno.h> |
| #include <sys/select.h> |
| #include <team.h> |
| |
| #define APPNAME "team_monitor" |
| |
| static char *get_port_name(struct team_handle *th, uint32_t ifindex) |
| { |
| static char ifname[32]; |
| |
| return team_ifindex2ifname(th, ifindex, ifname, sizeof(ifname)); |
| } |
| |
| static int die = 0; |
| |
| static void sigint_handler(int signum) |
| { |
| die = 1; |
| } |
| |
| static void do_main_loop(struct team_handle *th) |
| { |
| fd_set rfds; |
| fd_set rfds_tmp; |
| int fdmax; |
| int ret; |
| int tfd; |
| |
| FD_ZERO(&rfds); |
| tfd = team_get_event_fd(th); |
| FD_SET(tfd, &rfds); |
| fdmax = tfd + 1; |
| |
| while (1) { |
| rfds_tmp = rfds; |
| ret = select(fdmax, &rfds_tmp, NULL, NULL, NULL); |
| if (die) |
| break; |
| if (ret == -1) { |
| perror("select()"); |
| } |
| if (FD_ISSET(tfd, &rfds_tmp)) |
| team_handle_events(th); |
| } |
| } |
| |
| static int port_change_handler_func(struct team_handle *th, void *arg, |
| team_change_type_mask_t type_mask) |
| { |
| struct team_port *port; |
| |
| printf("------------------\nport change\n\tport list:\n"); |
| team_for_each_port(port, th) { |
| uint32_t ifindex = team_get_port_ifindex(port); |
| |
| printf("\tifname %s, linkup %d, changed %d, speed %d, " |
| "duplex %d\n", |
| get_port_name(th, ifindex), |
| team_is_port_link_up(port), |
| team_is_port_changed(port), |
| team_get_port_speed(port), |
| team_get_port_duplex(port)); |
| } |
| return 0; |
| } |
| |
| static struct team_change_handler port_change_handler = { |
| .func = port_change_handler_func, |
| .type_mask = TEAM_PORT_CHANGE, |
| }; |
| |
| static int option_change_handler_func(struct team_handle *th, void *arg, |
| team_change_type_mask_t type_mask) |
| { |
| struct team_option *option; |
| |
| printf("------------------\noption change\n\toption list:\n"); |
| team_for_each_option(option, th) { |
| printf("\topt_name: %s, changed %d\n", |
| team_get_option_name(option), |
| team_is_option_changed(option)); |
| } |
| return 0; |
| } |
| |
| static struct team_change_handler option_change_handler = { |
| .func = option_change_handler_func, |
| .type_mask = TEAM_OPTION_CHANGE, |
| }; |
| |
| int main(int argc, char *argv[]) |
| { |
| struct team_handle *th; |
| int err; |
| char *ifname; |
| uint32_t ifindex; |
| |
| if (argc < 2) { |
| fprintf(stderr, "Usage: %s TEAMDEV\n", APPNAME); |
| return 1; |
| } |
| |
| th = team_alloc(); |
| if (!th) { |
| fprintf(stderr, "team alloc failed.\n"); |
| return 1; |
| } |
| |
| ifname = argv[1]; |
| ifindex = team_ifname2ifindex(th, ifname); |
| if (!ifindex) { |
| fprintf(stderr, "Netdevice %s not found.\n", ifname); |
| return 1; |
| } |
| |
| err = team_init(th, ifindex); |
| if (err) { |
| fprintf(stderr, "team init failed\n"); |
| err = 1; |
| goto err_team_init; |
| } |
| |
| err = team_change_handler_register(th, &port_change_handler, NULL); |
| if (err) { |
| fprintf(stderr, "port change handler register failed\n"); |
| err = 1; |
| goto err_port_change_register; |
| } |
| |
| err = team_change_handler_register(th, &option_change_handler, NULL); |
| if (err) { |
| fprintf(stderr, "option change handler register failed\n"); |
| err = 1; |
| goto err_option_change_register; |
| } |
| |
| signal(SIGINT, sigint_handler); |
| |
| do_main_loop(th); |
| |
| team_change_handler_unregister(th, &option_change_handler, NULL); |
| err_option_change_register: |
| team_change_handler_unregister(th, &port_change_handler, NULL); |
| err_port_change_register: |
| err_team_init: |
| team_free(th); |
| |
| return err; |
| } |