Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/networking/libiproute/iplink.c

    r3232 r3621  
    22/*
    33 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     4 *          Patrick McHardy <kaber@trash.net>
    45 *
    56 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    67 */
    78#include <net/if.h>
    8 #include <net/if_packet.h>
     9/*#include <net/if_packet.h> - not needed? */
    910#include <netpacket/packet.h>
    1011#include <netinet/if_ether.h>
    1112
     13#include <linux/if_vlan.h>
    1214#include "ip_common.h"  /* #include "libbb.h" is inside */
    1315#include "rt_names.h"
    1416#include "utils.h"
    1517
     18#undef  ETH_P_8021AD
     19#define ETH_P_8021AD            0x88A8
     20#undef  VLAN_FLAG_REORDER_HDR
     21#define VLAN_FLAG_REORDER_HDR   0x1
     22#undef  VLAN_FLAG_GVRP
     23#define VLAN_FLAG_GVRP          0x2
     24#undef  VLAN_FLAG_LOOSE_BINDING
     25#define VLAN_FLAG_LOOSE_BINDING 0x4
     26#undef  VLAN_FLAG_MVRP
     27#define VLAN_FLAG_MVRP          0x8
     28#undef  IFLA_VLAN_PROTOCOL
     29#define IFLA_VLAN_PROTOCOL      5
     30
    1631#ifndef IFLA_LINKINFO
    1732# define IFLA_LINKINFO 18
    1833# define IFLA_INFO_KIND 1
     34# define IFLA_INFO_DATA 2
     35#endif
     36
     37#ifndef IFLA_VLAN_MAX
     38# define IFLA_VLAN_ID 1
     39# define IFLA_VLAN_FLAGS 2
     40struct ifla_vlan_flags {
     41    uint32_t    flags;
     42    uint32_t    mask;
     43};
    1944#endif
    2045
    2146/* taken from linux/sockios.h */
    2247#define SIOCSIFNAME  0x8923  /* set interface name */
     48
     49#if 0
     50# define dbg(...) bb_error_msg(__VA_ARGS__)
     51#else
     52# define dbg(...) ((void)0)
     53#endif
    2354
    2455/* Exits on error */
     
    278309}
    279310
     311static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size)
     312{
     313    static const char keywords[] ALIGN1 =
     314        "id\0"
     315        "protocol\0"
     316        "reorder_hdr\0"
     317        "gvrp\0"
     318        "mvrp\0"
     319        "loose_binding\0"
     320    ;
     321    static const char protocols[] ALIGN1 =
     322        "802.1q\0"
     323        "802.1ad\0"
     324    ;
     325    static const char str_on_off[] ALIGN1 =
     326        "on\0"
     327        "off\0"
     328    ;
     329    enum {
     330        ARG_id = 0,
     331        ARG_reorder_hdr,
     332        ARG_gvrp,
     333        ARG_mvrp,
     334        ARG_loose_binding,
     335        ARG_protocol,
     336    };
     337    enum {
     338        PROTO_8021Q = 0,
     339        PROTO_8021AD,
     340    };
     341    enum {
     342        PARM_on = 0,
     343        PARM_off
     344    };
     345    int arg;
     346    uint16_t id, proto;
     347    struct ifla_vlan_flags flags = {};
     348
     349    while (*argv) {
     350        arg = index_in_substrings(keywords, *argv);
     351        if (arg < 0)
     352            invarg_1_to_2(*argv, "type vlan");
     353
     354        NEXT_ARG();
     355        if (arg == ARG_id) {
     356            id = get_u16(*argv, "id");
     357            addattr_l(n, size, IFLA_VLAN_ID, &id, sizeof(id));
     358        } else if (arg == ARG_protocol) {
     359            arg = index_in_substrings(protocols, *argv);
     360            if (arg == PROTO_8021Q)
     361                proto = ETH_P_8021Q;
     362            else if (arg == PROTO_8021AD)
     363                proto = ETH_P_8021AD;
     364            else
     365                bb_error_msg_and_die("unknown VLAN encapsulation protocol '%s'",
     366                                     *argv);
     367            addattr_l(n, size, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
     368        } else {
     369            int param = index_in_strings(str_on_off, *argv);
     370            if (param < 0)
     371                die_must_be_on_off(nth_string(keywords, arg));
     372
     373            if (arg == ARG_reorder_hdr) {
     374                flags.mask |= VLAN_FLAG_REORDER_HDR;
     375                flags.flags &= ~VLAN_FLAG_REORDER_HDR;
     376                if (param == PARM_on)
     377                    flags.flags |= VLAN_FLAG_REORDER_HDR;
     378            } else if (arg == ARG_gvrp) {
     379                flags.mask |= VLAN_FLAG_GVRP;
     380                flags.flags &= ~VLAN_FLAG_GVRP;
     381                if (param == PARM_on)
     382                    flags.flags |= VLAN_FLAG_GVRP;
     383            } else if (arg == ARG_mvrp) {
     384                flags.mask |= VLAN_FLAG_MVRP;
     385                flags.flags &= ~VLAN_FLAG_MVRP;
     386                if (param == PARM_on)
     387                    flags.flags |= VLAN_FLAG_MVRP;
     388            } else { /*if (arg == ARG_loose_binding) */
     389                flags.mask |= VLAN_FLAG_LOOSE_BINDING;
     390                flags.flags &= ~VLAN_FLAG_LOOSE_BINDING;
     391                if (param == PARM_on)
     392                    flags.flags |= VLAN_FLAG_LOOSE_BINDING;
     393            }
     394        }
     395        argv++;
     396    }
     397
     398    if (flags.mask)
     399        addattr_l(n, size, IFLA_VLAN_FLAGS, &flags, sizeof(flags));
     400}
     401
    280402#ifndef NLMSG_TAIL
    281403#define NLMSG_TAIL(nmsg) \
     
    283405#endif
    284406/* Return value becomes exitcode. It's okay to not return at all */
    285 static int do_change(char **argv, const unsigned rtm)
     407static int do_add_or_delete(char **argv, const unsigned rtm)
    286408{
    287409    static const char keywords[] ALIGN1 =
    288         "link\0""name\0""type\0""dev\0";
     410        "link\0""name\0""type\0""dev\0""address\0";
    289411    enum {
    290412        ARG_link,
     
    292414        ARG_type,
    293415        ARG_dev,
     416        ARG_address,
    294417    };
    295418    struct rtnl_handle rth;
     
    300423    } req;
    301424    smalluint arg;
    302     char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL;
     425    char *name_str = NULL;
     426    char *link_str = NULL;
     427    char *type_str = NULL;
     428    char *dev_str = NULL;
     429    char *address_str = NULL;
    303430
    304431    memset(&req, 0, sizeof(req));
     
    313440    while (*argv) {
    314441        arg = index_in_substrings(keywords, *argv);
     442        if (arg == ARG_type) {
     443            NEXT_ARG();
     444            type_str = *argv++;
     445            dbg("type_str:'%s'", type_str);
     446            break;
     447        }
    315448        if (arg == ARG_link) {
    316449            NEXT_ARG();
    317450            link_str = *argv;
     451            dbg("link_str:'%s'", link_str);
    318452        } else if (arg == ARG_name) {
    319453            NEXT_ARG();
    320454            name_str = *argv;
    321         } else if (arg == ARG_type) {
    322             NEXT_ARG();
    323             type_str = *argv;
     455            dbg("name_str:'%s'", name_str);
     456        } else if (arg == ARG_address) {
     457            NEXT_ARG();
     458            address_str = *argv;
     459            dbg("address_str:'%s'", name_str);
    324460        } else {
    325461            if (arg == ARG_dev) {
     
    329465            }
    330466            dev_str = *argv;
     467            dbg("dev_str:'%s'", dev_str);
    331468        }
    332469        argv++;
     
    340477        addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str,
    341478                strlen(type_str));
     479
     480        if (*argv) {
     481            struct rtattr *data = NLMSG_TAIL(&req.n);
     482            addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0);
     483
     484            if (strcmp(type_str, "vlan") == 0)
     485                vlan_parse_opt(argv, &req.n, sizeof(req));
     486
     487            data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;
     488        }
     489
    342490        linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
    343491    }
     
    353501            addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
    354502        }
     503        if (address_str) {
     504            unsigned char abuf[32];
     505            int len = ll_addr_a2n(abuf, sizeof(abuf), address_str);
     506            dbg("address len:%d", len);
     507            if (len < 0)
     508                return -1;
     509            addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len);
     510        }
    355511    }
    356512    if (name_str) {
    357513        const size_t name_len = strlen(name_str) + 1;
    358514        if (name_len < 2 || name_len > IFNAMSIZ)
    359             invarg(name_str, "name");
     515            invarg_1_to_2(name_str, "name");
    360516        addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
    361517    }
     
    365521}
    366522
     523/* Other keywords recognized by iproute2-3.12.0: */
     524#if 0
     525        } else if (matches(*argv, "broadcast") == 0 ||
     526                strcmp(*argv, "brd") == 0) {
     527            NEXT_ARG();
     528            len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
     529            if (len < 0)
     530                return -1;
     531            addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
     532        } else if (matches(*argv, "txqueuelen") == 0 ||
     533                strcmp(*argv, "qlen") == 0 ||
     534                matches(*argv, "txqlen") == 0) {
     535            NEXT_ARG();
     536            if (qlen != -1)
     537                duparg("txqueuelen", *argv);
     538            if (get_integer(&qlen,  *argv, 0))
     539                invarg_1_to_2(*argv, "txqueuelen");
     540            addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
     541        } else if (strcmp(*argv, "mtu") == 0) {
     542            NEXT_ARG();
     543            if (mtu != -1)
     544                duparg("mtu", *argv);
     545            if (get_integer(&mtu, *argv, 0))
     546                invarg_1_to_2(*argv, "mtu");
     547            addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
     548                } else if (strcmp(*argv, "netns") == 0) {
     549                        NEXT_ARG();
     550                        if (netns != -1)
     551                                duparg("netns", *argv);
     552            if ((netns = get_netns_fd(*argv)) >= 0)
     553                addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
     554            else if (get_integer(&netns, *argv, 0) == 0)
     555                addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
     556            else
     557                                invarg_1_to_2(*argv, "netns");
     558        } else if (strcmp(*argv, "multicast") == 0) {
     559            NEXT_ARG();
     560            req->i.ifi_change |= IFF_MULTICAST;
     561            if (strcmp(*argv, "on") == 0) {
     562                req->i.ifi_flags |= IFF_MULTICAST;
     563            } else if (strcmp(*argv, "off") == 0) {
     564                req->i.ifi_flags &= ~IFF_MULTICAST;
     565            } else
     566                return on_off("multicast", *argv);
     567        } else if (strcmp(*argv, "allmulticast") == 0) {
     568            NEXT_ARG();
     569            req->i.ifi_change |= IFF_ALLMULTI;
     570            if (strcmp(*argv, "on") == 0) {
     571                req->i.ifi_flags |= IFF_ALLMULTI;
     572            } else if (strcmp(*argv, "off") == 0) {
     573                req->i.ifi_flags &= ~IFF_ALLMULTI;
     574            } else
     575                return on_off("allmulticast", *argv);
     576        } else if (strcmp(*argv, "promisc") == 0) {
     577            NEXT_ARG();
     578            req->i.ifi_change |= IFF_PROMISC;
     579            if (strcmp(*argv, "on") == 0) {
     580                req->i.ifi_flags |= IFF_PROMISC;
     581            } else if (strcmp(*argv, "off") == 0) {
     582                req->i.ifi_flags &= ~IFF_PROMISC;
     583            } else
     584                return on_off("promisc", *argv);
     585        } else if (strcmp(*argv, "trailers") == 0) {
     586            NEXT_ARG();
     587            req->i.ifi_change |= IFF_NOTRAILERS;
     588            if (strcmp(*argv, "off") == 0) {
     589                req->i.ifi_flags |= IFF_NOTRAILERS;
     590            } else if (strcmp(*argv, "on") == 0) {
     591                req->i.ifi_flags &= ~IFF_NOTRAILERS;
     592            } else
     593                return on_off("trailers", *argv);
     594        } else if (strcmp(*argv, "arp") == 0) {
     595            NEXT_ARG();
     596            req->i.ifi_change |= IFF_NOARP;
     597            if (strcmp(*argv, "on") == 0) {
     598                req->i.ifi_flags &= ~IFF_NOARP;
     599            } else if (strcmp(*argv, "off") == 0) {
     600                req->i.ifi_flags |= IFF_NOARP;
     601            } else
     602                return on_off("noarp", *argv);
     603        } else if (strcmp(*argv, "vf") == 0) {
     604            struct rtattr *vflist;
     605            NEXT_ARG();
     606            if (get_integer(&vf,  *argv, 0)) {
     607                invarg_1_to_2(*argv, "vf");
     608            }
     609            vflist = addattr_nest(&req->n, sizeof(*req),
     610                          IFLA_VFINFO_LIST);
     611            len = iplink_parse_vf(vf, &argc, &argv, req);
     612            if (len < 0)
     613                return -1;
     614            addattr_nest_end(&req->n, vflist);
     615        } else if (matches(*argv, "master") == 0) {
     616            int ifindex;
     617            NEXT_ARG();
     618            ifindex = ll_name_to_index(*argv);
     619            if (!ifindex)
     620                invarg_1_to_2(*argv, "master");
     621            addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
     622                  &ifindex, 4);
     623        } else if (matches(*argv, "nomaster") == 0) {
     624            int ifindex = 0;
     625            addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
     626                  &ifindex, 4);
     627        } else if (matches(*argv, "dynamic") == 0) {
     628            NEXT_ARG();
     629            req->i.ifi_change |= IFF_DYNAMIC;
     630            if (strcmp(*argv, "on") == 0) {
     631                req->i.ifi_flags |= IFF_DYNAMIC;
     632            } else if (strcmp(*argv, "off") == 0) {
     633                req->i.ifi_flags &= ~IFF_DYNAMIC;
     634            } else
     635                return on_off("dynamic", *argv);
     636        } else if (matches(*argv, "alias") == 0) {
     637            NEXT_ARG();
     638            addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
     639                  *argv, strlen(*argv));
     640            argc--; argv++;
     641            break;
     642        } else if (strcmp(*argv, "group") == 0) {
     643            NEXT_ARG();
     644            if (*group != -1)
     645                duparg("group", *argv);
     646            if (rtnl_group_a2n(group, *argv))
     647                invarg_1_to_2(*argv, "group");
     648        } else if (strcmp(*argv, "mode") == 0) {
     649            int mode;
     650            NEXT_ARG();
     651            mode = get_link_mode(*argv);
     652            if (mode < 0)
     653                invarg_1_to_2(*argv, "mode");
     654            addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
     655        } else if (strcmp(*argv, "state") == 0) {
     656            int state;
     657            NEXT_ARG();
     658            state = get_operstate(*argv);
     659            if (state < 0)
     660                invarg_1_to_2(*argv, "state");
     661            addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
     662        } else if (matches(*argv, "numtxqueues") == 0) {
     663            NEXT_ARG();
     664            if (numtxqueues != -1)
     665                duparg("numtxqueues", *argv);
     666            if (get_integer(&numtxqueues, *argv, 0))
     667                invarg_1_to_2(*argv, "numtxqueues");
     668            addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
     669                  &numtxqueues, 4);
     670        } else if (matches(*argv, "numrxqueues") == 0) {
     671            NEXT_ARG();
     672            if (numrxqueues != -1)
     673                duparg("numrxqueues", *argv);
     674            if (get_integer(&numrxqueues, *argv, 0))
     675                invarg_1_to_2(*argv, "numrxqueues");
     676            addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
     677                  &numrxqueues, 4);
     678        }
     679#endif
     680
    367681/* Return value becomes exitcode. It's okay to not return at all */
    368682int FAST_FUNC do_iplink(char **argv)
     
    371685        "add\0""delete\0""set\0""show\0""lst\0""list\0";
    372686    if (*argv) {
    373         smalluint key = index_in_substrings(keywords, *argv);
    374         if (key > 5) /* invalid argument */
    375             bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     687        int key = index_in_substrings(keywords, *argv);
     688        if (key < 0) /* invalid argument */
     689            invarg_1_to_2(*argv, applet_name);
    376690        argv++;
    377691        if (key <= 1) /* add/delete */
    378             return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
    379         else if (key == 2) /* set */
     692            return do_add_or_delete(argv, key ? RTM_DELLINK : RTM_NEWLINK);
     693        if (key == 2) /* set */
    380694            return do_set(argv);
    381695    }
Note: See TracChangeset for help on using the changeset viewer.