2 * Copyright (C) 2000 Lennert Buytenhek
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sys/types.h>
28 #include "libbridge.h"
29 #include "libbridge_private.h"
31 int br_socket_fd
= -1;
33 static int br_init(void)
35 if ((br_socket_fd
= socket(AF_LOCAL
, SOCK_STREAM
, 0)) < 0)
40 static void br_shutdown(void)
46 /* If /sys/class/net/XXX/bridge exists then it must be a bridge */
47 static int isbridge(const struct dirent
*entry
)
49 char path
[SYSFS_PATH_MAX
];
52 snprintf(path
, SYSFS_PATH_MAX
, SYSFS_CLASS_NET
"%s/bridge", entry
->d_name
);
53 return stat(path
, &st
) == 0 && S_ISDIR(st
.st_mode
);
57 * New interface uses sysfs to find bridges
59 static int new_foreach_bridge(int (*iterator
)(const char *name
, void *),
62 struct dirent
**namelist
;
65 count
= scandir(SYSFS_CLASS_NET
, &namelist
, isbridge
, alphasort
);
69 for (i
= 0; i
< count
; i
++) {
70 if (iterator(namelist
[i
]->d_name
, arg
))
74 for (i
= 0; i
< count
; i
++)
82 * Old interface uses ioctl
84 static int old_foreach_bridge(int (*iterator
)(const char *, void *),
88 char ifname
[IFNAMSIZ
];
89 int ifindices
[MAX_BRIDGES
];
90 unsigned long args
[3] = { BRCTL_GET_BRIDGES
,
91 (unsigned long)ifindices
, MAX_BRIDGES
};
93 num
= ioctl(br_socket_fd
, SIOCGIFBR
, args
);
95 dprintf("Get bridge indices failed: %s\n",
100 for (i
= 0; i
< num
; i
++) {
101 if (!if_indextoname(ifindices
[i
], ifname
)) {
102 dprintf("get find name for ifindex %d\n",
108 if(iterator(ifname
, iarg
))
117 * Go over all bridges and call iterator function.
118 * if iterator returns non-zero then stop.
120 static int br_foreach_bridge(int (*iterator
)(const char *, void *),
125 ret
= new_foreach_bridge(iterator
, arg
);
127 ret
= old_foreach_bridge(iterator
, arg
);
133 * Only used if sysfs is not available.
135 static int old_foreach_port(const char *brname
,
136 int (*iterator
)(const char *br
, const char *port
,
142 char ifname
[IFNAMSIZ
];
143 int ifindices
[MAX_PORTS
];
144 unsigned long args
[4] = { BRCTL_GET_PORT_LIST
,
145 (unsigned long)ifindices
, MAX_PORTS
, 0 };
147 memset(ifindices
, 0, sizeof(ifindices
));
148 strncpy(ifr
.ifr_name
, brname
, IFNAMSIZ
);
149 ifr
.ifr_data
= (char *) &args
;
151 err
= ioctl(br_socket_fd
, SIOCDEVPRIVATE
, &ifr
);
153 dprintf("list ports for bridge:'%s' failed: %s\n",
154 brname
, strerror(errno
));
159 for (i
= 0; i
< MAX_PORTS
; i
++) {
163 if (!if_indextoname(ifindices
[i
], ifname
)) {
164 dprintf("can't find name for ifindex:%d\n",
170 if (iterator(brname
, ifname
, arg
))
178 * Iterate over all ports in bridge (using sysfs).
180 static int br_foreach_port(const char *brname
,
181 int (*iterator
)(const char *br
, const char *port
, void *arg
),
185 struct dirent
**namelist
;
186 char path
[SYSFS_PATH_MAX
];
188 snprintf(path
, SYSFS_PATH_MAX
, SYSFS_CLASS_NET
"%s/brif", brname
);
189 count
= scandir(path
, &namelist
, 0, alphasort
);
191 return old_foreach_port(brname
, iterator
, arg
);
193 for (i
= 0; i
< count
; i
++) {
194 if (namelist
[i
]->d_name
[0] == '.'
195 && (namelist
[i
]->d_name
[1] == '\0'
196 || (namelist
[i
]->d_name
[1] == '.'
197 && namelist
[i
]->d_name
[2] == '\0')))
200 if (iterator(brname
, namelist
[i
]->d_name
, arg
))
203 for (i
= 0; i
< count
; i
++)
This page took 0.052249 seconds and 5 git commands to generate.