busybox/networking/ip.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   4 *
   5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   6 *
   7 * Changes:
   8 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
   9 * Bernhard Reutner-Fischer rewrote to use index_in_substr_array
  10 */
  11//config:config IP
  12//config:       bool "ip (35 kb)"
  13//config:       default y
  14//config:       help
  15//config:       The "ip" applet is a TCP/IP interface configuration and routing
  16//config:       utility.
  17//config:       Short forms (enabled below) are busybox-specific extensions.
  18//config:       The standard "ip" utility does not provide them. If you are
  19//config:       trying to be portable, it's better to use "ip CMD" forms.
  20//config:
  21//config:config IPADDR
  22//config:       bool "ipaddr (14 kb)"
  23//config:       default y
  24//config:       select FEATURE_IP_ADDRESS
  25//config:       help
  26//config:       Short form of "ip addr"
  27//config:
  28//config:config IPLINK
  29//config:       bool "iplink (17 kb)"
  30//config:       default y
  31//config:       select FEATURE_IP_LINK
  32//config:       help
  33//config:       Short form of "ip link"
  34//config:
  35//config:config IPROUTE
  36//config:       bool "iproute (15 kb)"
  37//config:       default y
  38//config:       select FEATURE_IP_ROUTE
  39//config:       help
  40//config:       Short form of "ip route"
  41//config:
  42//config:config IPTUNNEL
  43//config:       bool "iptunnel (9.6 kb)"
  44//config:       default y
  45//config:       select FEATURE_IP_TUNNEL
  46//config:       help
  47//config:       Short form of "ip tunnel"
  48//config:
  49//config:config IPRULE
  50//config:       bool "iprule (10 kb)"
  51//config:       default y
  52//config:       select FEATURE_IP_RULE
  53//config:       help
  54//config:       Short form of "ip rule"
  55//config:
  56//config:config IPNEIGH
  57//config:       bool "ipneigh (8.3 kb)"
  58//config:       default y
  59//config:       select FEATURE_IP_NEIGH
  60//config:       help
  61//config:       Short form of "ip neigh"
  62//config:
  63//config:config FEATURE_IP_ADDRESS
  64//config:       bool "ip address"
  65//config:       default y
  66//config:       depends on IP || IPADDR
  67//config:       help
  68//config:       Address manipulation support for the "ip" applet.
  69//config:
  70//config:config FEATURE_IP_LINK
  71//config:       bool "ip link"
  72//config:       default y
  73//config:       depends on IP || IPLINK
  74//config:       help
  75//config:       Configure network devices with "ip".
  76//config:
  77//config:config FEATURE_IP_ROUTE
  78//config:       bool "ip route"
  79//config:       default y
  80//config:       depends on IP || IPROUTE
  81//config:       help
  82//config:       Add support for routing table management to "ip".
  83//config:
  84//config:config FEATURE_IP_ROUTE_DIR
  85//config:       string "ip route configuration directory"
  86//config:       default "/etc/iproute2"
  87//config:       depends on FEATURE_IP_ROUTE
  88//config:       help
  89//config:       Location of the "ip" applet routing configuration.
  90//config:
  91//config:config FEATURE_IP_TUNNEL
  92//config:       bool "ip tunnel"
  93//config:       default y
  94//config:       depends on IP || IPTUNNEL
  95//config:       help
  96//config:       Add support for tunneling commands to "ip".
  97//config:
  98//config:config FEATURE_IP_RULE
  99//config:       bool "ip rule"
 100//config:       default y
 101//config:       depends on IP || IPRULE
 102//config:       help
 103//config:       Add support for rule commands to "ip".
 104//config:
 105//config:config FEATURE_IP_NEIGH
 106//config:       bool "ip neighbor"
 107//config:       default y
 108//config:       depends on IP || IPNEIGH
 109//config:       help
 110//config:       Add support for neighbor commands to "ip".
 111//config:
 112//config:config FEATURE_IP_RARE_PROTOCOLS
 113//config:       bool "Support displaying rarely used link types"
 114//config:       default n
 115//config:       depends on IP || IPADDR || IPLINK || IPROUTE || IPTUNNEL || IPRULE || IPNEIGH
 116//config:       help
 117//config:       If you are not going to use links of type "frad", "econet",
 118//config:       "bif" etc, you probably don't need to enable this.
 119//config:       Ethernet, wireless, infrared, ppp/slip, ip tunnelling
 120//config:       link types are supported without this option selected.
 121
 122//applet:IF_IP(      APPLET_NOEXEC(ip      , ip      , BB_DIR_SBIN, BB_SUID_DROP, ip      ))
 123//applet:IF_IPADDR(  APPLET_NOEXEC(ipaddr  , ipaddr  , BB_DIR_SBIN, BB_SUID_DROP, ipaddr  ))
 124//applet:IF_IPLINK(  APPLET_NOEXEC(iplink  , iplink  , BB_DIR_SBIN, BB_SUID_DROP, iplink  ))
 125//applet:IF_IPROUTE( APPLET_NOEXEC(iproute , iproute , BB_DIR_SBIN, BB_SUID_DROP, iproute ))
 126//applet:IF_IPRULE(  APPLET_NOEXEC(iprule  , iprule  , BB_DIR_SBIN, BB_SUID_DROP, iprule  ))
 127//applet:IF_IPTUNNEL(APPLET_NOEXEC(iptunnel, iptunnel, BB_DIR_SBIN, BB_SUID_DROP, iptunnel))
 128//applet:IF_IPNEIGH( APPLET_NOEXEC(ipneigh , ipneigh , BB_DIR_SBIN, BB_SUID_DROP, ipneigh ))
 129
 130//kbuild:lib-$(CONFIG_IP) += ip.o
 131//kbuild:lib-$(CONFIG_IPADDR) += ip.o
 132//kbuild:lib-$(CONFIG_IPLINK) += ip.o
 133//kbuild:lib-$(CONFIG_IPROUTE) += ip.o
 134//kbuild:lib-$(CONFIG_IPRULE) += ip.o
 135//kbuild:lib-$(CONFIG_IPTUNNEL) += ip.o
 136//kbuild:lib-$(CONFIG_IPNEIGH) += ip.o
 137
 138//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
 139//usage:#define ipaddr_trivial_usage
 140//usage:       "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]"
 141//usage:#define ipaddr_full_usage "\n\n"
 142//usage:       "ipaddr add|change|replace|delete dev IFACE [CONFFLAG-LIST] IFADDR\n"
 143//usage:       "        IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n"
 144//usage:       "                [anycast ADDR] [label STRING] [scope SCOPE]\n"
 145//usage:       "        PREFIX := ADDR[/MASK]\n"
 146//usage:       "        SCOPE := [host|link|global|NUMBER]\n"
 147//usage:       "        CONFFLAG-LIST := [CONFFLAG-LIST] CONFFLAG\n"
 148//usage:       "        CONFFLAG := [noprefixroute]\n"
 149//usage:       "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]"
 150//usage:
 151//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
 152//usage:#define iplink_trivial_usage
 153//usage:       /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n"
 154//usage:       "        [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n"
 155//usage:       "        [master IFACE | nomaster] [netns PID]"
 156// * short help shows only "set" command, long help continues (with just one "\n")
 157// * and shows all other commands:
 158//usage:#define iplink_full_usage "\n"
 159//usage:       "iplink add [link IFACE] IFACE [address MAC] type TYPE [ARGS]\n"
 160//usage:       "iplink delete IFACE type TYPE [ARGS]\n"
 161//usage:       "        TYPE ARGS := vlan VLANARGS | vrf table NUM\n"
 162//usage:       "        VLANARGS := id VLANID [protocol 802.1q|802.1ad] [reorder_hdr on|off]\n"
 163//usage:       "                [gvrp on|off] [mvrp on|off] [loose_binding on|off]\n"
 164//usage:       "iplink show [IFACE]"
 165//upstream man ip-link:
 166//=====================
 167//ip link add [link DEV] [ name ] NAME
 168//                   [ txqueuelen PACKETS ]
 169//                   [ address LLADDR ]
 170//                   [ broadcast LLADDR ]
 171//                   [ mtu MTU ] [index IDX ]
 172//                   [ numtxqueues QUEUE_COUNT ]
 173//                   [ numrxqueues QUEUE_COUNT ]
 174//                   type TYPE [ ARGS ]
 175//       ip link delete { DEVICE | dev DEVICE | group DEVGROUP } type TYPE [ ARGS ]
 176//       ip link set { DEVICE | dev DEVICE | group DEVGROUP } [ { up | down } ]
 177//                      [ arp { on | off } ]
 178//                      [ dynamic { on | off } ]
 179//                      [ multicast { on | off } ]
 180//                      [ allmulticast { on | off } ]
 181//                      [ promisc { on | off } ]
 182//                      [ trailers { on | off } ]
 183//                      [ txqueuelen PACKETS ]
 184//                      [ name NEWNAME ]
 185//                      [ address LLADDR ]
 186//                      [ broadcast LLADDR ]
 187//                      [ mtu MTU ]
 188//                      [ netns { PID | NAME } ]
 189//                      [ link-netnsid ID ]
 190//            [ alias NAME ]
 191//                      [ vf NUM [ mac LLADDR ]
 192//                 [ vlan VLANID [ qos VLAN-QOS ] ]
 193//                 [ rate TXRATE ]
 194//                 [ spoofchk { on | off} ]
 195//                 [ query_rss { on | off} ]
 196//                 [ state { auto | enable | disable} ] ]
 197//                 [ trust { on | off} ] ]
 198//            [ master DEVICE ]
 199//            [ nomaster ]
 200//            [ addrgenmode { eui64 | none | stable_secret | random } ]
 201//                      [ protodown { on | off } ]
 202//       ip link show [ DEVICE | group GROUP ] [up] [master DEV] [type TYPE]
 203//       ip link help [ TYPE ]
 204//TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
 205//          bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
 206//          gre | gretap | ip6gre | ip6gretap | vti | nlmon |
 207//          bond_slave | ipvlan | geneve | bridge_slave | vrf }
 208//usage:
 209//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
 210//usage:#define iproute_trivial_usage
 211//usage:       "list|flush|add|del|change|append|replace|test ROUTE"
 212//usage:#define iproute_full_usage "\n\n"
 213//usage:       "iproute list|flush SELECTOR\n"
 214//usage:       "        SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n"
 215//usage:       "        PREFIX := default|ADDR[/MASK]\n"
 216//usage:       "iproute get ADDR [from ADDR iif IFACE]\n"
 217//usage:       "        [oif IFACE] [tos TOS]\n"
 218//usage:       "iproute add|del|change|append|replace|test ROUTE\n"
 219//usage:       "        ROUTE := NODE_SPEC [INFO_SPEC]\n"
 220//usage:       "        NODE_SPEC := PREFIX"IF_FEATURE_IP_RULE(" [table TABLE_ID]")" [proto RTPROTO] [scope SCOPE] [metric METRIC]\n"
 221//usage:       "        INFO_SPEC := NH OPTIONS\n"
 222//usage:       "        NH := [via [inet|inet6] ADDR] [dev IFACE] [src ADDR] [onlink]\n"
 223//usage:       "        OPTIONS := [mtu [lock] NUM] [advmss [lock] NUM]"
 224//upstream man ip-route:
 225//======================
 226//ip route { show | flush } SELECTOR
 227//ip route save SELECTOR
 228//ip route restore
 229//ip route get ADDRESS [ from ADDRESS iif STRING  ] [ oif STRING ] [ tos TOS ]
 230//ip route { add | del | change | append | replace } ROUTE
 231//SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ] [ table TABLE_ID ] [ proto RTPROTO ] [ type TYPE ] [ scope SCOPE ]
 232//ROUTE := NODE_SPEC [ INFO_SPEC ]
 233//NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ] [ table TABLE_ID ] [ proto RTPROTO ] [ scope SCOPE ] [ metric METRIC ]
 234//INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ] ...
 235//NH := [ encap ENCAP ] [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS
 236// ..............................................................^ I guess [src ADDRESS] should be here
 237//FAMILY := [ inet | inet6 | ipx | dnet | mpls | bridge | link ]
 238//OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ] rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ] [ window NUMBER ] [ cwnd NUMBER ] [ ssthresh REALM ] [ realms REALM ]
 239//        [ rto_min TIME ] [ initcwnd NUMBER ] [ initrwnd NUMBER ] [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ] [ pref PREF ] [ expires TIME ]
 240//TYPE := [ unicast | local | broadcast | multicast | throw | unreachable | prohibit | blackhole | nat ]
 241//TABLE_ID := [ local | main | default | all | NUMBER ]
 242//SCOPE := [ host | link | global | NUMBER ]
 243//NHFLAGS := [ onlink | pervasive ]
 244//RTPROTO := [ kernel | boot | static | NUMBER ]
 245//FEATURES := [ ecn | ]
 246//PREF := [ low | medium | high ]
 247//ENCAP := [ MPLS | IP ]
 248//ENCAP_MPLS := mpls [ LABEL ]
 249//ENCAP_IP := ip id TUNNEL_ID dst REMOTE_IP [ tos TOS ] [ ttl TTL ]
 250//usage:
 251//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
 252//usage:#define iprule_trivial_usage
 253//usage:       "[list] | add|del SELECTOR ACTION"
 254//usage:#define iprule_full_usage "\n\n"
 255//usage:       "        SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK[/MASK]]\n"
 256//usage:       "                        [dev IFACE] [pref NUMBER]\n"
 257//usage:       "        ACTION := [table TABLE_ID] [nat ADDR]\n"
 258//usage:       "                        [prohibit|reject|unreachable]\n"
 259//usage:       "                        [realms [SRCREALM/]DSTREALM]\n"
 260//usage:       "        TABLE_ID := [local|main|default|NUMBER]"
 261//usage:
 262//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
 263//usage:#define iptunnel_trivial_usage
 264//usage:       "add|change|del|show [NAME]\n"
 265//usage:       "        [mode ipip|gre|sit] [remote ADDR] [local ADDR] [ttl TTL]"
 266//usage:#define iptunnel_full_usage "\n\n"
 267//usage:       "iptunnel add|change|del|show [NAME]\n"
 268//usage:       "        [mode ipip|gre|sit] [remote ADDR] [local ADDR]\n"
 269//usage:       "        [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n"
 270//usage:       "        [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]"
 271//usage:
 272//usage:#define ipneigh_trivial_usage
 273//usage:       "show|flush [to PREFIX] [dev DEV] [nud STATE]"
 274//usage:#define ipneigh_full_usage ""
 275//usage:
 276//usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE
 277//usage:# define IP_BAR_LINK   "|"
 278//usage:#else
 279//usage:# define IP_BAR_LINK   ""
 280//usage:#endif
 281//usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK
 282//usage:# define IP_BAR_TUNNEL "|"
 283//usage:#else
 284//usage:# define IP_BAR_TUNNEL ""
 285//usage:#endif
 286//usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK || ENABLE_FEATURE_IP_TUNNEL
 287//usage:# define IP_BAR_NEIGH  "|"
 288//usage:#else
 289//usage:# define IP_BAR_NEIGH  ""
 290//usage:#endif
 291//usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK || ENABLE_FEATURE_IP_TUNNEL || ENABLE_FEATURE_IP_NEIGH
 292//usage:# define IP_BAR_RULE   "|"
 293//usage:#else
 294//usage:# define IP_BAR_RULE   ""
 295//usage:#endif
 296//usage:
 297//usage:#define ip_trivial_usage
 298//usage:       "[OPTIONS] "
 299//usage:        IF_FEATURE_IP_ADDRESS("address")
 300//usage:        IF_FEATURE_IP_ROUTE(  IF_FEATURE_IP_ADDRESS("|")"route")
 301//usage:        IF_FEATURE_IP_LINK(   IP_BAR_LINK  "link")
 302//usage:        IF_FEATURE_IP_TUNNEL( IP_BAR_TUNNEL"tunnel")
 303//usage:        IF_FEATURE_IP_NEIGH(  IP_BAR_NEIGH "neigh")
 304//usage:        IF_FEATURE_IP_RULE(   IP_BAR_RULE  "rule")
 305//usage:       " [ARGS]"
 306//usage:#define ip_full_usage "\n\n"
 307//usage:       "OPTIONS := -f[amily] inet|inet6|link | -o[neline]\n"
 308//usage:        IF_FEATURE_IP_ADDRESS("\n"
 309//usage:        "ip addr "ipaddr_trivial_usage)
 310//usage:        IF_FEATURE_IP_ROUTE("\n"
 311//usage:        "ip route "iproute_trivial_usage)
 312//usage:        IF_FEATURE_IP_LINK("\n"
 313//usage:        "ip link "iplink_trivial_usage)
 314//usage:        IF_FEATURE_IP_TUNNEL("\n"
 315//usage:        "ip tunnel "iptunnel_trivial_usage)
 316//usage:        IF_FEATURE_IP_NEIGH("\n"
 317//usage:        "ip neigh "ipneigh_trivial_usage)
 318//usage:        IF_FEATURE_IP_RULE("\n"
 319//usage:        "ip rule "iprule_trivial_usage)
 320
 321#include "libbb.h"
 322
 323#include "libiproute/utils.h"
 324#include "libiproute/ip_common.h"
 325
 326typedef int FAST_FUNC (*ip_func_ptr_t)(char**);
 327
 328#if ENABLE_IPADDR \
 329 || ENABLE_IPLINK \
 330 || ENABLE_IPROUTE \
 331 || ENABLE_IPRULE \
 332 || ENABLE_IPTUNNEL \
 333 || ENABLE_IPNEIGH
 334static int ip_do(ip_func_ptr_t ip_func, char **argv)
 335{
 336        argv = ip_parse_common_args(argv + 1);
 337        return ip_func(argv);
 338}
 339#endif
 340
 341#if ENABLE_IPADDR
 342int ipaddr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 343int ipaddr_main(int argc UNUSED_PARAM, char **argv)
 344{
 345        return ip_do(do_ipaddr, argv);
 346}
 347#endif
 348#if ENABLE_IPLINK
 349int iplink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 350int iplink_main(int argc UNUSED_PARAM, char **argv)
 351{
 352        return ip_do(do_iplink, argv);
 353}
 354#endif
 355#if ENABLE_IPROUTE
 356int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 357int iproute_main(int argc UNUSED_PARAM, char **argv)
 358{
 359        return ip_do(do_iproute, argv);
 360}
 361#endif
 362#if ENABLE_IPRULE
 363int iprule_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 364int iprule_main(int argc UNUSED_PARAM, char **argv)
 365{
 366        return ip_do(do_iprule, argv);
 367}
 368#endif
 369#if ENABLE_IPTUNNEL
 370int iptunnel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 371int iptunnel_main(int argc UNUSED_PARAM, char **argv)
 372{
 373        return ip_do(do_iptunnel, argv);
 374}
 375#endif
 376#if ENABLE_IPNEIGH
 377int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 378int ipneigh_main(int argc UNUSED_PARAM, char **argv)
 379{
 380        return ip_do(do_ipneigh, argv);
 381}
 382#endif
 383
 384#if ENABLE_IP
 385static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM)
 386{
 387        bb_show_usage();
 388}
 389
 390int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 391int ip_main(int argc UNUSED_PARAM, char **argv)
 392{
 393        static const char keywords[] ALIGN1 = ""
 394                IF_FEATURE_IP_ADDRESS("address\0")
 395                IF_FEATURE_IP_ROUTE("route\0")
 396                IF_FEATURE_IP_ROUTE("r\0")
 397                IF_FEATURE_IP_LINK("link\0")
 398                IF_FEATURE_IP_TUNNEL("tunnel\0")
 399                IF_FEATURE_IP_TUNNEL("tunl\0")
 400                IF_FEATURE_IP_RULE("rule\0")
 401                IF_FEATURE_IP_NEIGH("neigh\0")
 402                ;
 403        static const ip_func_ptr_t ip_func_ptrs[] ALIGN_PTR = {
 404                ip_print_help,
 405                IF_FEATURE_IP_ADDRESS(do_ipaddr,)
 406                IF_FEATURE_IP_ROUTE(do_iproute,)
 407                IF_FEATURE_IP_ROUTE(do_iproute,)
 408                IF_FEATURE_IP_LINK(do_iplink,)
 409                IF_FEATURE_IP_TUNNEL(do_iptunnel,)
 410                IF_FEATURE_IP_TUNNEL(do_iptunnel,)
 411                IF_FEATURE_IP_RULE(do_iprule,)
 412                IF_FEATURE_IP_NEIGH(do_ipneigh,)
 413        };
 414        ip_func_ptr_t ip_func;
 415        int key;
 416
 417        argv = ip_parse_common_args(argv + 1);
 418        if (ARRAY_SIZE(ip_func_ptrs) > 1 && *argv)
 419                key = index_in_substrings(keywords, *argv++);
 420        else
 421                key = -1;
 422        ip_func = ip_func_ptrs[key + 1];
 423
 424        return ip_func(argv);
 425}
 426#endif
 427