Hi, list!

Attached is the patch that adds to BB ability to manage Ethernet bridges.
It's a stripped down version of brctl utility from GPL
bridge-utils<http://www.linux-foundation.org/en/Net:Bridge>
.
It just helped me to finish tuning of a linux gate which I wanted to be
controlled entirely by only BB utilities.
Hope it will be useful!

--
Vladimir Dronnikov
/* vi: set sw=4 ts=4: */
/*
 * stripped down brctl utility from bridge-utils
 *
 * Copyright (C) 2008 by Vladimir Dronnikov <[EMAIL PROTECTED]>
 *
 * Licensed under GPLv2, see file LICENSE in this tarball for details.
 */
#include "libbb.h"
#include <linux/sockios.h>
#include <net/if.h>

int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int brctl_main(int argc, char **argv)
{
#define cmd argv[1]
#define error cmd
#define bridge argv[2]
#define iface argv[3]

        int i;
        struct ifreq ifr;
        int fd = xsocket(AF_INET, SOCK_STREAM, 0);

        /* see how we're called */
        /* NOTE: index_in_strings SEGFAULTS (strcmp) if key is NULL. IMHO this 
should be fixed in libbb */
        /* NOTE: Meanwhile let cmd not be NULL */
        /* NOTE: index_in_strings returns -1 on empty first chunk and empty 
key. IMHO it should instead return 0 */
        /* NOTE: Meanwhile let first chunk be always (despite USE_FEATURE_...) 
non-empty */
        switch ((i=index_in_strings("show\0" "addbr\0" "delbr\0" "addif\0" 
"delif\0", cmd ? cmd : USE_FEATURE_BRCTL_SHOW("show") ""))) {

#define add_or_del (i%2)

                USE_FEATURE_BRCTL_SHOW(
                /* show bridge(s) info */
                case 0:
                        error = (char *)"to be implemented soon";
                        goto fail;
                )

                /* add or delete bridge */
                case 1:
                case 2:
                        /* check cmdline */
                        if (argc < 3)
                                goto show_usage;
                        /* NOTE: less bullet-proof than (add_or_del ? 
SIOCBRADDBR : SIOCBRDELBR) */
                        /* NOTE: but saves about 25 bytes */
                        if (ioctl(fd, SIOCBRADDBR-1+i, bridge)) {
                                switch (errno) {
                                        case EEXIST:
                                                error = (char *)"device %s 
already exists; can't create bridge with the same name";
                                                break;
                                        case ENXIO:
                                                error = (char *)"bridge %s 
doesn't exist; can't delete it";
                                                break;
                                        case EBUSY:
                                                error = (char *)"bridge %s is 
still up; can't delete it";
                                                break;
                                        default:
                                                error = (char *)(add_or_del ? 
"can't add bridge %s" : "can't delete bridge %s");
                                }
                                bb_perror_msg_and_die(error, bridge);
                        }
                        break;

                /* interface management */
                case 3:
                case 4:
                        /* check cmdline */
                        if (argc < 4)
                                goto show_usage;
                        /* check interface */
                        if (!(ifr.ifr_ifindex = if_nametoindex(iface))) {
                                errno = ENODEV;
                                /* NOTE: saves some bytes comparing with 
explicit bb_perror... */
                                error = (char *)"interface %s does not exist";
                                goto fail;
                        }
                        safe_strncpy(ifr.ifr_name, bridge, IFNAMSIZ);

                        /* add or delete interface */
                        if (ioctl(fd, SIOCBRADDIF-3+i, &ifr)) {
                                switch (errno) {
                                        case EBUSY:
                                                error = (char *)"device %s is 
already a member of a bridge %s";
                                                break;
                                        case ELOOP:
                                                error = (char *)"device %s is a 
bridge device itself";
                                                break;
                                        case EINVAL:
                                                error = (char *)"device %s is 
not a slave of %s";
                                                break;
                                        default:
                                                error = (char *)(add_or_del ? 
"can't add %s to bridge %s" : "can't delete %s from bridge %s");
                                }
fail:
                                bb_perror_msg_and_die(error, iface, bridge);
                        }
                        break;

                default:
show_usage:
                        bb_show_usage();
        }

        return 0;
}
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to